Ryan Perez · Motion system

Motion that explains.

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 formula Trigger + 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 audit See the model Disabled — no lift
1px hover lift, 0.98 pressed scale, no transform when disabled
Links
The Friction Audit, explained Underline that retracts instead
Animated underline only where it doesn't delay recognising the link
Cards
Interactive — lifts 4px The whole card is one destination
Informational — stays put Nothing to click, so nothing moves
Never animate a static card like a clickable one
Icons that change state
Chevron Refreshing
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 booked Enter 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.
{{ d.a }} {{ d.arrow }} {{ d.b }}
Escalation

Nine LAKA motion levels

{{ l.a }}{{ l.b }}
{{ e.t }}
Hard rules

Never, and always

{{ h.k }} {{ h.t }}
Approval test — all must pass
{{ a.t }}