# Motion & Micro-interactions

Applies the motion tokens from `02-design-tokens.md` and the "purposeful, never decorative" rule from `01-design-principles.md` #5. Every entry below exists because it communicates a state change — if a future addition can't name what it communicates, it doesn't belong here.

## General rules

- **Duration:** `motion.duration.fast` (120ms) for small, frequent interactions (hover, button press). `motion.duration.default` (180ms) for most transitions (a card appearing, a panel opening). `motion.duration.slow` (240ms) only for larger surface changes (a modal, a page-level transition). Nothing in the product animates slower than 240ms — anything that would need to is a sign the interaction should be instant instead.
- **Easing:** `motion.easing.default` (ease-out) everywhere. Ease-out (fast start, gentle finish) reads as responsive and confident; ease-in or linear motion reads as sluggish. No spring/bounce easing anywhere, per `01-design-principles.md`.
- **Reduced motion:** every animation listed here must have a `prefers-reduced-motion` fallback that replaces it with an instant state change — motion is a communication aid, never a required carrier of information.

## Specific micro-interactions

| Interaction | Motion | Communicates |
|---|---|---|
| Button press | Background opacity shifts over `fast` | The click registered |
| Suggestion card dismissed (`../ux/03-ux-patterns-and-conventions.md` rule 1) | Card fades and collapses its height over `default` | "This was handled" — reinforces that dismissing is a real, final action, not a no-op |
| Suggestion card accepted | Brief `color.success.500` flash on the action button before the card resolves (fades to its next state, e.g. becomes a confirmed campaign) over `default` | Confirmation the action succeeded, before the merchant navigates away |
| Form field saved (inline edit) | A small checkmark fades in beside the field over `fast`, then fades out after ~1.5s | "Saved" without an intrusive toast for low-stakes edits |
| Toast / confirmation banner (for actions from `../ux/03-ux-patterns-and-conventions.md` rule 3's "confirmation required" list) | Slides in from the top over `default`, auto-dismisses after ~4s or on manual dismiss | A money-impacting or irreversible action completed |
| Modal open/close | Backdrop fades over `default`; modal itself fades and scales from 98% to 100% over `default` | Focus has shifted to a new, temporary context |
| Page/section navigation | No transition animation — instant | Per `01-design-principles.md` rule 8: navigating is the most frequent interaction in the product; animating it would slow down exactly the action that most needs to feel fast |
| Empty state illustration/icon (`../ux/03-ux-patterns-and-conventions.md` rule 2) | Static, no animation | Decorative motion on a screen the merchant may sit on while deciding what to do next would violate the "purposeful only" rule |
| Loading state | A static skeleton (neutral-toned placeholder shapes matching the eventual content's layout), not a spinner, for anything taking longer than ~300ms | What kind of content is coming, and roughly how much of it — a spinner communicates only "wait," a skeleton communicates "wait, and here's the shape of what you'll see" |

## What deliberately has no motion

Hover states on table rows and nav items (`03-component-conventions.md`) are instant background-color changes, not transitions — at the density these appear (many rows, frequent mouse movement), animating every hover would read as visual noise rather than polish, directly violating `01-design-principles.md` rule 5's removal test.
