---
estimated_steps: 44
estimated_files: 3
skills_used: []
---

# T02: Redesign TechniquePage — meta line, video filenames, monospace signal chains

Redesign the frontend technique page to match the spec layout. Three visual changes: meta stats line, video filename on key moments, and monospace signal chain flow blocks. All CSS must use existing `var(--*)` tokens.

## Steps

1. In `frontend/src/api/public-client.ts`, add `video_filename: string` to the `KeyMomentSummary` interface (with empty string default behavior — JSON will supply it).

2. In `frontend/src/pages/TechniquePage.tsx`, add a meta stats line between the header and summary sections:
   - Compute unique source count: `new Set(technique.key_moments.map(km => km.video_filename).filter(Boolean)).size`
   - Moment count: `technique.key_moments.length`
   - Last updated: format `technique.updated_at` as a readable date
   - Render: `<div className="technique-header__stats">Compiled from {N} source{s} · {M} key moment{s} · Last updated {date}</div>`

3. In the key moments section, add the video filename between the title and timestamp:
   ```tsx
   {km.video_filename && (
     <span className="technique-moment__source">{km.video_filename}</span>
   )}
   ```

4. Redesign the signal chains section. Replace the `<ol className="technique-chain__steps">` with a monospace flow block:
   ```tsx
   <div className="technique-chain__flow">
     {steps.map((step, j) => (
       <span key={j}>
         {j > 0 && <span className="technique-chain__arrow"> → </span>}
         <span className="technique-chain__step">{String(step)}</span>
       </span>
     ))}
   </div>
   ```

5. In `frontend/src/App.css`, add CSS classes using only `var(--*)` tokens:
   - `.technique-header__stats` — secondary text color, smaller font, margin below header
   - `.technique-moment__source` — truncated text, muted color, monospace-ish, smaller font
   - `.technique-chain__flow` — monospace font, horizontal wrap, background surface, padding, border-radius
   - `.technique-chain__arrow` — accent color (cyan)
   - `.technique-chain__step` — inline display
   - Remove or restyle `.technique-chain__steps` (the old `<ol>` style)

6. Run `cd frontend && npm run build` to verify zero TypeScript errors.

7. Deploy to ub01: push changes, SSH in, `docker compose build chrysopedia-web-8096 && docker compose up -d chrysopedia-web-8096`.

## Constraints
- All CSS colors MUST use `var(--*)` tokens. The S02 dark theme established 84 semantic custom properties. Grep verification: `grep -P '#[0-9a-fA-F]{3,8}' frontend/src/App.css | grep -v ':root' | grep -v '^\/\*'` should return zero new hex colors.
- Do NOT modify `:root` custom property definitions unless adding a genuinely new semantic token.

## Must-Haves

- [ ] TypeScript `KeyMomentSummary` includes `video_filename: string`
- [ ] Meta stats line renders below technique title
- [ ] Key moment rows show video filename
- [ ] Signal chains render as monospace flow with arrow separators
- [ ] All new CSS uses `var(--*)` tokens only
- [ ] `npm run build` succeeds with zero errors

## Inputs

- `frontend/src/api/public-client.ts`
- `frontend/src/pages/TechniquePage.tsx`
- `frontend/src/App.css`
- `backend/schemas.py`

## Expected Output

- `frontend/src/api/public-client.ts`
- `frontend/src/pages/TechniquePage.tsx`
- `frontend/src/App.css`

## Verification

cd frontend && npm run build 2>&1 | tail -5 && echo 'BUILD OK' && grep -cP '#[0-9a-fA-F]{3,8}' src/App.css | grep -v ':root' || echo 'No hardcoded colors outside :root'
