Merge p15-w1-visualizer-controls into dev
Phase 15 — visualizer control-deck rework: screen-centered tinted MudOverlay (NowPlayingCard chrome), deterministic three-row LAVA/WAVE layout, lava/waveform lamp toggles backed by a genuine per-subsystem draw-skip, scroll/zoom slider, playful tooltips, green=interactive/light=static colour principle.
This commit is contained in:
@@ -376,49 +376,151 @@ h2, h3, h4, h5, h6,
|
||||
}
|
||||
|
||||
/* =============================================================================
|
||||
WAVEFORM VISUALIZER CONTROL PANEL (Phase 12 §3d-revised / §3g)
|
||||
The eight-knob panel hosted inside WaveformVisualizerControlPopover. MudPopover
|
||||
PORTALS its content out of the component's DOM subtree, so Blazor CSS isolation
|
||||
never reaches the rendered panel — its chrome must live here in the global sheet,
|
||||
not in the scoped WaveformVisualizerControls.razor.css. (The scoped file keeps only
|
||||
the inline-bar fallback Mix's legacy TopRowCenter mount uses, which is not portaled.)
|
||||
WAVEFORM VISUALIZER CONTROL PANEL (Phase 12 §3d-revised / §3g → Phase 15 re-layout)
|
||||
The control deck hosted inside WaveformVisualizerControlPopover, now a screen-centered
|
||||
tinted MudOverlay (Phase 15 §4). MudOverlay — like the former MudPopover — PORTALS its
|
||||
content out of the component's DOM subtree, so Blazor CSS isolation never reaches the
|
||||
rendered panel: its chrome, the three-row/section LAYOUT, the section labels, the slider,
|
||||
and the toggles all live here in the global sheet, not in the scoped
|
||||
WaveformVisualizerControls.razor.css. (The scoped file keeps only the legacy inline-bar
|
||||
fallback Mix's old TopRowCenter mount used, which is not portaled.)
|
||||
|
||||
The waveform-visualizer-control-panel class is applied ONLY when the component's
|
||||
PanelChrome="true" parameter is set — which WaveformVisualizerControlPopover does
|
||||
and Mix's inline mount does NOT. This prevents the chrome from leaking onto Mix's
|
||||
inline controls bar.
|
||||
PanelChrome="true" parameter is set — which the popover host does and Mix's inline mount
|
||||
does NOT — so the chrome never leaks onto an inline bar.
|
||||
|
||||
The NowPlaying Hero look (§3g): dark-navy ground, green-accent knobs, light icons,
|
||||
muted-navy filler — all from the deepdrft-* token source of truth, no hardcoded hex.
|
||||
The RadialKnob reads --mud-palette-* for its arc/track/center/label colours; we pin
|
||||
those palette vars to the Hero tokens ON THE PANEL so the panel reads the same
|
||||
navy/green/off-white regardless of the page's light/dark theme.
|
||||
CHROME (Phase 15 §5 — NowPlayingCard treatment): SQUARE corners, lighter-navy ground
|
||||
(navy-mid), a thin LIGHT border (--deepdrft-border-light, the NowPlayingCard 0.12-alpha
|
||||
light-on-dark idiom as a token). All token-sourced; no hardcoded hex.
|
||||
|
||||
COLOUR PRINCIPLE (§5 — green = interactive, light = non-interactive): the RadialKnob reads
|
||||
--mud-palette-* for its arc/pointer/center/label; we pin --mud-palette-primary to the green
|
||||
accent (interactive arcs/pointers) and --mud-palette-text-primary to light. Caption icons and
|
||||
section labels are LIGHT (static). The slider track/thumb and the lamp toggles are green.
|
||||
============================================================================= */
|
||||
.waveform-visualizer-control-panel.mix-visualizer-controls-bar {
|
||||
/* Dark-navy elevated panel ground (§3g: navy-mid for the elevated surface). */
|
||||
/* Lighter-navy elevated panel ground (§5: navy-mid). */
|
||||
background: var(--deepdrft-navy-mid);
|
||||
border: 1px solid var(--deepdrft-border-green);
|
||||
border-radius: 8px;
|
||||
/* Square corners + thin light border — NowPlayingCard chrome (§5). */
|
||||
border: 1px solid var(--deepdrft-border-light);
|
||||
border-radius: 0;
|
||||
/* Optional backdrop blur — cheap on a small modal panel, nice over the visualizer (§5). */
|
||||
backdrop-filter: blur(8px);
|
||||
padding: 1rem 1.25rem;
|
||||
/* Popover panel: cap width so eight 64px knobs wrap to a tidy grid rather than one long bar.
|
||||
This OVERRIDES the inline-bar min-height reserve (which only matters for Mix's non-popover mount). */
|
||||
/* Three-row sectioned deck: stack the rows top-to-bottom; conditional rows reserve no permanent
|
||||
height (§3 reflow discipline). This OVERRIDES the inline-bar min-height + flex-wrap (which only
|
||||
matter for Mix's non-portaled legacy mount). */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.75rem;
|
||||
min-height: 0;
|
||||
max-width: 340px;
|
||||
/* Pin the MudBlazor palette vars the portaled RadialKnob consumes to the Hero tokens. */
|
||||
--mud-palette-primary: var(--deepdrft-green-accent); /* knob value arc / pointer / center stroke */
|
||||
max-width: 420px;
|
||||
/* Pin the MudBlazor palette vars the portaled RadialKnob + slider consume. */
|
||||
--mud-palette-primary: var(--deepdrft-green-accent); /* knob arc/pointer + slider track/thumb (interactive) */
|
||||
--mud-palette-surface: var(--deepdrft-navy); /* knob center fill — darkest navy reads against the panel */
|
||||
--mud-palette-surface-variant: var(--deepdrft-muted); /* knob background track — muted-navy filler (§3g) */
|
||||
--mud-palette-text-primary: var(--deepdrft-white); /* knob value label — light (§3g) */
|
||||
--mud-palette-surface-variant: var(--deepdrft-muted); /* knob background track — muted-navy filler */
|
||||
--mud-palette-text-primary: var(--deepdrft-white); /* knob value label — light */
|
||||
}
|
||||
|
||||
/* Green-accent caption icons (§3g: light/green icons). MudIcon is portaled here too, so this is a
|
||||
plain global descendant selector — no ::deep, no scope attribute (CSS isolation does not reach
|
||||
inside the popover). */
|
||||
.waveform-visualizer-control-panel .waveform-visualizer-control-icon {
|
||||
color: var(--deepdrft-green-accent);
|
||||
/* ── Row layout (§3). Each row is a horizontal band. Row 1 (MODE) and row 3 (WAVE) use
|
||||
space-between so the right-pinned control (color / width) hugs the far edge. Row 2 (LAVA) uses
|
||||
flex-start so its label + four knobs group left rather than spreading edge-to-edge. ── */
|
||||
.waveform-visualizer-control-panel .wvc-row {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
gap: 0.85rem 1rem;
|
||||
}
|
||||
|
||||
/* Row 1 (MODE): two direct flex children — the left toggle group and the color knob tooltip wrapper.
|
||||
space-between pins the color knob to the far right and keeps it there when collisions hides. */
|
||||
.waveform-visualizer-control-panel .wvc-row-mode {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
/* Row 2 (LAVA): label + four knobs group left — no right-pinned control. */
|
||||
.waveform-visualizer-control-panel .wvc-row-section {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
/* Row 3 (WAVE): label + scroll-slider + width-knob tooltip wrappers are direct flex children.
|
||||
space-between pins the width knob to the far right while the label + slider sit left. */
|
||||
.waveform-visualizer-control-panel .wvc-row-wave {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
/* The left group of row 1 (toggles + conditional collisions) flows left; the color knob is the
|
||||
space-between right sibling, so it stays put when collisions hides (§3). */
|
||||
.waveform-visualizer-control-panel .wvc-row-left {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: flex-start;
|
||||
gap: 0.85rem 1rem;
|
||||
}
|
||||
|
||||
/* ── Section label "LAVA:" / "WAVE:" (§3, §5). NowPlayingCard .np-label TYPOGRAPHY (mono, uppercase,
|
||||
tracked), recoloured LIGHT — labels are static, so light by the colour principle (§5, §10.3). ── */
|
||||
.waveform-visualizer-control-panel .wvc-section-label {
|
||||
font-family: var(--deepdrft-font-mono);
|
||||
font-size: 0.6rem;
|
||||
letter-spacing: 0.25em;
|
||||
text-transform: uppercase;
|
||||
color: var(--deepdrft-white);
|
||||
align-self: center;
|
||||
flex: 0 0 auto;
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
/* ── The lamp toggles (§3 row 1). Iconographic lit/unlit lamp glyph, GREEN because interactive (§5).
|
||||
Color="Color.Primary" already drives the glyph currentColor to the pinned green --mud-palette-primary;
|
||||
this just sizes the hit-target to read as a row-1 peer of the knobs. ── */
|
||||
.waveform-visualizer-control-panel .wvc-toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* ── The scroll SLIDER (§8). Track/thumb green (the pinned --mud-palette-primary, interactive). Give it
|
||||
a sensible width so it reads as "position along a continuum" next to the rotary width knob. ── */
|
||||
.waveform-visualizer-control-panel .wvc-slider {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 0.3rem;
|
||||
min-width: 160px;
|
||||
flex: 1 1 auto;
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.waveform-visualizer-control-panel .wvc-slider .mud-slider {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Caption icons + section labels render LIGHT (§5/§9 colour principle: static/decorative = light). MudIcon
|
||||
is portaled here too, so this is a plain global descendant selector — no ::deep, no scope attribute (CSS
|
||||
isolation does not reach inside the overlay). The knob arcs/pointers + slider stay green (interactive). */
|
||||
.waveform-visualizer-control-panel .waveform-visualizer-control-icon {
|
||||
color: var(--deepdrft-white);
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
/* ── The modal overlay (Phase 15 §4). MudOverlay is already a full-viewport flex scrim that centers its
|
||||
content (.mud-overlay { display:flex; align-items:center; justify-content:center }), which gives the
|
||||
screen-centered panel on every host for free — we do NOT fight that positioning. We only (a) set the
|
||||
mild modal tint from the SINGLE --deepdrft-modal-scrim-alpha token (§10.5, one point of change) and
|
||||
(b) cap the centered content's height so a tall both-on deck scrolls inside the modal rather than
|
||||
overflowing the viewport. The overlay portals to the body, so these are plain global rules (no scope
|
||||
attribute). The doubled .mud-overlay-scrim.mud-overlay-dark selector (0,2,0) outranks MudBlazor's own
|
||||
.mud-overlay-dark (0,1,0), so the tint wins regardless of stylesheet load order. ── */
|
||||
.waveform-visualizer-control-overlay .mud-overlay-scrim.mud-overlay-dark {
|
||||
background-color: rgba(var(--deepdrft-scrim-rgb), var(--deepdrft-modal-scrim-alpha));
|
||||
}
|
||||
|
||||
.waveform-visualizer-control-overlay .mud-overlay-content {
|
||||
max-height: 90vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
@media (max-width: 419.98px) {
|
||||
.deepdrft-track-detail-meta {
|
||||
flex-direction: column;
|
||||
|
||||
Reference in New Issue
Block a user