Motion
How transitions are timed, and how to turn them off.
Animation is part of the component, not an add-on. Every transition derives from one duration token and one of three easing curves, so a screen full of components moves as a single system.
The curves
| Curve | Value | Used for |
|---|---|---|
| standard | cubic-bezier(.4, 0, .2, 1) | Colour, opacity, small position shifts |
| decelerate | cubic-bezier(.16, 1, .3, 1) | Enters — panels, popovers, toasts |
| spring | cubic-bezier(.34, 1.56, .64, 1) | Controls that should feel physical — switch thumbs, indicators |
Scaling everything at once
:root { --hk-motion: 120ms; } /* snappier everywhere */
:root { --hk-motion: 0ms; } /* off everywhere */Reduced motion
Every component checks prefers-reduced-motion and drops to an instant state change — including things driven by JavaScript, like the count-up directive, which snaps to its final number instead of skipping the update.
If you write your own transitions on top of a component, guard them the same way. A reduced-motion user should never see a component half-animate because a wrapper kept moving.