fix(ui): full-width spectrum + log-mapped bars; deeper sepia + soft art fade

Spectrum
- Logarithmic frequency-to-bar mapping (squared time so bins
  stretch toward the highs). Per-bar high-end gain ramps from
  1.0x at the lowest bar to 3.0x at the highest, so the right
  half of the spectrum no longer reads as dead air.
- Floor bumped from 6% to 12% so silent bars stay visible.
- Skip bin 0 (DC + sub-rumble) which was overwhelming the lows.
- Use peak (not average) within each band — punchier visual.
- Container height 56→64, gradient now copper-lo → copper →
  copper-hi for more visible top tips. min-width: 0 / box-sizing
  border-box ensures the row truly claims the full grid column.
- Backend FFT path is unchanged: WS audio_data → setFrequencyData
  → renderVisualizerFrame → updateEditorialSpectrum. No
  client-side analyzer added.

Album art (vinyl label)
- Deeper sepia (0.35→0.6) and lower saturate (0.85→0.7) so
  vibrant covers blend into the copper grooves.
- Soft radial mask: outer ~22% of the disc fades toward the
  vinyl black so the album art dissolves into the surface
  rather than terminating at a hard clip edge.
- Hover state pulls the fade inward and eases sepia back so
  the user can still see the real cover at near-natural color.
- Glow tint matches the new sepia depth.
This commit is contained in:
2026-04-25 02:07:20 +03:00
parent d937c1590c
commit 336d596b66
2 changed files with 78 additions and 29 deletions
+55 -21
View File
@@ -6639,29 +6639,58 @@ footer .separator { color: var(--ink-ghost); margin: 0 8px; }
display: block;
border-radius: 50%;
z-index: 2;
/* Vinyl-consistent tint: warm sepia + slight sharpen + subtle contrast.
Saturate pushed down so vibrant covers don't fight the copper palette. */
/* Heavy vinyl-consistent tint: deeper sepia + lower saturation
so vibrant covers blend with the copper grooves. */
filter:
sepia(0.35)
saturate(0.85)
contrast(1.08)
brightness(0.95)
hue-rotate(-6deg);
transition: filter 320ms var(--ease);
sepia(0.6)
saturate(0.7)
contrast(1.12)
brightness(0.88)
hue-rotate(-8deg);
transition: filter 480ms var(--ease), -webkit-mask-image 480ms var(--ease);
/* Soft radial fade — the outer ~12% of the art fades to black so
the album image dissolves into the vinyl surface rather than
cutting hard at the circular clip edge. */
-webkit-mask-image: radial-gradient(circle at 50% 50%,
black 0%,
black 78%,
rgba(0,0,0,0.85) 88%,
rgba(0,0,0,0.4) 96%,
transparent 100%);
mask-image: radial-gradient(circle at 50% 50%,
black 0%,
black 78%,
rgba(0,0,0,0.85) 88%,
rgba(0,0,0,0.4) 96%,
transparent 100%);
}
.now-playing:hover .vinyl-label #album-art {
/* On hover, ease back toward natural color so users can see the real art */
/* On hover, ease back toward natural color and pull the fade
inward so more of the real cover is visible. */
filter:
sepia(0.18)
saturate(0.95)
sepia(0.25)
saturate(0.92)
contrast(1.05)
brightness(1)
hue-rotate(-3deg);
brightness(0.98)
hue-rotate(-4deg);
-webkit-mask-image: radial-gradient(circle at 50% 50%,
black 0%,
black 88%,
rgba(0,0,0,0.9) 95%,
rgba(0,0,0,0.5) 99%,
transparent 100%);
mask-image: radial-gradient(circle at 50% 50%,
black 0%,
black 88%,
rgba(0,0,0,0.9) 95%,
rgba(0,0,0,0.5) 99%,
transparent 100%);
}
/* Match the glow tint to the album art treatment */
/* Match the glow tint and soft edge to the album art treatment */
.now-playing .vinyl-label #album-art-glow {
filter: blur(22px) saturate(1.2) sepia(0.35) hue-rotate(-6deg);
filter: blur(22px) saturate(1.1) sepia(0.5) hue-rotate(-8deg);
opacity: 0.4;
}
/* Tonearm */
@@ -6836,29 +6865,34 @@ body.visualizer-active .now-playing .spectrogram-canvas {
fill: currentColor;
}
/* ─── Spectrum bars (JS-injected; real audio when available) ── */
/* ─── Spectrum bars (JS-injected; real audio from backend FFT) ── */
.now-playing .spectrum {
display: flex;
align-items: flex-end;
justify-content: stretch;
gap: 2px;
height: 56px;
height: 64px;
margin: 36px 0 24px;
width: 100%;
/* Force the spectrum to claim the full grid column width even
if siblings (meta-grid cells) report intrinsic widths. */
box-sizing: border-box;
min-width: 0;
}
.now-playing .spectrum span {
display: block;
flex: 1 1 0;
min-width: 2px;
background: linear-gradient(to top, var(--copper-lo), var(--copper-hi));
opacity: 0.9;
min-width: 0;
background: linear-gradient(to top, var(--copper-lo) 0%, var(--copper) 60%, var(--copper-hi) 100%);
opacity: 0.92;
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;
transition: height 60ms linear;
will-change: height;
}
:root[data-playstate="playing"] .now-playing .spectrum span {
animation-play-state: running;