Audit every animated component in the design system and document its motion preset, reduced-motion behavior, and duration. Create reusable “motion recipes” that standardize common animation patterns (overlay enter/exit, accordion expand, toast slide, skeleton pulse). Fill the gap between the robust token layer in src/styles/motion.css and the undocumented per-component motion behavior. Reference ADR-002 and ADR-004 for motion governance.
Introduction
Overview
The design system defines motion tokens (--motion-instant through --motion-slow, easing curves, reduced-motion overrides) in src/styles/motion.css and applies them via Tailwind utilities (duration-fast, ease-standard, etc.). However, there is no component-level documentation of which motion preset each component uses, what happens under prefers-reduced-motion: reduce, or how long each animation actually lasts. This makes it difficult for developers to predict behavior, for designers to specify motion, and for accessibility auditors to verify compliance.
Goals
Audit all animated components and catalog their motion behavior (preset, duration, easing, reduced-motion fallback).
Create a “motion recipes” system — named, reusable CSS utility classes for common animation patterns (e.g., motion-overlay-enter, motion-accordion-expand, motion-toast-slide).
Ensure every animated component maps to a documented motion recipe.
Verify that all components degrade gracefully under prefers-reduced-motion: reduce.
Publish a Storybook docs page with an interactive motion catalog.
Non-Goals
Changing any existing animation timing (unless broken under reduced-motion).
Adding animation to components that are currently static.
Catalog every component with animation: what token it uses, what triggers it, and what reduced-motion does.
Motion recipes
Named CSS utility classes in src/styles/motion.css for overlay enter/exit, accordion expand/collapse, toast enter/exit, skeleton pulse, fade in/out, scale in/out.
Per-component documentation
Each animated component’s Storybook docs page gets a “Motion” section documenting its animation behavior.
Reduced-motion verification
Test every animated component with prefers-reduced-motion: reduce to ensure graceful degradation.
Motion catalog page
A Storybook docs page listing all motion recipes with interactive previews.
ADR-002 / ADR-004 alignment
Verify all motion choices align with existing ADR guidance.
Out of Scope
Item
Reason
New animations
Only documenting and standardizing existing motion; not adding animation to static components.
JavaScript animation libraries
CSS transitions and keyframes only; no new runtime dependencies.
Page-level transitions
Route transitions are an application concern, not a component concern.
Users and Pain Points
User
Pain Point
Developers extending components
Cannot determine which motion token a component uses without reading the source.
Designers specifying motion
No reference catalog to point to when specifying animation timing in design specs.
Accessibility auditors
Cannot verify reduced-motion compliance without manual testing of each component.
LLM agents building components
No recipe system to reference; agents pick arbitrary durations or skip animation entirely.
Definitions
Term
Definition
Motion preset
A combination of duration token, easing curve, and animation properties (e.g., opacity + transform).
Motion recipe
A named, reusable CSS class applying a specific motion preset to a specific interaction pattern (enter, exit, expand).
Reduced-motion
The prefers-reduced-motion: reduce media query, indicating the user prefers minimal animation.
Duration token
A CSS custom property from motion.css (e.g., --motion-standard: 160ms).
Easing curve
A CSS transition-timing-function or animation-timing-function (e.g., --ease-standard).
Current State
motion.css (src/styles/motion.css): Defines 6 duration tokens (instant through slow), 4 easing curves, and a prefers-reduced-motion override block that halves all durations and disables repeating animations.
Tailwind utilities: duration-fast, duration-standard, ease-standard, etc. are used in component class strings.
Existing motion utilities: .motion-control, .motion-control-emphasis, .motion-indicator, .motion-overlay-enter, .motion-toast-enter, .motion-toast-exit classes exist but are not documented.
Per-component docs: No component Storybook page documents its motion behavior.
All animations respect prefers-reduced-motion: reduce; no animation exceeds 100ms in reduced mode.
A11Y-02
No animation is the sole indicator of a state change; visual state (color, icon, position) always accompanies motion.
A11Y-03
Looping animations (skeleton pulse) stop or become static under prefers-reduced-motion: reduce.
A11Y-04
Motion catalog page includes a toggle to preview all recipes in reduced-motion mode.
Content and Documentation Requirements
ID
Requirement
DOC-01
Motion catalog Storybook page listing all recipes with live interactive previews.
DOC-02
Per-component “Motion” section in each animated component’s Storybook docs.
DOC-03
Migration guide for teams using ad-hoc inline transitions to adopt recipe classes.
DOC-04
Reference link to ADR-002 and ADR-004 from the motion catalog page.
Dependencies
Dependency
Type
Risk
src/styles/motion.css
Internal
Low — extending existing file.
ADR-002, ADR-004
Internal
Low — alignment check, no changes to ADRs.
All animated components
Internal
Medium — multiple files audited, but changes are CSS class swaps.
Risks and Tradeoffs
Risk
Likelihood
Impact
Mitigation
Recipe classes don’t cover every bespoke animation in the system
Medium
Low
Recipes cover the 80% case; edge cases document their custom behavior inline.
Refactoring to recipe classes introduces visual regression
Medium
Medium
Compare before/after with Chromatic/Percy; recipes match existing timings.
motion.css grows unwieldy with too many recipes
Low
Low
Cap at 10-12 recipes; complex animations compose multiple recipes.
Open Questions
#
Question
Owner
Status
OQ-01
Should the motion catalog page include a reduced-motion simulation toggle or rely on OS-level settings?
David Holmes
Open
OQ-02
Should motion recipes use CSS @layer for specificity isolation?
David Holmes
Open
OQ-03
Should there be a “motion-none” class for explicitly disabling animation on a component?
David Holmes
Open
Acceptance Criteria
#
Criterion
AC-01
A motion audit table exists documenting every animated component’s preset, duration, easing, and reduced-motion behavior.
AC-02
Motion recipe CSS classes are defined in src/styles/motion.css covering overlay, accordion, toast, fade, skeleton, and control-hover patterns.
AC-03
Each recipe includes reduced-motion fallback within the same class.
AC-04
All animated components use recipe classes (or document their custom behavior if they deviate).
AC-05
All components pass reduced-motion verification (no animation > 100ms).
AC-06
A Motion Catalog Storybook docs page exists with live recipe previews.
AC-07
pnpm typecheck and pnpm vitest run --project unit pass with zero errors.
AC-08
pnpm build-storybook succeeds without warnings related to motion classes.
LLM Handoff Instructions
When implementing this FRD:
Start with the audit. Use rg to find all uses of duration-, ease-, transition-, animation-, and @keyframes across src/. Build a table mapping each component to its motion behavior.
Then define recipes in src/styles/motion.css. Group audit findings into recipe categories. Each recipe is a CSS class with the full animation + reduced-motion fallback. Place them in the @layer utilities block alongside existing motion utilities.
Then refactor components to use recipe classes where they currently use ad-hoc inline transition classes. This should be a class swap, not a behavior change.
Then verify reduced-motion by running Storybook with prefers-reduced-motion: reduce emulated (Chrome DevTools > Rendering). Check that no animation exceeds 100ms.
Then document — add “Motion” sections to each animated component’s Storybook docs page, and create the Motion Catalog page.
Key files:
src/styles/motion.css — token and recipe definitions.
ADR-002 and ADR-004 — governance for motion decisions.
All component .tsx files with transition/animation classes.
Decision Log
Date
Decision
Rationale
2026-05-26
CSS-only recipes; no JavaScript animation library.
Keeps bundle small; CSS transitions cover all current use cases.
2026-05-26
Recipes include reduced-motion fallback in the same class (not a separate override).
Single class application ensures reduced-motion is never forgotten.
2026-05-26
Audit-first approach before defining recipes.
Recipes should match existing behavior, not impose new timings.