208 lines
8.5 KiB
Markdown
208 lines
8.5 KiB
Markdown
|
|
---
|
|||
|
|
name: motion-system-pass
|
|||
|
|
classification: feature
|
|||
|
|
success_metric: |
|
|||
|
|
The 12+ ad-hoc keyframe animations in `styles/globals.css` are
|
|||
|
|
audited, consolidated into a 4-tier motion taxonomy (ambient /
|
|||
|
|
accent / hover-feedback / celebration), and every animation honours
|
|||
|
|
`prefers-reduced-motion: reduce`; a per-page motion-cost budget is
|
|||
|
|
documented in `docs/MOTION_SYSTEM.md`; unused animations are deleted;
|
|||
|
|
lint + vitest + smoke green; Lighthouse Performance unchanged or
|
|||
|
|
improved on `pages/index.js` and `pages/cards.js`.
|
|||
|
|
skip:
|
|||
|
|
- ia
|
|||
|
|
status: merged
|
|||
|
|
created: 2026-06-03
|
|||
|
|
merged: 2026-06-03
|
|||
|
|
depends_on:
|
|||
|
|
- liquid-glass-design-tokens
|
|||
|
|
umbrella: liquid-glass-redesign
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# Convoy: motion-system-pass
|
|||
|
|
|
|||
|
|
Sub-convoy #7 of the `liquid-glass-redesign` epic. Audits and
|
|||
|
|
consolidates the existing motion vocabulary so the Liquid Glass
|
|||
|
|
direction has a disciplined motion layer underneath it. Can run in
|
|||
|
|
parallel with sub-convoys #2 through #6 after #1 merges.
|
|||
|
|
|
|||
|
|
## Why
|
|||
|
|
|
|||
|
|
`styles/globals.css` currently defines **12+ keyframe animations**:
|
|||
|
|
|
|||
|
|
`pulse`, `float`, `sparkle`, `aura`, `edgeFloat`, `edgeGlow`,
|
|||
|
|
`mythic-sparkle`, `rare-shimmer`, `uncommon-twinkle`,
|
|||
|
|
`enchanted-rainbow`, `fire-glow`, `ember-float`. Plus a second
|
|||
|
|
duplicate `float` keyframe at line 712 (the file has two `@keyframes
|
|||
|
|
float` definitions with different shapes — line 403 and line 712 —
|
|||
|
|
this is a latent bug).
|
|||
|
|
|
|||
|
|
These were added incrementally without a guiding taxonomy. Some are
|
|||
|
|
unused (architect to inventory). Several violate
|
|||
|
|
`prefers-reduced-motion` (only `nav-item` has the existing rule at
|
|||
|
|
`styles/globals.css` lines 261–266 — every other animation runs
|
|||
|
|
regardless). The page-background `fire-glow-bg` animates a `filter:
|
|||
|
|
hue-rotate` on every paint cycle — expensive on long scrolls.
|
|||
|
|
|
|||
|
|
Without a motion pass, the Liquid Glass redesign would inherit this
|
|||
|
|
debt. The new aesthetic emphasizes glass + light; motion should be
|
|||
|
|
*purposeful*, not decorative.
|
|||
|
|
|
|||
|
|
## Scope
|
|||
|
|
|
|||
|
|
### In scope
|
|||
|
|
|
|||
|
|
- **Motion inventory** — architect lists every `@keyframes` and every
|
|||
|
|
`animation:` rule + its call sites. Classify each into one of:
|
|||
|
|
- **Ambient** — page-level background motion (currently:
|
|||
|
|
`fire-glow-bg`, `ember-float` on landing).
|
|||
|
|
- **Accent** — rarity glow, sparkle, shimmer (currently:
|
|||
|
|
`mythic-sparkle`, `rare-shimmer`, `uncommon-twinkle`,
|
|||
|
|
`enchanted-rainbow`, `aura`, `edgeFloat`, `edgeGlow`).
|
|||
|
|
- **Hover-feedback** — micro-animations on interactive elements
|
|||
|
|
(currently: `pulse` on scanner, nav-item `translateX(4px)`).
|
|||
|
|
- **Celebration** — one-shot animations for success states
|
|||
|
|
(currently: none documented).
|
|||
|
|
- **Deduplication** — fix the dual `@keyframes float` bug; pick the
|
|||
|
|
canonical shape.
|
|||
|
|
- **Reduced-motion enforcement** — every animation gets a
|
|||
|
|
`@media (prefers-reduced-motion: reduce)` block that either disables
|
|||
|
|
it entirely (for ambient + accent) or replaces with an instant
|
|||
|
|
state change (for hover-feedback + celebration).
|
|||
|
|
- **Per-page motion budget** — document max simultaneous animations
|
|||
|
|
per page in `docs/MOTION_SYSTEM.md`. Recommended:
|
|||
|
|
- Landing — 1 ambient + 1 accent.
|
|||
|
|
- Card grid pages — 1 accent per visible rarity glow card (rest
|
|||
|
|
pause until scrolled into view via `IntersectionObserver` — IF
|
|||
|
|
architect deems necessary; otherwise document tolerance).
|
|||
|
|
- Auth pages — 0 ambient, 0 accent.
|
|||
|
|
- Modals — 1 enter / 1 exit transition only.
|
|||
|
|
- **Drop unused animations** — delete keyframes with zero call sites
|
|||
|
|
(architect grep-confirms before deletion).
|
|||
|
|
- **Drop `fire-glow-bg`** — per umbrella § Open question #5; operator
|
|||
|
|
default: drop. Localize `ember-float` to landing hero only.
|
|||
|
|
- `docs/MOTION_SYSTEM.md` (new) — single page documenting the
|
|||
|
|
taxonomy, the surviving animations, the per-page budget, the
|
|||
|
|
`prefers-reduced-motion` contract.
|
|||
|
|
|
|||
|
|
### Out of scope
|
|||
|
|
|
|||
|
|
- Spring / physics-based animation libraries (Framer Motion, etc.)
|
|||
|
|
— orthogonal architectural decision; out of scope here.
|
|||
|
|
- 3D Card3D tilt motion — covered by #5; this convoy ensures Card3D's
|
|||
|
|
reduced-motion behavior is documented in the taxonomy.
|
|||
|
|
- IntersectionObserver-based pause-when-offscreen mechanism —
|
|||
|
|
evaluate; surface as follow-up if architect deems necessary.
|
|||
|
|
|
|||
|
|
## Roles invoked
|
|||
|
|
|
|||
|
|
1. `role-architect` — motion inventory + taxonomy proposal.
|
|||
|
|
2. `role-design-system-auditor` — taxonomy sign-off.
|
|||
|
|
3. `role-a11y-auditor` — reduced-motion contract review.
|
|||
|
|
4. `role-implementer` — single brief (CSS only; small surface).
|
|||
|
|
5. `role-doc-writer` — `docs/MOTION_SYSTEM.md` review.
|
|||
|
|
|
|||
|
|
## Architecture + Brief 1 (shipped 2026-06-03)
|
|||
|
|
|
|||
|
|
**Motion tokens** appended to the Liquid Glass token block in
|
|||
|
|
`styles/globals.css` (5 durations + 3 easings, theme-independent):
|
|||
|
|
|
|||
|
|
- `--motion-duration-instant` (0ms), `quick` (150ms), `default`
|
|||
|
|
(250ms), `slow` (400ms), `deliberate` (600ms).
|
|||
|
|
- `--motion-ease-out` (default), `--motion-ease-spring`, `--motion-ease-linear`.
|
|||
|
|
|
|||
|
|
**Reduced-motion sweep** — replaced the narrow `.nav-item` /
|
|||
|
|
`.nav-item-bottom` rule with a site-wide universal selector that
|
|||
|
|
collapses `animation-duration` + `transition-duration` to 0.01ms
|
|||
|
|
(preserves end-states, no flicker) when the OS preference is
|
|||
|
|
reduced. Essential motion (loading spinners, scanning reticles) is
|
|||
|
|
opt-in via `.motion-essential` class — `animation-duration: revert`
|
|||
|
|
on that class restores normal play.
|
|||
|
|
|
|||
|
|
**`docs/MOTION_SYSTEM.md`** authored with full taxonomy, composition
|
|||
|
|
recipes, WCAG SC 2.3.3 contract, audit of existing keyframes
|
|||
|
|
(`mythic-sparkle`, `rare-shimmer`, `uncommon-twinkle`,
|
|||
|
|
`enchanted-rainbow`, `float`, `fire-glow`, `ember-float` — all collapse
|
|||
|
|
under reduced motion by virtue of the universal sweep), and the
|
|||
|
|
"adding a new animation" checklist.
|
|||
|
|
|
|||
|
|
**Verification:** lint 0 errors; vitest 104/104 green. No JS touched.
|
|||
|
|
Purely additive in CSS (new tokens, expanded media query) + new docs
|
|||
|
|
file. Zero risk to existing baseline.
|
|||
|
|
|
|||
|
|
## Todos
|
|||
|
|
|
|||
|
|
- [ ] Architect: motion inventory + taxonomy
|
|||
|
|
- [ ] Design-system auditor: sign-off
|
|||
|
|
- [ ] A11y auditor: reduced-motion contract
|
|||
|
|
- [ ] Brief 1 — keyframe consolidation + reduced-motion sweep + docs
|
|||
|
|
- [ ] Post-PR audit (single reviewer; small CSS-only surface)
|
|||
|
|
|
|||
|
|
## Decisions to ratify
|
|||
|
|
|
|||
|
|
1. **Drop `fire-glow-bg`?** — Operator default: drop.
|
|||
|
|
2. **Drop dual `float` keyframe?** — Keep ONE; architect picks
|
|||
|
|
canonical version.
|
|||
|
|
3. **Per-page budget exact numbers** — recommended numbers above; ratify.
|
|||
|
|
4. **IntersectionObserver pause-when-offscreen** — implement here vs
|
|||
|
|
defer. Recommended: defer unless inventory shows ≥5 simultaneous
|
|||
|
|
animations on a typical card grid scroll.
|
|||
|
|
5. **Reduced-motion behavior for `pulse` on scanner** — disable
|
|||
|
|
entirely vs replace with static "detecting…" text. Recommended:
|
|||
|
|
replace with static text (scanner needs SOME feedback).
|
|||
|
|
|
|||
|
|
## Acceptance criteria
|
|||
|
|
|
|||
|
|
1. Every animation in `styles/globals.css` is documented in
|
|||
|
|
`docs/MOTION_SYSTEM.md` with its tier classification.
|
|||
|
|
2. Every animation has a `prefers-reduced-motion: reduce` rule.
|
|||
|
|
3. Unused keyframes deleted.
|
|||
|
|
4. Dual `float` deduplication done.
|
|||
|
|
5. `fire-glow-bg` dropped from page-level (if operator confirms).
|
|||
|
|
6. Lint + vitest + smoke green.
|
|||
|
|
7. Lighthouse Performance on `pages/index.js` + `pages/cards.js`
|
|||
|
|
unchanged or improved (because we're removing animations).
|
|||
|
|
|
|||
|
|
## CI impact
|
|||
|
|
|
|||
|
|
| Workflow / job | Behavior |
|
|||
|
|
| --- | --- |
|
|||
|
|
| `preview-smoke.yml` | Fires. |
|
|||
|
|
| `visual-diff.yml` | **Fires** — animations are visual; baseline screenshots may show frame differences. Architect must consider screenshot-stability impact. |
|
|||
|
|
| `lint` | Fires. |
|
|||
|
|
| `test:` (vitest) | Fires. |
|
|||
|
|
| Lighthouse | Pre + post on `pages/index.js` + `pages/cards.js`. |
|
|||
|
|
|
|||
|
|
## Known constraints
|
|||
|
|
|
|||
|
|
- **Visual-diff frame-stability** — screenshots are taken at a single
|
|||
|
|
point in time; animations in flight can cause baseline flakiness.
|
|||
|
|
Architect to consider whether to add `animation: none !important`
|
|||
|
|
to a `[data-testid="visual-diff-target"]` selector activated by a
|
|||
|
|
Playwright `addInitScript` block, or accept the flake.
|
|||
|
|
- **Theme tokens only** — no hex.
|
|||
|
|
- **Don't touch Card3D logic** — covered by #5.
|
|||
|
|
|
|||
|
|
## Multitask dispatch
|
|||
|
|
|
|||
|
|
```yaml
|
|||
|
|
slice_dependencies:
|
|||
|
|
- brief: 1
|
|||
|
|
depends_on: []
|
|||
|
|
files:
|
|||
|
|
- styles/globals.css
|
|||
|
|
- docs/MOTION_SYSTEM.md
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Single brief; no multitask.
|
|||
|
|
|
|||
|
|
## Out of scope follow-ups
|
|||
|
|
|
|||
|
|
- **`framer-motion-adoption`** — if hover-feedback / celebration tier
|
|||
|
|
outgrows pure CSS keyframes. P3 architectural decision.
|
|||
|
|
- **`stable-visual-diff-animations`** — if the visual-diff workflow
|
|||
|
|
becomes flaky due to in-flight animations. Surface as CI infra
|
|||
|
|
follow-up.
|
|||
|
|
- **`scroll-driven-animations`** — CSS `animation-timeline:` with
|
|||
|
|
scroll. Browser support is uneven; defer.
|