Phase 10 W1: de-noise Mix visualizer, clip to live player-bar height, redraw lava-lamp icon

This commit is contained in:
daniel-c-harvey
2026-06-16 11:12:20 -04:00
parent 74b9c02722
commit ff37efea89
3 changed files with 40 additions and 17 deletions
@@ -1,8 +1,19 @@
/* 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. */
and never intercepts pointer events — except the zoom slider, which re-enables them on itself.
Footer clip (Phase 10 W1, spec §2c): the backdrop must stop cleanly ABOVE the audio player bar so
no lava/waveform pixel paints over or under it. `overflow: hidden` clips the canvas to this box, and
`bottom` is inset by the player bar's LIVE height — `--player-height`, the custom property the player
already publishes on :root via its ResizeObserver (AudioPlayerBar + Interop/layout/spacer.ts). That
var tracks the expanded bar's border-box height across breakpoints/error-banner reflow, and resets to
0 when the bar is minimized — so the clip line follows the bar's actual current height with no extra
coupling: when minimized the var is 0 and the backdrop reaches the viewport bottom (the floating FAB,
z-index 1300, simply sits over it — there is no full-width bar to clip to), matching spec §2c. The
0px fallback keeps the backdrop full-height on any page that doesn't host the player. */
.mix-waveform-bg {
position: fixed;
inset: 0;
bottom: var(--player-height, 0px);
z-index: 0;
pointer-events: none;
overflow: hidden;
@@ -855,9 +855,13 @@ void main() {
// most effective "this is glass" cue (spec §4f.4).
float fresnel = pow(1.0 - max(dot(N, V), 0.0), GLASS_FRESNEL_POWER);
// Frosted translucency: a subtle noise modulation of alpha so edges read soft/lit
// rather than hard — the "frosted glass" cue done in-shader (no CSS blur, §4f.3).
float frost = 0.85 + 0.15 * valueNoise(vec2(screenX * 0.05, screenYTop * 0.05));
// REMOVED (Phase 10 W1 de-noise, spec §3): the screen-space "frost" alpha noise —
// frost = 0.85 + 0.15 * valueNoise(vec2(screenX*0.05, screenYTop*0.05)). It was a
// static value-noise keyed to SCREEN coordinates (not the moving fluid), so it sat as
// a fixed grainy/dirty film over the whole ribbon — exactly the "static-looking texture
// that makes the screen look dirty" Daniel rejected. Alpha is now the clean backdrop
// opacity with no grain. (Fluid-tied noise — the bubble swell and the colour-field drift,
// both keyed to mix-time — is retained: it moves with the audio and does not read as dirt.)
// Compose the lit glass colour: field base + warped refraction, lifted by sheen and
// a Fresnel rim toward the VIVID moss accent, plus a white-hot specular dot. Using the
@@ -867,9 +871,10 @@ void main() {
lit = mix(lit, vividAccent * 1.3, fresnel * 0.7); // rim glows vivid moss
lit += spec * vec3(1.0); // specular is white light
// Alpha: the backdrop opacity, lifted at the rim (Fresnel) so edges catch light, and
// softened by the frost. Pre-multiplied output for the ONE/ONE_MINUS_SRC_ALPHA blend.
float alpha = inside * RIBBON_OPACITY * frost;
// Alpha: the backdrop opacity, lifted at the rim (Fresnel) so edges catch light.
// (Frost removed — see the de-noise note above.) Pre-multiplied output for the
// ONE/ONE_MINUS_SRC_ALPHA blend.
float alpha = inside * RIBBON_OPACITY;
alpha = clamp(alpha + inside * fresnel * RIBBON_OPACITY * 0.8, 0.0, 1.0);
fragColor = vec4(lit * alpha, alpha);
+17 -10
View File
@@ -24,17 +24,24 @@ public static class DDIcons
""";
/// <summary>
/// Lava lamp - the Mix visualizer settings glyph. Inner path/shape markup for MudBlazor's Icon= slot
/// (no outer &lt;svg&gt; wrapper — MudBlazor supplies that). Tapered base, tall rounded glass vessel,
/// a cap, and three suspended blobs at varied heights. The silhouette is currentColor so it themes
/// with its context (Color.Secondary tint, light/dark). The blobs carry a warm two-tone accent à la
/// the gas-lamp flame so the lamp reads as "lit" at icon size; coordinates are in the 24×24 space
/// that matches MudBlazor's viewBox="0 0 24 24" wrapper.
/// Lava lamp - the Mix visualizer settings glyph. Classic 1970s "Lava" silhouette, redrawn (Phase 10
/// W1). Inner path/shape markup for MudBlazor's Icon= slot (no outer &lt;svg&gt; wrapper — MudBlazor
/// supplies that); coordinates in the 24×24 space matching viewBox="0 0 24 24".
///
/// Bottom→top: a WIDE truncated-cone metal BASE (widest at the very bottom, tapering up to a narrow
/// waist); a tall tapered GLASS VESSEL on the base — bulbous/rounded at the bottom, tapering up to a
/// roundedly-pointed (teardrop/bullet) top; a small truncated-cone metal CAP on top mirroring the base.
/// The metal base + cap are <c>currentColor</c> so the silhouette stays tintable with its context
/// (Color.Secondary, light/dark). The fluid + blobs are hard navy/moss so the lamp reads as "lit" at
/// icon size: navy (#17283F) vessel fluid with 3 varied moss (#429D6A) lava blobs suspended in it.
/// NOTE: these hexes mirror the app theme tokens (navy ~#17283F/#0D1B2A, moss ~#3D7A68/#429D6A).
/// </summary>
public const string LavaLamp = """
<path fill="currentColor" d="M9 1h6l-1.2 3h-3.6zM7.5 21l1.7-15h5.6l1.7 15zM6 21h12v2H6z"/>
<ellipse cx="12" cy="17.5" rx="2.6" ry="2.2" fill="#FF9800"/>
<ellipse cx="10.4" cy="12.5" rx="1.5" ry="1.7" fill="#FFB74D"/>
<ellipse cx="13.3" cy="9.5" rx="1.1" ry="1.3" fill="#FFCA28"/>
<path fill="currentColor" d="M5 23L8 19.6H16L19 23Z"/>
<path fill="#17283F" d="M12 4C14.4 7 16 11 16 14.5 16 18 14.3 19.6 12 19.6 9.7 19.6 8 18 8 14.5 8 11 9.6 7 12 4Z"/>
<path fill="currentColor" d="M10.7 4L11.1 2H12.9L13.3 4Z"/>
<circle cx="12" cy="16" r="2" fill="#429D6A"/>
<circle cx="10.3" cy="12" r="1.4" fill="#429D6A"/>
<circle cx="13.2" cy="8.5" r="1" fill="#429D6A"/>
""";
}