How it works
A finite state machine drives variants; `layout` smooths the width change; the check mark is drawn with pathLength.
idle → loading → success / error. Width, icon and colour morph as one continuous object.
A finite state machine drives variants; `layout` smooths the width change; the check mark is drawn with pathLength.
Width change is layout-animated (transform + scale correction), not animated `width`.
aria-live="polite" announces each state; the button is aria-disabled while busy.
transition={{ type: 'spring', stiffness: 400, damping: 30, mass: 1 }}