Motion
LAW — locked, CI-gatedMotion
Section titled “Motion”principle. motion is feedback, not decoration. every animation names its purpose in one word — feedback, spatial consistency, state indication, jarring-change prevention, explanation, delight — or it is not built. delight is a budget spent only on rare, first-time moments. data the user is reading never moves for style.
rule (law; resolved values normative in docs/foundations/motion-annex.md, whose named curves are the token core’s easing tokens by decision 0015).
- the gate. frequency decides: actions fired 100+ times a day (keyboard shortcuts, command-palette toggles) never animate; tens a day (hover, list navigation) get instant feedback or at most 150ms on opacity/background only; occasional surfaces (modals, drawers, toasts) take standard motion; rare and first-time surfaces hold the delight budget.
- Distira’s own register, from the token core: flyout 180ms grow-from-anchor plus fade; canvas glide 200ms; chip press 100ms tint pulse; exit at roughly two-thirds of enter; everything else instant.
- press feedback: scale 0.96 over 150ms ease-out. disabled controls never scale. a static opt-out exists where motion would distract.
- entrances never start at scale(0). trigger-anchored popovers, dropdowns, and menus start at 0.95; modals at 0.96; tooltips at 0.97 — each with opacity from 0, and the transform origin at the trigger (modals exempt; they stay centred).
- easing tokens: ease-out
cubic-bezier(0.23, 1, 0.32, 1)is the one strong curve for entrances and exits; the drawer curvecubic-bezier(0.32, 0.72, 0, 1)for sheets and drawers; ease-in-outcubic-bezier(0.77, 0, 0.175, 1)for on-screen movement. never ease-in on interface elements. durations: interface motion under 300ms (drawers up to 500ms on the drawer curve only); exits 150ms ease-out; toasts 250ms ease-out, their character carried by travel distance, not duration. - stagger, by scope, one number each: staged semantic entrances 100ms; intra-list item entrances 50ms; word-by-word headline entrances 80ms, on first-run and explanatory surfaces only. stagger never applies to routine interactions and never blocks interaction while it plays.
- springs are named tokens — glide, snap, settle — reserved for gestures and the flourish layer, near critically damped: the gesture settle resolves as a spring of duration 0.5 with bounce 0.2; bounce lives only in 0.1–0.3, only for drag-to-dismiss and rare-tier play; icon cross-fades take a spring of duration 0.3 with bounce always 0, or the 300ms ease-out token. (pinning each named preset’s constants in the token file is the token core’s remaining motion gap, with the annex values as the resolved starting set.)
- properties: animate transform and opacity only; clip-path is the sanctioned fourth property for scrims, reveals, and holds-to-confirm. the one layout exception is accordion height, capped at 200ms, measured, never to
auto. transitions, not keyframes, for anything fireable twice a second; every animation is interruptible and reverses from its current state. - hold-to-confirm asymmetry: the deliberate phase is 2s linear. progress fills don’t ease, because an eased fill makes the wait look shorter than it is. the release answers in 200ms ease-out.
- theme switches suppress all transitions for a frame; a theme change is not a motion moment.
rule — reduced motion and motion-off (law). reduced-motion gating ships with the animation, never as a follow-up. under the operating system’s reduced-motion setting, movement, scale, and blur collapse to an opacity cross-fade; nothing is removed instantly, and comprehension aids stay. Distira’s own motion-off is stronger and absolute: everything freezes, every tier, including the delight tier; state changes become instant, and the static cue (colour, icon, label) that every animated change must also leave carries the full meaning.
worked example. the popover opens: 180ms, growing from the tray icon that summoned it, starting at 0.95 scale with its origin at the anchor, on the ease-out token. a chip inside it, pressed, answers in two registers at once: the 100ms tint pulse (the register) and the 0.96 scale over 150ms (press feedback). dismiss it and the exit runs shorter than the enter, back along the path it came. with motion-off set, all of it becomes instant state changes and nothing is lost: every state has its static cue.
the register, moving
Section titled “the register, moving”Four specimens, one per entry in the register. The loops stretch time to stay watchable (a three-second cycle), and each label carries the true numbers, read from the token source. Set reduced motion at the system level and the specimens freeze, and a note replaces them: the static cue carries the meaning, as the law below requires of every surface.
flyout
reduced motion is on: this specimen holds still. the state change is instant, and its static cue — colour, icon, label — carries the meaning.
glide
reduced motion is on: this specimen holds still. the state change is instant, and its static cue — colour, icon, label — carries the meaning.
press
reduced motion is on: this specimen holds still. the state change is instant, and its static cue — colour, icon, label — carries the meaning.
exit
reduced motion is on: this specimen holds still. the state change is instant, and its static cue — colour, icon, label — carries the meaning.
Canonical text: §6, motion, in the design language document; resolved values in docs/foundations/motion-annex.md; governed by decision 0015.