Skip to content

Motion

Motion tokens drive all animation and transition timing. Durations zero automatically under prefers-reduced-motion — every component using these tokens respects the user preference without extra media queries.

TokenValueUsage
--duration-fast150msMicro-interactions, hover states
--duration-normal250msDefault — most transitions
--duration-slow400msComplex animations, entrances
TokenValueUsage
--ease-outcubic-bezier(0.0, 0, 0.2, 1)Entrances — starts fast, slows down
--ease-incubic-bezier(0.4, 0, 1, 1)Exits — starts slow, speeds up
--ease-in-outcubic-bezier(0.4, 0, 0.2, 1)Movement between states
--ease-springcubic-bezier(0.34, 1.56, 0.64, 1)Springy overshoot — scale animations

Combine duration and easing into a single token:

TokenValue
--transition-fastvar(--duration-fast) var(--ease-out)
--transition-normalvar(--duration-normal) var(--ease-out)
--transition-slowvar(--duration-slow) var(--ease-out)
.button {
transition: background-color var(--transition-fast);
}

Durations are zeroed in tokens/_motion.scss under prefers-reduced-motion. No per-component handling needed:

@media (prefers-reduced-motion: reduce) {
:root {
--duration-fast: 0ms;
--duration-normal: 0ms;
--duration-slow: 0ms;
}
}