Foundations
Motion
Sidelay animations live in packages/ui/tokens.css as duration and easing tokens, and are driven by Motion (formerly Framer Motion) — the React component-level animation library. CSS-only animations remain available via tw-animate-css, page transitions via next-view-transitions.
Durations
Five steps from instant (focus rings, micro-feedback) to slower (page transitions). Default is --duration-base (180ms).
Instant
60ms--duration-instantFocus rings, hover dots, atomic feedback.
Fast
120ms--duration-fastButtons, small UI state changes.
Base
180ms--duration-baseDefault for nearly everything.
Slow
280ms--duration-slowModals, popovers entering.
Slower
480ms--duration-slowerFull-page transitions, hero reveals.
Easings
Five curves. All five demos run at --duration-slow (280ms) so the difference is in the shape of the motion, not its length.
Linear
280ms--ease-linearConstant speed. Use only for progress meters and continuous loops.
Ease in
280ms--ease-inAccelerates. Use for things leaving the screen.
Ease out
280ms--ease-outDecelerates. The default for things entering.
Ease in-out
280ms--ease-in-outSymmetric. Use when an element changes its mind mid-transition.
Spring (overshoot)
280ms--ease-springSlight overshoot. Use sparingly, for delightful confirmation moments.
Spring physics
Motion's spring system simulates physical springs (stiffness + damping) instead of a fixed duration. Drag the ball below — it releases and snaps back with momentum. Use spring for drag, flick, and elastic feedback; stick to cubic-bezier durations everywhere else.
Drag me
Reduced motion
Motion exposes useReducedMotion(), which mirrors the OS-level prefers-reduced-motion media query. When set, the demos on this page snap to their end state with no animation. Mirror this pattern in every component: animations are optional, content is not.
Reduced motion is OFF. Toggle System Settings → Accessibility → Display → Reduce motion to see the page fall back to no-animation behaviour.