Curve Fill Button
A hover state that paints across the control behind a curved edge instead of a straight one.
Build a button whose hover fill arrives behind a curved edge. Structure: a pill button with overflow hidden, an absolutely positioned inline SVG behind the label, and the label above it on a higher stacking layer. The sheet: one path with a BOWED leading edge and a flat trailing end, something like M 40 0 C 12 22, 12 48, 40 70 L 200 70 L 200 0 Z in a 200x70 viewBox with preserveAspectRatio="none". Animate it on x from -104% to 0 on hover, 420ms, ease [0.4, 0, 0.2, 1]. Two sizing rules that decide whether it looks finished: 1. The curve is the entire point. A straight edge sliding across is a background transition everyone already has; the bow is what makes the fill read as a wave arriving. 2. Make the sheet WIDER than the button, about 112 percent, so the flat trailing end always covers the far edge. Size it exactly and a sliver of the old background survives at the end of the sweep. The button itself must NOT move. No scale, no lift. A control that shifts under the pointer moves the target the person was aiming at, and the fill is already saying enough. Recolour the label about 100ms BEHIND the sweep, so the ink changes after the wave has passed under it rather than before it arrives. Bind the same state to FOCUS as well as hover. A hover-only fill means keyboard users get a button with no feedback at all. On exit, run the same curve back out. Snapping the fill off is the cheapest possible ending to the nicest part of the interaction. Under prefers-reduced-motion, leave the sheet parked off the control and keep the label at its resting colour. It is still a button. Colors as tokens: accent for the sheet, on-primary ink for the label while filled, your normal ink and surface tokens at rest. Build the component, not this demo of it. - Ambient motion that IS the component may loop: a drifting background, a marquee, a spinner while something is genuinely loading. - Do not add any timer, interval, loop or script that performs a person's action by itself. No auto-hover, no auto-click, no cycling through states, no pretend submitting, no replaying the interaction on a schedule. - Every state that answers a person waits for a real event from that person. - Placeholder copy and sample content are welcome. Simulated behaviour is not.