From 6f00c6fa54fcd86a1bfaf9a4fc9931b14091fe8d Mon Sep 17 00:00:00 2001 From: daniel-c-harvey Date: Wed, 17 Jun 2026 13:44:00 -0400 Subject: [PATCH] docs(phase-15): spec visualizer controls enhancements (modal popover, sectioned layout, lava/waveform toggles) --- PLAN.md | 20 + ...ase-15-visualizer-controls-enhancements.md | 439 ++++++++++++++++++ 2 files changed, 459 insertions(+) create mode 100644 product-notes/phase-15-visualizer-controls-enhancements.md diff --git a/PLAN.md b/PLAN.md index bd28d87..5076889 100644 --- a/PLAN.md +++ b/PLAN.md @@ -239,6 +239,26 @@ Sequenced as **eight waves**; the critical path is `11.A → 11.B → 11.C → 1 --- +## Phase 15 — Visualizer Controls Enhancements + +A presentation + interaction rework of the **waveform visualizer control surface** — the eight-RadialKnob panel (Phase 12) hosted by `WaveformVisualizerControlPopover`. **Not** a renderer change: the WebGL2 visualizer, the eight continuous dial values + their defaults, and the `Changed`-event bridge seam are all unchanged. This phase reworks how the controls are *reached and presented*, adds **two on/off toggles** (lava, waveform), and gives the panel a **deterministic, sectioned layout** that encodes the visualizer's composition (lava field + waveform ribbon, optionally overlaid). Full design, layout contract, primitive rationale, tooltip copy, acceptance, and wave decomposition: `product-notes/phase-15-visualizer-controls-enhancements.md`. + +**Phase number:** 14 is taken by the `p14-w1-releases-consolidation` worktree (concurrent session); 13 is the highest landed phase in `COMPLETED.md`. 15 is the next free number. + +**The load-bearing reframe.** Today the eight knobs read as a flat, equal grid — the user cannot tell which knobs drive the lava vs. the waveform, and neither subsystem can be turned off. The new layout sections the controls by subsystem and the two toggles make "lava only" / "waveform only" first-class. The screen-centering and chrome are polish around that. + +**Daniel's five requirements (verbatim intent):** (1) panel look-and-feel follows `NowPlayingCard` — square corners, lighter navy, thin light border; (2) popover becomes **screen-centered + modal-tinted** — use the right MudBlazor overlay primitive, do not fight an anchored popover into the center; (3) deterministic three-row layout — **row 1:** lava toggle, waveform toggle, then (only if both on) collisions knob, then color knob far-right; **row 2 (lava on):** "LAVA:" + Gravity/Heat/two-Fluid knobs; **row 3 (waveform on):** "WAVE:" + scroll/zoom **slider** + width knob far-right; (4) playful, non-technical tooltip per control; (5) knob caption icons go **light**, not accent-green. + +**Primitive decision (spec §4): `MudOverlay` (centered, `DarkBackground` tint, modal), not `MudPopover`.** `MudPopover` is by design *anchored* to its trigger — screen-centering means fighting its positioning model (the "do not fight MudBlazor" Daniel called out). `MudOverlay` gives screen-centering + the modal tint with the smallest delta from today's idiom (we already host a `MudOverlay` for dismissal; it graduates from transparent click-catcher to tinted scrim that holds the panel). `MudDialog` is the documented fallback if `MudOverlay` centering fights the knob-drag overlay — escalate, don't hand-roll a fixed-position div. CSS-isolation constraint persists (overlay portals content out of the subtree → panel chrome stays in the **global** `deepdrft-styles.css`, not the scoped `.razor.css`). + +**The one renderer-adjacent touch.** The two new toggles back two new `WaveformVisualizerControlState` booleans (`LavaEnabled` / `WaveformEnabled`, both default true). The bridge (`WaveformVisualizer`) must learn to enable/disable the corresponding subsystem in the WebGL module on `Changed` — the one place this phase reaches past pure presentation. The C# seam is fully specified; the TS-side enable/disable surface is staff-engineer's call against the live module (spec §6, open question §10.1). + +**Sequenced as one wave, four tracks** (small enough to ship as a single bundled PR — recommended, since the tracks are tightly coupled around one component pair and splitting would be churn): **15.A** state booleans + bridge wiring (load-bearing); **15.B** screen-centered tinted-modal primitive + NowPlayingCard chrome; **15.C** deterministic re-layout + toggles + scroll-slider; **15.D** tooltips + light icon colour. Dependency shape: `15.A → {15.B, 15.C} → 15.D`. + +**Open questions for Daniel (spec §10):** (1) does "off" mean fully not-drawn or dimmed (recommend not-drawn), and does the WebGL module already have a per-subsystem enable path; (2) scroll/zoom binds to `ScrollSpeed` alone (the only matching dial) — confirm; (3) "LAVA:"/"WAVE:" labels green-accent (NowPlayingCard idiom) or light to match the new icons (recommend green-accent); (4) toggle widget — iconographic (lamp lit/unlit, waveform shown/hidden) vs. plain switch; (5) tint opacity (~0.3–0.4, Daniel eyeballs). **Post-landing doc-keeper note** (not this phase's work): root `CLAUDE.md` wrongly places `DDIcons.cs` in `DeepDrftPublic.Client.Common` — it lives in `DeepDrftShared.Client/Common`. + +--- + ## 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 1–5. Phase numbers are organisational, not sequencing. diff --git a/product-notes/phase-15-visualizer-controls-enhancements.md b/product-notes/phase-15-visualizer-controls-enhancements.md new file mode 100644 index 0000000..e72aa58 --- /dev/null +++ b/product-notes/phase-15-visualizer-controls-enhancements.md @@ -0,0 +1,439 @@ +# Phase 15 — Visualizer Controls Enhancements (Design Spec) + +Status: **design-complete, implementation-ready** (with open questions flagged at §10). Author: +product-designer. Date: 2026-06-17. **No code has been written by this doc.** + +This is a presentation + interaction rework of the **waveform visualizer control surface** — the eight +RadialKnob panel introduced in Phase 12 and hosted by `WaveformVisualizerControlPopover`. It does **not** +touch the WebGL2 renderer, the `WaveformVisualizerControlState` value model, the `Changed`-event bridge +seam, or any playback path. It is a widget/layout/primitive rework of how the controls are *presented and +reached*, and it adds **two new on/off toggles** (lava, waveform) plus **deterministic conditional +visibility** of the existing knobs. The visualizer stays read-only — no control added here is a seek +surface (the standing read-only contract, Phase 10 §D / Phase 12). + +## Phase numbering + +This is **Phase 15**, not 14. Phase 13 (CMS Public Landing) is the highest landed phase in +`COMPLETED.md`. Phase **14** is in active use by the `p14-w1-releases-consolidation` worktree (another +concurrent session). A second worktree, `nowplaying-card-reactivity`, is also live and touches the +NowPlaying surface this phase is adjacent to — so 14 is taken and 15 is the next genuinely-free number. + +Cross-references (read these before implementing): +- `DeepDrftPublic.Client/Controls/WaveformVisualizerControls.razor[.css]` — the eight-knob panel being + re-laid-out. Today: a `flex-wrap` grid of eight knobs in `.mix-visualizer-controls-bar`, gated only by a + single `Visible` bool. +- `DeepDrftPublic.Client/Controls/WaveformVisualizerControlPopover.razor` — the `MudPopover`-based host + being re-primitived (§4). Today: `MudPopover Fixed` anchored to the lava-lamp trigger + a transparent + `MudOverlay` for dismissal (no tint). +- `DeepDrftPublic.Client/Controls/NowPlayingCard.razor[.css]` — the **look-and-feel reference** for the + panel chrome (§5). Square corners, faint light border, light type on a dark ground. +- `DeepDrftPublic.Client/Controls/SharePopover.razor` — the established overlay/dismissal idiom + (`MudOverlay Visible OnClick`, `AutoClose` off so a knob drag does not dismiss). Carry it forward. +- `DeepDrftShared.Client/Components/RadialKnob.razor` — **consumed, not modified.** Fixed API. Note: it + emits a single `