feat(public): scrolling Canvas 2D Mix visualizer — windowed, playback-coupled, zoomable, read-only (8.K W2)

This commit is contained in:
daniel-c-harvey
2026-06-14 18:20:32 -04:00
parent c608fa345a
commit 2d0a565765
8 changed files with 698 additions and 132 deletions
@@ -1,31 +1,39 @@
/* Full-viewport fixed backdrop. Sits behind page content (negative-ish z-index within the
detail layout) and never intercepts pointer events until click-to-seek ships. */
/* Full-viewport fixed backdrop. Sits behind the detail content (.mix-detail-foreground is z-index:1)
and never intercepts pointer events — except the zoom slider, which re-enables them on itself. */
.mix-waveform-bg {
position: fixed;
inset: 0;
z-index: 0;
pointer-events: none;
overflow: hidden;
display: flex;
align-items: center;
}
.mix-waveform-bg--empty {
/* No datum: nothing to draw. Kept as a hook for a future flat-line fallback. */
}
.mix-waveform-svg {
/* The canvas fills the viewport. The glassy/frosted treatment is a CSS backdrop-blur on this layer
(the ribbon's luminous depth is drawn inside the canvas by the module); together they read as lit
glass moving behind the content rather than a hard chart. */
.mix-waveform-canvas {
position: absolute;
inset: 0;
width: 100%;
height: 60vh;
margin: auto 0;
opacity: 0.18;
height: 100%;
display: block;
backdrop-filter: blur(2px);
-webkit-backdrop-filter: blur(2px);
}
/* Native SVG elements — scoped CSS stamps these directly, no ::deep needed. */
.mix-waveform-fill {
fill: var(--mud-palette-text-secondary);
/* Zoom slider — a small viewing control pinned to the bottom-right. Pointer events are re-enabled
here only (the backdrop stays inert), and it is never a seek surface. */
.mix-waveform-zoom {
position: absolute;
right: 1.5rem;
bottom: 1.5rem;
width: 180px;
max-width: 40vw;
pointer-events: auto;
opacity: 0.7;
transition: opacity 0.2s ease;
}
.mix-waveform-played {
fill: var(--mud-palette-primary);
.mix-waveform-zoom:hover {
opacity: 1;
}