Reconcile transport drawing variants, admin controls and theme cascades
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
<meta name="robots" content="noindex" />
|
||||
<meta name="theme-color" content="#0a0c12" />
|
||||
<title>Lyrics Studio</title>
|
||||
<link rel="stylesheet" href="download-actions.css" />
|
||||
<style>
|
||||
:root {
|
||||
color-scheme: dark;
|
||||
@@ -193,7 +194,7 @@
|
||||
.transport { display: flex; align-items: center; gap: 8px; margin-top: 10px; flex-wrap: wrap; }
|
||||
.round { width: 42px; height: 42px; border-radius: 50%; border: 1px solid var(--line-2); background: rgba(255,255,255,.06); display: grid; place-items: center; font-size: 12px; font-weight: 800; }
|
||||
.round.big { width: 52px; height: 52px; border: 0; background: var(--grad); box-shadow: 0 10px 24px -8px var(--a1); }
|
||||
.round svg { width: 20px; height: 20px; fill: #fff; }
|
||||
.round svg { width: 20px; height: 20px; }
|
||||
.clock { font: 600 17px var(--mono); letter-spacing: -.02em; min-width: 108px; text-align: center; }
|
||||
.clock b { color: var(--a2); } .clock span { color: var(--text-dim); font-size: 13px; }
|
||||
.seg { display: inline-flex; padding: 3px; border-radius: 13px; background: rgba(0,0,0,.35); border: 1px solid var(--line); }
|
||||
@@ -384,7 +385,7 @@
|
||||
<canvas id="wave" height="64"></canvas>
|
||||
<div class="transport">
|
||||
<button class="round" id="bBack" type="button" title="Back 5 s" aria-label="Back 5 seconds">−5</button>
|
||||
<button class="round big" id="bPlay" type="button" aria-label="Play or pause"><svg viewBox="0 0 24 24"><path id="playIcon" d="M8 5v14l11-7z"/></svg></button>
|
||||
<button class="round big" id="bPlay" type="button" aria-label="Play or pause"><svg id="playIcon" class="transport-icon" data-transport-icon="play" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use class="transport-shape transport-shape-classic" href="#transport-play"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-play-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-play-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-play-bento-hub"/></svg></button>
|
||||
<button class="round" id="bFwd" type="button" title="Forward 5 s" aria-label="Forward 5 seconds">+5</button>
|
||||
<div class="clock"><b id="cur">0:00.00</b> <span>/ <span id="dur">0:00</span></span></div>
|
||||
<select class="mini" id="rate" title="Playback speed" aria-label="Playback speed">
|
||||
@@ -1172,8 +1173,8 @@
|
||||
const a = new Audio(url); a.preload = 'auto';
|
||||
a.addEventListener('timeupdate', tick); a.addEventListener('seeked', tick);
|
||||
a.addEventListener('loadedmetadata', () => { if (a.duration) { LE.dur = a.duration; $('dur').textContent = fmtT(a.duration).slice(0, -3); } draw(); });
|
||||
a.addEventListener('play', () => { $('playIcon').setAttribute('d', 'M7 5h4v14H7zM13 5h4v14h-4z'); });
|
||||
a.addEventListener('pause', () => { $('playIcon').setAttribute('d', 'M8 5v14l11-7z'); });
|
||||
a.addEventListener('play', () => { TransportIcons.set($('bPlay'),'pause'); });
|
||||
a.addEventListener('pause', () => { TransportIcons.set($('bPlay'),'play'); });
|
||||
a.addEventListener('error', () => say('No playable audio for this song on the server — you can still edit the text.', 'err'));
|
||||
a.playbackRate = Number($('rate').value);
|
||||
LE.audio = a;
|
||||
|
||||
@@ -9,3 +9,30 @@ html[data-layout="glass-stage"] :is(.dl-row,.download-job) .download-action { bo
|
||||
html[data-layout="glass-stage"] :is(.dl-row,.download-job) .download-action:hover { border-color:var(--glass-line); background:var(--tile-hi); color:var(--text); }
|
||||
html[data-layout="glass-stage"] :is(.dl-row,.download-job) .download-action.danger { color:var(--accent-bright); }
|
||||
html[data-layout="glass-stage"] :is(.dl-row,.download-job) .download-action:focus-visible { outline-color:var(--accent-bright); }
|
||||
|
||||
/* Transport drawings and touch targets survive layout/state changes. */
|
||||
.transport-icon { display:inline-block; flex:none; width:24px; height:24px; vertical-align:middle; fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; pointer-events:none; }
|
||||
.transport-shape { display:none; }
|
||||
.transport-shape-classic { display:inline; }
|
||||
html:is([data-layout="f7-swipe"],[data-layout="glass-stage"],[data-layout="bento-hub"]) .transport-shape-classic { display:none; }
|
||||
html[data-layout="f7-swipe"] .transport-shape-f7-swipe,
|
||||
html[data-layout="glass-stage"] .transport-shape-glass-stage,
|
||||
html[data-layout="bento-hub"] .transport-shape-bento-hub { display:inline; }
|
||||
html[data-layout="f7-swipe"] .transport-shape-f7-swipe { fill:currentColor; stroke-width:.7; }
|
||||
html[data-layout="f7-swipe"] .transport-icon:is([data-transport-icon="play"],[data-transport-icon="pause"],[data-transport-icon="previous"],[data-transport-icon="next"],[data-transport-icon="forward"]),
|
||||
html[data-layout="f7-swipe"] #controls .transport-icon:is([data-transport-icon="play"],[data-transport-icon="pause"],[data-transport-icon="previous"],[data-transport-icon="next"],[data-transport-icon="forward"]) { fill:currentColor; stroke-width:.7; }
|
||||
html[data-layout="f7-swipe"] :is([data-transport-icon="back10"],[data-transport-icon="forward10"],[data-transport-icon="back15"]) .transport-shape { fill:none; stroke-width:2; }
|
||||
html[data-layout="glass-stage"] .transport-icon,
|
||||
html[data-layout="glass-stage"] #controls .transport-icon { stroke-width:1.5; }
|
||||
html[data-layout="bento-hub"] .transport-icon { stroke-width:2; stroke-linejoin:round; }
|
||||
button:has(> .transport-icon), a.np-btn:has(> .transport-icon) { min-width:44px; min-height:44px; }
|
||||
button:has(> .transport-icon) { align-items:center; justify-content:center; }
|
||||
html[data-layout="f7-swipe"] :is(#playBtn,#stgPlay,.service-btn-play,.rv-play) { border-radius:50%; }
|
||||
html[data-layout="f7-swipe"] #playBtn { width:64px; height:64px; }
|
||||
html[data-layout="glass-stage"] :is(#playBtn,.mini-btn,.rv-tbtn):has(> .transport-icon) { background:var(--tile,rgba(255,255,255,.08)); border:1px solid var(--line); backdrop-filter:blur(12px); }
|
||||
html[data-layout="bento-hub"] :is(#playBtn,.mini-btn,.service-btn,.rv-tbtn):has(> .transport-icon) { border-radius:16px; }
|
||||
.car-controls .transport-icon { width:36px; height:36px; margin-right:12px; }
|
||||
.gh-seek .transport-icon, .empty-icon .transport-icon { width:48px; height:48px; }
|
||||
.ph-logo .transport-icon { width:60%; height:60%; }
|
||||
|
||||
.home-pl-play:has(> .transport-icon) { min-width:44px; min-height:44px; }
|
||||
|
||||
@@ -36,7 +36,8 @@
|
||||
root.document.body.appendChild(defs);
|
||||
root.MediaIcons = media;
|
||||
}
|
||||
// Shared transport symbols: CSS switches drawings without replacing live controls.
|
||||
// Select variants on visible use elements: ancestor CSS in referenced SVG groups
|
||||
// can report changed styles without repainting the cloned geometry in Chromium.
|
||||
const transportPaths = {
|
||||
play: '<path d="m8 5 11 7-11 7z"/>',
|
||||
pause: '<rect x="6" y="5" width="4" height="14" rx="1"/><rect x="14" y="5" width="4" height="14" rx="1"/>',
|
||||
@@ -60,11 +61,13 @@
|
||||
paths: transportPaths, variants: transportVariants,
|
||||
svg(kind) {
|
||||
if (!transportPaths[kind]) throw new Error('Unknown transport icon: ' + kind);
|
||||
return `<svg class="transport-icon" data-transport-icon="${kind}" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use href="#transport-${kind}"/></svg>`;
|
||||
return `<svg class="transport-icon" data-transport-icon="${kind}" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true">${Object.keys(transportVariants).map(layout=>`<use class="transport-shape transport-shape-${layout}" href="#transport-${kind}${layout==='classic'?'':'-'+layout}"/>`).join('')}</svg>`;
|
||||
},
|
||||
set(button, kind, label) {
|
||||
if (!button) return;
|
||||
const iconId=button.querySelector?.('.transport-icon')?.id;
|
||||
button.innerHTML = this.svg(kind);
|
||||
if(iconId)button.querySelector('.transport-icon').id=iconId;
|
||||
button.setAttribute('aria-label', label || (kind === 'pause' ? 'Pause' : 'Play'));
|
||||
}
|
||||
};
|
||||
@@ -72,7 +75,7 @@
|
||||
const defs = root.document.createElementNS('http://www.w3.org/2000/svg','svg');
|
||||
defs.setAttribute('aria-hidden','true'); defs.setAttribute('width','0'); defs.setAttribute('height','0');
|
||||
defs.style.position='absolute'; defs.style.pointerEvents='none';
|
||||
defs.innerHTML='<defs>'+Object.keys(transportPaths).map(kind=>`<g id="transport-${kind}">${Object.entries(transportVariants).map(([layout,paths])=>`<g class="transport-shape transport-shape-${layout}">${paths[kind]}</g>`).join('')}</g>`).join('')+'</defs>';
|
||||
defs.innerHTML='<defs>'+Object.keys(transportPaths).flatMap(kind=>Object.entries(transportVariants).map(([layout,paths])=>`<g id="transport-${kind}${layout==='classic'?'':'-'+layout}">${paths[kind]}</g>`)).join('')+'</defs>';
|
||||
root.document.body.appendChild(defs); root.TransportIcons=transport;
|
||||
}
|
||||
const paths = {
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
add:'<path d="M12 5v14M5 12h14"/>', close:'<path d="m6 6 12 12M18 6 6 18"/>',
|
||||
search:'<circle cx="10.5" cy="10.5" r="6.5"/><path d="m16 16 5 5"/>',
|
||||
save:'<use href="#media-download"/>',
|
||||
play:'<use href="#transport-play"/>', pause:'<use href="#transport-pause"/>',
|
||||
next:'<use href="#transport-next"/>', previous:'<use href="#transport-previous"/>',
|
||||
play:'<use class="transport-shape transport-shape-classic" href="#transport-play"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-play-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-play-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-play-bento-hub"/>', pause:'<use class="transport-shape transport-shape-classic" href="#transport-pause"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-pause-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-pause-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-pause-bento-hub"/>',
|
||||
next:'<use class="transport-shape transport-shape-classic" href="#transport-next"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-next-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-next-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-next-bento-hub"/>', previous:'<use class="transport-shape transport-shape-classic" href="#transport-previous"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-previous-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-previous-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-previous-bento-hub"/>',
|
||||
repeat:'<path d="m17 2 4 4-4 4M3 11V8a2 2 0 0 1 2-2h16M7 22l-4-4 4-4m14-1v3a2 2 0 0 1-2 2H3"/>',
|
||||
edit:'<path d="m14 5 5 5M4 20l5-1L21 7l-4-4L5 15z"/>',
|
||||
lyrics:'<rect x="9" y="3" width="6" height="11" rx="3"/><path d="M5 10v2a7 7 0 0 0 14 0v-2M12 19v3M8 22h8"/>',
|
||||
|
||||
@@ -42,12 +42,12 @@
|
||||
<!-- Sidebar -->
|
||||
<aside id="sidebar" class="sidebar">
|
||||
<div class="brand">
|
||||
<span class="brand-mark"><svg class="transport-icon" data-transport-icon="play" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use href="#transport-play"/></svg></span> YT Player
|
||||
<span class="brand-mark"><svg class="transport-icon" data-transport-icon="play" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use class="transport-shape transport-shape-classic" href="#transport-play"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-play-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-play-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-play-bento-hub"/></svg></span> YT Player
|
||||
</div>
|
||||
|
||||
<nav class="nav">
|
||||
<button class="nav-item active" data-view="search"><span class="legacy-nav-icon" aria-hidden="true">🔍</span><svg class="classic-nav-icon" hidden viewBox="0 0 24 24" aria-hidden="true"><circle cx="10.5" cy="10.5" r="6.5"/><path d="m16 16 5 5"/></svg> Search</button>
|
||||
<button class="nav-item" data-view="queue"><svg class="transport-icon" data-transport-icon="play" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use href="#transport-play"/></svg> Queue <span id="navQueueCount" class="nav-badge hidden">0</span></button>
|
||||
<button class="nav-item" data-view="queue"><svg class="transport-icon" data-transport-icon="play" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use class="transport-shape transport-shape-classic" href="#transport-play"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-play-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-play-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-play-bento-hub"/></svg> Queue <span id="navQueueCount" class="nav-badge hidden">0</span></button>
|
||||
<button class="nav-item" data-view="history"><span class="legacy-nav-icon" aria-hidden="true">🕘</span><svg class="classic-nav-icon" hidden viewBox="0 0 24 24" aria-hidden="true"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 2"/></svg> History</button>
|
||||
<button class="nav-item" data-view="saved"><svg class="media-icon media-nav-icon" data-media-icon="offline" viewBox="0 0 24 24" aria-hidden="true"><use href="#media-offline"/></svg> Saved</button>
|
||||
<button class="nav-item" data-view="downloads"><svg class="media-icon media-nav-icon" data-media-icon="download" viewBox="0 0 24 24" aria-hidden="true"><use href="#media-download"/></svg> Downloads <span id="navDlCount" class="nav-badge hidden">0</span></button>
|
||||
@@ -140,7 +140,7 @@
|
||||
</div>
|
||||
<div id="playerPlaceholder" class="player-placeholder">
|
||||
<div class="hero">
|
||||
<div class="ph-logo"><svg class="transport-icon" data-transport-icon="play" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use href="#transport-play"/></svg></div>
|
||||
<div class="ph-logo"><svg class="transport-icon" data-transport-icon="play" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use class="transport-shape transport-shape-classic" href="#transport-play"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-play-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-play-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-play-bento-hub"/></svg></div>
|
||||
<h1 class="hero-title">YT Player</h1>
|
||||
<p class="hero-tagline">Ad-free YouTube — no login needed. Search, play, and discover videos shaped by what you listen to.</p>
|
||||
<div class="hero-pills">
|
||||
@@ -178,9 +178,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="stg-mid">
|
||||
<button id="stgBack" class="stg-skip" type="button" aria-label="Back 10 seconds"><svg class="transport-icon" data-transport-icon="back10" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use href="#transport-back10"/></svg></button>
|
||||
<button id="stgPlay" class="stg-play" type="button" aria-label="Play or pause"><svg class="transport-icon" data-transport-icon="play" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use href="#transport-play"/></svg></button>
|
||||
<button id="stgFwd" class="stg-skip" type="button" aria-label="Forward 10 seconds"><svg class="transport-icon" data-transport-icon="forward10" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use href="#transport-forward10"/></svg></button>
|
||||
<button id="stgBack" class="stg-skip" type="button" aria-label="Back 10 seconds"><svg class="transport-icon" data-transport-icon="back10" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use class="transport-shape transport-shape-classic" href="#transport-back10"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-back10-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-back10-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-back10-bento-hub"/></svg></button>
|
||||
<button id="stgPlay" class="stg-play" type="button" aria-label="Play or pause"><svg class="transport-icon" data-transport-icon="play" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use class="transport-shape transport-shape-classic" href="#transport-play"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-play-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-play-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-play-bento-hub"/></svg></button>
|
||||
<button id="stgFwd" class="stg-skip" type="button" aria-label="Forward 10 seconds"><svg class="transport-icon" data-transport-icon="forward10" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use class="transport-shape transport-shape-classic" href="#transport-forward10"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-forward10-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-forward10-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-forward10-bento-hub"/></svg></button>
|
||||
</div>
|
||||
<div class="stg-bot"><span class="stg-chip"><b id="stgZoom">Pinch 1.0×</b></span><span class="stg-chip"><i class="stg-dot"></i><b id="stgBuf">Buffered</b></span></div>
|
||||
</div>
|
||||
@@ -207,11 +207,11 @@
|
||||
</div>
|
||||
<button id="waveLoud" class="wave-loud hidden" type="button">⚡ Jump to the loudest part</button>
|
||||
<div class="deck-main">
|
||||
<button id="prevBtn" class="ctrl" title="Previous" aria-label="Previous"><svg class="transport-icon" data-transport-icon="previous" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use href="#transport-previous"/></svg></button>
|
||||
<button id="back10Btn" class="ctrl skip10" type="button" title="Back 10 seconds" aria-label="Back 10 seconds"><svg class="transport-icon" data-transport-icon="back10" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use href="#transport-back10"/></svg></button>
|
||||
<button id="playBtn" class="ctrl play" title="Play/Pause" aria-label="Play or pause"><svg class="transport-icon" data-transport-icon="play" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use href="#transport-play"/></svg></button>
|
||||
<button id="fwd10Btn" class="ctrl skip10" type="button" title="Forward 10 seconds" aria-label="Forward 10 seconds"><svg class="transport-icon" data-transport-icon="forward10" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use href="#transport-forward10"/></svg></button>
|
||||
<button id="nextBtn" class="ctrl" title="Next" aria-label="Next"><svg class="transport-icon" data-transport-icon="next" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use href="#transport-next"/></svg></button>
|
||||
<button id="prevBtn" class="ctrl" title="Previous" aria-label="Previous"><svg class="transport-icon" data-transport-icon="previous" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use class="transport-shape transport-shape-classic" href="#transport-previous"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-previous-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-previous-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-previous-bento-hub"/></svg></button>
|
||||
<button id="back10Btn" class="ctrl skip10" type="button" title="Back 10 seconds" aria-label="Back 10 seconds"><svg class="transport-icon" data-transport-icon="back10" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use class="transport-shape transport-shape-classic" href="#transport-back10"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-back10-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-back10-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-back10-bento-hub"/></svg></button>
|
||||
<button id="playBtn" class="ctrl play" title="Play/Pause" aria-label="Play or pause"><svg class="transport-icon" data-transport-icon="play" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use class="transport-shape transport-shape-classic" href="#transport-play"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-play-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-play-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-play-bento-hub"/></svg></button>
|
||||
<button id="fwd10Btn" class="ctrl skip10" type="button" title="Forward 10 seconds" aria-label="Forward 10 seconds"><svg class="transport-icon" data-transport-icon="forward10" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use class="transport-shape transport-shape-classic" href="#transport-forward10"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-forward10-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-forward10-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-forward10-bento-hub"/></svg></button>
|
||||
<button id="nextBtn" class="ctrl" title="Next" aria-label="Next"><svg class="transport-icon" data-transport-icon="next" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use class="transport-shape transport-shape-classic" href="#transport-next"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-next-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-next-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-next-bento-hub"/></svg></button>
|
||||
<div id="dkModeHost" hidden><button id="shuffleBtn" class="ctrl" title="Shuffle upcoming tracks (S)" aria-label="Shuffle"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M16 3h5v5M4 20 21 3M21 16v5h-5M15 15l6 6M4 4l5 5"/></svg></button><button id="repeatBtn" class="ctrl" title="Repeat list when finished (R)" aria-label="Repeat list"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M17 2l4 4-4 4M3 12v-2a4 4 0 0 1 4-4h14M7 22l-4-4 4-4M21 12v2a4 4 0 0 1-4 4H3"/></svg></button><button id="loopBtn" class="ctrl" title="Loop this video (L)"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M17 2l4 4-4 4M3 12v-2a4 4 0 0 1 4-4h14M7 22l-4-4 4-4M21 12v2a4 4 0 0 1-4 4H3M11 10.2l1.6-.9v5.4"/></svg></button></div>
|
||||
</div>
|
||||
<div class="deck-vol vol">
|
||||
@@ -473,9 +473,9 @@
|
||||
<span id="serviceCurTime">0:00</span> / <span id="serviceDurTime">0:00</span>
|
||||
</div>
|
||||
<div class="service-controls">
|
||||
<button id="servicePrevBtn" class="service-btn" type="button" aria-label="Previous track"><svg class="transport-icon" data-transport-icon="previous" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use href="#transport-previous"/></svg></button>
|
||||
<button id="servicePlayBtn" class="service-btn service-btn-play" type="button" aria-label="Play or Pause"><svg class="transport-icon" data-transport-icon="play" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use href="#transport-play"/></svg></button>
|
||||
<button id="serviceNextBtn" class="service-btn" type="button" aria-label="Next track"><svg class="transport-icon" data-transport-icon="next" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use href="#transport-next"/></svg></button>
|
||||
<button id="servicePrevBtn" class="service-btn" type="button" aria-label="Previous track"><svg class="transport-icon" data-transport-icon="previous" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use class="transport-shape transport-shape-classic" href="#transport-previous"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-previous-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-previous-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-previous-bento-hub"/></svg></button>
|
||||
<button id="servicePlayBtn" class="service-btn service-btn-play" type="button" aria-label="Play or Pause"><svg class="transport-icon" data-transport-icon="play" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use class="transport-shape transport-shape-classic" href="#transport-play"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-play-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-play-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-play-bento-hub"/></svg></button>
|
||||
<button id="serviceNextBtn" class="service-btn" type="button" aria-label="Next track"><svg class="transport-icon" data-transport-icon="next" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use class="transport-shape transport-shape-classic" href="#transport-next"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-next-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-next-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-next-bento-hub"/></svg></button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -490,7 +490,7 @@
|
||||
<!-- Mini now-playing bar -->
|
||||
<div id="miniBar" class="mini-bar hidden">
|
||||
<div class="mini-bar-inner">
|
||||
<button id="miniPlayBtn" class="mini-btn" aria-label="Play"><svg class="transport-icon" data-transport-icon="play" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use href="#transport-play"/></svg></button>
|
||||
<button id="miniPlayBtn" class="mini-btn" aria-label="Play"><svg class="transport-icon" data-transport-icon="play" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use class="transport-shape transport-shape-classic" href="#transport-play"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-play-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-play-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-play-bento-hub"/></svg></button>
|
||||
<div class="mini-info">
|
||||
<div id="miniTitle" class="mini-title"></div>
|
||||
<div id="miniChannel" class="mini-channel"></div>
|
||||
@@ -567,9 +567,9 @@
|
||||
<div class="rv-times"><span id="rvCur">0:00</span><span id="rvDur">0:00</span></div>
|
||||
</div>
|
||||
<div class="rv-transport">
|
||||
<button id="rvPrev" class="rv-tbtn" type="button" aria-label="Previous"><svg class="transport-icon" data-transport-icon="previous" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use href="#transport-previous"/></svg></button>
|
||||
<button id="rvToggle" class="rv-tbtn rv-play" type="button" aria-label="Play or pause"><svg class="transport-icon" data-transport-icon="play" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use href="#transport-play"/></svg></button>
|
||||
<button id="rvNext" class="rv-tbtn" type="button" aria-label="Next"><svg class="transport-icon" data-transport-icon="next" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use href="#transport-next"/></svg></button>
|
||||
<button id="rvPrev" class="rv-tbtn" type="button" aria-label="Previous"><svg class="transport-icon" data-transport-icon="previous" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use class="transport-shape transport-shape-classic" href="#transport-previous"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-previous-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-previous-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-previous-bento-hub"/></svg></button>
|
||||
<button id="rvToggle" class="rv-tbtn rv-play" type="button" aria-label="Play or pause"><svg class="transport-icon" data-transport-icon="play" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use class="transport-shape transport-shape-classic" href="#transport-play"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-play-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-play-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-play-bento-hub"/></svg></button>
|
||||
<button id="rvNext" class="rv-tbtn" type="button" aria-label="Next"><svg class="transport-icon" data-transport-icon="next" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use class="transport-shape transport-shape-classic" href="#transport-next"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-next-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-next-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-next-bento-hub"/></svg></button>
|
||||
</div>
|
||||
<div class="rv-volume">
|
||||
<span>🔊</span><input id="rvVolume" type="range" min="0" max="100" value="100" /><span id="rvVolVal">100%</span>
|
||||
@@ -591,7 +591,7 @@
|
||||
<span class="bottom-nav-label">Search</span>
|
||||
</button>
|
||||
<button class="bottom-nav-btn" data-view="queue" aria-label="Queue">
|
||||
<span class="bottom-nav-icon"><svg class="transport-icon" data-transport-icon="play" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use href="#transport-play"/></svg></span>
|
||||
<span class="bottom-nav-icon"><svg class="transport-icon" data-transport-icon="play" viewBox="0 0 24 24" fill="none" stroke="currentColor" aria-hidden="true"><use class="transport-shape transport-shape-classic" href="#transport-play"/><use class="transport-shape transport-shape-f7-swipe" href="#transport-play-f7-swipe"/><use class="transport-shape transport-shape-glass-stage" href="#transport-play-glass-stage"/><use class="transport-shape transport-shape-bento-hub" href="#transport-play-bento-hub"/></svg></span>
|
||||
<span class="bottom-nav-label">Queue</span>
|
||||
<span id="bnQueueCount" class="bottom-nav-badge hidden">0</span>
|
||||
</button>
|
||||
|
||||
@@ -4356,25 +4356,3 @@ html[data-layout="bento-hub"] .media-shape-classic { display:none; }
|
||||
html[data-layout="f7-swipe"] .media-shape-f7-swipe,
|
||||
html[data-layout="glass-stage"] .media-shape-glass-stage,
|
||||
html[data-layout="bento-hub"] .media-shape-bento-hub { display:inline; }
|
||||
|
||||
/* Transport drawings and touch targets survive layout/state changes. */
|
||||
.transport-icon { display:inline-block; flex:none; width:24px; height:24px; vertical-align:middle; fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; stroke-linejoin:round; pointer-events:none; }
|
||||
.transport-shape { display:none; }
|
||||
.transport-shape-classic { display:inline; }
|
||||
html:is([data-layout="f7-swipe"],[data-layout="glass-stage"],[data-layout="bento-hub"]) .transport-shape-classic { display:none; }
|
||||
html[data-layout="f7-swipe"] .transport-shape-f7-swipe,
|
||||
html[data-layout="glass-stage"] .transport-shape-glass-stage,
|
||||
html[data-layout="bento-hub"] .transport-shape-bento-hub { display:inline; }
|
||||
html[data-layout="f7-swipe"] .transport-shape-f7-swipe { fill:currentColor; stroke-width:.7; }
|
||||
html[data-layout="f7-swipe"] :is([data-transport-icon="back10"],[data-transport-icon="forward10"],[data-transport-icon="back15"]) .transport-shape { fill:none; stroke-width:2; }
|
||||
html[data-layout="glass-stage"] .transport-icon { stroke-width:1.5; }
|
||||
html[data-layout="bento-hub"] .transport-icon { stroke-width:2; stroke-linejoin:round; }
|
||||
button:has(> .transport-icon), a.np-btn:has(> .transport-icon) { min-width:44px; min-height:44px; }
|
||||
button:has(> .transport-icon) { align-items:center; justify-content:center; }
|
||||
html[data-layout="f7-swipe"] :is(#playBtn,#stgPlay,.service-btn-play,.rv-play) { border-radius:50%; }
|
||||
html[data-layout="f7-swipe"] #playBtn { width:64px; height:64px; }
|
||||
html[data-layout="glass-stage"] :is(#playBtn,.mini-btn,.rv-tbtn):has(> .transport-icon) { background:var(--tile,rgba(255,255,255,.08)); border:1px solid var(--line); backdrop-filter:blur(12px); }
|
||||
html[data-layout="bento-hub"] :is(#playBtn,.mini-btn,.service-btn,.rv-tbtn):has(> .transport-icon) { border-radius:16px; }
|
||||
.car-controls .transport-icon { width:36px; height:36px; margin-right:12px; }
|
||||
.gh-seek .transport-icon, .empty-icon .transport-icon { width:48px; height:48px; }
|
||||
.ph-logo .transport-icon { width:60%; height:60%; }
|
||||
|
||||
@@ -183,7 +183,7 @@ html[data-layout="bento-hub"] .player-pane.empty .player-stage { border:0; borde
|
||||
html[data-layout="bento-hub"] :is(#controls,.now-meta,.notes-panel,.upnext,.related-panel) { flex-shrink:0; padding:16px; border:1px solid var(--line); border-radius:16px; background:var(--bg-1); box-shadow:var(--shadow-sm); }
|
||||
html[data-layout="bento-hub"] #controls { gap:12px; }
|
||||
html[data-layout="bento-hub"] #controls .deck-main { gap:8px; }
|
||||
html[data-layout="bento-hub"] #controls .deck-main .ctrl { width:44px; height:44px; min-width:44px; padding:10px; background:var(--bg-2); color:var(--text); border:1px solid var(--line); border-radius:999px; box-shadow:none; }
|
||||
html[data-layout="bento-hub"] #controls .deck-main .ctrl { width:44px; height:44px; min-width:44px; padding:10px; background:var(--bg-2); color:var(--text); border:1px solid var(--line); border-radius:16px; box-shadow:none; }
|
||||
html[data-layout="bento-hub"] #controls .deck-main .ctrl.play { width:56px; height:56px; padding:14px; background:var(--accent); color:var(--on-accent); border:0; box-shadow:0 6px 18px -4px var(--accent-glow); }
|
||||
html[data-layout="bento-hub"] #controls .deck-main .ctrl.play svg { width:28px; height:28px; }
|
||||
html[data-layout="bento-hub"] #controls .deck-main .ctrl.active { color:var(--accent-sec); border-color:var(--accent-sec); }
|
||||
@@ -314,7 +314,7 @@ html[data-layout="bento-hub"] .hero-title { background:none; -webkit-text-fill-c
|
||||
html[data-layout="bento-hub"] .ph-logo { width:56px; height:56px; border-radius:16px; color:var(--on-accent); animation:none; }
|
||||
html[data-layout="bento-hub"] .player-pane.empty :is(#controls,#nowPlayingMeta,#notesPanel,.upnext) { display:none; }
|
||||
html[data-layout="bento-hub"] .body:has(.cards[data-view="settings"]) #listFilterBar { display:none; }
|
||||
html[data-layout="bento-hub"] #controls .deck-main .ctrl { border-radius:999px; }
|
||||
html[data-layout="bento-hub"] #controls .deck-main .ctrl { border-radius:16px; }
|
||||
html[data-layout="bento-hub"] #controls input[type="range"]::-webkit-slider-thumb { border:0; box-shadow:var(--shadow-sm); }
|
||||
html[data-layout="bento-hub"] #nowPlayingMeta .np-actions :is(#addBtn,#saveBtn,#exportBtn,#serviceBtn) { border:1px solid var(--line); border-radius:10px; background:var(--bg-2); color:var(--text); box-shadow:none; min-width:44px; }
|
||||
html[data-layout="bento-hub"] #nowPlayingMeta .np-actions #saveBtn.done { color:var(--accent-sec); }
|
||||
|
||||
@@ -87,7 +87,7 @@ html[data-layout="glass-stage"] .stg-skip, html[data-layout="glass-stage"] .stg-
|
||||
html[data-layout="glass-stage"] .stg-skip { width: 46px; height: 46px; border-radius: 50%; background: rgba(0, 0, 0, 0.45); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); }
|
||||
html[data-layout="glass-stage"] .stg-skip svg { width: 26px; height: 26px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
|
||||
html[data-layout="glass-stage"] .stg-play { width: 62px; height: 62px; border-radius: 50%; border: 0; background: linear-gradient(135deg, #ff553c, #ff8471); box-shadow: 0 0 34px rgba(255, 85, 60, 0.6); }
|
||||
html[data-layout="glass-stage"] .stg-play svg { width: 32px; height: 32px; fill: currentColor; stroke: none; }
|
||||
html[data-layout="glass-stage"] .stg-play svg { width: 32px; height: 32px; fill: none; stroke: currentColor; stroke-width:1.5; }
|
||||
|
||||
/* ---- 2. deck ---- */
|
||||
html[data-layout="glass-stage"] #controls { padding: 16px; gap: 14px; }
|
||||
@@ -95,7 +95,7 @@ html[data-layout="glass-stage"] #controls .deck-main { display: flex; justify-co
|
||||
html[data-layout="glass-stage"] #controls .deck-main .ctrl { width: 46px; height: 46px; border-radius: 16px; background: var(--tile); border: 1px solid var(--glass-line); }
|
||||
html[data-layout="glass-stage"] #controls .deck-main .ctrl.skip10 { display: grid; width: 44px; height: 44px; color: var(--text-2); }
|
||||
html[data-layout="glass-stage"] #controls .deck-main .ctrl.skip10 svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
|
||||
html[data-layout="glass-stage"] #controls .deck-main .ctrl.play { width: 64px; height: 64px; border-radius: 50%; border: 0; background: var(--grad); box-shadow: 0 12px 30px rgba(255, 85, 60, 0.55), 0 0 20px rgba(255, 85, 60, 0.35); }
|
||||
html[data-layout="glass-stage"] #controls .deck-main .ctrl.play { width: 64px; height: 64px; border-radius: 50%; border: 1px solid var(--glass-line); background: var(--tile); backdrop-filter:blur(12px); box-shadow:none; }
|
||||
html[data-layout="glass-stage"] #controls .deck-main .ctrl.play svg { width: 32px; height: 32px; }
|
||||
html[data-layout="glass-stage"] #controls .time { font: 600 12px var(--mono); }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user