Start with immediate state feedback. Add movement only when it explains hierarchy, direction, relationship, progress or outcome. Remove it when it merely delays the interface. Every specimen below is running at its real duration and easing.
The formulaTrigger + Target + Property + Duration + Easing + Direction + Outcome
Duration
Six durations, running live
Each bar loops at its own token so the difference is felt, not read.
{{ d.token }}{{ d.ms }}{{ d.use }}
{{ r.t }}
Easing
Five curves, drawn and moving
{{ e.t }}{{ e.token }}
{{ e.use }}
No bounce or elastic easing on routine interface controls — and never during errors or destructive actions.
Magnitude
How far a thing is allowed to move
If the distance exceeds what is needed to explain the change, reduce it.
{{ m.t }}{{ m.range }}
{{ m.use }}
Priority
When two animations compete
{{ p.n }}{{ p.t }}
IF decorative motion competes with functional motion, THEN remove decorative motion.
Anatomy
Fourteen decisions per animation
If the intended outcome cannot be stated, the animation is not justified.
{{ a.a }}{{ a.b }}
Interactive feedback
Hover, press, focus — try them
80ms for the press, 150ms for hover and colour. Anything slower and the control feels broken.
Buttons
Book the auditSee the modelDisabled — no lift
1px hover lift, 0.98 pressed scale, no transform when disabled
Links
The Friction Audit, explainedUnderline that retracts instead
Animated underline only where it doesn't delay recognising the link
Cards
Interactive — lifts 4pxThe whole card is one destination
Informational — stays putNothing to click, so nothing moves
Never animate a static card like a clickable one
Icons that change state
ChevronRefreshing
Rotate on open, spin while processing — never spin a static settings icon
Enter & exit
Surfaces arriving from where they belong
{{ s.t }}{{ s.spec }}
{{ s.label }}
{{ s.d }}
{{ r.t }}
Progress & status
Loading is a promise, not a decoration
Spinner · indeterminate
Duration unknown
Nothing under ~300ms gets a spinner at all
Skeleton · predictable
Use when the structure of what's coming is known
In-button · width preserved
Scoring…
The button never changes size mid-submit
Status · once, then still
Audit bookedEnter a work email in the format name@company.ca
One restrained pop for success. Errors get words, not movement.
Stagger
Sequence, or all at once
+{{ s.ms }}{{ s.t }}
{{ r.t }}
Choreography
One primary event per viewport
Trigger→Response→Transition→Result
{{ h.a }}{{ h.b }}
More than three unrelated animations at once: group them or cut them. If decorative motion is stronger than task feedback, the hierarchy is wrong.
Jobs
Ten jobs motion can hold
An animation is allowed if it does at least one of these. If it does none, it goes.
{{ j.t }}
{{ g.n }}{{ g.t }}
{{ g.role }}
{{ r.a }}{{ r.b }}
Direction
Direction has to mean something
If movement does not communicate location, hierarchy or sequence, fade instead.