Motion
Motion shows what changed, where it came from, and where it went. In Wolf-Rayet motion also uses attention. So how much something may move depends on its attention level.
Principles
Purposeful. Motion explains a change. If people would lose nothing without it, remove it.
Limited. Movement draws the eye, so it is budgeted like colour. Each attention level has a longest duration it may use. Only Demanded elements may keep moving.
Accessible. When a reader asks for reduced motion, every change shortens to 110ms and repeating motion slows or stops. Nothing flashes, and nothing sweeps across the screen.
Fast. Nothing waits for an animation to finish. Exits are quicker than entrances, so something you dismiss never gets in the way.
Duration
How long a change takes. Short for things people do often, longer for things that are rarer and larger.
| Token | Value | Use for |
|---|---|---|
| --wr-duration-0 | 80ms | Hover and press feedback that happens many times a minute. |
| --wr-duration-1 | 110ms | Small entrances and exits. The longest duration Ambient may use. |
| --wr-duration-2 | 155ms | Popups, menus and state changes that should be noticed. |
| --wr-duration-3 | 220ms | Drawers and larger surfaces arriving on screen. |
| --wr-duration-4 | 305ms | The longest a single change may take. Only for Demanded elements. |
| --wr-duration-5 | 430ms | Longer than any level allows. Components do not use it. |
Easing
How a change speeds up and slows down. Choose the curve by what the element is doing.
| Token | Curve | Use for |
|---|---|---|
| --wr-easing-enter | cubic-bezier(0, 0, 0.2, 1) | Things arriving. Fast start, soft landing. |
| --wr-easing-exit | cubic-bezier(0.4, 0, 1, 1) | Things leaving. Slow start, then fast. |
| --wr-easing-standard | cubic-bezier(0.2, 0, 0, 1) | Things that change in place, like a colour or a size. |
| --wr-easing-emphasized | cubic-bezier(0.05, 0.7, 0.1, 1) | A demand arriving. Used sparingly. |
| --wr-easing-linear | cubic-bezier(0, 0, 1, 1) | Loops, like a spinner, where no moment matters more than another. |
Properties
What changes. Pick one, or two at most.
Motion by attention level
What each level may do, and the longest duration it may use. A component declares its level and takes its motion limits from it.
| Level | May | Longest |
|---|---|---|
| 0 · Substrate | Nothing. The page itself does not move. | 0ms |
| 1 · Ambient | Enter and exit. | 110ms |
| 2 · Marked | Enter, exit, and change state. | 155ms |
| 3 · Directed | Also arrive: move across the screen to draw the eye. | 220ms |
| 4 · Demanded | Also keep moving until someone responds. | 305ms |
A spinner or a loading bar repeats because work is still running, not because it wants attention. Loops use the period tokens, --wr-period-0 to --wr-period-4, and never repeat faster than once every 800ms. Under reduced motion they slow to once every 3 seconds or stop.
Component tokens
Every component with a token record has its own motion tokens. Use these first.
| Token | What it is |
|---|---|
| --wr-<component>-transition-duration | The longest duration the component's level allows. |
| --wr-<component>-transition-easing | The easing curve set in its token record. |
| --wr-<component>-sustained-duration | Only on components that may keep moving while they demand attention. |
A build check reads every stylesheet. A component with a token record must use its own motion tokens. No stylesheet may use a raw duration or curve.
Best practices
Do
Don't
Do
Don't
Accessibility
Reduced motion is handled by the tokens, not by each component. When the setting is on, every level's longest duration becomes 110ms and loops slow down, so a component that uses its own tokens is covered without writing anything. Check every screen with the setting on, and make sure it still works with no motion at all.