fix(player): wire accent picker to editorial copper palette + visual polish
Lint & Test / test (push) Successful in 9s
Lint & Test / test (push) Successful in 9s
The accent picker only mutated --accent / --accent-hover, but the redesign reads everything off --copper, --copper-hi, --copper-lo, --copper-glow. --accent was a one-way alias of --copper, so picking a color did nothing. Frontend (player.js): - applyAccentColor now drives --copper, --copper-hi, --copper-lo, and a new --copper-rgb triplet (used by every soft tint / glow on both themes) - darkenColor / hexToRgbTriple helpers added beside lightenColor CSS (styles.css): - introduce --copper-rgb tokens for both themes; --copper-glow now derives from rgba(var(--copper-rgb), 0.35) so it follows the picker - replace 21 hardcoded rgba(224,128,56,...) / rgba(31,78,61,...) literals across hover bgs, focus halos, glows, vinyl-label gradients with rgba(var(--copper-rgb), ...) - replace the light-theme vinyl-label gradient hexes with var(--copper) / var(--copper-lo) Other player polish in this changeset: - track-masthead: padding-right clamp(12px, 1.5vw, 24px) so VU meter, spectrum tail, end timecode and controls sit inset from the panel edge (zeroed on the single-column mobile breakpoint to keep symmetry) - VU meter 140→120 px, volume slider 80→64 px to free up row width so the cluster stays inline with prev/play/next instead of wrapping - light-theme VU meter override: cream gauge face, dark-ink scale ticks, hunter-emerald needle (replaces the hardcoded black gauge) - fullscreen meta-cell labels: var(--ink-faint) → var(--copper) so STATE and SOURCE read as part of the same editorial system as the kicker
This commit is contained in:
@@ -113,7 +113,8 @@
|
||||
--copper: #E08038;
|
||||
--copper-hi: #F4A064;
|
||||
--copper-lo: #B0561F;
|
||||
--copper-glow: rgba(224, 128, 56, 0.35);
|
||||
--copper-rgb: 224, 128, 56;
|
||||
--copper-glow: rgba(var(--copper-rgb), 0.35);
|
||||
|
||||
--amber: #F5C26B;
|
||||
--jade: #7AB294;
|
||||
@@ -167,7 +168,8 @@
|
||||
--copper: #1F4E3D; /* hunter emerald in light mode */
|
||||
--copper-hi: #2D6A53;
|
||||
--copper-lo: #143E2F;
|
||||
--copper-glow: rgba(31, 78, 61, 0.18);
|
||||
--copper-rgb: 31, 78, 61;
|
||||
--copper-glow: rgba(var(--copper-rgb), 0.18);
|
||||
|
||||
--amber: #C29D31;
|
||||
--jade: #4D8C6F;
|
||||
@@ -4751,7 +4753,7 @@ body.visualizer-active .vinyl-stage .spectrogram-canvas {
|
||||
justify-content: center;
|
||||
}
|
||||
:root[data-theme="light"] .vinyl-stage .vinyl-wrap .vinyl-label {
|
||||
background: linear-gradient(135deg, #1F4E3D 0%, #143E2F 100%);
|
||||
background: linear-gradient(135deg, var(--copper) 0%, var(--copper-lo) 100%);
|
||||
box-shadow:
|
||||
inset 0 0 18px rgba(0, 0, 0, 0.4),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.06),
|
||||
@@ -4946,7 +4948,7 @@ body.visualizer-active .vinyl-stage .spectrogram-canvas {
|
||||
border: 1px solid var(--rule-strong);
|
||||
border-radius: 4px 4px 0 0;
|
||||
overflow: hidden;
|
||||
box-shadow: inset 0 2px 6px rgba(0,0,0,0.5), inset 0 0 30px rgba(224,128,56,0.08);
|
||||
box-shadow: inset 0 2px 6px rgba(0,0,0,0.5), inset 0 0 30px rgba(var(--copper-rgb), 0.08);
|
||||
}
|
||||
.vu-meter::before {
|
||||
content: "";
|
||||
@@ -5128,7 +5130,7 @@ body.visualizer-active .vinyl-stage .spectrogram-canvas {
|
||||
height: 10px;
|
||||
background: var(--copper);
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 14px var(--copper-glow), 0 0 0 4px rgba(224, 128, 56, 0.12);
|
||||
box-shadow: 0 0 14px var(--copper-glow), 0 0 0 4px rgba(var(--copper-rgb), 0.12);
|
||||
transition: none;
|
||||
}
|
||||
|
||||
@@ -5169,7 +5171,7 @@ body.visualizer-active .vinyl-stage .spectrogram-canvas {
|
||||
transition: all 220ms var(--ease);
|
||||
}
|
||||
.controls button:hover {
|
||||
background: rgba(224, 128, 56, 0.06);
|
||||
background: rgba(var(--copper-rgb), 0.06);
|
||||
border-color: var(--copper);
|
||||
color: var(--copper);
|
||||
}
|
||||
@@ -5213,7 +5215,7 @@ body.visualizer-active .vinyl-stage .spectrogram-canvas {
|
||||
.mute-btn:hover {
|
||||
border-color: var(--copper);
|
||||
color: var(--copper);
|
||||
background: rgba(224, 128, 56, 0.06);
|
||||
background: rgba(var(--copper-rgb), 0.06);
|
||||
}
|
||||
|
||||
#volume-slider {
|
||||
@@ -5232,7 +5234,7 @@ body.visualizer-active .vinyl-stage .spectrogram-canvas {
|
||||
height: 14px;
|
||||
background: var(--copper);
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 12px var(--copper-glow), 0 0 0 4px rgba(224, 128, 56, 0.12);
|
||||
box-shadow: 0 0 12px var(--copper-glow), 0 0 0 4px rgba(var(--copper-rgb), 0.12);
|
||||
border: 0;
|
||||
cursor: grab;
|
||||
}
|
||||
@@ -5297,7 +5299,7 @@ body.visualizer-active .vinyl-stage .spectrogram-canvas {
|
||||
.vinyl-toggle-btn.active {
|
||||
border-color: var(--copper);
|
||||
color: var(--copper);
|
||||
background: rgba(224, 128, 56, 0.06);
|
||||
background: rgba(var(--copper-rgb), 0.06);
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════
|
||||
@@ -5581,7 +5583,7 @@ body.visualizer-active .vinyl-stage .spectrogram-canvas {
|
||||
.view-toggle-btn:last-child { border-right: 0; }
|
||||
.view-toggle-btn:hover {
|
||||
color: var(--copper);
|
||||
background: rgba(224, 128, 56, 0.04);
|
||||
background: rgba(var(--copper-rgb), 0.04);
|
||||
}
|
||||
.view-toggle-btn.active {
|
||||
background: var(--ink);
|
||||
@@ -5987,7 +5989,7 @@ body.visualizer-active .vinyl-stage .spectrogram-canvas {
|
||||
border-color: var(--copper);
|
||||
border-style: solid;
|
||||
color: var(--copper);
|
||||
background: rgba(224, 128, 56, 0.04);
|
||||
background: rgba(var(--copper-rgb), 0.04);
|
||||
}
|
||||
.add-card-icon {
|
||||
font-family: var(--serif);
|
||||
@@ -6356,7 +6358,7 @@ dialog::backdrop {
|
||||
font-size: 10px;
|
||||
}
|
||||
.icon-select-cell:hover {
|
||||
background: rgba(224, 128, 56, 0.06);
|
||||
background: rgba(var(--copper-rgb), 0.06);
|
||||
color: var(--copper);
|
||||
}
|
||||
|
||||
@@ -6848,7 +6850,7 @@ body.audio-spectrum-live .now-playing .spectrum span {
|
||||
width: 10px; height: 10px;
|
||||
background: var(--copper);
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 14px var(--copper-glow), 0 0 0 4px rgba(224, 128, 56, 0.12);
|
||||
box-shadow: 0 0 14px var(--copper-glow), 0 0 0 4px rgba(var(--copper-rgb), 0.12);
|
||||
transition: none;
|
||||
}
|
||||
|
||||
@@ -6879,7 +6881,7 @@ body.audio-spectrum-live .now-playing .spectrum span {
|
||||
.now-playing .btn-trans:hover {
|
||||
border-color: var(--copper);
|
||||
color: var(--copper);
|
||||
background: rgba(224, 128, 56, 0.06);
|
||||
background: rgba(var(--copper-rgb), 0.06);
|
||||
}
|
||||
.now-playing .btn-trans:disabled {
|
||||
opacity: 0.35;
|
||||
@@ -6955,7 +6957,7 @@ body.audio-spectrum-live .now-playing .spectrum span {
|
||||
.now-playing .vu-volume .mute-btn:hover {
|
||||
border-color: var(--copper);
|
||||
color: var(--copper);
|
||||
background: rgba(224, 128, 56, 0.06);
|
||||
background: rgba(var(--copper-rgb), 0.06);
|
||||
}
|
||||
.now-playing .vu-volume .mute-btn svg {
|
||||
width: 14px;
|
||||
@@ -7007,7 +7009,7 @@ body.audio-spectrum-live .now-playing .spectrum span {
|
||||
border: 1px solid var(--rule-strong);
|
||||
border-radius: 4px 4px 0 0;
|
||||
overflow: hidden;
|
||||
box-shadow: inset 0 2px 6px rgba(0,0,0,0.5), inset 0 0 30px rgba(224,128,56,0.08);
|
||||
box-shadow: inset 0 2px 6px rgba(0,0,0,0.5), inset 0 0 30px rgba(var(--copper-rgb), 0.08);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.now-playing .vu-meter::before {
|
||||
@@ -7066,7 +7068,7 @@ body.audio-spectrum-live .now-playing .spectrum span {
|
||||
border-color: var(--rule-strong);
|
||||
box-shadow:
|
||||
inset 0 1px 2px rgba(26, 23, 21, 0.08),
|
||||
inset 0 0 24px rgba(31, 78, 61, 0.05);
|
||||
inset 0 0 24px rgba(var(--copper-rgb), 0.05);
|
||||
}
|
||||
:root[data-theme="light"] .now-playing .vu-meter::before {
|
||||
background: repeating-conic-gradient(from 195deg at 50% 100%,
|
||||
@@ -7079,7 +7081,7 @@ body.audio-spectrum-live .now-playing .spectrum span {
|
||||
}
|
||||
:root[data-theme="light"] .now-playing .vu-needle {
|
||||
background: linear-gradient(to top, var(--copper) 0%, var(--copper-lo) 70%, var(--ink) 100%);
|
||||
box-shadow: 0 0 6px rgba(31, 78, 61, 0.25);
|
||||
box-shadow: 0 0 6px rgba(var(--copper-rgb), 0.25);
|
||||
}
|
||||
|
||||
/* Mobile VU cluster: stack below controls */
|
||||
@@ -7233,7 +7235,7 @@ body.audio-spectrum-live .now-playing .spectrum span {
|
||||
.browser-container .browser-refresh-btn:hover,
|
||||
.browser-container .browser-play-all-btn:hover {
|
||||
color: var(--copper) !important;
|
||||
background: rgba(224, 128, 56, 0.06) !important;
|
||||
background: rgba(var(--copper-rgb), 0.06) !important;
|
||||
}
|
||||
.browser-container .view-toggle-btn.active {
|
||||
background: var(--ink) !important;
|
||||
@@ -7752,7 +7754,7 @@ select option {
|
||||
border-color: var(--copper) !important;
|
||||
border-style: solid !important;
|
||||
color: var(--copper) !important;
|
||||
background: rgba(224, 128, 56, 0.04) !important;
|
||||
background: rgba(var(--copper-rgb), 0.04) !important;
|
||||
}
|
||||
.settings-container .add-card-icon {
|
||||
font-family: var(--serif);
|
||||
@@ -7987,7 +7989,7 @@ select option {
|
||||
.display-container .display-power-btn:hover {
|
||||
color: var(--copper) !important;
|
||||
border-color: var(--copper) !important;
|
||||
background: rgba(224, 128, 56, 0.06) !important;
|
||||
background: rgba(var(--copper-rgb), 0.06) !important;
|
||||
}
|
||||
|
||||
/* Brightness control row */
|
||||
@@ -8138,7 +8140,7 @@ select option {
|
||||
font-size: 10px;
|
||||
}
|
||||
.icon-select-cell:hover {
|
||||
background: rgba(224, 128, 56, 0.06) !important;
|
||||
background: rgba(var(--copper-rgb), 0.06) !important;
|
||||
color: var(--copper) !important;
|
||||
}
|
||||
|
||||
@@ -8396,7 +8398,7 @@ select option {
|
||||
}
|
||||
.mini-control-btn:hover {
|
||||
border-color: var(--copper) !important;
|
||||
background: rgba(224, 128, 56, 0.08) !important;
|
||||
background: rgba(var(--copper-rgb), 0.08) !important;
|
||||
color: var(--copper) !important;
|
||||
}
|
||||
.mini-control-btn svg {
|
||||
@@ -8768,7 +8770,7 @@ body.is-fullscreen-player .player-container {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background:
|
||||
radial-gradient(ellipse at 30% 35%, rgba(224, 128, 56, 0.05) 0%, transparent 55%),
|
||||
radial-gradient(ellipse at 30% 35%, rgba(var(--copper-rgb), 0.05) 0%, transparent 55%),
|
||||
radial-gradient(ellipse at center, var(--bg-paper) 0%, var(--bg-deep) 75%);
|
||||
display: grid;
|
||||
place-items: stretch;
|
||||
@@ -9069,7 +9071,7 @@ body.is-fullscreen-player .now-playing .meta-cell .label {
|
||||
font-family: var(--mono);
|
||||
font-size: 9px;
|
||||
letter-spacing: 0.32em;
|
||||
color: var(--ink-faint);
|
||||
color: var(--copper);
|
||||
}
|
||||
body.is-fullscreen-player .now-playing .meta-cell .value {
|
||||
font-family: var(--mono);
|
||||
|
||||
@@ -145,6 +145,22 @@ export function lightenColor(hex, percent) {
|
||||
return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`;
|
||||
}
|
||||
|
||||
function darkenColor(hex, percent) {
|
||||
const num = parseInt(hex.replace('#', ''), 16);
|
||||
const r = Math.max(0, (num >> 16) - Math.round(255 * percent / 100));
|
||||
const g = Math.max(0, ((num >> 8) & 0xff) - Math.round(255 * percent / 100));
|
||||
const b = Math.max(0, (num & 0xff) - Math.round(255 * percent / 100));
|
||||
return `#${((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1)}`;
|
||||
}
|
||||
|
||||
function hexToRgbTriple(hex) {
|
||||
const num = parseInt(hex.replace('#', ''), 16);
|
||||
const r = (num >> 16) & 0xff;
|
||||
const g = (num >> 8) & 0xff;
|
||||
const b = num & 0xff;
|
||||
return `${r}, ${g}, ${b}`;
|
||||
}
|
||||
|
||||
export function initAccentColor() {
|
||||
const saved = localStorage.getItem('accentColor');
|
||||
if (saved) {
|
||||
@@ -159,8 +175,18 @@ export function initAccentColor() {
|
||||
}
|
||||
|
||||
export function applyAccentColor(color, hover) {
|
||||
document.documentElement.style.setProperty('--accent', color);
|
||||
document.documentElement.style.setProperty('--accent-hover', hover);
|
||||
const root = document.documentElement.style;
|
||||
root.setProperty('--accent', color);
|
||||
root.setProperty('--accent-hover', hover);
|
||||
// Editorial palette tokens — the redesign reads these directly,
|
||||
// so the picker must drive them too (the --accent alias alone has
|
||||
// no effect once components moved off it).
|
||||
root.setProperty('--copper', color);
|
||||
root.setProperty('--copper-hi', hover);
|
||||
root.setProperty('--copper-lo', darkenColor(color, 12));
|
||||
root.setProperty('--copper-rgb', hexToRgbTriple(color));
|
||||
// --copper-glow inherits the rgba(var(--copper-rgb), 0.35) formula
|
||||
// declared in styles.css, so it picks up the new RGB automatically.
|
||||
localStorage.setItem('accentColor', color);
|
||||
const dot = document.getElementById('accentDot');
|
||||
if (dot) dot.style.background = color;
|
||||
|
||||
Reference in New Issue
Block a user