Skip to content

Redesign reveals page: immersive six-ink set-tracker view with two-view toggle #390

Description

@Doberjohn

Context

The /reveals page (shown only during a set's reveal season, gated by VITE_IS_REVEAL_SEASON + RevealsGate) is currently a hero + per-franchise card grids. For Set 13 — "Attack of the Vine!" we want a richer, season-long page whose primary attraction is six per-color completion trackers (34 cards each, 204 total) that visibly fill and brighten as cards reveal, with the franchises and new mechanics as secondary draws.

A high-fidelity design was produced in Claude Design (desktop + mobile handoffs in apps/web/reveals page redesign/). This issue recreates that design inside the existing React codebase using real reveal data, preserving the current franchise-grid experience as a second, toggleable view (the new tracker view is the default). Success: a visitor lands on an immersive tracker showing all six inks' progress, can open any ink's diamond mosaic of real card art, read the new-franchises and "new this set" mechanic spotlights, and toggle to the classic franchise grid — all responsive from ~360px to desktop.

Prerequisites

  • Write access to Doberjohn/inkweave; work on a feature/<n>-reveals-redesign branch (source edits blocked on master by the branch-verification hook)
  • VITE_IS_REVEAL_SEASON=true in apps/web/.env.local (else /reveals redirects home)
  • Set 13 preview images present (apps/web/public/card-images-preview/13*.avif, committed in 3380dcb for Set 13 reveal season, preview-card parser, and Temporary Shift support #388)
  • Node + pnpm; pnpm install done; Playwright browsers installed for pre-push E2E
  • Familiarity with the two handoff specs: apps/web/reveals page redesign/README.md (desktop) and .../design_handoff_reveals_page_mobile/README.md (mobile deltas)
  • Knowledge that preview cards use color/subtypes/fullText/rarity field names (vs engine ink/classifications/text)

Implementation Steps

Phase 0 — Data plumbing (engine + loader)

Step 1: Surface rarity on the card type

Add the field the diamond's rarity breakdown + per-card gem need.

// packages/synergy-engine/src/types/card.ts — add to LorcanaCard
rarity?: string; // "Common" | "Uncommon" | "Rare" | "Super Rare" | "Legendary" | "Enchanted"

Then carry it through the web loader (apps/web/src/features/cards/loader.ts) where preview cards are normalized, and confirm classifications (from preview subtypes) and the per-card cost/color already flow through.

Verify: pnpm build:engine succeeds; a loaded Set 13 card has rarity and classifications populated.

Step 2: Reveal-progress + set-composition logic

apps/web/src/features/reveals/setComposition.ts   // SET_TOTAL=204, PER_INK=34, RARITY_SPLIT=[12,8,8,3,2,1]
apps/web/src/features/reveals/rarity.ts            // 6 rarities: name, total, color, clip-shape
apps/web/src/features/reveals/useRevealProgress.ts // real per-ink counts, per-rarity tallies, scattered order, totals

useRevealProgress replaces the prototype's fake revealPct: group revealed Set 13 cards by ink (split dual-ink), tally per-rarity from real card.rarity, and compute a deterministic scattered slot order per ink (stable hash seeded by ink key).

Verify: unit test asserts Σ per-ink counts === totalRevealed and rarity tallies sum correctly against fixture cards.

Step 3: Franchise→ink association

// apps/web/src/features/reveals/franchise.ts — extend FranchiseConfig
ink: InkColor; // up→'sapphire', monsters-inc→'emerald', turning-red→'ruby'

Verify: pnpm test:web for franchise tests passes.

Phase 1 — Shared visual primitives

Step 4: Build ProgressRing, RarityGem, CardSlot under apps/web/src/features/reveals/, each reading theme.INK_COLORS and accepting size props (so desktop/mobile differ by token, not branching). RarityGem uses the clip-path shapes (circle/square/triangle/diamond/pentagon/hexagon + rainbow conic). CardSlot renders unrevealed (ink watermark placeholder) vs revealed (real AVIF via smallImageUrl + cost pip + rarity gem), and onClick opens the card modal via CardModalContext for revealed slots.

Verify: Storybook stories render each at desktop + mobile sizes; pnpm dev shows a revealed slot opening the modal on click.

Phase 2 — Tracker view

Step 5: RevealHero (eyebrow, Tinos title, intro, countdown + revealed stat panels, OverallProgressBar with six ink segments) — countdown/date from useCountdown/revealDates, totals from useRevealProgress.

Step 6: InkTrackerStrip + InkTrackerTile (6 tiles, ProgressRing + name + count; auto-fit minmax(150px) desktop / fixed 2-col mobile; selected state glow; default selected = Amethyst).

Step 7: InkBoard (header with ink badge + count + "COLOR COMPLETE" ribbon at 34; CardMosaic diamond [4,6,7,7,6,4]; RarityBreakdown grid). Glow + bloom scale with fill = count/34.

Verify: pnpm dev/reveals: selecting an ink swaps the board; revealed cards show real art; counts match useRevealProgress; screenshot at desktop width.

Phase 3 — Secondary sections

Step 8: NewFranchises — 3 cards using existing public/art/franchises/{up,monsters-inc,turning-red}.webp as the 210px/150px key-art regions, with ink-tinted bloom from the franchise→ink map.

Step 9: WhatsNewSection — curated content file apps/web/src/features/reveals/setSpotlights.ts driving 3 "new mechanic" cards (🌿 Vine & Floodborn Matters · 👥 Team Characters/Combo & Duo Shift · ⏳ Temporary Shift) + 2 "tribe spotlight" cards (🐼 Red Panda · 🍯 Hunny), each with icon, ★ NEW badge (Vineling/Team/Temporary Shift only), one-line summary, example card names. Static display in v1.

Verify: counts shown match data (Vineling 5, Team 11, Red Panda 7, Hunny 6, Temporary Shift 3).

Phase 4 — Two-view toggle + integration

Step 10: ViewToggle + RevealsPage orchestration. New "Tracker" view (Phases 2-3) is the default; "Franchises" view reuses the existing FranchiseTier + useRevealCards grid unchanged. Keep CompactHeader and reuse EtherealBackground.

Verify: toggling swaps views without remount errors; default load shows Tracker.

Phase 5 — Responsive

Step 11: Apply the mobile delta table (hero 88→42px, trackers→2-col, ring 82→64, slots 58×80→46×64 gaps 7→5, rarity→3-col, franchises/mechanics→single column, drop release-date cell). Mosaic widest row = 7×46+6×5 = 352px must fit 390px with no horizontal page scroll (only the mosaic rail may scroll).

Verify: resize to 390px → no horizontal page scroll; screenshot mobile.

Phase 6 — Stories + tests

Step 12: A .stories.tsx for every new component (story-coverage gate blocks push otherwise); focused unit tests for useRevealProgress, rarity, scatter order. Run full gate.

Verify: pnpm check:stories, pnpm test, pnpm build all green.

Files Affected

Created

File Purpose
apps/web/src/features/reveals/setComposition.ts 204 total / 34 per-ink / rarity-split constants
apps/web/src/features/reveals/rarity.ts 6 rarity configs (total, color, clip shape)
apps/web/src/features/reveals/useRevealProgress.ts Real per-ink counts, per-rarity tallies, scatter order
apps/web/src/features/reveals/setSpotlights.ts Curated "new this set" mechanics + tribes content
apps/web/src/features/reveals/ProgressRing.tsx (+ stories) Conic-gradient progress ring
apps/web/src/features/reveals/RarityGem.tsx (+ stories) Clip-path rarity gem
apps/web/src/features/reveals/CardSlot.tsx (+ stories) Mosaic slot (revealed art / placeholder, modal on click)
apps/web/src/features/reveals/CardMosaic.tsx (+ stories) Diamond [4,6,7,7,6,4] mosaic
apps/web/src/features/reveals/InkBoard.tsx (+ stories) Featured board (header + mosaic + rarity breakdown)
apps/web/src/features/reveals/InkTrackerStrip.tsx / InkTrackerTile.tsx (+ stories) Six ink tracker tiles
apps/web/src/features/reveals/OverallProgressBar.tsx (+ stories) Six-segment hero progress bar
apps/web/src/features/reveals/RevealHero.tsx (+ stories) New hero (title, countdown+stats, bar)
apps/web/src/features/reveals/NewFranchises.tsx (+ stories) 3 franchise key-art cards
apps/web/src/features/reveals/WhatsNewSection.tsx (+ stories) Mechanics + tribe spotlights band
apps/web/src/features/reveals/ViewToggle.tsx (+ stories) Tracker ⇄ Franchises view switch

Modified

File Change
packages/synergy-engine/src/types/card.ts Add rarity?: string to LorcanaCard
apps/web/src/features/cards/loader.ts Carry rarity through; confirm classifications/cost/color
apps/web/src/features/reveals/franchise.ts Add ink per franchise (up→sapphire, monsters-inc→emerald, turning-red→ruby)
apps/web/src/pages/RevealsPage.tsx Orchestrate two-view toggle; default to Tracker; reuse EtherealBackground/CompactHeader
apps/web/src/features/reveals/index.ts Export new components/hooks
CLAUDE.md (design-system mirror section) Note reveals redesign if design tokens touched

Testing / Verification

Data

  • pnpm build:engine → succeeds with rarity on LorcanaCard
  • useRevealProgress unit test → per-ink counts sum to total; rarity tallies correct
  • Spotlight counts render Vineling 5 / Team 11 / Red Panda 7 / Hunny 6 / Temporary Shift 3

Tracker view (desktop)

  • /reveals defaults to Tracker view → six rings show real per-ink counts /34
  • Click an ink tile → board swaps; revealed slots show real AVIF art + cost pip + rarity gem
  • Click a revealed slot → card modal opens (unrevealed slots inert)
  • Hero bar + "cards revealed" total match the per-ink counts

Sections

  • New-franchises shows 3 cards with real key art + ink bloom
  • "New this set" shows 3 mechanics + 2 tribes with ★ badges on new classifications only

Toggle + responsive

  • Toggle → existing franchise grid view renders; toggle back → Tracker
  • At 390px: 2-col trackers, 46×64 slots, single-col sections, no horizontal page scroll
  • pnpm check:stories, pnpm test, pnpm build green; pre-push E2E passes

Acceptance Criteria

  • /reveals defaults to the new Tracker view; a toggle switches to the existing franchise-grid view and back
  • Six ink trackers render real per-ink revealed counts out of 34; selecting one swaps the featured board (default Amethyst)
  • Diamond mosaic shows revealed slots with real card art + cost pip + real-rarity gem; unrevealed slots show the placeholder watermark; clicking a revealed slot opens the card modal
  • Rarity breakdown uses each card's real rarity (not the prototype's rank-faked rarity)
  • Hero stats + overall bar derive from the same per-ink counts
  • New-franchises section uses real art/franchises/*.webp with the franchise→ink bloom
  • "New this set" band shows the 3 mechanics + 2 tribe spotlights with correct counts and ★-new badges
  • Fully responsive ~360–430px and desktop; no horizontal page scroll on mobile
  • CompactHeader retained; EtherealBackground reused
  • Every new component has a story; pnpm test + pnpm build pass
  • Existing franchise-grid view (FranchiseTier/useRevealCards) preserved, not deleted

Rollback

  • Phase 0 (engine/loader): git revert the type/loader commit → rarity optional, no consumer breaks (additive field).
  • Tracker view / sections: new components are additive; revert their commits → no effect on other pages.
  • Toggle/integration (RevealsPage.tsx): revert to prior RevealsPage → page returns to franchise-only layout; or set the default-view constant back to 'franchises' to ship the toggle with the old view as default without a revert.
  • Kill switch: set VITE_IS_REVEAL_SEASON=false (Vercel env) → /reveals redirects home, hiding the feature entirely while a fix is prepared.
  • Full rollback: revert the feature PR (squash commit) → page restored to pre-redesign state; rarity field revert optional (harmless if left).

References

  • Design handoffs: apps/web/reveals page redesign/README.md (desktop), .../design_handoff_reveals_page_mobile/README.md (mobile deltas), .../Reveals Page.dc.html (prototype logic: build_board/ring/gem)
  • Current impl: apps/web/src/pages/RevealsPage.tsx, apps/web/src/features/reveals/{Hero,FranchiseTier,franchise,revealDates,useRevealCards,useRevealPhase,useCountdown}.{tsx,ts}
  • Set 13 data: apps/web/public/data/previewCards.json; preview images committed in 3380dcb (Set 13 reveal season, preview-card parser, and Temporary Shift support #388)
  • Mechanics sources: packages/synergy-engine/SHIFT_TARGET_RULE.md (Shift variants), engine Shift-variant work commits c627f6b/ff12db5
  • Theme: apps/web/src/shared/constants/theme.ts (ink colors, easings); ink SVGs apps/web/src/assets/
  • Deferred follow-ups: Floodborn-matters synergy rule (strongest rule-candidate), Red Panda / Hunny tribal rules; reveals promo-card copy refresh; mechanics-card deep-linking; rarity-denominator confirmation when set completes

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew feature or functionalityuiUser interface

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions