diff --git a/docs/uiux/reduced-motion-fallback-spec.md b/docs/uiux/reduced-motion-fallback-spec.md new file mode 100644 index 0000000..00c6bd7 --- /dev/null +++ b/docs/uiux/reduced-motion-fallback-spec.md @@ -0,0 +1,59 @@ +# Reduced-Motion Fallback Specification + +## Document Metadata + +- Owner: UX Design and Research +- Partners: Engineering, Accessibility QA +- Status: Implemented — companion to `motion-reduced-motion-policy.md` +- Scope: Every animated component in the dashboard, its default motion, and its `prefers-reduced-motion` fallback +- WCAG baseline: WCAG 2.1 AA (Success Criterion 2.3.3 — Animation from Interactions) + +## Purpose + +`motion-reduced-motion-policy.md` defines the component-agnostic motion system. This document is the +**per-component specification**: it lists every animated component, classifies its reduced-motion +fallback as one of three predictable behaviors, and pins the implementation details so behavior is +reviewable and testable. + +## Fallback classification + +| Classification | Meaning | +| --- | --- | +| **Fade-only** | Any translate/scale path is removed; only opacity animates, capped at `--motion-duration-xs` (80 ms) | +| **No motion** | All transition/animation properties are removed (`transition: none` / `animation: none`); state changes are instant | +| **Dampened** | Duration shortened and amplitude reduced, but a (usually single-axis, opacity-only) transition remains | + +## Per-component fallback table + +| Component | File(s) | Default motion | Reduced-motion fallback | Classification | +| --- | --- | --- | --- | --- | +| Toast | `src/components/ToastItem.tsx`, `src/index.css` (`.toast-entering`, `.toast-exiting`) | Enter: slide + scale + fade (`toast-enter`, `--motion-duration-lg`). Exit: slide + fade (`toast-exit`, `--motion-duration-sm`). JS auto-dismiss 300 ms enter / 200 ms exit timers | `@keyframes` redefined to opacity-only; `.toast-entering`/`.toast-exiting` run at `--motion-duration-xs`. JS timers honour `useReducedMotion()` (80 ms both phases) | Fade-only | +| Modal | `src/index.css` (`.modal-backdrop`, `.modal-dialog`, `modal-in`) | Backdrop: fade in. Dialog: fade + scale (0.98 → 1) at `--motion-duration-md` | `modal-in` collapses to opacity-only at `--motion-duration-xs` | Fade-only | +| Drawer (audit log) | `src/components/audit-log/AuditLogDetailDrawer.tsx` (`auditDrawerIn`, `auditDrawerBackdropIn`) | Slide from right (`--motion-duration-lg`) + backdrop fade (`--motion-duration-md`) | In-component `