Submit button

Loading feedback should feel like one continuous state change, not three separate UI swaps. Click the button: the label yields to a spinner, the spinner settles into a green checkmark, then the control soft-resets so you can try it again.

The timings are deliberate — about 1.2s of loading so the spinner is readable, then a short hold on success before returning to idle. Reduced-motion users get a quick crossfade between states instead of the spin and check draw.