fix(ui): snap player view directly from Studio Reference mockup
Wholesale replacement of the player view markup + a verbatim mockup CSS block scoped to .now-playing. Previous approach kept restyling legacy classes which left a layered, inconsistent result. This is a clean snap: same DOM structure as the mockup, same CSS rules, mapped onto existing JS-touched IDs. Markup - One <section class="now-playing"> with vinyl-stage on left and track-masthead on right - Vinyl spins via data-playstate and contains album art as the circular center label (existing #album-art img preserved) - SVG tonearm pivots in/out by data-playstate - Track masthead: .kicker (copper italic mono), large italic-serif .track-title, italic .track-byline, mono .track-album - Meta grid: 2 cells (State / Source) with mono labels + italic serif values - 30 .spectrum bars between metadata and transport - .transport: progress-row (timecode + .progress-track + timecode) and .controls (3 .btn-trans buttons + .vu-cluster) - Volume slider, mute button, visualizer toggle moved to a .visually-hidden block — they remain functional for JS / a11y but no longer compete for visual real estate. Volume control happens via the always-visible mini player. VU cluster (mockup-faithful) - 140x60 VU meter with conic-gradient grid background, copper needle, "VU" label - Stacked readout: "OUT <strong>SYS</strong>" / "VOL <strong>72%</strong>" - Click anywhere on cluster toggles mute (calls toggleMute()) - When muted: needle turns rust, readout strong turns rust, OUT label switches to MUTE JS hooks - updatePlaybackState already sets :root[data-playstate] (drives spin + tonearm) - Volume tick now updates #vu-vol and #vu-out - updateMuteIcon updates #vu-out + .vu-cluster.muted class Scoping - All new CSS is .now-playing-prefixed so other tabs and dialogs are untouched - Legacy .progress-bar:hover scaleY and ::after scale(0) are defeated with !important inside .now-playing
This commit is contained in:
@@ -157,10 +157,10 @@
|
||||
</div>
|
||||
|
||||
<div class="player-container" data-tab-content="player" role="tabpanel" id="panel-player">
|
||||
<div class="player-layout now-playing">
|
||||
<section class="now-playing player-layout">
|
||||
|
||||
<!-- Vinyl stage with album art as label -->
|
||||
<div class="album-art-container vinyl-stage">
|
||||
<!-- Vinyl stage with album art as label, plus tonearm -->
|
||||
<div class="vinyl-stage album-art-container">
|
||||
<div class="vinyl">
|
||||
<div class="vinyl-label">
|
||||
<img id="album-art-glow" class="album-art-glow" src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 300 300'%3E%3Crect fill='%23282828' width='300' height='300'/%3E%3C/svg%3E" alt="" aria-hidden="true">
|
||||
@@ -188,21 +188,19 @@
|
||||
</div>
|
||||
|
||||
<!-- Track masthead -->
|
||||
<div class="player-details track-masthead">
|
||||
<div class="track-masthead player-details">
|
||||
|
||||
<div class="kicker"><span data-i18n="player.kicker">Now Playing</span></div>
|
||||
|
||||
<div class="track-info">
|
||||
<div id="track-title" data-i18n="player.no_media">No media playing</div>
|
||||
<div id="artist"></div>
|
||||
<div id="album"></div>
|
||||
</div>
|
||||
<h1 class="track-title" id="track-title" data-i18n="player.no_media">No media playing</h1>
|
||||
<div class="track-byline" id="artist"></div>
|
||||
<div class="track-album" id="album"></div>
|
||||
|
||||
<!-- Editorial metadata grid (State + Source; timecodes are on the timeline) -->
|
||||
<!-- 2-cell metadata grid -->
|
||||
<div class="meta-grid meta-grid-2">
|
||||
<div class="meta-cell">
|
||||
<div class="meta-label" data-i18n="meta.state">State</div>
|
||||
<div class="meta-value">
|
||||
<div class="label" data-i18n="meta.state">State</div>
|
||||
<div class="value">
|
||||
<svg class="state-icon" id="state-icon" viewBox="0 0 24 24">
|
||||
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm-2 14.5v-9l6 4.5-6 4.5z"/>
|
||||
</svg>
|
||||
@@ -210,8 +208,8 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="meta-cell">
|
||||
<div class="meta-label" data-i18n="meta.source">Source</div>
|
||||
<div class="meta-value source-value">
|
||||
<div class="label" data-i18n="meta.source">Source</div>
|
||||
<div class="value source-value">
|
||||
<span class="source-icon" id="sourceIcon"></span>
|
||||
<span id="source" data-i18n="player.unknown_source">Unknown</span>
|
||||
</div>
|
||||
@@ -228,64 +226,55 @@
|
||||
<span></span><span></span><span></span><span></span><span></span>
|
||||
</div>
|
||||
|
||||
<!-- Transport: progress + controls + VU cluster -->
|
||||
<!-- Transport -->
|
||||
<div class="transport">
|
||||
<div class="progress-container progress-row">
|
||||
<div class="progress-row">
|
||||
<span class="timecode elapsed" id="current-time">0:00</span>
|
||||
<div class="progress-bar progress-track" id="progress-bar" data-duration="0" role="slider" aria-label="Playback position" aria-valuemin="0" aria-valuemax="0" aria-valuenow="0">
|
||||
<div class="progress-track progress-bar" id="progress-bar" data-duration="0" role="slider" aria-label="Playback position" aria-valuemin="0" aria-valuemax="0" aria-valuenow="0">
|
||||
<div class="progress-fill" id="progress-fill"></div>
|
||||
</div>
|
||||
<span class="timecode" id="total-time">0:00</span>
|
||||
</div>
|
||||
|
||||
<div class="controls">
|
||||
<button onclick="previousTrack()" data-i18n-title="player.previous" title="Previous" id="btn-previous">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M6 6h2v12H6zm3.5 6l8.5 6V6z"/>
|
||||
</svg>
|
||||
<button class="btn-trans" onclick="previousTrack()" data-i18n-title="player.previous" title="Previous" id="btn-previous">
|
||||
<svg viewBox="0 0 24 24"><path d="M6 6h2v12H6zm3.5 6l8.5 6V6z"/></svg>
|
||||
</button>
|
||||
<button class="primary" onclick="togglePlayPause()" data-i18n-title="player.play" title="Play/Pause" id="btn-play-pause">
|
||||
<svg viewBox="0 0 24 24" id="play-pause-icon">
|
||||
<path d="M8 5v14l11-7z"/>
|
||||
</svg>
|
||||
<button class="btn-trans primary" onclick="togglePlayPause()" data-i18n-title="player.play" title="Play/Pause" id="btn-play-pause">
|
||||
<svg viewBox="0 0 24 24" id="play-pause-icon"><path d="M8 5v14l11-7z"/></svg>
|
||||
</button>
|
||||
<button onclick="nextTrack()" data-i18n-title="player.next" title="Next" id="btn-next">
|
||||
<svg viewBox="0 0 24 24">
|
||||
<path d="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z"/>
|
||||
</svg>
|
||||
<button class="btn-trans" onclick="nextTrack()" data-i18n-title="player.next" title="Next" id="btn-next">
|
||||
<svg viewBox="0 0 24 24"><path d="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z"/></svg>
|
||||
</button>
|
||||
|
||||
<!-- VU cluster: needle visual + slider + readout -->
|
||||
<div class="vu-cluster">
|
||||
<div class="vu-cluster" onclick="toggleMute()" title="Click to mute / use mini player to adjust volume" role="button" tabindex="0">
|
||||
<div class="vu-meter" aria-hidden="true">
|
||||
<div class="vu-needle" id="vuNeedle"></div>
|
||||
</div>
|
||||
<div class="volume-container">
|
||||
<button class="mute-btn" onclick="toggleMute()" data-i18n-title="player.mute" title="Mute" id="btn-mute">
|
||||
<svg viewBox="0 0 24 24" id="mute-icon">
|
||||
<path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<input type="range" id="volume-slider" min="0" max="100" value="50" aria-label="Volume">
|
||||
<div class="volume-display" id="volume-display">50%</div>
|
||||
<div class="vu-readout">
|
||||
<span>OUT <strong id="vu-out">SYS</strong></span>
|
||||
<span>VOL <strong id="vu-vol">50%</strong></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Audio visualizer toggle (button shown by JS only when supported) -->
|
||||
<div class="source-info">
|
||||
<span class="source-label">
|
||||
<span class="vinyl-mode-label" data-i18n="player.modes">Modes</span>
|
||||
</span>
|
||||
<div class="player-toggles">
|
||||
<button class="vinyl-toggle-btn" onclick="toggleVisualizer()" id="visualizerToggle" data-i18n-title="player.visualizer" title="Audio visualizer" style="display:none">
|
||||
<svg viewBox="0 0 24 24" width="16" height="16"><path fill="currentColor" d="M3 18h2v-8H3v8zm4 0h2V6H7v12zm4 0h2V2h-2v16zm4 0h2v-6h-2v6zm4 0h2V9h-2v9z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<!-- Hidden but functional: slider + mute + visualizer toggle.
|
||||
Adjustment happens via the always-visible mini player. -->
|
||||
<div class="visually-hidden">
|
||||
<button class="mute-btn" onclick="toggleMute()" data-i18n-title="player.mute" title="Mute" id="btn-mute">
|
||||
<svg viewBox="0 0 24 24" id="mute-icon">
|
||||
<path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02z"/>
|
||||
</svg>
|
||||
</button>
|
||||
<input type="range" id="volume-slider" min="0" max="100" value="50" aria-label="Volume">
|
||||
<div id="volume-display">50%</div>
|
||||
<button onclick="toggleVisualizer()" id="visualizerToggle" data-i18n-title="player.visualizer" title="Audio visualizer" style="display:none">
|
||||
<svg viewBox="0 0 24 24" width="16" height="16"><path fill="currentColor" d="M3 18h2v-8H3v8zm4 0h2V6H7v12zm4 0h2V2h-2v16zm4 0h2v-6h-2v6zm4 0h2V9h-2v9z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<!-- Media Browser Section -->
|
||||
|
||||
Reference in New Issue
Block a user