# ChicoryTV SPA Design Tokens Themes Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Implement issue #79 by making the SPA consume the ChicoryTV design-system token layer and switch live among the three shipped themes with persistence.

**Architecture:** Keep `design-system/styles.css` as the single token entry imported by `web/src/designSystem.ts`. Add a small typed theme contract in `web/src/designSystem.ts` that applies `data-theme` to `<html>`, maps warm to the design-system default, and persists the selection. Render a compact theme switcher from `App.tsx`, and align `shell.css` to real design-system custom properties.

**Tech Stack:** Vite, React 19, TypeScript, Vitest, Testing Library, CSS custom properties.

---

### Task 1: Theme Contract Tests

**Files:**
- Modify: `web/src/App.test.tsx`

- [x] **Step 1: Write failing tests**

Add tests that assert:
- `applyDesignSystemTheme("warm")` removes `data-theme` from `<html>` and stores `warm`.
- `applyDesignSystemTheme("cool")` sets `data-theme="cool"` and stores `cool`.
- Invalid persisted values fall back to `warm`.
- The app renders three theme buttons and clicking `dual` sets `data-theme="dual"`.

- [x] **Step 2: Run tests to verify failure**

Run: `cd web && npm test -- --run src/App.test.tsx`
Expected: FAIL because the theme functions and switcher do not exist yet.

### Task 2: Minimal Theme Implementation

**Files:**
- Modify: `web/src/designSystem.ts`
- Modify: `web/src/App.tsx`

- [x] **Step 1: Implement theme functions**

Export `designSystemThemes`, `defaultDesignSystemTheme`, `getStoredDesignSystemTheme`, and `applyDesignSystemTheme`.

- [x] **Step 2: Render switcher**

Use React state initialized from `getStoredDesignSystemTheme()`, apply the theme on mount and click, and expose accessible buttons named for Warm chicory, Cool periwinkle, and Dual accent.

- [x] **Step 3: Run focused tests**

Run: `cd web && npm test -- --run src/App.test.tsx`
Expected: PASS.

### Task 3: Token-Aligned Shell CSS

**Files:**
- Modify: `web/src/shell.css`
- Modify: `web/index.html`

- [x] **Step 1: Replace scaffold token names**

Replace non-existent custom properties with actual design-system aliases: `--surface-app`, `--ctv-bg-sunken`, `--surface-card`, `--surface-raised`, `--border-hairline`, `--text-on-accent`, `--ctv-ok-soft`, spacing, radius, type, and motion tokens.

- [x] **Step 2: Use warm default correctly**

Remove `data-theme="warm"` from `web/index.html` so the design-system default `:root` warm theme is used until JavaScript applies persisted state.

- [x] **Step 3: Respect reduced motion**

Add `@media (prefers-reduced-motion: reduce)` rules that disable shell transitions.

### Task 4: Verification

**Files:**
- No further production changes expected.

- [x] **Step 1: Run verification**

Run:
- `cd web && npm test -- --run`
- `cd web && npm run lint`
- `cd web && npm run typecheck`
- `cd web && npm run build`

- [x] **Step 2: Use done skill**

Run the `done` skill workflow for issue #79 before final handoff.
