diff --git a/CONTEXT.md b/CONTEXT.md index 36c90d0..c8ecde4 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -2462,6 +2462,137 @@ payload bump), gated on T-KEYTRK; plus a **Wave 2 shell-integration item** (the Zone-panel curve-editor UI through the L1 kit), gated on the foundation track and composing with the S-VIEW-2 Sample face + S-VIEW-3 envelope overlay. +### The Sample-face recomposition — full-width hero, knob deck, curve popup (r11; Daniel, 2026-07-27) + +> **Additive S-VIEW revision (r11) — the layout spec for the Wave B editor rebuild.** Recomposes +> the landed S-VIEW-1..10 Sample face after Daniel's DAW pass: **every linear slider becomes a +> small radial knob** grouped into a fenced **knob deck**, the two **mode toggles shrink** from +> full-width control rows to compact group-header segments, and the **inline velocity-curve box +> is replaced by a miniature curve preview button** that summons a **full-size popup editor** — +> freeing the **hero waveform to run full width**. Engine, params, storage, and persistence are +> all **unchanged** — this is a pure view recomposition of existing controls (zero component-state +> change, no new persisted fields, VST3 class UID unchanged). The **knob primitive** itself +> (minimal arc ~6→4 o'clock, needle indicator, vertical drag) is a **separate in-flight track**; +> this section specs the layout that consumes it. Directives (Daniel, 2026-07-27): radial knobs +> replacing all sliders, grouped "in a reasonable way" with **the envelope controls grouped +> together intuitively**; pitch-engine and Gate/Trigger toggles **not full-width**; the velocity +> curve as a **small square preview button right of the preview-velocity control** opening a +> popup with the full-size editor, **right-click removing a control point** in the popup; the +> waveform preview **full-width**. Product framing: `docs/product/midi-playback.md` §Addendum r11. + +**Inventory contract — every landed Sample-face element has a named home (nothing silently +dropped):** + +| Landed element (S-VIEW-1..10) | r11 home | +|---|---| +| Title band: name + live readout, Browse + Zone nav buttons | Unchanged | +| Hero waveform + S11 markers (start/loop/loop-fill) + "(decoding…)" placeholder | Unchanged, now **full width** (the velCurve carve-out is gone) | +| Envelope overlay polyline + draggable nodes (S-VIEW-3/F2) | Unchanged, over the full-width hero | +| Inline velocity-curve box (trace, node drag, click-add, Alt-click delete, drag-off delete) | **Popup editor** — all interactions preserved, + new right-click delete; summoned from the mini preview button | +| Fenced root spectral strip + root marker drag | Unchanged (cluster left, now remainder-width) | +| Preview-trigger button | Unchanged (cluster) | +| Preview-velocity horizontal slider | **Radial knob** in the cluster ("Vel"), same persisted `previewVelocity` seam (envelope-v6, untouched) | +| Mono \| Stereo toggle | Unchanged (cluster, right-anchored) | +| Mode row (Gate\|Trigger, full-width toggle) | **Compact toggle in the AMP ENVELOPE group caption row** | +| Pitch eng row (Varisp\|Preserve, full-width toggle) | **Compact toggle in the PITCH group caption row** | +| Attack / Hold / Decay / Sustain / Release sliders (Gate) | **Knobs in the AMP ENVELOPE group** | +| Length % / Fade in / Fade out sliders (Trigger) | **Knobs in the AMP ENVELOPE group** (time-ordered: Fade In · Length % · Fade Out) | +| Pitch env row (Off\|On, full-width toggle) | **Compact toggle in the PITCH ENV group caption row** | +| P.Attack / P.Decay / P.Depth sliders | **Knobs in the PITCH ENV group** | +| Key track slider | **Knob in the PITCH group** | +| Empty state ("pick a capture") + S13 drop-hint banner | Unchanged | + +**Band order (top → bottom) — hero becomes the elastic band.** Title (26, unchanged) → **hero +(full width between kPad margins, ELASTIC: absorbs all height left after the fixed bands, floor +150px)** → cluster (52, unchanged height) → **knob deck (fixed-height, bottom-anchored; ~92px +per deck row)**. The old fixed-150 hero + rest-of-window slider stack inverts: the control +surface is now the fixed band and the waveform grows with the window. At the unchanged 840×620 +default this yields a ~430px hero (see fork R11-F1 for the height call). + +**The knob deck — three fenced groups, left → right.** Each group is a hairline-bordered +`bg/panel` box with a **caption row** (~20px: micro-caps caption left; the group's **compact +mode toggle right-anchored in the caption row** — this is where the not-full-width toggles +live) over a **knob row** of fixed cells. Knob cell: **48w × 58h** — 28px knob centered, 12px +`Font::Micro` label beneath in `text/dim`; **the label swaps to the live value during +hover/drag** (no third line, no permanent value clutter). Toggle segments reuse the Mono/Stereo +grammar (~44–52px per segment, 18px tall, Active segment accent-primary). Groups: + +- **AMP ENVELOPE** — caption toggle: **Gate | Trigger** (`kPlayMode`). Knobs, Gate: **Attack · + Hold · Decay · Sustain · Release**; Trigger: **Fade In · Length % · Fade Out** (a deliberate + time-order reorder of today's row order — left-to-right matches the drawn envelope). The group + **reserves the 5-cell Gate width** so a mode flip repopulates in place and never reflows the + neighboring groups (Trigger simply leaves two cells blank). This is the "envelope controls + grouped together as a unit" directive: the group IS the envelope, its toggle picks the shape, + and the hero's envelope overlay is the same params drawn large (two surfaces, one model — + unchanged from S-VIEW-F2). +- **PITCH** — caption toggle: **Varisp | Preserve** (`kPitchEngine`). Knob: **Key Track** + (0–200%, the S-VIEW-6 scalar). Key tracking is repitch math, so it lives with the engine that + applies it. +- **PITCH ENV** — caption toggle: **Off | On** (`kPitchEnvEnable`). Knobs: **P.Attack · P.Decay + · P.Depth**. Its own fenced envelope unit, mirroring AMP ENVELOPE's grammar at smaller scale. + When Off, the three knobs draw `Disabled` (kit state) rather than vanish — stable geometry. + +Group gaps 12px; deck side margins kPad. Sum at these metrics ≈ 610px wide; **below that width +the pure module wraps whole trailing groups to a second deck row deterministically** (the deck +grows, the elastic hero shrinks toward its floor — the 560px `checkSizeConstraint` minimum +forces PITCH ENV onto row two, which is acceptable at the floor). + +**The cluster band (root + preview + curve button).** Root strip keeps the left side but becomes +**remainder-width** (min ~200px) instead of a fixed 55%; the right side is a fixed-width +right-anchored run: **Preview button (64w) · Vel knob cell (48w, the radial preview-velocity +knob) · curve preview button (28×28, immediately right of the Vel knob — per the directive) · +Mono | Stereo (right-anchored, unchanged)**. The **curve preview button** is a hairline-bordered +`bg/cell` square with the zone's live velocity curve traced in miniature (1px secondary-accent +trace, no node markers at this scale); Hover lifts it, and it draws **Active (accent-primary +border)** while its popup is open. It re-renders live as the popup edits the curve. + +**The popup curve editor.** Summoned by left-click on the curve preview button. A **centered +sheet over the Sample face**: a 0.50-alpha `bg/base` wash over the whole window (lighter than +Browse's 0.82 — this is a focused sub-editor, the Sample face stays legible behind it), then a +`bg/panel` + hairline sheet, **width clamp(60% of window, 360..520), height clamp(55%, 260..380)**. +Inside: a ~22px title row ("VELOCITY → AMP" micro-caps left, a **Close (×) button** 18×18 right), +and the **full-size curve box** filling the remainder using the existing `curveBoxFromRect` +inset/mapping-box grammar (one coordinate formula, as landed). Interactions are **identical to +the landed inline editor** — node drag with mouse-up commit, empty-space click adds + grabs a +point, Alt-click delete, drag-off delete (the box+24px drag-off margin stays inside the sheet, +so it cannot collide with dismissal) — **plus the NEW right-click delete (issue 3c): right-click +on a node removes it**, committing immediately through the same path as Alt-click, with the +existing `deletePoint` endpoint guard making endpoint right-clicks a safe no-op. Right-click +becomes the *primary* delete affordance; Alt-click and drag-off remain as landed alternates +(nothing dropped). **Dismiss:** Close click, click on the wash outside the sheet (only when no +drag is in flight), or Esc. Popup state (open flag + target zone) is editor-local, never +persisted. The `dragStartMap_` rollback contract is unchanged. + +**Module architecture (r11 delta — house pattern preserved).** + +- **Pure NEW `knob_deck`** — group boxes, caption rows, compact-toggle rects, knob-cell rects, + deterministic group wrap, and hit-test (point → control id + element kind). Mirror of + `action_bar` / `param_slider`; consumes the same shell-owned control-id descriptors; + engine-free, LICE-free, unit-tested (layout at reference widths, wrap at the 560 floor, + hit-test at cell/toggle boundaries). +- **Pure NEW `curve_popup`** — sheet/close/box geometry from the window size + the + outside-sheet dismissal test. Mirror of `overflow_menu`; unit-tested at the size clamps. +- **The knob primitive** (value↔needle-angle map, arc geometry, vertical-drag delta→value) is + the **separate in-flight track**; `knob_deck` treats a knob cell as a rect and defers + value↔angle to the primitive. Layout-level contract on it: vertical drag with resolution at + least matching the retired sliders; a Shift fine-drag is optional polish (mirroring the + envelope-node note), not required. +- **`param_slider` retires from the Sample face** (and from the Zone panel under fork R11-F2); + its toggle-segment helpers may be reused for the compact toggles or subsumed into `knob_deck` + — implementer's call at build. The preview-velocity control becomes a knob cell bound to the + same persisted `previewVelocity` (seam untouched). +- **Shell (`reasampler_editor.cpp`):** re-lays `computeSampleBands` (elastic hero, fixed deck), + draws groups/knobs/mini-button/popup through the **L1 kit** by palette role, routes + right-click (verify `WM_RBUTTONDOWN` reaches the child wndproc — see must-verify) and Esc. + Knob drags commit on mouse-up exactly as slider drags did (live invalidate, `commitAndReload` + on release); the knobs and the hero's envelope nodes stay two surfaces on one param model. + +**Spec'd aesthetic defaults (decided here; Daniel can veto at smoke test):** label↔value +swap-in on knob cells; Trigger knob time-order (Fade In · Length % · Fade Out); popup wash +0.50; group captions AMP ENVELOPE / PITCH / PITCH ENV; disabled-not-hidden PITCH ENV knobs. +The two genuinely open aesthetic calls are forks **R11-F1** and **R11-F2** in the fork ledger +below. + ### Engineering prerequisite 1 — drop-to-FX bug (routed to implementation, NOT a design call) **Symptom (Daniel):** dropping a capture onto a track's FX chain does not instantiate + init @@ -2569,15 +2700,27 @@ face without scrolling, and cannot be resized below the constraint floor. preview velocity **persists** via envelope-v6 `ComponentState`; the envelope overlay's nodes are **draggable** via the pure `envelope_edit` module. They are no longer open questions.)* -- **S-VIEW-F3 — Browse modal presentation.** Full-window overlay (lean — the modal-picker feel) vs. - a large centered sheet with a dimmed Sample behind. Presentation detail; either satisfies "easy - to summon and dismiss." **Still Daniel's call.** +- **S-VIEW-F3 — Browse modal presentation. SETTLED (2026-07-27): full-window overlay** — landed + in S-VIEW-1/S-VIEW-5 (Browse renders as a full-window modal over Sample). Recorded here so the + ledger matches PLAN.md; no longer open. - **R10-F1 — velocity-curve default (Daniel, 2026-07-27).** **Option A: flat y=1** (Daniel's verbatim default — every velocity plays at full level; NOT back-compat with today's linear `velocity/127`, so existing zones' dynamics change) vs. **Option B: linear y = x/127** (bit- identical to the shipped engine; contradicts the verbatim "full level" default). **Lean A**, flagged as a deliberate shipped-behavior change, not a silent regression. This is the only non-back-compat surface the velocity-curve feature introduces. **Daniel's call.** +- **R11-F1 — hero height vs. default window (r11; Daniel, 2026-07-27).** With the knob deck + collapsing ~312px of slider rows into ~92px, the elastic hero at the unchanged 840×620 + default runs ~430px tall — waveform-dominant (Simpler-like; envelope-node drags gain vertical + precision). Alternative: shrink the default to ~840×520 (hero ~330px, a tighter face). + **Lean: keep 840×620 + elastic hero** — the freed space going to the waveform is the point of + the recomposition, and no default-size churn. Purely aesthetic. **Daniel's call.** +- **R11-F2 — Zone-panel parity (r11; Daniel, 2026-07-27).** Convert the Zone param panel to the + same knob deck + curve-preview-button/popup (one control grammar everywhere; retires + `param_slider`'s slider rows outright) vs. leave Zone on the landed slider rows (smaller Wave + B, but the same params render as knobs on Sample and sliders on Zone — a grammar fork). + **Lean: parity** — one grammar, and the two surfaces already share one storage site (S15-F2). + Cost: Wave B scope grows by the Zone panel re-lay. **Daniel's call.** ### Must-verify before build (S-VIEW) @@ -2609,6 +2752,17 @@ preview velocity **persists** via envelope-v6 `ComponentState`; the envelope ove - **Velocity-curve eval monotonicity (r10)** — confirm the pure `velocity_curve` bezier is monotonic in x over the 0–127×0–1 box (one output per velocity) and that control-point edits stay clamped + x-ordered at the boundaries. +- **Right-click routing (r11)** — confirm `WM_RBUTTONDOWN`/`WM_RBUTTONUP` reach the editor's child + wndproc (today only left-button + move are handled) before committing to right-click node delete; + same sweep for Esc/`VK_ESCAPE` key routing while the curve popup is open (the Browse search box + already takes keyboard input, so the focus path exists — confirm the popup sees it). +- **Deck wrap + hero floor (r11)** — confirm the pure `knob_deck` wrap is deterministic at the + 560×460 `checkSizeConstraint` floor (PITCH ENV onto row two) and the elastic hero's 150px floor + holds with a two-row deck at minimum height. +- **Knob primitive contract (r11)** — confirm the separately-built knob primitive and `knob_deck` + agree on the knob-cell rect and the value↔angle map (one formula each side of the seam), so the + drawn needle and the drag hit-test can never drift — the same one-formula discipline as + `curveBoxFromRect`. --- diff --git a/PLAN.md b/PLAN.md index 4242dda..a6383dc 100644 --- a/PLAN.md +++ b/PLAN.md @@ -210,6 +210,47 @@ piano-key pattern work; drop-a-capture-onto-FX instantiates a playing instance. - [x] **S-VIEW-1 through S-VIEW-10** — all landed (Wave 1 core + Wave 2 shell + Wave 3 velocity-curve editor UI). See `COMPLETED.md` §S-VIEW for the full entry set. +### Phase S editor Wave B — Sample-face recomposition (r11; Daniel, 2026-07-27) + +> Daniel's post-landing DAW pass on the S-VIEW editor: **all linear sliders → small radial +> knobs** grouped into a fenced knob deck (envelope controls grouped as a unit); the **mode +> toggles compact**, not full-width; the **inline velocity-curve box → a miniature curve +> preview button + full-size popup editor** (right-click deletes a node in the popup); the +> **hero waveform full-width**. A pure view recomposition — zero engine/state/persistence +> change, VST3 class UID unchanged. Authoritative layout spec: **CONTEXT.md §S-VIEW → "The +> Sample-face recomposition (r11)"** (band order, group taxonomy, cell metrics, popup +> geometry, inventory contract — nothing silently dropped). Product framing: +> `docs/product/midi-playback.md` §Addendum r11. **GATED on the knob-primitive track** +> (separate, in flight) — S-VIEW-11/12 consume the primitive, they do not build it. +> All drawing through the L1 kit; all layout/hit-test in pure geometry modules. + +- [ ] **S-VIEW-11 — the knob deck.** Pure **`knob_deck`** (group boxes + caption rows + + compact-toggle rects + knob-cell rects + deterministic group wrap + hit-test; mirror of + `action_bar`/`param_slider`; unit-tested) + shell: the Sample control strip becomes three + fenced groups — **AMP ENVELOPE** (Gate|Trigger caption toggle; Attack·Hold·Decay·Sustain· + Release or Fade In·Length %·Fade Out knobs, 5-cell width reserved so mode flips never + reflow), **PITCH** (Varisp|Preserve caption toggle; Key Track knob), **PITCH ENV** (Off|On + caption toggle; P.Attack·P.Decay·P.Depth knobs, Disabled-not-hidden when Off). Slider rows + + full-width toggles retire from the Sample face; the hero becomes the elastic band + (bottom-anchored fixed deck). Preview-velocity slider becomes a cluster knob cell (same + persisted seam). +- [ ] **S-VIEW-12 — curve popup + full-width hero.** Pure **`curve_popup`** (sheet/close/box + geometry + outside-sheet dismissal test; mirror of `overflow_menu`; unit-tested) + shell: + the inline velocity-curve box leaves the hero band (**hero runs full width**, S11 markers + + envelope overlay unchanged); a **28×28 miniature curve preview button** lands immediately + right of the preview-velocity knob (live miniature trace; Active while its popup is open); + click opens the **centered popup** hosting the full-size curve editor — all landed + interactions preserved (drag, click-add, Alt-click delete, drag-off delete) **plus NEW + right-click node delete** (endpoint-guarded, commits like Alt-click). Dismiss: Close ×, + outside-click (no drag in flight), Esc. +- [ ] **S-VIEW-13 — Zone-panel parity (gated on fork R11-F2).** The Zone param panel adopts + the same knob deck + curve-preview-button/popup; retires `param_slider`'s slider rows + outright (one control grammar on both surfaces of the one storage site). + +**Open forks (Daniel's to call before Wave B builds)** — recorded in the CONTEXT.md §S-VIEW +fork ledger: **R11-F1** hero height vs. default window (lean: elastic hero, keep 840×620); +**R11-F2** Zone-panel parity (lean: yes — one grammar). + ### Phase S editor prerequisites — routed to staff-engineer (bug + default; NOT design forks) > Framed in CONTEXT.md §S-VIEW; both are functional prerequisites with the SDK swept and no @@ -217,11 +258,12 @@ piano-key pattern work; drop-a-capture-onto-FX instantiates a playing instance. > **S-VIEW-BUG-1 and S-VIEW-SIZE-1 have both landed (Wave 1) — see `COMPLETED.md`.** ### Phase S editor redesign — forks (Daniel's to call) -*(All forks settled: S-VIEW-F1 and S-VIEW-F2 SETTLED 2026-07-27 — folded into S-VIEW-4 / S-VIEW-3. -F1: preview velocity persists via envelope-v6 `ComponentState`. F2: envelope nodes are draggable -via the pure `envelope_edit` module. R10-F1 SETTLED 2026-07-27 — Option A flat y=1, folded into -S-VIEW-9. S-VIEW-F3 SETTLED — full-window overlay, implemented as Browse renders as a full-window -modal over Sample (landed in S-VIEW-1/S-VIEW-5). No open forks remain.)* +*(r9/r10 forks all settled: S-VIEW-F1 and S-VIEW-F2 SETTLED 2026-07-27 — folded into S-VIEW-4 / +S-VIEW-3. F1: preview velocity persists via envelope-v6 `ComponentState`. F2: envelope nodes are +draggable via the pure `envelope_edit` module. R10-F1 SETTLED 2026-07-27 — Option A flat y=1, +folded into S-VIEW-9. S-VIEW-F3 SETTLED — full-window overlay, implemented as Browse renders as a +full-window modal over Sample (landed in S-VIEW-1/S-VIEW-5). **r11 opens two new forks — R11-F1 +(hero height vs. default window) and R11-F2 (Zone-panel parity) — see the Wave B block above.**)* --- diff --git a/docs/product/midi-playback.md b/docs/product/midi-playback.md index 4f3c7b5..e5199e6 100644 --- a/docs/product/midi-playback.md +++ b/docs/product/midi-playback.md @@ -7,7 +7,13 @@ the **product framing behind a scoped phase**. Its build roadmap lives in **PLAN *why* (the plugin-format reasoning, the bare-VST3-vs-JUCE assessment, the settled decision record). -Status: framed by product-designer (2026-07-26), **revised 2026-07-27 (r9)**. r9 records the +Status: framed by product-designer (2026-07-26), **revised 2026-07-27 (r11)**. r11 records the +**Sample-face recomposition** (Daniel's post-landing DAW pass, 2026-07-27): all linear sliders → +grouped radial knobs, compact mode toggles, the inline velocity-curve box → a preview button + +popup editor with right-click node delete, and the hero waveform full-width — the layout spec for +the Wave B editor rebuild. Two new forks open (R11-F1 hero height/default window, R11-F2 +Zone-panel parity); all r9/r10 forks — including S-VIEW-F3 — are settled and landed. See the r11 +Addendum in §4. r9 records the **three-view editor redesign** (Sample / Browse / Zone) and its follow-up settlements: the S-VIEW-F1 and S-VIEW-F2 forks are now **SETTLED** (2026-07-27) — **preview velocity persists** via the instrument's own VST3 component state (envelope bump to v6, *not* the extension's project @@ -1217,6 +1223,69 @@ Addendum is the *why*; those are the *what/how*. --- +### Addendum — Sample-face recomposition: knob deck, curve popup, full-width hero (Daniel, 2026-07-27, r11) + +**Framing.** S-VIEW-1..10 landed and Daniel DAW-tested the three-view editor. The verdict on the +*model* is good (Sample-as-home holds); the verdict on the *composition* is not: a 12-row stack of +full-width horizontal sliders and full-width two-segment toggles reads as a settings form, not an +instrument. r11 recomposes the Sample face into the hardware-sampler grammar the references +(Simpler, Phase Plant, and every hardware groovebox) actually use — **a big waveform and a deck of +small labelled knobs in functional clusters** — and drives the **Wave B editor rebuild**. + +**Directives (Daniel, 2026-07-27, relayed):** +- **Radial knobs (issue 4).** All the linear sliders become smaller radial knobs — minimal arc + (~6→4 o'clock), needle indicator, vertical drag. The knob *primitive* is being built on its own + track; r11 specs the layout that consumes it. Group the controls "in a reasonable way," and + **group the envelope controls together intuitively** as a unit. +- **Mode toggles (issue 4).** The pitch-engine and Gate/Trigger toggles must **not** be + full-width — size and place them sensibly within the grouped composition. +- **Velocity curve as button + popup (issue 3d).** Replace the inline curve box with a **small + square preview button** (the curve drawn on it in miniature) **to the right of the + preview-velocity control**; clicking it opens a **popup** hosting the full-size curve editor. + This frees the **waveform preview to become full-width**. +- **Right-click delete (issue 3c).** In the popup curve editor, right-click removes a control + point. + +**The composition calls (r11).** + +1. **Three fenced knob groups: AMP ENVELOPE / PITCH / PITCH ENV.** The grouping follows the + parameter taxonomy the engine already has, not an invented one. AMP ENVELOPE hosts the + Gate|Trigger toggle in its caption row (the toggle *selects the envelope shape*, so it heads + the envelope group — that is the "envelope controls as a unit" directive made structural) over + the AHDSR knobs (Gate) or Fade In · Length % · Fade Out (Trigger, reordered to time order). + PITCH hosts the Varisp|Preserve toggle + the Key Track knob (key tracking is repitch math — it + lives with the engine that applies it). PITCH ENV is its own small envelope unit (Off|On + caption toggle + P.Attack/P.Decay/P.Depth), mirroring AMP ENVELOPE's grammar. +2. **Toggles live in the group caption rows.** Compact two-segment toggles (Mono/Stereo-sized) + right-anchored in each group's micro-caps caption row — not-full-width, and *placed where they + explain themselves* (each toggle captions the knobs it reconfigures). +3. **The hero inverts from fixed to elastic.** Collapsing ~312px of slider rows into a ~92px deck + makes the control surface the fixed band and the full-width waveform the elastic one — the + Simpler/Phase-Plant proportion. Fork **R11-F1** (Daniel): keep the 840×620 default (hero + ~430px, waveform-dominant — the lean) or shrink the default to ~840×520. +4. **Popup over inline for the velocity curve.** The inline box bought a permanently visible + editor at the cost of 168px of hero width for a control most sessions touch once. The + mini-button keeps the curve *visible* (live miniature, glanceable) while the popup gives the + *editor* more room than the inline box ever had. All landed interactions carry over; right-click + becomes the primary node-delete, with Alt-click and drag-off kept as alternates — nothing + dropped. +5. **One grammar on both surfaces (fork R11-F2, lean yes).** The Zone param panel should adopt the + same knob deck + button/popup — Sample and Zone already edit one storage site (S15-F2); the lean + is that they should speak one control grammar too. Daniel's call (it grows Wave B scope). + +**What does NOT change (guardrails).** Zero engine/state/persistence change — this is a view +recomposition of *existing* controls; no new params, no component-state bump, VST3 class UID +unchanged. All drawing through the L1 kit by palette role; all layout/hit-test in new pure modules +(`knob_deck`, `curve_popup` — mirrors of `action_bar`/`overflow_menu`); the knobs and the hero's +envelope nodes remain two surfaces on one param model (S-VIEW-F2's structural sync, untouched). +The full inventory contract (every landed element → its r11 home) is in the CONTEXT.md spec. + +**Where the spec lives:** CONTEXT.md §Phase S — editor view-model redesign (S-VIEW) → "The +Sample-face recomposition (r11)"; PLAN.md §Phase S — editor Wave B (S-VIEW-11/12/13 + forks +R11-F1/R11-F2). This Addendum is the *why*; those are the *what/how*. + +--- + ## Where this landed With D1/D5/D6 locked and **D-A..D-D all settled (2026-07-26)**, the instrument is scoped