docs(plan): add Phase 20 Theater Mode spec and roadmap entry

This commit is contained in:
daniel-c-harvey
2026-06-20 19:08:44 -04:00
parent 54cba7eea0
commit 021801999c
2 changed files with 380 additions and 0 deletions
+53
View File
@@ -443,6 +443,59 @@ not the same work; this phase does not satisfy or depend on that one.
---
## Phase 20 — Theater Mode (public Release Detail views)
A presentation-only feature on the **public listener site** (`DeepDrftPublic` / `DeepDrftPublic.Client`;
**no CMS, no API, no data, no schema change**). On a Release Detail view, a new toggle clears the page
chrome away from the visualizer: hide the release content (`@if`-gated header/meta/track-list/blurb and
the Session/Mix hero overlay) so the lava-lamp + waveform field fills the surface unobstructed, while
the **player bar grows** to carry the release identity the hidden page would otherwise show — cover art,
release title, and a release-mode share. Borrowed namesake: YouTube/Twitch "theater mode" — collapse the
surrounding chrome to let the media (here, the visualizer) take over, one reversible toggle. Full design,
component-by-component placement, the SOLID state seam, theming reuse, acceptance criteria, and open
questions: `product-notes/phase-20-theater-mode.md`.
**Scope — the three detail views (verified):** `Pages/CutDetail.razor` (scaffold `Ambient` visualizer),
`Pages/SessionDetail.razor` (mounts the visualizer directly — **does not** use `ReleaseDetailScaffold`),
`Pages/MixDetail.razor` (scaffold, full-bleed mode-A visualizer). The feature must behave **identically**
across all three; the Session-doesn't-use-the-scaffold asymmetry is the key constraint the state design
works around.
**Architectural spine.** **One boolean, multiple observers** (memory: *one source, multiple views*).
Recommended home: **widen `WaveformVisualizerControlState` with a `TheaterMode` flag** (Option A — the
object is already scoped, session-persistent, observed via its `Changed` event, gated on the same
`LavaEnabled || WaveformEnabled` the Theater button reads, and *explicitly designed to widen by adding a
field + default*); the SRP-purist alternative is a dedicated `TheaterModeState` holder (Option B). The
**detail pages own only the content `@if`** (each page gates the fragments it renders, so the scaffold
stays Theater-unaware and Session is covered the same way); the **player bar owns only the enlargement**
(reads `CurrentTrack.Release` — `Title`/`ImagePath`/`EntryKey`/`Medium`, all already on the DTO — and
renders a small `NowShowingPanel` presentational sub-component); the **toggle button owns only the
mutation**. No page reaches into the bar; the bar reaches into no page.
**Theming (DRY — hard requirement).** The toggle is a `MudIconButton` in `.dd-accent-icon` (green-accent
glyph both themes, zero new CSS — same as the lava-lamp trigger it sits beside); the enlarged bar binds
existing theme-aware aliases (`--deepdrft-page-surface`/`-text`/`-text-muted`), reuses the
`deepdrft-track-detail-cover-art` cover idiom, and wraps the release `SharePopover` in `.dd-accent-icon`.
**No new dark overrides, no new palette `Color`, no new token family.**
**Button placement + gating.** A new right-side icon button immediately **left of the lava-lamp toggle**,
visible only when `LavaEnabled || WaveformEnabled`, disabled until interactive, with an on/off active
state. Material `Theaters` glyph for v1 (bespoke `DDIcons` deferred — Phase 17 OQ7 precedent).
**Open questions for Daniel (spec §9) — none block a first cut, but several are genuine product calls:**
(OQ1) Theater icon — Material `Theaters` vs. bespoke (recommend Material now); (OQ2) bar enlargement when
nothing is playing — page's release vs. playing-release-only (recommend playing-only, keeps the seam
clean); (OQ3) state home — Option A widen vs. Option B dedicated holder; (OQ4) back link stays in Theater
(recommend keep — it's navigation chrome); (OQ5) persistence — session-scoped/reset-on-reload vs. cookie
(recommend session-scoped, matches visualizer-state precedent); (OQ6) Theater on the home hero/NowPlaying
panel too, or detail-pages-only (recommend detail-pages-only for v1, as scoped).
**Status: proposed — awaiting Daniel sign-off on §9 before scoping waves.** Cold-start once signed off;
no dependency on any in-flight phase (Phases 11/16/17 — the player bar, queue, and visualizer it builds
on — are all complete).
---
## Working with this file
- **Add items by extending an existing phase first**; only create a new phase when the addition genuinely doesn't fit any of 15. Phase numbers are organisational, not sequencing.