Brik Design System
Foundation

Motion

Duration and easing tokens — reach for the semantic aliases, and know that the numeric suffix is a step index rather than a millisecond value.

Motion tokens define how long a transition runs and how it accelerates. Three semantic duration aliases cover almost every case; the numeric primitives underneath them exist for the rare long-running animation.

The numeric suffix is a step index, not a millisecond value. --duration-400 is 500ms, not 400ms. The suffix tracks milliseconds up to --duration-300 and then stops. Reach for --duration-sm / --duration-md / --duration-lg instead — they name the intent and cannot be misread.

Semantic durations

The default choice. These carry the overwhelming majority of motion in BDS, and every component CSS file should reach for one of them first.

TokenResolves toUse case
--bds-duration-sm100msMicro-interactions — hover, focus
--bds-duration-md200msStandard transitions — buttons, cards
--bds-duration-lg300msEmphasis — modals, sheets, reveals
--bds-duration-xl500msCross-fades, long reveals — one rung past --bds-duration-lg

Defined in tokens/gap-fills.css as aliases of the numeric primitives below. The step words follow the t-shirt ramp per ADR-033 § 3; the legacy fast / normal / slow are sm / md / lg grandfathered pending rename.

Periodic durations

A separate class from the transition tier above. These are not tween lengths — they are the period of a continuous loop or the dwell before a timed advance, so they live in seconds and carry a role name rather than a step (ADR-033 § Named exceptions, the same basis as --shadow-overlay). Reach for the semantic durations for any tween; only continuous or auto-advancing motion uses these.

TokenValueUse case
--bds-duration-marquee55sFull marquee loop period — logo tickers, continuous scroll
--bds-duration-autoplay10sDwell before auto-advance — carousels, media tabs

Defined in tokens/gap-fills.css. Measured from inspiration teardowns; re-run the Playwright capture before treating a value as canon later — vendor sites drift.

Numeric durations

The underlying primitive scale, generated from Figma. Use one of these only when no semantic alias fits — a long-running progress animation, for example.

TokenValueSuffix matches value
--bds-duration-100100msyes
--bds-duration-200200msyes
--bds-duration-300300msyes
--bds-duration-400500msno
--bds-duration-500800msno
--bds-duration-6001000msno

The break at --duration-400 is the trap: it reads as 400ms and resolves to 500ms, so an animation lands 25% slower than intended and nothing errors. If you are reaching past --duration-300, read the value rather than the name.

Easing

Four curves, each with a distinct job. Pair --ease-out with most UI transitions — deceleration reads as responsive because the motion starts fast.

TokenValueUse case
--bds-ease-outcubic-bezier(0.16, 1, 0.3, 1)Decelerate — most UI transitions
--bds-ease-incubic-bezier(0.7, 0, 0.84, 0)Accelerate — exits, collapses
--bds-ease-in-outcubic-bezier(0.65, 0, 0.35, 1)Symmetric — looping, continuous
--bds-ease-springcubic-bezier(0.34, 1.56, 0.64, 1)Overshoot bounce — pop-in, badge appear
--bds-ease-spring-softcubic-bezier(0, 1.08, 0.77, 1.01)Gentle overshoot settle — media/panel entrance (softer than --bds-ease-spring)
--bds-ease-linearlinearConstant velocity — marquees, continuous loops

Defined alongside the semantic durations in tokens/gap-fills.css.

Reach for --ease-out / --ease-in for ordinary decelerate / accelerate needs — there is deliberately no separate --ease-decel / --ease-accel. --ease-spring-soft is the one exception the house curves did not already cover: a settle that overshoots just past its target without the visible bounce of --ease-spring.

Stagger

Fixed offsets for sequencing a group of elements into view — apply an increasing stagger as animation-delay across siblings.

TokenValue
--stagger-10ms
--stagger-250ms
--stagger-3100ms
--stagger-4150ms
--stagger-5200ms
--stagger-6250ms

Stagger tokens ship in dist/bridge.css, not dist/tokens.css. They sit outside the canonical token registry, so a consumer that imports only the token bundle will not have them.

Where these live

Motion tokens are authored in three different places, which matters when you need to change one.

Token groupSourceEditable
--bds-duration-100 … --bds-duration-600Figma → design-tokens/tokens-studio.json → tokens/figma-tokens.cssFigma only — the CSS is auto-generated
--bds-duration-sm / -normal / -slow, all --ease-*tokens/gap-fills.cssHand-authored
--stagger-1 … --stagger-6tokens/bridge.cssHand-authored

Ready-made utility classes built on these tokens — .bds-enter-*, .bds-anim-* — live in tokens/motion-classes.css over the keyframes in tokens/animations.css. Prefer an existing class before writing a new animation.

  • Motion — tiers, effects, and when to escalate beyond CSS
  • Interaction states — the states these transitions animate between

On this page

💬