fix(ui): close more gaps with mockup (tabs, mini player, volume control)
Tabs - Replace SVG icons with mockup-style numeric badges (01..05) - Hide the legacy .tab-indicator (was rendering as a long copper bar above the strip); active tab gets its own copper underline via .tab-btn.active::after - Numbers turn copper on the active tab Player view - Volume control restored: mute button + slim copper slider live inside the VU cluster, on the right of the readout, separated by a hairline. Slider is the existing #volume-slider so all JS hooks (bidirectional sync, drag, etc.) keep working. - Track title font scaled down (clamp 34..64) and clamped to 3 lines with ellipsis so long YouTube-style titles don't dominate the masthead. Adds word-break + overflow-wrap. - #artist:empty and #album:empty are now display:none so blank rows don't leave a gap when the source provides no metadata. Mini player - Forced display: grid with 4 columns: track / controls / progress / volume. Was inheriting legacy display:flex which pushed elements into a single non-aligned row. - Position locked: position: fixed, bottom: 0, left/right: 0 with !important. The strip is firmly anchored to the viewport bottom. - Top edge progress (::before) painted in copper with glow. - Responsive collapse: hide progress at <=880px, hide volume at <=540px, leaving track + controls on phones. i18n - tab.player default text aligned to "Now Spinning" (matches existing en/ru values added earlier).
This commit is contained in:
@@ -4294,21 +4294,22 @@ header .brand-sub {
|
||||
margin: 14px 0 36px;
|
||||
border-radius: 0;
|
||||
gap: 0;
|
||||
position: relative;
|
||||
overflow-x: auto;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
.tab-bar::-webkit-scrollbar { display: none; }
|
||||
|
||||
/* Hide the legacy tab-indicator entirely — we use ::after on .tab-btn.active instead */
|
||||
.tab-indicator {
|
||||
background: var(--copper);
|
||||
box-shadow: 0 0 12px var(--copper-glow);
|
||||
height: 2px;
|
||||
bottom: -1px;
|
||||
border-radius: 0;
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.tab-btn {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
color: var(--ink-mute);
|
||||
padding: 18px 22px 16px;
|
||||
padding: 18px 26px 16px;
|
||||
border-radius: 0;
|
||||
font-family: var(--sans);
|
||||
font-size: 13px;
|
||||
@@ -4316,8 +4317,11 @@ header .brand-sub {
|
||||
letter-spacing: 0.04em;
|
||||
transition: color 180ms var(--ease);
|
||||
position: relative;
|
||||
gap: 10px;
|
||||
display: inline-flex;
|
||||
align-items: baseline;
|
||||
gap: 10px;
|
||||
white-space: nowrap;
|
||||
cursor: pointer;
|
||||
}
|
||||
.tab-btn:hover { color: var(--ink-soft); background: transparent; }
|
||||
.tab-btn.active {
|
||||
@@ -4330,8 +4334,35 @@ header .brand-sub {
|
||||
font-variation-settings: 'opsz' 60;
|
||||
}
|
||||
|
||||
.tab-btn svg { opacity: 0.7; }
|
||||
.tab-btn.active svg { opacity: 1; color: var(--copper); }
|
||||
/* Tab number badge (replaces the icon) */
|
||||
.tab-btn .tab-num {
|
||||
font-family: var(--mono);
|
||||
font-style: normal;
|
||||
font-size: 10px;
|
||||
color: var(--ink-faint);
|
||||
letter-spacing: 0.15em;
|
||||
font-weight: 400;
|
||||
}
|
||||
.tab-btn.active .tab-num {
|
||||
color: var(--copper);
|
||||
}
|
||||
|
||||
/* Hide any remaining legacy SVG icons on tabs */
|
||||
.tab-btn svg {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Active tab underline — only under the active tab */
|
||||
.tab-btn.active::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: -1px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
background: var(--copper);
|
||||
box-shadow: 0 0 12px var(--copper-glow);
|
||||
}
|
||||
|
||||
/* ─── Update + connection banners ───────────────────────────── */
|
||||
.update-banner,
|
||||
@@ -5156,17 +5187,102 @@ body.visualizer-active .vinyl-stage .spectrogram-canvas {
|
||||
}
|
||||
|
||||
/* ═══════════════════════════════════════════════════════════════
|
||||
MINI PLAYER — console strip
|
||||
MINI PLAYER — sticky console strip (3-column grid)
|
||||
═══════════════════════════════════════════════════════════════ */
|
||||
.mini-player {
|
||||
background: linear-gradient(180deg, rgba(14, 13, 11, 0.7) 0%, rgba(14, 13, 11, 0.96) 30%);
|
||||
/* Override legacy display: flex with explicit grid */
|
||||
display: grid !important;
|
||||
grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr) auto;
|
||||
column-gap: 24px;
|
||||
row-gap: 0;
|
||||
align-items: center;
|
||||
background: linear-gradient(180deg, rgba(14, 13, 11, 0.72) 0%, rgba(14, 13, 11, 0.96) 30%);
|
||||
backdrop-filter: blur(20px) saturate(160%);
|
||||
-webkit-backdrop-filter: blur(20px) saturate(160%);
|
||||
border-top: 1px solid var(--rule-strong);
|
||||
box-shadow: none;
|
||||
padding: 14px 32px;
|
||||
gap: 28px;
|
||||
position: relative;
|
||||
padding: 12px 32px;
|
||||
/* Anchor firmly to the bottom of the viewport */
|
||||
position: fixed !important;
|
||||
bottom: 0 !important;
|
||||
left: 0 !important;
|
||||
right: 0 !important;
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
/* Top edge progress line in copper */
|
||||
.mini-player::before {
|
||||
background: var(--copper) !important;
|
||||
height: 2px !important;
|
||||
box-shadow: 0 0 8px var(--copper-glow);
|
||||
}
|
||||
|
||||
/* Column 1: track info */
|
||||
.mini-player .mini-player-info {
|
||||
grid-column: 1;
|
||||
grid-row: 1;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
/* Column 2: transport (centered) */
|
||||
.mini-player .mini-controls {
|
||||
grid-column: 2;
|
||||
grid-row: 1;
|
||||
justify-self: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
/* Column 3: progress (timecodes + bar) */
|
||||
.mini-player .mini-progress-container {
|
||||
grid-column: 3;
|
||||
grid-row: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
justify-self: stretch;
|
||||
align-items: stretch;
|
||||
min-width: 180px;
|
||||
max-width: 360px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.mini-player .mini-progress-container .mini-time-display {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
/* Column 4: volume controls */
|
||||
.mini-player .mini-volume-container {
|
||||
grid-column: 4;
|
||||
grid-row: 1;
|
||||
justify-self: end;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 880px) {
|
||||
.mini-player {
|
||||
grid-template-columns: minmax(0, 1fr) auto auto;
|
||||
column-gap: 14px;
|
||||
}
|
||||
.mini-player .mini-progress-container { display: none; }
|
||||
.mini-player .mini-volume-container { grid-column: 3; }
|
||||
}
|
||||
|
||||
@media (max-width: 540px) {
|
||||
.mini-player {
|
||||
grid-template-columns: minmax(0, 1fr) auto;
|
||||
padding: 10px 14px;
|
||||
}
|
||||
.mini-player .mini-volume-container { display: none; }
|
||||
}
|
||||
|
||||
.mini-player::before {
|
||||
@@ -6507,13 +6623,22 @@ body.visualizer-active .now-playing .spectrogram-canvas {
|
||||
.now-playing #track-title {
|
||||
font-family: var(--serif);
|
||||
font-weight: 400;
|
||||
font-size: clamp(42px, 5.6vw, 78px);
|
||||
line-height: 0.96;
|
||||
font-size: clamp(34px, 4.4vw, 64px);
|
||||
line-height: 0.98;
|
||||
letter-spacing: -0.02em;
|
||||
font-variation-settings: 'opsz' 144;
|
||||
margin-bottom: 18px;
|
||||
color: var(--ink);
|
||||
margin-top: 0;
|
||||
/* Long titles get clamped to 3 lines with ellipsis */
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 3;
|
||||
line-clamp: 3;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
word-break: break-word;
|
||||
overflow-wrap: anywhere;
|
||||
hyphens: auto;
|
||||
}
|
||||
.now-playing .track-title em {
|
||||
font-style: italic;
|
||||
@@ -6531,7 +6656,6 @@ body.visualizer-active .now-playing .spectrogram-canvas {
|
||||
margin-bottom: 4px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.now-playing .track-album,
|
||||
.now-playing #album {
|
||||
font-family: var(--sans);
|
||||
@@ -6543,6 +6667,14 @@ body.visualizer-active .now-playing .spectrogram-canvas {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
/* Hide byline/album rows when their content is empty so they
|
||||
don't leave a stretched blank gap. JS leaves them empty when
|
||||
the source provides no metadata. */
|
||||
.now-playing #artist:empty,
|
||||
.now-playing #album:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ─── 2-cell metadata grid ────────────────────────────────── */
|
||||
.now-playing .meta-grid {
|
||||
display: grid;
|
||||
@@ -6772,20 +6904,13 @@ body.visualizer-active .now-playing .spectrogram-canvas {
|
||||
width: 24px; height: 24px;
|
||||
}
|
||||
|
||||
/* VU cluster — display-only, click toggles mute */
|
||||
/* VU cluster — meter + readout + integrated volume control */
|
||||
.now-playing .vu-cluster {
|
||||
margin-left: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
transition: opacity 200ms var(--ease);
|
||||
}
|
||||
.now-playing .vu-cluster:hover { opacity: 0.85; }
|
||||
.now-playing .vu-cluster:focus-visible {
|
||||
outline: 1px solid var(--copper);
|
||||
outline-offset: 4px;
|
||||
}
|
||||
.now-playing .vu-cluster.muted .vu-needle {
|
||||
background: linear-gradient(to top, var(--rust) 0%, var(--ink-mute) 100%);
|
||||
@@ -6793,6 +6918,78 @@ body.visualizer-active .now-playing .spectrogram-canvas {
|
||||
}
|
||||
.now-playing .vu-cluster.muted .vu-readout strong { color: var(--rust); }
|
||||
|
||||
/* Integrated volume control: tiny mute icon + slim copper slider */
|
||||
.now-playing .vu-volume {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
padding-left: 12px;
|
||||
border-left: 1px solid var(--rule);
|
||||
margin-left: 4px;
|
||||
}
|
||||
.now-playing .vu-volume .mute-btn {
|
||||
background: transparent;
|
||||
border: 1px solid var(--rule-strong);
|
||||
color: var(--ink-soft);
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border-radius: 50%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: all 180ms var(--ease);
|
||||
flex-shrink: 0;
|
||||
}
|
||||
.now-playing .vu-volume .mute-btn:hover {
|
||||
border-color: var(--copper);
|
||||
color: var(--copper);
|
||||
background: rgba(224, 128, 56, 0.06);
|
||||
}
|
||||
.now-playing .vu-volume .mute-btn svg {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
fill: currentColor;
|
||||
}
|
||||
.now-playing .vu-volume #volume-slider {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 80px;
|
||||
height: 2px;
|
||||
background: var(--rule-strong);
|
||||
border-radius: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
flex: none;
|
||||
}
|
||||
.now-playing .vu-volume #volume-slider::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: var(--copper);
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 8px var(--copper-glow);
|
||||
border: 0;
|
||||
cursor: grab;
|
||||
}
|
||||
.now-playing .vu-volume #volume-slider::-moz-range-thumb {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
background: var(--copper);
|
||||
border-radius: 50%;
|
||||
border: 0;
|
||||
cursor: grab;
|
||||
}
|
||||
.now-playing .vu-volume #volume-slider::-moz-range-track {
|
||||
height: 2px;
|
||||
background: var(--rule-strong);
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.now-playing .vu-meter {
|
||||
position: relative;
|
||||
width: 140px;
|
||||
|
||||
Reference in New Issue
Block a user