Motion

Movement should feel like the interface is already running, and the user just caught up to it. Fast, confident, out of the way. Never decorative.

Durations

Four speeds

Pick by scale: small elements move fast, big elements move slow. Hover the bar to see the relative length.

Token
Value
Use for
Relative
--dur-xs
100ms
Hover state, press feedback, color change
--dur-sm
200ms
Small movements: chip select, toggle, icon swap
--dur-md
320ms
Panels, drawers, modal enter
--dur-lg
520ms
Page transitions, onboarding moves, celebratory states
Easings

Six curves

Hover any card to play the animation. Standard is the default — only reach for the others when the motion wants to say something specific.

Standard
The default. Moving in one direction.
cubic-bezier(0.2, 0, 0, 1)
Emphasized
Anything the user initiated directly.
cubic-bezier(0.3, 0.7, 0, 1)
Accelerate
Exits. Something leaving the screen.
cubic-bezier(0.4, 0, 1, 1)
Decelerate
Entrances. Something arriving.
cubic-bezier(0, 0, 0.2, 1)
Spring
Rare. Celebratory success states only.
cubic-bezier(0.34, 1.56, 0.64, 1)
Linear
Progress bars, loading, anything time-bound.
linear
Principles

How we move

01

Fast on exit, slower on entrance.

A modal opens in 320ms · closes in 200ms. The user's already moved on — don't make them wait for the curtain.

02

Never animate opacity alone.

Something that just fades in feels ghostly. Add a short translate (4–8px) so the motion reads as a move, not a reveal.

03

Stagger by 40ms, never more.

When multiple elements enter together, offset them slightly so the eye can follow. Longer and the sequence feels slow.

04

Respect reduced motion.

Under prefers-reduced-motion, swap every transition for a crossfade at 80ms. No translates, no springs.