---
name: liquid-glass-redesign
classification: epic
success_metric: |
  Deck Hearth's UI reads as a modern, glass-forward fireplace: every surface
  that previously used opaque warm-cream / wood-grain panels now uses a
  tunable glass token system (translucency + backdrop blur + warm gradient
  rim-light); every modal blurs the page behind it; the brand warmth
  (ember / flame / gold) survives as accent and motion, not as a heavy
  panel fill. Eight sub-convoys ship behind the existing visual-diff +
  smoke + vitest gates; no regression in the launch-readiness checklist.
skip: []
status: open
created: 2026-06-03
---

# Liquid Glass Redesign — design-system epic

Umbrella convoy capturing the full pivot from the current "warm panel +
side-highlight + heavy gradient" visual language to a **Liquid Glass**
aesthetic that retains Deck Hearth's fireplace warmth as accent, gradient,
and motion — not as panel fill. Each lettered section below maps to a
dedicated sub-convoy that an architect will refine and an implementer (or
multitask fleet of implementers) will ship.

This convoy is **planning-only**. No source files are touched here. Each
sub-convoy below is a separate, gated, visual-diff-bounded PR (or
multitask group of PRs).

---

## 1. Vision

The product is **Deck Hearth** — a fireplace. Today the UI renders a
fireplace by making every panel look like wood. That is *thematic but
dated*: it gives every surface the same heavy mass, fights the actual
content (cards, decks, lists), and forces motion / glow to do all the
"modern" work alone.

The new direction is the opposite read of "fireplace":

- The **room** is glass — softly translucent, with the page (the actual
  hearth: cards, deck lists, scan frames) glowing through.
- The **fire** is the accent — ember orange / flame / gold reads as
  *light cast onto* the glass, not *paint applied to* the glass.
- The **warmth** comes from gradients and slow motion, not from beige
  panel fills.

Concretely the visual contract is:

| Layer | Before | After |
| --- | --- | --- |
| Panel fill | Opaque `--bg-secondary` / `--bg-tertiary` warm cream | `rgba(bg-secondary, 0.55–0.75)` + `backdrop-filter: blur(20–32px) saturate(140%)` |
| Border | Solid `--border` wood line | Hairline `1px` inner ring + outer hairline; light theme uses warm-white inner highlight (`rgba(255,255,255,0.55)`) |
| Shadow | Single-axis drop shadow | Stacked elevation: ambient soft outer + accent-tinted rim ("ember rim" on hover/focus) |
| Modal backdrop | Dim overlay only | Blur-and-dim: `backdrop-filter: blur(18px)` + `rgba(bg-primary, 0.4)`; ember vignette toward the center to retain hearth warmth |
| Buttons (primary) | Solid flame gradient pill | Glass pill with ember rim-light gradient on top edge + animated micro-glow on hover; matches Apple-style "Liquid Glass" tinted material |
| Cards (TCG cards) | Heavy ember box shadow + opaque container | Container goes glass; rarity glows REMAIN but tightened (one-shadow stack, reduced bloom) so they read against glass |
| Logo / brand | DH monogram in solid gradient pill | Same monogram, glass pill, inner ember gradient ring |

The deliverable is a **reusable token + primitive kit**, not 50 one-off
class names.

---

## 2. Why now

Three things make this the right moment:

1. **Brand is settled.** `pick-a-name` (PR #21, 2026-05-24) ratified
   Deck Hearth as the canonical name. No more rebranding noise mid-design.
2. **Test infrastructure is in place.** `Screenshot diff` workflow
   (`visual-diff.yml`) fires on every PR touching `pages/**` /
   `components/**` / `styles/**` / `tailwind.config.js` / `postcss.config.js`,
   and `seed-visual-baselines-on-linux` (PR #58, 2026-06-02) shipped the
   first Linux baseline. Smoke (3/3, 2.9s) defends auth + page-render on
   every PR. Vitest (21/21) defends Layout's logged-out branch. A
   design-system redesign without these gates would be reckless; with
   them, it's tractable.
3. **The component fleet is small enough to enumerate.** 42 components in
   `components/`, ~15 modals, 1 Layout, 1 MobileNavigation. The full
   design migration is bounded — not a year-long redesign treadmill.

This convoy does **NOT** ship before the eight P0 ship-blockers (already
**8/8 RESOLVED**, 2026-05-24) and **does** ship in parallel with the
queued P2/P3 polish convoys listed in `.convoys/ship-readiness.md` §
Queued convoys. It does not block launch — but it dramatically raises
the launch-day quality bar.

---

## 3. Hard scoping rules

- **No new third-party CSS framework.** Tailwind + CSS variables stays.
  Liquid Glass is implemented as new tokens + a small primitive set.
- **No TypeScript adoption.** Files stay `.js`. See `AGENTS.md` Gotcha #9.
- **Theme tokens, not hex.** Every new color reads from a CSS variable.
  The hex sweep is a dedicated sub-convoy (#8 below).
- **Both themes ship together.** Light and dark each get their own glass
  recipe — the light theme uses a warm-white inner highlight, dark uses
  a black-glass with ember-rim. Never ship one theme without the other.
- **Brand warmth survives.** Ember (`#d84315` RGB `216,67,21`) and Flame
  (`#ff6f00`) remain the canonical accents. Gold (`#ffab40`) remains for
  rarity / celebration. No new accent hues without operator ratification.
- **Reduced-motion is mandatory.** Every animation introduced honours
  `prefers-reduced-motion`. Existing `fire-glow-bg` and `ember-float`
  animations get audited under #7.
- **Accessibility is non-negotiable.** Glass + warm-cream backgrounds
  often fail AA. Every token comes with a documented contrast measurement
  vs `--text-primary` AND `--text-secondary` in both themes.
- **Browser support.** `backdrop-filter` is supported in all evergreen
  browsers (Safari 18+, Chrome 76+, Firefox 103+). Fallback in
  `@supports not (backdrop-filter: blur(20px)) { ... }` per the existing
  pattern in `styles/globals.css` lines 815–819 — use a solid-with-alpha
  fallback, never a hard-opaque revert.
- **Performance budget.** Stacked `backdrop-filter` on long scroll lists
  is expensive. Card grids may NOT use glass on every card item — glass
  is for the *container*, not every card. The per-card surface stays
  cheap (solid + cheap shadow). The card detail VIEW gets glass.
- **No flag rollout needed.** The repo has no feature-flag wrapper.
  Migration is incremental by sub-convoy; visual diff catches breakage
  per PR; a bad sub-convoy can be reverted independently.
- **One sub-convoy per PR (or per multitask group).** Do not bundle
  primitives + layout + cards into a single PR — visual diff becomes
  unreadable and rollback impossible.

---

## 4. Dependency graph

```
                  ┌────────────────────────────────────────┐
                  │ 1. liquid-glass-design-tokens          │
                  │    (CSS vars + docs; no UI change)     │
                  └──────────────────┬─────────────────────┘
                                     │
                ┌────────────────────┼────────────────────┐
                │                    │                    │
                ▼                    ▼                    ▼
   ┌────────────────────┐  ┌────────────────────┐  ┌──────────────────────┐
   │ 2. modal-and-      │  │ 3. form-primitives │  │ 7. motion-system     │
   │    surface-        │  │    <Button>        │  │    audit + reduced-  │
   │    primitive       │  │    <Input>         │  │    motion sweep      │
   │    <GlassSurface>  │  │    <SearchBar>     │  │                      │
   │    <Modal>         │  │    + sweep         │  │                      │
   │    + modal sweep   │  └─────────┬──────────┘  └──────────┬───────────┘
   └─────────┬──────────┘            │                         │
             │                       │                         │
             ▼                       ▼                         │
   ┌────────────────────┐  ┌────────────────────┐              │
   │ 4. layout-shell    │  │ 5. card-surfaces   │              │
   │    Layout +        │  │    CardItem,       │              │
   │    MobileNav +     │  │    CardDetailView, │              │
   │    header          │  │    Card3D, rarity  │              │
   └─────────┬──────────┘  └─────────┬──────────┘              │
             │                       │                         │
             └──────────┬────────────┘                         │
                        ▼                                      │
              ┌────────────────────┐                           │
              │ 6. public-and-auth │                           │
              │    /, /login,      │                           │
              │    /signup, public │                           │
              │    collection/deck │                           │
              └─────────┬──────────┘                           │
                        │                                      │
                        └──────────┬───────────────────────────┘
                                   ▼
                       ┌────────────────────┐
                       │ 8. cleanup-legacy- │
                       │    design-css      │
                       │    (delete dead    │
                       │    utilities; hex  │
                       │    sweep)          │
                       └────────────────────┘
```

**Strict-blockers:**

- #1 blocks all other sub-convoys (they consume the tokens).
- #2 blocks #4 (Layout consumes `<GlassSurface>`) and #5 (`CardDetailView` modal-like surfaces).
- #4 + #5 block #6 (public + auth pages compose Layout + cards).
- #7 can run in parallel with anything after #1 (it audits motion, not surfaces).
- #8 ships last — it deletes utilities the previous sub-convoys must have stopped using.

**Multitask opportunities:**

- After #1 merges: `/multitask` #2, #3, #7 (disjoint file sets).
- After #2 merges: the **modal sweep** inside #2 itself fans out via
  `/multitask` — one brief per ~3 modals (see #2's seed convoy file).
- After #4 + #5 merge: `/multitask` per-page in #6 (`index`, `login`,
  `signup`, `community/collections`, `community/decks` are file-disjoint).

---

## 5. Sub-convoy summaries

Each sub-convoy has its own `.convoys/<slug>.md` seed file (open status,
awaiting role-conductor refinement when picked up). Brief shape:

### 1. `liquid-glass-design-tokens` (foundation — no UI change)

**File**: `.convoys/liquid-glass-design-tokens.md`. Adds the new token
layer to `styles/globals.css` (`--glass-surface-*`, `--glass-blur-*`,
`--rim-light-*`, `--ember-rim-*`, `--elevation-*`) for both themes, plus
a `docs/DESIGN_TOKENS.md` reference page with contrast measurements.
**Zero component changes** — this is plumbing. Visual diff is expected
to be a no-op (or trivially noisy from CSS reordering). Unblocks
everything else.

### 2. `liquid-glass-modal-and-surface-primitive`

**File**: `.convoys/liquid-glass-modal-and-surface-primitive.md`.
Extracts `<GlassSurface>` (the panel primitive) + `<Modal>` (the
backdrop + dialog primitive with focus trap, ESC-to-close, ARIA-correct
shape). Migrates **all ~15 modals** in `components/*Modal.js` +
`ScanDisambiguationDialog.js` + `OCRSettings.js` to the new primitive.
Inner multitask fan-out: one brief per ~3 modals (see seed for slice
list). Closes the "Modal patterns" finding from `ship-readiness.md`
role-design-system-auditor.

### 3. `liquid-glass-form-primitives`

**File**: `.convoys/liquid-glass-form-primitives.md`. Extracts
`<Button>` (variants: primary glass, ghost glass, ember rim, gold
celebrate), `<Input>` (glass input field with floating focus rim),
`<SearchBar>`. Replaces the existing `.btn-primary` / `.btn-flame` /
`.btn-ember` / `.btn-gold` / `.input-field` / `.search-bar` utility
classes incrementally — utility classes stay aliased to the new tokens
until #8 sweeps them. **No** new global utility classes are introduced.

### 4. `liquid-glass-layout-shell`

**File**: `.convoys/liquid-glass-layout-shell.md`. `components/Layout.js`
(826 lines — the sidebar + header + theme toggle + profile dropdown) and
`components/MobileNavigation.js` (bottom-bar + mobile drawer) move to
glass surfaces. The sidebar becomes a glass rail; the header becomes a
glass top-bar with subtle ember rim under the page edge; the mobile
bottom-bar's existing `backdrop-filter: blur(16px)` (`styles/globals.css`
line 807) is upgraded to the canonical token + rim. **Highest-blast PR**
in the portfolio because Layout is on every authenticated page — visual
diff for this PR will be loud; baselines must be re-seeded on Linux
post-merge (see `seed-visual-baselines-on-linux` precedent).

### 5. `liquid-glass-card-surfaces`

**File**: `.convoys/liquid-glass-card-surfaces.md`. `components/CardItem.js`
(card grid item), `components/CardDetailView.js`, `components/Card3D.js`,
plus rarity FX reconciliation. The existing rarity-glow stack
(`rarity-glow-mythic` / `rare` / `uncommon` / `enchanted` in
`styles/globals.css` lines 568–697) is **tightened** — collapsed from a
3-layer shadow stack to a 2-layer shadow stack, then re-tuned against
the new glass container so the glow reads against translucency. **Per-card
performance budget**: card grid items stay cheap (no `backdrop-filter`
on the grid item itself); glass goes on the *container* and the *detail
view*.

### 6. `liquid-glass-public-and-auth`

**File**: `.convoys/liquid-glass-public-and-auth.md`. `pages/index.js`
(316-line landing), `pages/login.js`, `pages/signup.js`, public
collection/deck views (`pages/cards.js` `PublicCardsView`,
`pages/collection/[id].js` public branch, `pages/deck/[id].js` public
branch). These pages are the **first impression** — they get the most
polish budget. Multitask-friendly: per-page briefs, file-disjoint.

### 7. `motion-system-pass`

**File**: `.convoys/motion-system-pass.md`. Audits and consolidates the
existing motion vocabulary (`pulse`, `float`, `sparkle`, `aura`,
`edgeFloat`, `edgeGlow`, `mythic-sparkle`, `rare-shimmer`,
`uncommon-twinkle`, `enchanted-rainbow`, `fire-glow`, `ember-float`).
Defines a four-tier motion taxonomy (ambient / accent / hover-feedback /
celebration), enforces `prefers-reduced-motion` on every tier, and
documents a per-page motion budget. Drops unused animations. Can run in
parallel with #2–#5.

### 8. `cleanup-legacy-design-css`

**File**: `.convoys/cleanup-legacy-design-css.md`. After every other
sub-convoy has migrated off the legacy utility classes, this sub-convoy
deletes them. In scope: `.gradient-text-blue`, `.gradient-text-purple`,
`.gradient-text-pink`, `.glow-blue`, `.glow-purple`, `.glow-pink`,
`.gradient-bg-fire`, `.gradient-bg-golden`, `.gradient-bg-ember` (if
unused post-migration), the legacy color mappings (`--accent-blue`,
`--accent-purple`, `--accent-pink` in both themes), hardcoded hex sweep
across `components/**` + `pages/**`. Strict-deletion convoy — no new
styling.

---

## 6. CI impact summary

| Sub-convoy | `preview-smoke` | `visual-diff` | `lint` | `vitest` |
| --- | --- | --- | --- | --- |
| 1. design-tokens | Fires | **Fires** (CSS change) — baselines stable | Fires | Fires |
| 2. modal-and-surface | Fires | **Fires + LOUD** — modals change shape | Fires | Fires (Layout tests stable) |
| 3. form-primitives | Fires | **Fires + LOUD** — buttons everywhere | Fires | Fires |
| 4. layout-shell | Fires | **Fires + LOUDEST** — Layout on every page | Fires | Fires + 5 Layout assertions defended |
| 5. card-surfaces | Fires | **Fires + LOUD** — card grids change | Fires | Fires |
| 6. public-and-auth | Fires | **Fires** — landing + auth pages | Fires | Fires + smoke "sign-in page renders" asserts post-migration |
| 7. motion-system | Fires | **Fires** — animations re-tuned | Fires | Fires |
| 8. cleanup | Fires | Fires (should be no-op visually) | Fires | Fires |

**Post-merge per sub-convoy**: re-seed Linux baselines for the affected
surfaces (the `seed-visual-baselines-on-linux` Docker workflow already
documented in `AGENTS.md` § 6 is the canonical path).

**No new CI gates** are required by this epic. Existing gates carry it.

---

## 7. Risk register

| Risk | Mitigation |
| --- | --- |
| `backdrop-filter` performance on long card grids | Per-card surface stays solid; glass only on container + detail view (Hard scoping rule). |
| Light-theme contrast fail when text overlays glass | Every token ships with documented contrast measurements (#1's deliverable). |
| Visual diff floods every PR with noise | One sub-convoy per PR (Hard scoping rule); re-seed baselines on merge. |
| Brand drift (someone introduces purple/blue glass) | #8 keeps the legacy `accent-blue/purple/pink` aliases alive until the last moment, then deletes them in one PR — making accidental reintroduction visible at lint time post-cleanup. |
| Mobile bottom-nav already has glass; PR #4 may double-stack it | #4's architect note: respect the existing `.mobile-nav-backdrop` rule (`styles/globals.css` line 807); upgrade to the canonical token, do not re-implement on top. |
| Modal focus-trap regressions | `<Modal>` primitive in #2 lands with focus-trap + ESC-to-close + ARIA — the role-a11y-auditor findings in `ship-readiness.md` § Role-a11y-auditor are closed by #2. |
| Animation count explodes | #7 enforces the four-tier motion taxonomy with a per-page budget. |
| TypeScript adoption pressure | Hard scoping rule: NO `.ts` files. JavaScript-only per `AGENTS.md` Gotcha #9. |
| Sub-convoys block each other indefinitely | Dependency graph is explicit; #1 → fan-out; multitask after #1 → multitask after #4+#5 → cleanup. |
| User pushback on lost warmth | Vision contract makes warmth survive as accent + motion. Hold the ember/flame/gold token names; just change how they're applied. |

---

## 8. Acceptance criteria (epic-level)

The epic is "done" when:

1. All eight sub-convoys are merged (`status: merged` or `shipped` in
   each `.convoys/<slug>.md`).
2. `docs/DESIGN_TOKENS.md` reflects the as-shipped token surface (kept
   fresh by #1, audited by every subsequent sub-convoy).
3. `npm run lint` and `npm run test:run` and `npm run test:smoke` all
   green on `main` post-merge of #8.
4. Linux visual baselines re-seeded for every UI surface touched
   (`seed-visual-baselines-on-linux` workflow run logged).
5. AGENTS.md § "Branding" section updated with one paragraph naming the
   Liquid Glass direction + pointer at `docs/DESIGN_TOKENS.md`.
6. `.cursor/rules/ui-and-theming.mdc` updated to make the new tokens +
   primitives the canonical pattern (the existing "Two systems coexist"
   note becomes obsolete after #8).
7. Lighthouse mobile + desktop scores on `pages/index.js` no worse than
   the pre-redesign baseline (Performance, Accessibility).

---

## 9. Roles invoked (epic-level)

This umbrella does NOT itself invoke roles — each sub-convoy invokes its
own role chain. The typical chain per sub-convoy is:

1. `role-conductor` — writes the sub-convoy from its seed.
2. `role-ux-reviewer` — for sub-convoys #2, #4, #5, #6.
3. `role-design-system-auditor` — for sub-convoys #1, #2, #3, #5, #7.
4. `role-a11y-auditor` — for sub-convoys #2, #3, #4.
5. `role-architect` — every sub-convoy (decides brief boundaries +
   multitask shape).
6. `role-implementer` — one or more per sub-convoy.
7. Post-PR audit fleet (`/multitask role-reviewer +
   role-design-system-auditor + role-a11y-auditor`) on every visual PR.
8. `role-doc-writer` — updates `docs/DESIGN_TOKENS.md` after #1; updates
   `AGENTS.md` + `.cursor/rules/ui-and-theming.mdc` after #8.

---

## 10. Open questions for the operator

These need ratification before #1's architect starts. They are NOT
re-litigations of the design vision — they are precise tuning calls:

1. **Glass tint strength.** Two reference points:
   - **Apple Liquid Glass** (iOS 19) — very translucent (~30–40% surface
     opacity), strong blur (~30px), tinted vibrancy.
   - **Linear / Vercel / Arc Browser** — less translucent (~70–85%),
     softer blur (~12–20px), borderline frosted.
   Where on this spectrum does Deck Hearth sit? Recommended default:
   **Apple-leaning** (lower opacity, stronger blur, warmer rim) — the
   product is a personal hearth, not an enterprise tool.

2. **Light-theme glass base.** Two options:
   - **Warm white** (`rgba(254, 252, 248, 0.55)` — the existing
     `--bg-primary-light` with alpha) — keeps the cream warmth.
   - **Cool white** (`rgba(255, 255, 255, 0.6)`) — true Apple-style
     glass; reads more "modern" but loses warmth on flat panels.
   Recommended default: **warm white**, with ember-rim doing the
   warmth lifting.

3. **Dark-theme glass base.**
   - **Warm black** (`rgba(26, 15, 10, 0.55)` — existing
     `--bg-primary-dark` with alpha) — matches the wood-charcoal floor.
   - **Cool black** (`rgba(0, 0, 0, 0.6)`) — true Apple style.
   Recommended default: **warm black**.

4. **Hover ember rim intensity.** Glow on hover is core to the vibe.
   How "alive" should it be?
   - **Subtle** — `box-shadow: 0 0 0 1px rgba(216, 67, 21, 0.4) inset`
     (1px ring on top edge only).
   - **Pronounced** — adds an outer 8–12px `rgba(216, 67, 21, 0.25)`
     bloom.
   Recommended default: **pronounced on interactive primaries** (buttons,
   focused inputs, selected cards); **subtle on ambient surfaces** (nav
   rail, header).

5. **Drop the current `fire-glow-bg` page-background animation?** It
   currently animates the whole-page background `filter: hue-rotate(...)`
   — expensive on long scrolls and visually fights the glass aesthetic.
   Recommended: **drop**, retain `ember-float` as a localized accent on
   the landing hero only.

6. **Sub-convoy sequencing under launch pressure.** If the operator
   wants to launch publicly before the epic completes, ship #1 → #2 →
   #4 (modals + Layout) as the minimum-viable redesign, then ship #3,
   #5, #6, #7, #8 post-launch. Confirm.

These six are tabled for sub-convoy #1's architect gate.

---

## 11. How to start

Per `.cursor/agents/role-conductor.md`, start the first sub-convoy with:

> *"Run role-conductor: start a new convoy `liquid-glass-design-tokens`
> from the seed `.convoys/liquid-glass-design-tokens.md`. Success =
> tokens + docs ship; zero component changes; visual-diff baselines
> stable; lint + vitest + smoke green."*

The Conductor will set classification, skip flags, and hand off to
`role-design-system-auditor` + `role-architect`.

After #1 merges, the operator can dispatch #2, #3, #7 in parallel via
`/multitask`. Track per-sub-convoy status in the frontmatter of each
seed file; mirror the rolling state into the "Design system redesign
portfolio" section of `.convoys/ship-readiness.md`.
