Foundations
Motion
One motion grammar: a short duration vocabulary, a small set of easings, and a reduced-motion answer for every animation. No component invents its own timing.
Durations
Five values, chosen by what the user is tracking — not by how impressive the effect looks.
motion.instant70msState echo: pressed feedback, hover tint.motion.fast140msDefault for colour, border and opacity changes.motion.normal200msFunctional movement: tabs, popovers, tooltips.motion.slow300msLarger surfaces entering: menus, dialogs, reveals.motion.slower460msRare: page-level reveals and chart entrance.Easing
Press play and watch the same distance covered with different curves.
ease.standard
300ms · cubic-bezier(0.2, 0, 0, 1)ease.enter
300ms · cubic-bezier(0.16, 1, 0.3, 1)ease.exit
300ms · cubic-bezier(0.4, 0, 1, 1)ease.emphasized
300ms · cubic-bezier(0.3, 0.85, 0.15, 1)ease.overshoot
300ms · cubic-bezier(0.34, 1.32, 0.64, 1)Tiers
Motion is budgeted by tier. Tier 3 has no place in a dashboard.
| Tier | Name | Budget | Examples | Rule |
|---|---|---|---|---|
1 | Functional | 140–220ms | Tabs, tooltip, popover, dialog, switch, sidebar. | Fast, precise, predictable. Never removed — only shortened under reduced motion. |
2 | Micro delight | 180–480ms | BorderGlow sweep, shine, hover lift, number ticker, shimmer, spotlight. | At most one per view. Must degrade to a static state with no loss of meaning. |
3 | Atmospheric | 2s+ | Hero backgrounds, report covers, special AI surfaces. | Landing pages and reports only. Never inside dense application UI. |
Reduced motion
Every animation in Luc UI has a stated fallback. Use the “Motion auto / Reduced” control in the top bar to review both paths live.
Current mode
full70ms140ms200ms300ms460ms
A traveling highlight stops traveling but still marks the element. A number ticker jumps to its value. A dialog fades. Nothing that carries meaning is deleted.
How it is implemented
styles/base.cssclamps every animation and transition to ~0ms underprefers-reduced-motion.- Elements marked
data-motion-essential(spinner, live dot) keep a slow pulse so the indicator still means “working”. - Behavioural animation (ticker, reveal, BorderGlow travel) calls
useReducedMotion()and takes a static path.
Rules
Do
- Animate transform and opacity; avoid animating layout properties.
- Make exits shorter than entrances.
- Use
luc-transitionso timing stays in one place.
Don't
- Spring-overshoot a professional surface.
- Animate something that is not a response to a user action.
- Use motion to hide a slow data load.