Although this sounds flippant, the design process is where unknowns should be uncovered. It is easier to change design before a line of code is written.
Design is precisely what is needed in order for the dev team to break down the projects into tiny chunks where nothing is unknown.
Your time estimates should always include time for research and design. The customer can sign off on what you're about to write at the end of that (whereas beforehand you give them a wild ballpark figure made by senior devs - not management!)
Yeah but too many customers change their mind even after they've signed off. Then you're left with strictly enforcing a contract or making adaptations.
You're right, design is very very necessary and should be given plenty of time. But it's not a magic bullet.
In terms of contract, I have found this works best (recommended by my lawyer (a former ASF lawyer)): 30% upfront, 50% at first delivery, then they have 2 months to find bugs, final delivery is when the bugs are fixed that's when you take the last 20%. This way, you're certain to always get 80%.
If they want the liberty to "change their mind on the fly" then they should buy man-days which is a completely other thing. Or, they can buy supplementary mandays for whatever they want at the daily rate without changing the contract, or, they can just wait to finish this contract and start another one.
Your time estimates should always include time for research and design. The customer can sign off on what you're about to write at the end of that (whereas beforehand you give them a wild ballpark figure made by senior devs - not management!)