Motion specimen
Seven decisions, and everything that follows from them.
Any one animation is easy. Making a whole product’s worth feel consistent is the hard part, and this page is the system ours come from. Everything below runs on the real spring engine with the real values, so what you see is what the product does.
Five springs, and only one of them bounces
Four sit at a damping ratio between 0.74 and 0.92 and differ only in speed; bouncy is the one that leaves that line. So the choice is 'how fast', and then separately 'does this one overshoot' — the same two questions the editor's spring pad asks, which is not a coincidence. These are the editor's own preset buttons: there is one vocabulary in this product, not two.
Deliberate and heavy. Rare enough that using it is a statement.
Large surfaces that should feel unhurried rather than slow.
The default. Overlays, panels, most entrances.
Small controls that should feel mechanical — a switch, an indicator.
The only one with visible overshoot. Toasts, badges, arrivals.
Five durations — and they govern tweens, not springs
This is the decision that surprised me building it. A spring has no duration: it runs until it rests, and how long that takes falls out of stiffness, damping and distance. So this scale governs TWEENS only — opacity, color, anything eased — while a spring's length is derived from the spring. Conflating them has a visible symptom: give a spring a duration shorter than its settle time and the exporter can no longer emit a native spring, so you get a hundred sampled numbers instead of one line.
Five distances. Never an arbitrary 23
Two entrances that travel 16px and 23px look like two people worked on them. The top of the scale is deliberately modest — nothing in an interface needs to travel 120px to say it arrived; that reads as a page transition, which is a different statement.
Opacity leads transform
A thing is fully visible before it has finished arriving, so you read it while it settles rather than watching a ghost slide into place. Left: the fade finishes at 220ms while the spring runs on. Right: both locked to the same length, which is what it looks like when nobody decided.
An exit is the entrance, faster and shorter
Leaving is not a performance — the user has already decided. Reversing an entrance at the same speed makes dismissing something feel like it is arguing with you. So an exit takes the next stiffer spring and travels 60% of the distance.
Stagger is 60, 100 or 160ms — and the step must be even
Not a style rule, an export rule. An even step is what collapses into staggerChildren: one number that any number of children inherit. An uneven step exports as N separate animations, which is longer and worse code. These are the same three values the editor's multi-select control offers.
Emphasis returns, so its return is a tween
A nudge in scale that comes back. The push out uses the spring; the return does not — a spring returning to where it started overshoots past it and reads as a wobble rather than as attention. One rule, and it is the sort of thing only becomes obvious next to the version that gets it wrong.
Everything on this page is generated from the same values the product uses. Change one and this page changes with it, and so do the twelve animated components at /components, which are built on them.