diff --git a/media_server/static/css/styles.css b/media_server/static/css/styles.css index aeaf8f9..3322eca 100644 --- a/media_server/static/css/styles.css +++ b/media_server/static/css/styles.css @@ -216,7 +216,7 @@ box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.08); } -/* Dynamic Background Canvas */ +/* Dynamic Background Canvas — editorial-toned (warm, subtle) */ .bg-shader-canvas { position: fixed; top: 0; @@ -227,10 +227,23 @@ pointer-events: none; opacity: 0; transition: opacity 0.6s ease; + /* Sepia + slight desaturation keeps the shader colors palette-aligned */ + filter: sepia(0.4) saturate(0.75) contrast(0.95) brightness(0.9) hue-rotate(-8deg); + /* Multiply blends the bright shader into the warm dark page background */ + mix-blend-mode: screen; } .bg-shader-canvas.visible { - opacity: 1; + /* Lower max opacity so it reads as atmosphere, not foreground */ + opacity: 0.45; +} + +:root[data-theme="light"] .bg-shader-canvas { + filter: sepia(0.35) saturate(0.7) contrast(1.05) brightness(1.05) hue-rotate(-12deg); + mix-blend-mode: multiply; +} +:root[data-theme="light"] .bg-shader-canvas.visible { + opacity: 0.35; } body.dynamic-bg-active { @@ -4368,31 +4381,101 @@ header .brand-sub { box-shadow: 0 0 12px var(--copper-glow); } -/* ─── Update + connection banners ───────────────────────────── */ +/* ─── Update + connection banners (editorial) ────────────────── */ .update-banner, .connection-banner { - background: var(--bg-card); - border: 1px solid var(--copper); - border-radius: 0; - color: var(--ink-soft); - box-shadow: 0 0 24px var(--copper-glow); - font-family: var(--sans); - font-size: 13px; + /* Override legacy fixed-top + accent background */ + position: fixed !important; + top: 0 !important; + left: 0 !important; + right: 0 !important; + z-index: 1001; + background: rgba(33, 30, 24, 0.94) !important; + color: var(--ink-soft) !important; + border: 0 !important; + border-bottom: 1px solid var(--copper) !important; + border-radius: 0 !important; + box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4) !important; + padding: 12px 32px !important; + font-family: var(--mono) !important; + font-size: 11px !important; + letter-spacing: 0.12em !important; + text-transform: uppercase !important; + font-weight: 400 !important; + backdrop-filter: blur(20px) saturate(160%); + -webkit-backdrop-filter: blur(20px) saturate(160%); + display: flex; + align-items: center; + justify-content: center; + gap: 18px; } -.update-banner a, -.connection-banner-btn { +/* Tiny copper hairline accent on the bottom edge */ +.update-banner::before, +.connection-banner::before { + content: ""; + position: absolute; + bottom: -1px; + left: 32px; + right: 32px; + height: 1px; + background: linear-gradient(90deg, transparent, var(--copper), transparent); + opacity: 0.7; +} +/* Brand prefix */ +.update-banner > span:first-child::before, +.connection-banner > span:first-child::before { + content: "● "; color: var(--copper); - font-family: var(--mono); - font-size: 11px; - letter-spacing: 0.12em; - text-transform: uppercase; - border-color: var(--copper); - border-radius: 0; - background: transparent; + margin-right: 6px; +} +.update-banner a { + color: var(--copper) !important; + text-decoration: none !important; + font-family: var(--mono) !important; + font-size: 11px !important; + letter-spacing: 0.18em !important; + text-transform: uppercase !important; + font-weight: 500 !important; + border: 1px solid var(--copper); + padding: 6px 14px; + transition: all 180ms var(--ease); +} +.update-banner a:hover { + background: var(--copper); + color: var(--bg-deep) !important; + opacity: 1 !important; +} +.update-banner-close { + background: transparent !important; + color: var(--ink-mute) !important; + border: 0 !important; + font-size: 18px !important; + width: 24px; + height: 24px; + padding: 0 !important; + margin-left: 8px; + cursor: pointer; + transition: color 180ms var(--ease); + opacity: 1 !important; +} +.update-banner-close:hover { + color: var(--copper) !important; +} +.connection-banner-btn { + color: var(--copper) !important; + font-family: var(--mono) !important; + font-size: 11px !important; + letter-spacing: 0.18em !important; + text-transform: uppercase !important; + border: 1px solid var(--copper) !important; + border-radius: 0 !important; + background: transparent !important; + padding: 6px 14px !important; + transition: all 180ms var(--ease); } .connection-banner-btn:hover { - background: var(--copper); - color: var(--bg-deep); + background: var(--copper) !important; + color: var(--bg-deep) !important; } /* ═══════════════════════════════════════════════════════════════ @@ -6753,61 +6836,39 @@ body.visualizer-active .now-playing .spectrogram-canvas { fill: currentColor; } -/* ─── Spectrum bars ───────────────────────────────────────── */ +/* ─── Spectrum bars (JS-injected; real audio when available) ─── */ .now-playing .spectrum { display: flex; align-items: flex-end; - justify-content: center; - gap: 3px; - height: 38px; - margin: 36px auto 24px; - max-width: 480px; + justify-content: stretch; + gap: 2px; + height: 56px; + margin: 36px 0 24px; + width: 100%; } .now-playing .spectrum span { display: block; - width: 3px; - flex: 0 0 3px; + flex: 1 1 0; + min-width: 2px; background: linear-gradient(to top, var(--copper-lo), var(--copper-hi)); - opacity: 0.85; + opacity: 0.9; transform-origin: bottom; border-radius: 99px 99px 0 0; + height: var(--bar-h, 40%); animation: sr-snap-bar 1.1s ease-in-out infinite; + animation-delay: var(--bar-delay, 0s); animation-play-state: paused; + transition: height 80ms linear; } :root[data-playstate="playing"] .now-playing .spectrum span { animation-play-state: running; } -.now-playing .spectrum span:nth-child(1) { animation-delay: -0.10s; height: 30%; } -.now-playing .spectrum span:nth-child(2) { animation-delay: -0.45s; height: 60%; } -.now-playing .spectrum span:nth-child(3) { animation-delay: -0.20s; height: 80%; } -.now-playing .spectrum span:nth-child(4) { animation-delay: -0.55s; height: 50%; } -.now-playing .spectrum span:nth-child(5) { animation-delay: -0.30s; height: 95%; } -.now-playing .spectrum span:nth-child(6) { animation-delay: -0.05s; height: 70%; } -.now-playing .spectrum span:nth-child(7) { animation-delay: -0.65s; height: 40%; } -.now-playing .spectrum span:nth-child(8) { animation-delay: -0.25s; height: 85%; } -.now-playing .spectrum span:nth-child(9) { animation-delay: -0.40s; height: 55%; } -.now-playing .spectrum span:nth-child(10) { animation-delay: -0.10s; height: 75%; } -.now-playing .spectrum span:nth-child(11) { animation-delay: -0.50s; height: 35%; } -.now-playing .spectrum span:nth-child(12) { animation-delay: -0.15s; height: 90%; } -.now-playing .spectrum span:nth-child(13) { animation-delay: -0.60s; height: 45%; } -.now-playing .spectrum span:nth-child(14) { animation-delay: -0.30s; height: 65%; } -.now-playing .spectrum span:nth-child(15) { animation-delay: -0.45s; height: 85%; } -.now-playing .spectrum span:nth-child(16) { animation-delay: -0.20s; height: 55%; } -.now-playing .spectrum span:nth-child(17) { animation-delay: -0.55s; height: 70%; } -.now-playing .spectrum span:nth-child(18) { animation-delay: -0.10s; height: 30%; } -.now-playing .spectrum span:nth-child(19) { animation-delay: -0.40s; height: 80%; } -.now-playing .spectrum span:nth-child(20) { animation-delay: -0.25s; height: 60%; } -.now-playing .spectrum span:nth-child(21) { animation-delay: -0.50s; height: 90%; } -.now-playing .spectrum span:nth-child(22) { animation-delay: -0.15s; height: 50%; } -.now-playing .spectrum span:nth-child(23) { animation-delay: -0.60s; height: 70%; } -.now-playing .spectrum span:nth-child(24) { animation-delay: -0.30s; height: 40%; } -.now-playing .spectrum span:nth-child(25) { animation-delay: -0.45s; height: 85%; } -.now-playing .spectrum span:nth-child(26) { animation-delay: -0.20s; height: 55%; } -.now-playing .spectrum span:nth-child(27) { animation-delay: -0.55s; height: 75%; } -.now-playing .spectrum span:nth-child(28) { animation-delay: -0.10s; height: 35%; } -.now-playing .spectrum span:nth-child(29) { animation-delay: -0.40s; height: 65%; } -.now-playing .spectrum span:nth-child(30) { animation-delay: -0.25s; height: 95%; } - +/* When real audio data is driving heights, freeze the CSS animation + so JS-set heights aren't overridden by the keyframe. */ +body.audio-spectrum-live .now-playing .spectrum span { + animation: none !important; + transition: height 50ms linear; +} @keyframes sr-snap-bar { 0%, 100% { transform: scaleY(0.4); } 50% { transform: scaleY(1); } diff --git a/media_server/static/index.html b/media_server/static/index.html index 42953ed..4453337 100644 --- a/media_server/static/index.html +++ b/media_server/static/index.html @@ -216,15 +216,9 @@ - -
+ +