docs(phase-10): respec Mix visualizer controls as in-flow container between back link and lava-lamp
This commit is contained in:
@@ -66,8 +66,12 @@ Cross-references (read these before implementing):
|
||||
- `DeepDrftPublic.Client/Controls/MixZoomMapping.cs` — reused unchanged for the scroll-speed control.
|
||||
- `DeepDrftPublic.Client/Controls/MixWaveformVisualizer.razor[.cs/.css]` — the bridge. Extend the handle
|
||||
with the new control setters; the `.css` gains the overflow-clip work (§2).
|
||||
- `DeepDrftPublic.Client/Pages/MixDetail.razor[.css]` — the page; the controls area gains the inline
|
||||
collapse/expand knob-bar (§7).
|
||||
- `DeepDrftPublic.Client/Pages/MixDetail.razor[.css]` — the page; the controls move into an **in-flow
|
||||
container between the back link and the lava-lamp** on the detail top row (§7b). The old
|
||||
`.mix-visualizer-controls-anchor` + `position:absolute` floating structure is **removed**.
|
||||
- `DeepDrftPublic.Client/Controls/ReleaseDetailScaffold.razor[.cs]` — the detail chrome; gains a new
|
||||
optional **`TopRowCenter`** slot so the top row hosts `back | center-controls | action` (§7b). The slot
|
||||
stays null for Track/Cut/Session, which render the back link alone — reusability preserved.
|
||||
- `DeepDrftPublic.Client/Pages/SessionDetail.razor[.css]` — the **NowPlaying / hero aesthetic** the
|
||||
knob-bar must match (§7e).
|
||||
- `DeepDrftPublic.Client/Controls/AudioPlayerBar/AudioPlayerBar.razor[.css]` — the footer/player bar
|
||||
@@ -85,8 +89,9 @@ Cross-references (read these before implementing):
|
||||
metaballs in the existing fragment shader, sharing the *same plane* as the waveform **with real 2D
|
||||
collision** — the waveform pushes the fluid out of its way. Replace the navy↔moss treatment with a
|
||||
**three-color, OKLab-interpolated, per-segment-baked gradient** that animates along three combined
|
||||
motions. Replace the four-knob popover with a **seven-knob inline collapse/expand knob-bar** styled to
|
||||
match the hero NowPlaying aesthetic. Remove the static noise texture that makes the screen look dirty.
|
||||
motions. Replace the four-knob popover with a **seven-knob in-flow controls container that sits between
|
||||
the back link and the lava-lamp toggle** on the detail top row (reflowing the layout in place — not a
|
||||
floating/absolutely-positioned bar), styled to match the hero NowPlaying aesthetic. Remove the static noise texture that makes the screen look dirty.
|
||||
Redraw the lava-lamp trigger glyph to the classic 1970s silhouette (§7f).
|
||||
|
||||
**In scope.**
|
||||
@@ -100,8 +105,8 @@ Redraw the lava-lamp trigger glyph to the classic 1970s silhouette (§7f).
|
||||
height (§6).
|
||||
- **Seven controls** replacing the four: scroll speed, gradient rotation speed, lava gravity, lava heat,
|
||||
blob density/size, collision strength, waveform width (§7).
|
||||
- The **inline collapse/expand knob-bar** (replacing the popover) styled to the NowPlaying hero
|
||||
aesthetic (§7).
|
||||
- The **in-flow controls container between the back link and the lava-lamp** (replacing the popover, and
|
||||
superseding the rejected `position:absolute` floating bar) styled to the NowPlaying hero aesthetic (§7b).
|
||||
- A **redrawn `DDIcons.LavaLamp`** glyph — classic 1970s lava-lamp silhouette (§7f).
|
||||
- **Overflow clipping** to the dynamic footer height (§2).
|
||||
- **Removing the static noise texture** (§3).
|
||||
@@ -133,7 +138,7 @@ Redraw the lava-lamp trigger glyph to the classic 1970s silhouette (§7f).
|
||||
| Color model (HSL navy↔moss) | — | OKLab three-color gradient, 3 motions (§6) |
|
||||
| Glass treatment | — | folded into the blob shading (§4f); no separate glass dials |
|
||||
| Static noise/frost texture | — | **removed** (§3) |
|
||||
| Controls (4 knobs, popover) | — | 7 knobs in an inline collapse/expand bar (§7) |
|
||||
| Controls (4 knobs, popover) | — | 7 knobs in an in-flow container between back & lamp (§7) |
|
||||
| Lava-lamp trigger glyph | trigger placement kept | glyph **redrawn** (§7f) |
|
||||
|
||||
---
|
||||
@@ -534,41 +539,109 @@ live). Recommended starting points: scroll speed ~mid, rotation ~0.3, gravity ~0
|
||||
~0.4, collision ~0.5, width ~0.6. The **~20% gravity / ~100% heat** anchor reflects Daniel's stated sweet
|
||||
spot (§4c). These are feel-anchors, not commitments.
|
||||
|
||||
### 7b. The inline collapse/expand knob-bar (decided — NOT a popover or drawer)
|
||||
### 7b. The in-flow controls container — between the back link and the lava-lamp (redesigned 2026-06-16)
|
||||
|
||||
**Decision (Daniel, 2026-06-16): the controls are an inline collapse/expand knob-bar, NOT a floating
|
||||
popover or a drawer.** The seven RadialKnobs live **inline in the controls area** (where the controls sit
|
||||
today) as an **`@if`-guarded flex row** that **animates open and closed in place**. It must read as
|
||||
**part of the controls collapsing/expanding** — the knob row expanding out from its predecessor — **not**
|
||||
a separate surface hanging off the icon.
|
||||
**Decision (Daniel, 2026-06-16): the controls are an in-flow container that lives BETWEEN the back link
|
||||
(left) and the lava-lamp toggle (right), on the detail top row. It is NOT a floating popover, NOT a
|
||||
drawer, and NOT a `position:absolute` element anchored under the lamp.** Expanding it **reflows the
|
||||
layout in place** — the container grows in the row's flow between back and lamp — it never overlays the
|
||||
page, never clips, and never overlaps the masthead/hero.
|
||||
|
||||
**The mechanism (no MudPopover, no MudDrawer):**
|
||||
> **This redesign supersedes the first realization of §7b.** The first implementation read the
|
||||
> "inline collapse/expand" intent as an *absolutely-positioned floating bar anchored under the lamp*
|
||||
> (`.mix-visualizer-controls-anchor` stacked the lamp over the bar; the bar was
|
||||
> `position:absolute; top:calc(100% + 0.5rem); right:0; z-index:3`). That is a "floating-but-inline
|
||||
> popover" — Daniel rejects it: it clipped to a vertical sliver (only ~4 of 7 knobs visible) and read as
|
||||
> a detached window hanging off the icon. **Remove the `position:absolute` rule and the
|
||||
> `.mix-visualizer-controls-anchor` floating structure entirely.** The container must take real layout
|
||||
> space in the row, not float over it.
|
||||
|
||||
- A **bound `bool`** (e.g. `_controlsExpanded`) gates the knob row. The **lava-lamp icon button toggles
|
||||
it** — the same `DDIcons.LavaLamp` trigger kept from Phase 10 §7c, now redrawn (§7f), now a
|
||||
collapse/expand toggle instead of a popover anchor.
|
||||
- When toggled open, the flex row of seven knobs **animates open** via **CSS transition** — width / opacity
|
||||
/ transform — **expanding out from the icon / its predecessor element**, so it reads as the controls
|
||||
growing in place. When toggled closed it collapses back the same way. (Seven knobs is wider than six —
|
||||
see the wrap note below.)
|
||||
- **Animation intent:** a smooth in-place expansion (expand-from-icon / slide-open flex row), reading as
|
||||
one continuous collapse/expand of the controls area — not a panel popping into existence over the page.
|
||||
Use the codebase's existing transition vocabulary (the existing controls/transition CSS) so the motion
|
||||
feels native, not bolted on.
|
||||
- **No floating surface.** There is no overlay, no anchored popover panel, no edge drawer. The knob row is
|
||||
a real inline child of the controls area that occupies layout when open and collapses to nothing
|
||||
(or to just the icon) when closed.
|
||||
**Placement — restructure the scaffold's top row into three zones (recommended).**
|
||||
|
||||
**Why this over the Phase 10 popover.** The popover read as a detached panel hanging off the icon; Daniel
|
||||
wants the controls to *be* the controls — collapsing and expanding in place. The inline animated flex row
|
||||
keeps the seven knobs in the page's flow, makes the open/close a property of the controls themselves, and
|
||||
avoids the popover/drawer overlay machinery entirely. (Prior-art touchstone: an inline "expand for
|
||||
advanced settings" disclosure row — e.g. a toolbar that grows a secondary row of controls in place —
|
||||
rather than a flyout/menu.)
|
||||
`ReleaseDetailScaffold`'s top row is today a two-zone `MudStack Row Justify="SpaceBetween"`:
|
||||
`back-link (left) | @TopRightAction (right)`. Restructure it into **three zones**:
|
||||
|
||||
**Layout note.** Seven knobs in a flex row may wrap on narrow viewports (e.g. 4×3 / 3×4 / 2-row) — a
|
||||
layout call, but all seven must remain reachable, and the wrap must still read as part of the inline
|
||||
collapse/expand (the whole block grows/shrinks), not as a separate surface.
|
||||
```
|
||||
back-link (left) | @TopRowCenter (the controls container) | @TopRightAction (the lamp)
|
||||
```
|
||||
|
||||
- **Add a new optional `RenderFragment? TopRowCenter` slot** to the scaffold, rendered between the back
|
||||
link and `@TopRightAction` on the same row. The row becomes a three-child flex row: back link pinned
|
||||
left, lamp pinned right, the center slot occupying the space between (and growing/shrinking with the
|
||||
container's expand/collapse — see motion below).
|
||||
- **Mix** supplies the seven-knob `MixVisualizerControls` to `TopRowCenter` and keeps the lava-lamp
|
||||
`MudIconButton` in `TopRightAction`. The lamp toggles the container; the container reveals in the
|
||||
center zone.
|
||||
- **Reusability holds.** Track / Cut / Session supply neither `TopRowCenter` nor `TopRightAction`, so the
|
||||
row degrades to **back-link-alone**, exactly as today. The center slot is a generic "affordance between
|
||||
back and action" seam — it follows the scaffold's existing "variance rides a slot, never a flag"
|
||||
convention (Phase 9 §5.3), the same way `TopRightAction` and `TopContent` already do. With
|
||||
`Justify="SpaceBetween"` an absent center slot collapses to nothing and back/action sit at the two
|
||||
edges unchanged.
|
||||
|
||||
**Why a scaffold center slot over a MixDetail-composed row.** Composing the whole `back | controls | lamp`
|
||||
row inside MixDetail (and suppressing the scaffold's own back row) would duplicate the back-link markup,
|
||||
break the scaffold's "owns the back link" invariant, and fork the one place every medium's back
|
||||
navigation lives. The center slot keeps the scaffold the single owner of the row and adds Mix's piece as
|
||||
data, not as a structural fork. **Recommended: the scaffold gains the `TopRowCenter` slot.**
|
||||
(`TopContent` — the existing below-the-row band — is the *responsive fallback target*, not the primary
|
||||
home; see the responsive note in §7b-responsive below.)
|
||||
|
||||
**The expand/collapse mechanism — in-flow, no float, no overlay (no MudPopover, no MudDrawer):**
|
||||
|
||||
- A **bound `bool`** (`_controlsExpanded`) gates the container. The **lava-lamp icon button toggles it** —
|
||||
the same `DDIcons.LavaLamp` trigger kept from Phase 10 §7c, now redrawn (§7f), now an in-flow
|
||||
expand/collapse toggle. The icon swaps to its FILLED variant while expanded (§7f / Part B); a knob drag
|
||||
never collapses the container (the toggle flips only on the lamp's click).
|
||||
- **Collapsed:** the container occupies **no or minimal space** in the center zone — `max-width: 0` (or
|
||||
`width: 0`) + `opacity: 0` + `overflow: hidden`, and `visibility: hidden` + `pointer-events: none` so
|
||||
the collapsed knobs are not focusable or hit-testable. Back and lamp sit at the row's two edges with the
|
||||
center collapsed between them.
|
||||
- **Expanded:** the container **grows horizontally in place** between back and lamp — a `max-width` (or
|
||||
`width`) + `opacity` (+ optional slight `transform`) CSS transition — so the seven knobs reveal **in the
|
||||
row's flow**, pushing nothing over the page. **No `position: absolute`, no `float`, no `z-index` stacking
|
||||
hack, no anchored panel.** The row reflows to accommodate the container; when the container is wider than
|
||||
the available center space it wraps in-flow (see responsive, below) — it never clips to a sliver.
|
||||
- **Motion intent:** a smooth horizontal grow/shrink of a real in-flow element, reading as **the controls
|
||||
area opening between the back link and the lamp** — not a panel appearing over the page. Reuse the
|
||||
existing transition vocabulary (the `cubic-bezier(0.22, 0.61, 0.36, 1)` easing already in
|
||||
`MixVisualizerControls.razor.css`) so the motion feels native. The `max-height` collapse can stay as a
|
||||
secondary axis for the wrap case, but the **primary** animated axis is horizontal width in the row.
|
||||
|
||||
**Must not overlap the masthead/hero.** Because the container lives in the top row (above the masthead,
|
||||
which the scaffold renders below this row) and reflows in-flow, an expanded container **pushes the row's
|
||||
own height** — it must never paint over the masthead, the hero/cover, or the waveform backdrop. If the
|
||||
expanded container is tall (wrapped to multiple knob rows on narrow widths), the top row grows and the
|
||||
masthead moves down with normal document flow; no overlap, no clipping.
|
||||
|
||||
**Why this over the rejected floating bar.** The floating `position:absolute` bar read as a detached
|
||||
window hanging off the lamp and clipped because its width was constrained by the lamp's narrow column.
|
||||
An in-flow container between back and lamp *is* the controls sitting in the layout — the open/close is a
|
||||
property of the row reflowing, the seven knobs get the row's full horizontal space, and there is zero
|
||||
overlay machinery. (Prior-art touchstone: a toolbar that grows a secondary in-flow region of controls in
|
||||
place between two pinned end-affordances — e.g. a browser address bar revealing inline controls between
|
||||
the back button and the menu — not a flyout anchored to an icon.)
|
||||
|
||||
### 7b-responsive. Narrow-width behavior — stay in-flow, never clip
|
||||
|
||||
The seven knobs are wide; on a narrow row the center zone cannot hold them on one line. **Recommended:
|
||||
the container wraps to a second in-flow line under the back/lamp row** rather than clipping or scrolling
|
||||
off-edge. Two acceptable realizations (staff-engineer's call, both in-flow):
|
||||
|
||||
1. **Flex-wrap in place.** The seven-knob flex row `flex-wrap: wrap`s within the center zone; when the
|
||||
center zone is too narrow the whole top row grows taller and the knobs reflow to 4×3 / 3×4 / two rows.
|
||||
The row's height grows in-flow; the masthead moves down. All seven stay reachable.
|
||||
2. **Drop to the `TopContent` band when narrow.** Below a breakpoint, the container renders in the
|
||||
scaffold's existing **`TopContent` slot** (the full-width in-flow band below the back/lamp row, above
|
||||
the masthead) instead of the center zone — giving it the full container width to lay the seven knobs
|
||||
out without crowding the back/lamp. This is still fully in-flow (it is literally the `TopContent`
|
||||
position) and never floats. Use the center zone on wide rows, the `TopContent` band on narrow rows.
|
||||
|
||||
**Either way: in-flow, no overlay, no edge-clipping, no horizontal-scroll-that-hides-knobs.** A
|
||||
horizontally-scrolling inline strip is a *last-resort* fallback only if wrapping proves visually worse —
|
||||
and even then it must be a real in-flow scroll region with a visible affordance, never a clipped sliver.
|
||||
All seven knobs must always be reachable. The wrap/drop must still read as part of the controls
|
||||
container opening, not as a separate surface.
|
||||
|
||||
### 7c. State — widen to seven properties
|
||||
|
||||
@@ -746,9 +819,13 @@ convention, and the theme-alignment discipline — not the exact coordinates.)
|
||||
19. **Waveform width.** Dragging the waveform-width control narrows/widens the waveform band across its
|
||||
range; narrowing it visibly clears horizontal space for the lava (and shrinks the collision boundary
|
||||
the fluid parts around). The datum/scroll geometry is otherwise unchanged.
|
||||
20. **Inline collapse/expand.** Clicking the lava-lamp icon expands the seven-knob flex row **in place**
|
||||
(animated open/closed via CSS transition), reading as the controls collapsing/expanding — **not** a
|
||||
floating popover or drawer. Clicking again collapses it; dragging a knob does not collapse it.
|
||||
20. **In-flow container between back and lamp.** The controls container sits **inline on the detail top
|
||||
row, between the back link (left) and the lava-lamp toggle (right)**. Clicking the lava-lamp icon
|
||||
expands it **in the layout flow** (animated open/closed via CSS width/opacity transition), reflowing
|
||||
the row — **not** a floating popover, drawer, or `position:absolute` bar, and **not** clipped to a
|
||||
sliver. Collapsed it takes no/minimal space (back and lamp at the row's two edges). All seven knobs are
|
||||
visible and horizontal when expanded; the expansion never overlaps the masthead/hero. Clicking again
|
||||
collapses it; dragging a knob does not collapse it.
|
||||
21. **NowPlaying aesthetic.** The knob-bar's surface color + structure match the session hero now-playing
|
||||
overlay (translucent dark glass, overlay-label typography, `Color.Secondary` accents).
|
||||
22. **Persistence + read-only.** All seven positions survive SPA nav within a session, reset on fresh
|
||||
@@ -795,13 +872,15 @@ sourced from `DeepDrftPalettes` with no hardcoded duplicates. **Acceptance:** §
|
||||
per-segment-bake requirement (§6b motion 2) uses the mix-time-keyed realization so it travels with the
|
||||
segment by construction (decided — §6b).
|
||||
|
||||
### Wave R4 — Seven controls + the NowPlaying-styled inline knob-bar
|
||||
### Wave R4 — Seven controls + the NowPlaying-styled in-flow controls container
|
||||
Widen `MixVisualizerControlState` to **seven** properties (including the new **waveform width** control,
|
||||
§7a); replace the four-knob popover with the seven-knob **inline collapse/expand knob-bar** (§7b —
|
||||
`@if`-guarded animated flex row, lava-lamp icon toggles it, no popover/drawer); wire the waveform-width
|
||||
control to scale the waveform-band extent and its collision boundary (§7a); style it to the session-hero
|
||||
aesthetic; extend the bridge handle with the new setters (including `setWaveformWidth`). **Acceptance:**
|
||||
§8 #18–#22.
|
||||
§7a); add the scaffold's **`TopRowCenter`** slot and move the seven-knob `MixVisualizerControls` into an
|
||||
**in-flow container between the back link and the lava-lamp** (§7b — animated horizontal grow/shrink in
|
||||
the row's flow, lava-lamp icon toggles it, **no popover/drawer, no `position:absolute`**; **remove** the
|
||||
old `.mix-visualizer-controls-anchor` + `position:absolute` floating structure); handle the narrow-width
|
||||
in-flow wrap/drop (§7b-responsive); wire the waveform-width control to scale the waveform-band extent and
|
||||
its collision boundary (§7a); style it to the session-hero aesthetic; extend the bridge handle with the
|
||||
new setters (including `setWaveformWidth`). **Acceptance:** §8 #18–#22.
|
||||
|
||||
**Dependency shape:** `Wave R1 → Wave R2 → (Wave R3 ‖ Wave R4)`. Wave R1 is a quick unblock (and folds in
|
||||
the independent icon redraw). Wave R2 is the prerequisite for everything visual. Waves R3 (color) and R4
|
||||
@@ -814,8 +893,9 @@ ranges/transfer-functions by hand once on screen throughout (his standing prefer
|
||||
## 10. Open items
|
||||
|
||||
Tuning knobs, one undecided behavior call, and one deferred future idea — the controls-UI fork and the
|
||||
per-segment-storage fork are both now **decided** (§7b inline knob-bar; §6b mix-time-keyed). None of the
|
||||
items below block starting Wave R1.
|
||||
per-segment-storage fork are both now **decided** (§7b in-flow controls container between back & lamp —
|
||||
redesigned 2026-06-16, superseding the rejected `position:absolute` floating bar; §6b mix-time-keyed).
|
||||
None of the items below block starting Wave R1.
|
||||
|
||||
- **§4c, §5d — transfer functions:** heat 0..1 → rise/morph intensity; collision 0..1 → soft↔hard blend
|
||||
shape; restitution coefficients; penetration-penalty curve. All staff-engineer tuning tasks with the
|
||||
|
||||
Reference in New Issue
Block a user