docs(phase-15): resolve all five open questions
off = fully absent (real draw-skip seam); scroll/zoom binds ScrollSpeed; labels light, lamp toggles green, mild tint from one token. Unify under green = interactive, light = non-interactive.
This commit is contained in:
@@ -251,11 +251,13 @@ A presentation + interaction rework of the **waveform visualizer control surface
|
||||
|
||||
**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).
|
||||
**The one renderer-adjacent touch.** The two new toggles back two new `WaveformVisualizerControlState` booleans (`LavaEnabled` / `WaveformEnabled`, both default true). The bridge (`WaveformVisualizer`) must enable/disable the corresponding subsystem in the WebGL module on `Changed` — the one place this phase reaches past pure presentation. **"Off" means fully absent** (resolved 2026-06-17): the subsystem is not drawn, contributes no collisions, incurs no render cost — not dimmed. This is a **real build**, not a flag flip: the implementer should expect the per-subsystem draw-skip seam **does not yet exist** in `WaveformVisualizer.ts` and that building it is part of 15.A (spec §6, §10.1). Budget the renderer touch as a draw-skip path, not a one-line uniform push.
|
||||
|
||||
**Colour principle — green = interactive, light = non-interactive** (resolved 2026-06-17). One rule governs every control's colour: interactive elements (the lamp toggles, knob arcs/pointers, scroll slider) are **green-accent**; static/decorative elements (the "LAVA:" / "WAVE:" section labels, knob caption icons) are **light**. This unifies the original requirement 5 (icons light), the section-label colour, and the toggle colour into one principle — apply it uniformly, not per-control (spec §5).
|
||||
|
||||
**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`.
|
||||
**Open questions — all RESOLVED 2026-06-17 (spec §10, kept visible):** (1) "off" means **fully absent** (not drawn, no collisions, no render cost — not dimmed); the per-subsystem draw-skip seam is expected **not** to exist yet and building it is part of 15.A; (2) scroll/zoom binds to **`ScrollSpeed` alone**; (3) "LAVA:"/"WAVE:" labels are **light** (green is reserved for interactive elements); (4) toggles are **iconographic lamp toggles** (lit/unlit), **green** because interactive; (5) tint opacity is **mild** and resolves from a **single token/constant** (one point of change, no repeated magic number). **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`.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# 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.**
|
||||
Status: **design-complete, implementation-ready** (all five open questions resolved by Daniel 2026-06-17 —
|
||||
see §10). Author: product-designer. Date: 2026-06-17 (resolutions folded 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**
|
||||
@@ -87,8 +88,10 @@ change; the centering and chrome are the polish around it.
|
||||
`Changed`; `WaveformVisualizer` still subscribes and pushes the affected dial. The bridge cannot tell a
|
||||
knob from a slider from a toggle — it re-reads state on `Changed`. **One bridge addition is required**:
|
||||
the bridge must learn to act on the two new booleans (enable/disable the lava and waveform subsystems in
|
||||
the WebGL module). That is a real renderer-side touch and is the one place this phase reaches past pure
|
||||
presentation — see §6 and the open question §10.1.
|
||||
the WebGL module). "Off" means the subsystem is **genuinely not drawn** (no render cost), which means
|
||||
building a real per-subsystem draw-skip path in `WaveformVisualizer.ts` — the implementer should expect
|
||||
this enable seam **does not yet exist** and is part of the work, not a one-line flag. That is the one
|
||||
place this phase reaches past pure presentation — see §6 and resolved OQ §10.1.
|
||||
- The lava-lamp **trigger glyph** (`DDIcons.LavaLamp`/`LavaLampFilled`) and its placement on each host
|
||||
(Mix `TopRightAction`, Cut/Session ambient, NowPlaying corner). Unchanged.
|
||||
- **Persistence model** — still DI-scoped `WaveformVisualizerControlState`: survives SPA nav, resets on
|
||||
@@ -106,8 +109,10 @@ two toggle states, the visible controls and their order are fully determined.
|
||||
### Row 1 — Mode row (always visible)
|
||||
|
||||
Left to right:
|
||||
1. **Lava toggle** — on/off toggle button. Turns the lava field on/off.
|
||||
2. **Waveform toggle** — on/off toggle button. Turns the waveform ribbon on/off.
|
||||
1. **Lava toggle** — an **iconographic lamp toggle** (lit/unlit lamp glyph), **green** (interactive, per
|
||||
the §5 colour principle). Turns the lava field on/off. (Resolved 2026-06-17 — OQ §10.4.)
|
||||
2. **Waveform toggle** — an **iconographic lamp toggle** (lit/unlit), **green** (interactive). Turns the
|
||||
waveform ribbon on/off. Same lamp-toggle treatment as the lava toggle for a consistent row-1 pair.
|
||||
3. **Collisions knob** — visible **only if BOTH lava AND waveform are on** (collisions are the interaction
|
||||
between the two subsystems; with only one present there is nothing to collide). Backed by
|
||||
`CollisionStrength`.
|
||||
@@ -121,7 +126,8 @@ not reflow the color knob leftward.
|
||||
|
||||
### Row 2 — LAVA section (visible only if lava is on)
|
||||
|
||||
A label **"LAVA:"** (mono, uppercase, light — the NowPlaying `.np-label` idiom) then, left to right:
|
||||
A label **"LAVA:"** (mono, uppercase, **light** — NowPlaying `.np-label` *typography*, recoloured light per
|
||||
the §5 colour principle: labels are static, so light) then, left to right:
|
||||
- **Gravity** knob — `LavaGravity`.
|
||||
- **Heat** knob — `LavaHeat`.
|
||||
- **Fluid amount** knob — `FluidAmount`.
|
||||
@@ -136,9 +142,8 @@ A label **"WAVE:"** (same idiom as LAVA:) then, left to right:
|
||||
- **Scroll/zoom slider** — a **slider, not a knob** (the one widget-type change this phase makes; §8).
|
||||
Backed by `ScrollSpeed`. Rationale: scroll/zoom is a "position along a continuum" feel — a horizontal
|
||||
slider reads that more naturally than a rotary knob, and it visually distinguishes the one
|
||||
spatial/temporal control from the eight physical-property knobs. (Open question §10.2: is it
|
||||
`ScrollSpeed` alone, or does "scroll/zoom" want the zoom mapping too? `ScrollSpeed` is the only matching
|
||||
dial that exists; treated as `ScrollSpeed` here.)
|
||||
spatial/temporal control from the eight physical-property knobs. **Binds to `ScrollSpeed` alone**
|
||||
(confirmed 2026-06-17 — OQ §10.2); no separate zoom dimension is folded in.
|
||||
- **Width** knob — pinned to the **far right** of row 3. `WaveformWidth`.
|
||||
|
||||
### Visibility truth table
|
||||
@@ -201,8 +206,11 @@ the documented fallback — note it and escalate rather than hand-rolling a fixe
|
||||
|
||||
- Lava-lamp icon click → open the overlay (the icon trigger and its glyph are unchanged from Phase 12).
|
||||
- Overlay visible → a **slight page tint** behind the panel so the panel reads as modal (Daniel:
|
||||
"slight tint … reads as modal"). Use `MudOverlay`'s dark background at a **low opacity** — slight, not a
|
||||
blackout. Recommend ~0.3–0.4 scrim alpha; final value is Daniel's to eyeball on screen.
|
||||
"slight tint … reads as modal"). Use `MudOverlay`'s dark background at a **mild** opacity — slight, not a
|
||||
blackout (resolved 2026-06-17 — OQ §10.5: go mild). **The tint opacity must have one single point of
|
||||
truth** — a single token/constant (e.g. a `--deepdrft-modal-scrim-alpha` token in `deepdrft-tokens.css`,
|
||||
or one named const), **not a magic number repeated at call sites.** Mild ≈ 0.3 alpha as a starting eyeball
|
||||
value, set once in that single token so a future change is one edit.
|
||||
- Click the tint (outside the panel) → close. Mirror `SharePopover`: `OnClick` on the overlay closes.
|
||||
- **`AutoClose` stays off / outside-click must not fire during a knob drag.** RadialKnob mounts its own
|
||||
full-viewport `position:fixed; z-index:9999` mouse-capture div while dragging (see `RadialKnob.razor`
|
||||
@@ -228,6 +236,24 @@ still cannot reach the panel. Panel chrome **stays in the global `deepdrft-style
|
||||
|
||||
## 5. Look and feel — NowPlayingCard tokens
|
||||
|
||||
### Color principle (governs every control's colour, resolved 2026-06-17)
|
||||
|
||||
**green = interactive, light = non-interactive.** This single rule decides the colour of every element on
|
||||
the panel:
|
||||
- **Interactive** elements — the two lamp **toggles** (§3 row 1, §10.4), the knob **arcs/pointers**, the
|
||||
scroll **slider** track/thumb, and any other control the user can grab — are **green-accent**
|
||||
(`--deepdrft-green-accent` / the pinned `--mud-palette-primary`).
|
||||
- **Static / decorative** elements — the **"LAVA:" / "WAVE:" section labels** (§10.3), the knob **caption
|
||||
icons** (§9, requirement 5), and any other label or ornament the user cannot act on — are **light**
|
||||
(`--deepdrft-white`).
|
||||
|
||||
This is one rule, not three instructions: Daniel's original requirement 5 (caption icons light), OQ3
|
||||
(section labels light), and OQ4 (toggles green because interactive) are all the same principle. Apply it
|
||||
uniformly; do not colour controls case-by-case. The affected sections below reference back to this rule
|
||||
rather than restating the rationale.
|
||||
|
||||
### Chrome
|
||||
|
||||
The panel chrome follows `NowPlayingCard` (`.now-playing` in `NowPlayingCard.razor.css`): **square
|
||||
corners, a lighter-navy ground, a thin light border.**
|
||||
|
||||
@@ -237,7 +263,7 @@ corners, a lighter-navy ground, a thin light border.**
|
||||
| Ground | `rgba(250,250,248,0.06)` over a dark surface | **lighter navy** — `--deepdrft-navy-mid` (current) is acceptable; Daniel says "lighter navy," so favour navy-mid over the darkest navy. Confirm on screen. |
|
||||
| Border | `1px solid rgba(250,250,248,0.12)` (thin, light) | **thin light border** — replace the current `--deepdrft-border-green` with a faint light border in the NowPlayingCard spirit (light-on-dark, ~0.12 alpha). |
|
||||
| Backdrop | `backdrop-filter: blur(8px)` | optional — nice over the visualizer; cheap on a small modal panel. Taste call. |
|
||||
| Label type | `--deepdrft-font-mono`, 0.6rem, 0.25em tracking, uppercase, `--deepdrft-green-accent` | reuse this idiom for the **"LAVA:" / "WAVE:" section labels** (§3). Daniel wants light icons (§9) but the *text labels* matching the NowPlaying green-accent label is consistent — confirm whether labels are green-accent (matching `.np-label`) or light (matching the icon change). **Open question §10.3.** |
|
||||
| Label type | `--deepdrft-font-mono`, 0.6rem, 0.25em tracking, uppercase, `--deepdrft-green-accent` | reuse this **typographic** idiom (mono/tracking/uppercase) for the **"LAVA:" / "WAVE:" section labels** (§3), but recolour to **light** (`--deepdrft-white`), not green-accent. Labels are static, so by the colour principle above they are light; green is reserved for interactive elements. (Resolved 2026-06-17 — OQ §10.3.) |
|
||||
| Knob palette pins | n/a | keep the existing pinned `--mud-palette-*` → Hero tokens block (green-accent arc, navy center, light label). **Except**: icon colour changes to light (§9). |
|
||||
|
||||
The existing global block `.waveform-visualizer-control-panel.mix-visualizer-controls-bar` is where most of
|
||||
@@ -262,12 +288,17 @@ out-of-the-box state — no visible change on first open.
|
||||
|
||||
The two toggles mutate their boolean + call `NotifyChanged()`, exactly as the knobs do. **The bridge
|
||||
(`WaveformVisualizer`) must learn to act on these two booleans** — on `Changed`, read `LavaEnabled` /
|
||||
`WaveformEnabled` and enable/disable the corresponding subsystem in the WebGL module (push an `enable`
|
||||
uniform/flag, or skip the subsystem's draw). This is the one renderer-adjacent touch in the phase. The
|
||||
exact JS-module surface (a `setLavaEnabled(bool)` / `setWaveformEnabled(bool)` interop pair, or folding
|
||||
into existing uniform pushes) is **staff-engineer's call against the live `WaveformVisualizer.ts`** — see
|
||||
open question §10.1. The C# side of the seam is fully specified here; the TS side is a small additive
|
||||
uniform/branch.
|
||||
`WaveformEnabled` and enable/disable the corresponding subsystem in the WebGL module.
|
||||
|
||||
**"Off" means fully absent (resolved 2026-06-17 — OQ §10.1).** When a subsystem is off it is **not drawn,
|
||||
contributes no collisions, and incurs no render cost.** It is *not* dimmed, *not* drawn-then-hidden, *not*
|
||||
faded — the subsystem's draw path is genuinely skipped. This sharpens the renderer touch beyond a flag
|
||||
toggle: **the implementer should check `WaveformVisualizer.ts` for an existing per-subsystem enable seam
|
||||
but should expect it does not yet exist.** Building that enable/disable seam — a real "don't render this
|
||||
subsystem" path (skip the draw call / early-out, not a `visible=false` uniform on a subsystem that still
|
||||
runs) — is **part of the work**, not a found primitive to flip. This is the one place the phase reaches
|
||||
into the renderer, and it is a small build, not a one-line uniform push. The C# side of the seam is fully
|
||||
specified here; the TS side is the additive draw-skip path staff-engineer builds against the live module.
|
||||
|
||||
Conditional-visibility logic (§3) reads these same booleans in `WaveformVisualizerControls.razor` `@if`
|
||||
guards — single source of truth, no duplicated flag.
|
||||
@@ -321,11 +352,12 @@ keep their types.
|
||||
|
||||
The knob caption icons today are tinted `--deepdrft-green-accent` (global rule
|
||||
`.waveform-visualizer-control-panel .waveform-visualizer-control-icon { color: var(--deepdrft-green-accent); }`).
|
||||
Daniel wants them **light**. Change that rule's `color` to `--deepdrft-white` (the panel's light token),
|
||||
keeping the `opacity: 0.85`. This is a one-line token swap in the global sheet. The knob **arcs/pointers
|
||||
stay green-accent** (the `--mud-palette-primary` pin) — only the Material caption *icons* go light. (This
|
||||
is why §5's section-label colour is an open question §10.3 — with icons now light, a green-accent text
|
||||
label may look inconsistent; Daniel decides.)
|
||||
Daniel wants them **light** — this is the §5 colour principle applied: caption icons are static/decorative,
|
||||
so light. Change that rule's `color` to `--deepdrft-white` (the panel's light token), keeping the
|
||||
`opacity: 0.85`. This is a one-line token swap in the global sheet. The knob **arcs/pointers stay
|
||||
green-accent** (the `--mud-palette-primary` pin) — they are the interactive part of the control, so green
|
||||
by the same principle. Only the Material caption *icons* go light. The "LAVA:" / "WAVE:" section labels go
|
||||
light by the same rule (§5, §10.3 resolved).
|
||||
|
||||
The scoped fallback rule (`.mix-visualizer-control ::deep .mix-visualizer-control-icon` in the
|
||||
`.razor.css`) tints to `--mud-palette-primary` for the legacy inline mount — if that mount is dead post-
|
||||
@@ -333,27 +365,27 @@ Phase-12, this is moot; if it survives, align it to light too for consistency. F
|
||||
|
||||
---
|
||||
|
||||
## 10. Open questions for Daniel
|
||||
## 10. Open questions for Daniel — all RESOLVED 2026-06-17
|
||||
|
||||
1. **Bridge action on the new toggles (§6).** Disabling a subsystem in the renderer — does the WebGL module
|
||||
already have an enable/disable path per subsystem (lava draw, waveform draw), or does this need new
|
||||
interop (`setLavaEnabled` / `setWaveformEnabled`)? This is the one renderer-side touch; staff-engineer
|
||||
confirms against `WaveformVisualizer.ts`. **Does Daniel want "off" to mean fully not-drawn, or
|
||||
faded/dimmed?** (Recommend: fully not-drawn — a toggle should read as on/off, not a dimmer.)
|
||||
2. **Scroll/zoom binding (§3, §8).** "Scroll/zoom" — is this `ScrollSpeed` alone (the only matching dial),
|
||||
or does Daniel also want a zoom/resolution dimension folded in? The standalone resolution control was
|
||||
removed in Phase 10 (folded into scroll speed via `WaveformZoomMapping`). Treated here as `ScrollSpeed`;
|
||||
confirm.
|
||||
3. **Section-label colour (§5, §9).** With caption icons going light, should the "LAVA:" / "WAVE:" section
|
||||
labels be green-accent (matching NowPlayingCard's `.np-label`) or light (matching the new icon colour)?
|
||||
Recommend **green-accent** — it preserves the NowPlayingCard label idiom and gives the rows a colour
|
||||
anchor against the otherwise-light controls. Daniel's eye.
|
||||
4. **Toggle widget (§3 row 1).** Daniel said "toggle buttons." Recommend `MudToggleIconButton` or a
|
||||
`MudButton` pair styled to the panel (lit/unlit), so each toggle reads as on/off at a glance — possibly
|
||||
reusing the lava-lamp lit/unlit glyph spirit for the lava toggle. Exact widget is staff-engineer's;
|
||||
confirm whether Daniel wants iconographic toggles (lamp lit/unlit, waveform shown/hidden) or plain
|
||||
text/switch toggles.
|
||||
5. **Tint opacity (§4).** "Slight" tint — recommend ~0.3–0.4 scrim alpha. Daniel eyeballs final.
|
||||
(Kept visible per the project convention: resolved OQs are marked, not deleted.)
|
||||
|
||||
1. **Bridge action on the new toggles (§6). — RESOLVED 2026-06-17:** "Off" means **fully absent** — the
|
||||
subsystem is not drawn, contributes no collisions, and incurs **no render cost** (not dimmed, not
|
||||
drawn-then-hidden). The implementer should check `WaveformVisualizer.ts` for an existing per-subsystem
|
||||
enable seam but should **expect it does not yet exist**; building that genuine "don't render this
|
||||
subsystem" path (skip the draw, not a no-op `visible` uniform) is **part of the work**. This is a real
|
||||
renderer-side build, not a one-line flag toggle. (Reflected in §6 and the 15.A track scope.)
|
||||
2. **Scroll/zoom binding (§3, §8). — RESOLVED 2026-06-17:** The scroll/zoom slider binds to **`ScrollSpeed`
|
||||
alone**. No separate zoom/resolution dimension is folded in.
|
||||
3. **Section-label colour (§5, §9). — RESOLVED 2026-06-17:** "LAVA:" / "WAVE:" labels are **LIGHT**, not
|
||||
green. Rationale: green is reserved for interactive elements; labels are static, so light. (This is the
|
||||
§5 colour principle — green = interactive, light = non-interactive.)
|
||||
4. **Toggle widget (§3 row 1). — RESOLVED 2026-06-17:** The toggles **ARE iconographic lamp toggles**
|
||||
(lit/unlit lamp glyph), and they are **green because they are interactive** (the §5 colour principle).
|
||||
Not plain text/switch toggles.
|
||||
5. **Tint opacity (§4). — RESOLVED 2026-06-17:** Go **mild**. There must be **one single point of
|
||||
truth/change** for the tint opacity — a single token/constant, not a magic number repeated at call
|
||||
sites. (≈ 0.3 alpha as a starting eyeball value, set once in that token.)
|
||||
|
||||
---
|
||||
|
||||
@@ -371,13 +403,17 @@ Phase-12, this is moot; if it survives, align it to light too for consistency. F
|
||||
far-right of row 1 and does not reflow when collisions hides; both-off leaves toggles + color only.
|
||||
5. **Chrome:** panel has square corners, lighter-navy ground, thin light border — visibly matching
|
||||
NowPlayingCard's treatment. All colours token-sourced; no new hardcoded hex.
|
||||
6. **Widget types:** scroll/zoom is a slider; the other seven continuous controls are knobs; lava/waveform
|
||||
are toggle buttons.
|
||||
7. **Icons light:** knob caption icons render light (not green-accent); knob arcs/pointers stay green-accent.
|
||||
6. **Widget types:** scroll/zoom is a slider bound to `ScrollSpeed` alone; the other seven continuous
|
||||
controls are knobs; lava/waveform are **iconographic lamp toggles** (lit/unlit).
|
||||
7. **Colour principle (green = interactive, light = non-interactive):** knob caption icons render **light**;
|
||||
"LAVA:" / "WAVE:" section labels render **light**; knob arcs/pointers, the scroll slider, and the lamp
|
||||
toggles render **green-accent**. No control is coloured against this rule. The tint scrim alpha resolves
|
||||
from a single token/constant (one point of change), set to a mild value.
|
||||
8. **Tooltips:** every control has a hover tooltip with the playful copy (§7, as approved); group
|
||||
`aria-label`s remain for screen readers.
|
||||
9. **Toggles persist + drive the renderer:** flipping lava/waveform off visibly removes that subsystem from
|
||||
the visualizer; the state survives SPA nav and resets on fresh load (DI-scoped state). Both default on.
|
||||
9. **Toggles persist + drive the renderer:** flipping lava/waveform off **fully removes** that subsystem
|
||||
from the visualizer — not drawn, no collisions, no render cost (not dimmed). The state survives SPA nav
|
||||
and resets on fresh load (DI-scoped state). Both default on.
|
||||
10. **No regression:** the read-only contract holds (no control seeks); the eight existing dials behave
|
||||
exactly as before when their subsystem is on; the bridge `Changed` seam is intact.
|
||||
|
||||
@@ -392,12 +428,16 @@ to ship as a single PR if Daniel prefers (recommend one bundled PR — the track
|
||||
one component pair and splitting would be churn); the decomposition below is for orientation and parallel
|
||||
reasoning, not a mandate to split.
|
||||
|
||||
### 15.A — State booleans + bridge wiring (load-bearing prerequisite)
|
||||
### 15.A — State booleans + bridge wiring + per-subsystem draw-skip seam (load-bearing prerequisite)
|
||||
- Add `LavaEnabled` / `WaveformEnabled` (+ `Default*` consts) to `WaveformVisualizerControlState`.
|
||||
- Teach `WaveformVisualizer` (the bridge) to push the two booleans to the WebGL module on `Changed`
|
||||
(resolves OQ §10.1 with staff-engineer).
|
||||
- Teach `WaveformVisualizer` (the bridge) to push the two booleans to the WebGL module on `Changed`.
|
||||
- **Build the per-subsystem enable/disable seam in `WaveformVisualizer.ts`** so an "off" subsystem is
|
||||
**genuinely not drawn** (no render cost — skip the draw path, not a `visible=false` uniform on a
|
||||
still-running subsystem). Per OQ §10.1, expect this seam **does not yet exist** — building it is part of
|
||||
this track, not flipping a found flag. This is the one real renderer-side build in the phase.
|
||||
- **Touches:** `Services/WaveformVisualizerControlState.cs`, `Controls/WaveformVisualizer.razor`(.cs),
|
||||
and the TS module `DeepDrftPublic/Interop/visualizer/WaveformVisualizer.ts` (the one renderer touch).
|
||||
and the TS module `DeepDrftPublic/Interop/visualizer/WaveformVisualizer.ts` (the one renderer touch —
|
||||
now a build, not a uniform push; budget for it accordingly).
|
||||
- **Gates:** 15.B, 15.C.
|
||||
|
||||
### 15.B — Screen-centered tinted modal primitive + NowPlayingCard chrome
|
||||
|
||||
Reference in New Issue
Block a user