Identity / Motion
Motion
Motion confirms that something happened. It never performs. The live site uses five durations and two curves.
01Tokens
| Token | Value | Use |
|---|---|---|
--dur-fast | 120ms | Hover, press |
--dur-base | 200ms | Card lift, menu |
--dur-slow | 420ms | Section reveal |
--ease-out | cubic-bezier(.2,.7,.2,1) | Everything entering |
--ease-in-out | cubic-bezier(.6,0,.4,1) | Panels, theme cross-fade |
--reveal-shift | 12px | Reveal travel |
--reveal-stagger | 70ms | Between siblings |
--move-press | 0.5px | Button press |
02Rules
- Nothing moves more than 12px.
- No parallax, no autoplay loops, no scroll-jacking.
- Charts and figures appear whole. Values never count up or bars never grow in, because animation implies a trend the data may not show.
- Under
prefers-reduced-motion, every duration is 0 and reveals are skipped (built into tokens.css). - Never animate the logo.
03Where motion is used
| Surface | Motion | Token |
|---|---|---|
| Button press | 0.5px translate down | --move-press + --dur-fast |
| Link card hover | 2px lift, shadow | --dur-base + --ease-out |
| Menu / theme | Panel cross-fade | --dur-base + --ease-in-out |
| Section enter | 12px rise, opacity | --reveal-shift + --dur-slow, stagger --reveal-stagger |
| Deck slides and steps | 150ms opacity fade only | Hard-coded in deck.css; removed under reduced motion |
- If a new interaction needs motion, pick from the table. Do not invent a duration.
- Deck motion is separate from site motion on purpose: projected rooms need a shorter fade and no travel.
04Do and don't
Do
A primary button darkens on press and moves 0.5px.
Confirms the click.
Live site buttons
Don’t
A hero figure floats, pulses or parallaxes as you scroll.
Performs. Distracts from the claim.
Illustrative
Do
A card lifts 2px on hover, then settles.
Shows the card is interactive.
Live link cards
Don’t
Bars grow in from zero when they enter the viewport.
Implies a trend the data may not have.
Illustrative