⚠️ Design system CSS not found. Check the path in cms/docs.config.js → designSystemPath, then re-run npm run docgen.

Motion

Four easings, a duration scale, and the page tokens on top

Website / Motion
Download .md file
Open .md in new tab
On this page
  • Easing
  • Duration
  • Page transitions
  • Naming a new semantic token
  • Reduced motion
  • Rules

Motion is two primitive scales with a thin semantic layer on top. Easings say how a movement is shaped, durations say how long it takes, and the --motion-page-* tokens combine the two for the transitions between pages. Nothing on the site should reach for a raw cubic-bezier or a millisecond value.

Easing

Four curves, each with a job. The difference between them is where the movement spends its time.

Token Curve Use
cubic-bezier(0.4, 0, 1, 1) Exits. Slow start, accelerating away — the element leaves under its own steam
cubic-bezier(0.16, 1, 0.3, 1) Entrances. Fast start with a long tail, so the element arrives and settles
cubic-bezier(0.65, 0, 0.35, 1) Swaps and anything continuous. Symmetric, so it reads as one sweep
cubic-bezier(0.86, 0, 0.07, 1) Large layout shifts that should feel decisive. Near-still at both ends, fast through the middle

ease-in

ease-out

ease-in-out

emphasized

transition-timing-function: var(--ease-out);

Duration

The same t-shirt steps as spacing and type, so the vocabulary carries across.

Token Value Use Token Value Use
100ms Hovers and presses 1800ms Long entrances
200ms Toasts, focus, button state 2000ms Orchestrated sequences
400ms Dropdowns, expanding rows 2500ms Cinematic sequences
600ms Drawers, dialogs, page fades 3000ms Ambient loops
800ms Full-area entrances 4000ms Background motion
1200ms Hero motion and page transitions 6000ms The slowest step available
1500ms Extended reveals 30ms A per-item delay step, not a duration

2xs · 100ms

xs · 200ms

s · 400ms

m · 600ms

l · 800ms

xl · 1200ms

Page transitions

The semantic layer is small on purpose: today its only consumer is the page transition between documents, which the docs kit drives.

Token Resolves to Governs
· -easing · A page arriving
· -easing · A page leaving
· -easing · One container replacing another
· -easing · The cross-fade inside a swap

Open, close and swap all resolve to --duration-xl, so a navigation takes about 1.2 seconds end to end; the fade is --duration-m, 600ms. All four easings are --ease-in-out. These are engine defaults, deliberately untouched. They are :root tokens, so assets/css/theme.css can re-point them directly if the tempo should be brisker — the kit's wiring is inherited unchanged.

Naming a new semantic token

Semantic motion tokens follow a three-slot grammar, so a new one has a name before it has a value.

Slot Values
Scope page · surface · element · feedback — how much of the screen the motion covers
Event open · close · swap · enter · exit · fade · hover · press
Property duration or easing, always the last slot

So --motion-surface-enter-duration is legible before anyone looks it up, and that is the point of the grammar.

Reduced motion

The engine ships no global reset. There is no * rule zeroing every duration — instead each component carries its own @media (prefers-reduced-motion: reduce) block (thirteen of them in design-system.css), and assets/docs-kit/barba-docs.js checks matchMedia before it animates a page transition. Anything new has to do the same; nothing will do it on your behalf.

@media (prefers-reduced-motion: reduce) {
  .thing { animation: none; }
}
  • Every animation must survive being switched off. A reader with reduced motion set should still reach the same end state; if turning the motion off loses information, the motion was carrying meaning it should not have been.
  • Write the guard with the animation, not afterwards. There is no global net to fall back on, so an animation shipped without one simply ignores the preference.

The two demos on this page stop when reduced motion is set, which a page about motion is the last place to get wrong.

Rules

  • Never write a raw cubic-bezier or a millisecond value. Both scales exist so that motion across the site stays recognisably one system.
  • Match the curve to the direction. Entrances take --ease-out, exits take --ease-in; swapping them makes an element look like it is fighting the interaction.
  • Reach for a semantic token before a primitive. If a new kind of motion needs one and none exists, the semantic layer is missing a token — the fix is upstream, not a local millisecond.
On this page
  • Easing
  • Duration
  • Page transitions
  • Naming a new semantic token
  • Reduced motion
  • Rules
Previous Layout
Next Iconography

© 2026 BlackDoctor