# SPA modularization — App.tsx screen/shell extraction epic (#243)

Why the ChicoryTV SPA was decomposed out of a monolithic `App.tsx`, and the conventions the
extraction froze (single-file screens, screen-owned route wrappers, explicit primary-action
ownership). Pure structural moves — no API/route/CSS/behavior change — so the rationale is
about *boundaries*, relocated from the append-only `docs/decisions.md` at the v26.9.0
consolidation. Cross-links: `docs/spa-conventions.md` §2/§6/§10.

Issue trail: epic #243 — phase 1 #244 (Channels), phase 2 #245 (Playouts), phase 4 #247
(shell/routing + primary actions). Refs #238 #230.

## Contents

---

## Records formerly in this file

Each record below moved to its own file under `records/` (ersatztv#610); the rationale is
unchanged. Resolve by **key** — that is the stable identity. A date-based pointer from
another doc or an old issue comment should land here and then follow the link.

- 2026-07-11 — Channels screen extraction (#244): single-file screen, no sibling helper dir (epic #243 phase 1) — [`spa.channels-screen-extraction`](records/spa/channels-screen-extraction.md)
- 2026-07-14 — Playouts screen extraction (#245): screen-owned route wrapper (epic #243 phase 2) — [`spa.playouts-screen-extraction`](records/spa/playouts-screen-extraction.md)
- 2026-07-15 — App shell/routing extraction + explicit primary-action ownership (#247) — [`spa.app-shell-extraction`](records/spa/app-shell-extraction.md)
