Bring Glass Stage closer to the mockup: HUD chips, sleep card, chapter badge, A-B group, playlist banner and P2P strip
This commit is contained in:
@@ -2758,7 +2758,7 @@ function fitLyricLines(list, { maxShare = 0.17, maxPx = 160, minPx = 18, uniform
|
||||
const Notes = (() => {
|
||||
const LC = window.LyricsCore;
|
||||
const panel = $('notesPanel');
|
||||
const noop = { load() {}, tick() {}, addBookmark() {}, handleSyncKey() { return false; }, serviceRefresh() {} };
|
||||
const noop = { load() {}, tick() {}, addBookmark() {}, handleSyncKey() { return false; }, serviceRefresh() {}, chapterAt() { return null; } };
|
||||
if (!panel || !LC) return noop;
|
||||
|
||||
const CACHE_KEY = 'ytpNotesCache';
|
||||
@@ -3897,6 +3897,7 @@ const Notes = (() => {
|
||||
return {
|
||||
load, tick, addBookmark, addNote, handleSyncKey, serviceRefresh, refreshFlags: () => { sv.flagsKey = ''; renderServiceButtons(); setPanelFlagMode(sv.panelFlag && flagsEnabled()); paintFlags(); loadFlags(); },
|
||||
stageLyrics: { render: renderStage, set: setStageLyrics, on: stageOn },
|
||||
chapterAt: (t) => { const c = chapters().slice().sort((a, b) => a.t - b.t); let k = -1; c.forEach((x, i) => { if (x.t <= t) k = i; }); return k < 0 ? null : { n: k + 1, of: c.length, title: c[k].title || '' }; },
|
||||
};
|
||||
})();
|
||||
|
||||
@@ -3905,6 +3906,7 @@ const Notes = (() => {
|
||||
const skip = (d) => { try { Player.seek(Math.max(0, Player.master.currentTime + d)); } catch { /* not ready */ } };
|
||||
const on = (id, fn) => { const el = document.getElementById(id); if (el) el.addEventListener('click', fn); };
|
||||
on('back10Btn', () => skip(-10)); on('fwd10Btn', () => skip(10));
|
||||
on('upnextClear', () => clearQueue());
|
||||
on('stgBack', () => skip(-10)); on('stgFwd', () => skip(10));
|
||||
on('stgPlay', () => $('playBtn').click());
|
||||
const setAudio = (v) => { const t = $('audioOnlyToggle'); if (t && t.checked !== v) { t.checked = v; t.dispatchEvent(new Event('change', { bubbles: true })); } };
|
||||
@@ -3932,6 +3934,19 @@ const Notes = (() => {
|
||||
box.innerHTML = list.map(([t, a]) => `<button type="button" class="dchip${a ? ' on' : ''}"></button>`).join('');
|
||||
[...box.children].forEach((b, i) => { b.textContent = list[i][0]; b.onclick = openMoreControls; });
|
||||
}
|
||||
const ch = $('chBadge');
|
||||
if (ch) {
|
||||
const c = Notes.chapterAt ? Notes.chapterAt((Player.master && Player.master.currentTime) || 0) : null;
|
||||
ch.hidden = !c;
|
||||
if (c) ch.textContent = `CH ${String(c.n).padStart(2, '0')}: ${String(c.title).toUpperCase().slice(0, 18)}`;
|
||||
}
|
||||
const V = $('video');
|
||||
const zoom = $('stgZoom'), buf = $('stgBuf');
|
||||
if (zoom && V) { const m = /scale\(([\d.]+)\)/.exec(V.style.transform || ''); zoom.textContent = 'Pinch ' + (m ? Number(m[1]).toFixed(1) : '1.0') + '×'; }
|
||||
if (buf && V && V.duration && V.buffered.length) {
|
||||
const end = V.buffered.end(V.buffered.length - 1);
|
||||
buf.textContent = end >= V.duration - 1 ? 'Fully buffered' : 'Buffered ' + Math.round((end / V.duration) * 100) + '%';
|
||||
}
|
||||
const q = $('qualitySelect'), sq = $('stgQuality');
|
||||
if (sq && q && q.options.length) sq.textContent = q.options[q.selectedIndex] ? q.options[q.selectedIndex].text : 'Auto';
|
||||
const ao = !!data.settings.audioOnly;
|
||||
@@ -7385,6 +7400,7 @@ function setListPaneHidden(hidden) {
|
||||
}
|
||||
|
||||
function renderList() {
|
||||
{ const ls = $('listSub'); if (ls) ls.textContent = ''; const ps = $('p2pStrip'); if (ps) ps.classList.add('hidden'); }
|
||||
setListPaneHidden(view.type === 'search' && !searchResults.length && !searchAttempted);
|
||||
if (view.type === 'settings') { renderSettings(); return; }
|
||||
if (view.type === 'saved') { renderSaved(); return; }
|
||||
@@ -7460,6 +7476,10 @@ function renderList() {
|
||||
const pl = data.playlists.find((p) => p.id === view.id);
|
||||
els.listTitle.textContent = pl ? pl.name : 'Playlist';
|
||||
if (pl) {
|
||||
{ const secs = (pl.videos || []).reduce((a, v) => a + (Number(v.duration) || 0), 0);
|
||||
const h = Math.floor(secs / 3600), m = Math.round((secs % 3600) / 60);
|
||||
$('listSub').textContent = `${pl.videos.length} track${pl.videos.length === 1 ? '' : 's'}${secs ? ' · ' + (h ? h + 'h ' : '') + m + 'm' : ''}`; }
|
||||
renderP2pStrip();
|
||||
const playAll = document.createElement('button');
|
||||
playAll.textContent = '▶ Play all';
|
||||
playAll.className = 'la-primary';
|
||||
@@ -7467,6 +7487,7 @@ function renderList() {
|
||||
const playFull = document.createElement('button');
|
||||
playFull.textContent = '▶ Play in full';
|
||||
playFull.className = 'la-main';
|
||||
playFull.dataset.sub = 'Start to finish';
|
||||
playFull.title = 'Play every video start to finish — ignores saved positions and A-B loops, stops after the last one';
|
||||
playFull.onclick = () => {
|
||||
if (!pl.videos.length) return;
|
||||
@@ -7476,6 +7497,7 @@ function renderList() {
|
||||
const serviceBtn = document.createElement('button');
|
||||
serviceBtn.textContent = '🎤 Service mode';
|
||||
serviceBtn.className = 'la-main';
|
||||
serviceBtn.dataset.sub = 'Full lyrics';
|
||||
serviceBtn.title = 'Set-list view with screen wake lock';
|
||||
serviceBtn.onclick = () => {
|
||||
if (!pl.videos || !pl.videos.length) { toast('Playlist is empty'); return; }
|
||||
@@ -7484,6 +7506,7 @@ function renderList() {
|
||||
const queueAll = document.createElement('button');
|
||||
queueAll.textContent = '+ Queue';
|
||||
queueAll.className = 'la-main';
|
||||
queueAll.dataset.sub = `+${pl.videos.length} items`;
|
||||
queueAll.onclick = () => { pl.videos.forEach((v) => addToQueue(v, { quiet: true })); toast('Added playlist to queue'); };
|
||||
const rename = document.createElement('button');
|
||||
rename.textContent = 'Rename';
|
||||
@@ -7714,6 +7737,36 @@ async function exportToDevice(video) {
|
||||
// ============================================================================
|
||||
// "On other devices" — videos held by sharing devices (P2P), as a playlist
|
||||
// ============================================================================
|
||||
|
||||
// Glass Stage: a compact "On other devices" card under a playlist (same data as the 📡 view).
|
||||
let p2pStripAt = 0, p2pStripData = null;
|
||||
async function renderP2pStrip() {
|
||||
const box = $('p2pStrip');
|
||||
if (!box || document.documentElement.dataset.layout !== 'glass-stage' || !WEB || data.settings.p2pReceive === false) return;
|
||||
if (!p2pStripData || Date.now() - p2pStripAt > 60000) {
|
||||
try { const r = await fetch('/api/p2p/available?limit=3'); p2pStripData = r.ok ? await r.json() : null; } catch { p2pStripData = null; }
|
||||
p2pStripAt = Date.now();
|
||||
}
|
||||
if (view.type !== 'playlist') return;
|
||||
const items = (p2pStripData && p2pStripData.ok && p2pStripData.items) || [];
|
||||
if (!items.length) { box.classList.add('hidden'); return; }
|
||||
const online = items.filter((i) => i.online).length;
|
||||
box.innerHTML = `<div class="ps-head"><span>On other devices</span><i class="ps-dot${online ? ' on' : ''}"></i></div>
|
||||
<p class="ps-sub">${items.length} video${items.length === 1 ? '' : 's'} held by other devices · ${online ? online + ' online now' : 'none online'}</p>`;
|
||||
items.forEach((it) => {
|
||||
const v = { id: it.id, title: it.title || videoTitleById(it.id) || it.id, channel: it.channel || '', duration: it.duration || 0, thumbnail: `https://i.ytimg.com/vi/${it.id}/mqdefault.jpg` };
|
||||
const row = document.createElement('div');
|
||||
row.className = 'ps-row';
|
||||
row.innerHTML = '<span class="ps-ic">📡</span><span class="ps-txt"><b></b><small></small></span><button type="button" class="ps-dl" aria-label="Save to this device">⤓</button>';
|
||||
row.querySelector('b').textContent = v.title;
|
||||
row.querySelector('small').textContent = `${fmtBytes(it.size)}${it.height ? ' · ' + it.height + 'p' : ''} · ${it.online ? 'Online' : 'Offline'}`;
|
||||
row.querySelector('.ps-dl').onclick = () => exportToDevice(v);
|
||||
row.querySelector('.ps-txt').onclick = () => playFromList([v], 0, 'p2p');
|
||||
box.appendChild(row);
|
||||
});
|
||||
box.classList.remove('hidden');
|
||||
}
|
||||
|
||||
async function renderP2pList() {
|
||||
els.listTitle.textContent = '📡 On other devices';
|
||||
els.listActions.innerHTML = '';
|
||||
@@ -10008,8 +10061,8 @@ function updateAbUI() {
|
||||
const aSet = abA !== null, bSet = abB !== null;
|
||||
const aBtn = $('abABtn'), bBtn = $('abBBtn'), clrBtn = $('abClearBtn');
|
||||
const ind = $('abIndicator');
|
||||
if (aBtn) aBtn.classList.toggle('active', aSet);
|
||||
if (bBtn) bBtn.classList.toggle('active', bSet);
|
||||
if (aBtn) { aBtn.classList.toggle('active', aSet); if (aSet) aBtn.dataset.t = fmtTime(abA); else delete aBtn.dataset.t; }
|
||||
if (bBtn) { bBtn.classList.toggle('active', bSet); if (bSet) bBtn.dataset.t = fmtTime(abB); else delete bBtn.dataset.t; }
|
||||
if (clrBtn) clrBtn.classList.toggle('hidden', !(aSet && bSet));
|
||||
if (ind) ind.classList.toggle('hidden', !aSet && !bSet);
|
||||
const q = document.querySelector('.dk-quick');
|
||||
|
||||
@@ -164,6 +164,7 @@
|
||||
<button id="stgPlay" class="stg-play" type="button" aria-label="Play or pause"><svg viewBox="0 0 24 24" aria-hidden="true" class="fill"><path d="M9 5.5v13l10-6.5z"/></svg></button>
|
||||
<button id="stgFwd" class="stg-skip" type="button" aria-label="Forward 10 seconds"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M20 12a8 8 0 1 1-3-6.2M20 4v4.5h-4.5"/><text x="12" y="15.5" text-anchor="middle" font-size="7.5" font-weight="700" fill="currentColor" stroke="none">10</text></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>
|
||||
</div>
|
||||
|
||||
@@ -183,6 +184,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<span id="durTime" class="time">0:00</span>
|
||||
<span id="chBadge" class="ch-badge" hidden></span>
|
||||
<button id="fsMini" class="fs-mini" type="button" title="Fullscreen" aria-label="Fullscreen"><svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 9V4h5M20 9V4h-5M4 15v5h5M20 15v5h-5"/></svg></button>
|
||||
</div>
|
||||
<button id="waveLoud" class="wave-loud hidden" type="button">⚡ Jump to the loudest part</button>
|
||||
@@ -235,7 +237,8 @@
|
||||
</div>
|
||||
|
||||
<div id="sleepStatus" class="sleep-status hidden">
|
||||
<span id="sleepCountdown" class="sleep-countdown"></span>
|
||||
<span class="sl-ic" aria-hidden="true"><svg viewBox="0 0 24 24"><path d="M20 14.5A8.5 8.5 0 0 1 9.5 4a8.5 8.5 0 1 0 10.5 10.5z"/></svg></span>
|
||||
<span class="sl-txt"><span id="sleepCountdown" class="sleep-countdown"></span><small class="sl-sub">Audio fades out smoothly</small></span>
|
||||
<button id="sleepCancelBtn" class="sleep-cancel">✕ Cancel</button>
|
||||
</div>
|
||||
|
||||
@@ -335,6 +338,7 @@
|
||||
<div class="upnext-header">
|
||||
<span>Up next</span>
|
||||
<span id="upnextCount" class="upnext-count">0</span>
|
||||
<button id="upnextClear" class="upnext-clear" type="button">Clear</button>
|
||||
</div>
|
||||
<div id="upnextList" class="upnext-list"></div>
|
||||
</div>
|
||||
@@ -353,6 +357,7 @@
|
||||
<section id="listPane" class="list-pane">
|
||||
<div class="list-header">
|
||||
<h2 id="listTitle">Search</h2>
|
||||
<p id="listSub" class="list-sub"></p>
|
||||
<div id="listActions" class="list-actions"></div>
|
||||
</div>
|
||||
<div id="listFilterBar" class="list-filter-bar hidden">
|
||||
@@ -367,6 +372,7 @@
|
||||
</div>
|
||||
<div id="status" class="status hidden"></div>
|
||||
<div id="cards" class="cards"></div>
|
||||
<div id="p2pStrip" class="p2p-strip hidden"></div>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@@ -207,3 +207,131 @@ html[data-layout="glass-stage"] #controls .deck-main #nextBtn { order: 5; }
|
||||
html[data-layout="glass-stage"] #nowPlayingMeta .np-actions .np-more-host .np-btn { flex: 0 0 auto !important; width: auto !important; min-width: 0 !important; height: 34px !important; }
|
||||
html[data-layout="glass-stage"] .stg-overlay { justify-content: flex-start; }
|
||||
html[data-layout="glass-stage"] .stg-mid { margin: auto 0; }
|
||||
|
||||
/* =========================== fidelity pass (matches the approved mockup) =========================== */
|
||||
.stg-bot, .ch-badge, .upnext-clear, .list-sub, .p2p-strip { display: none; }
|
||||
.sleep-status .sl-ic, .sleep-status .sl-sub { display: none; }
|
||||
|
||||
/* stage HUD */
|
||||
html[data-layout="glass-stage"] .stg-bot { display: flex; position: absolute; left: 12px; right: 12px; bottom: 12px; justify-content: space-between; pointer-events: none; }
|
||||
html[data-layout="glass-stage"] .stg-bot .stg-chip { height: 26px; font: 500 10px var(--mono); text-transform: none; letter-spacing: 0; color: var(--text-2); }
|
||||
html[data-layout="glass-stage"] .stg-overlay { justify-content: flex-start; }
|
||||
html[data-layout="glass-stage"] .player-pane.empty .stg-bot { display: none; }
|
||||
|
||||
/* sleep timer card */
|
||||
html[data-layout="glass-stage"] .sleep-status {
|
||||
display: flex; align-items: center; gap: 12px; padding: 10px 14px; border-radius: 18px; margin-top: 12px;
|
||||
background: rgba(13, 14, 18, 0.6); border: 1px solid var(--glass-line); -webkit-backdrop-filter: blur(20px); backdrop-filter: blur(20px);
|
||||
}
|
||||
html[data-layout="glass-stage"] .sleep-status.hidden { display: none; }
|
||||
html[data-layout="glass-stage"] .sleep-status .sl-ic { display: grid; place-items: center; width: 34px; height: 34px; border-radius: 12px; background: rgba(255, 85, 60, 0.12); border: 1px solid rgba(255, 85, 60, 0.25); color: var(--accent-bright); flex: none; }
|
||||
html[data-layout="glass-stage"] .sleep-status .sl-ic svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.9; stroke-linecap: round; stroke-linejoin: round; }
|
||||
html[data-layout="glass-stage"] .sleep-status .sl-txt { flex: 1; min-width: 0; display: grid; }
|
||||
html[data-layout="glass-stage"] .sleep-status .sleep-countdown { font: 600 12px var(--ui); color: var(--text); }
|
||||
html[data-layout="glass-stage"] .sleep-status .sl-sub { display: block; font: 400 11px var(--ui); color: var(--text-dim); }
|
||||
html[data-layout="glass-stage"] .sleep-cancel { height: 30px; padding: 0 14px; border-radius: 99px; background: rgba(255, 255, 255, 0.06); border: 1px solid var(--glass-line); color: var(--text-2); font: 600 11px var(--ui); }
|
||||
|
||||
/* seek row: thicker gradient track, chapter badge */
|
||||
html[data-layout="glass-stage"] #controls .seek { height: 6px; }
|
||||
html[data-layout="glass-stage"] #controls .ch-badge { display: inline-block; padding: 3px 10px; border-radius: 99px; background: rgba(255, 255, 255, 0.06); border: 1px solid var(--glass-line); color: var(--accent-bright); font: 600 10px var(--mono); letter-spacing: 0.04em; white-space: nowrap; }
|
||||
html[data-layout="glass-stage"] #controls .ch-badge[hidden] { display: none; }
|
||||
html[data-layout="glass-stage"] #controls #waveLoud {
|
||||
width: 100%; padding: 8px 14px; border-radius: 14px; text-align: left; font: 500 12px var(--ui); color: var(--accent-bright);
|
||||
background: linear-gradient(90deg, rgba(255, 85, 60, 0.16), transparent); border: 1px solid rgba(255, 85, 60, 0.22);
|
||||
}
|
||||
|
||||
/* quick row: A-B group · Fullscreen · More */
|
||||
html[data-layout="glass-stage"] #controls .dk-quick { flex-wrap: nowrap; }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick #abABtn,
|
||||
html[data-layout="glass-stage"] #controls .dk-quick #abBBtn,
|
||||
html[data-layout="glass-stage"] #controls .dk-quick #abClearBtn:not(.hidden) {
|
||||
display: inline-flex; align-items: center; justify-content: center; flex: 0 0 auto; width: auto; height: 40px; padding: 0 10px; border-radius: 0; border: 0; background: transparent;
|
||||
font: 600 11px var(--mono); color: var(--text-dim);
|
||||
}
|
||||
html[data-layout="glass-stage"] #controls .dk-quick #abABtn { order: 1; border-radius: 14px 0 0 14px; border: 1px solid var(--glass-line); border-right: 0; background: var(--tile); }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick #abBBtn { order: 2; border-top: 1px solid var(--glass-line); border-bottom: 1px solid var(--glass-line); background: var(--tile); }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick #abClearBtn { order: 3; border-radius: 0 14px 14px 0; border: 1px solid var(--glass-line); border-left: 0; background: var(--tile); }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick #abClearBtn.hidden { display: none; }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick #abABtn::after, html[data-layout="glass-stage"] #controls .dk-quick #abBBtn::after { content: attr(data-t); margin-left: 4px; }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick #abABtn[data-t]::after, html[data-layout="glass-stage"] #controls .dk-quick #abBBtn[data-t]::after { content: "[" attr(data-t) "]"; }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick .ctrl.active { color: var(--accent-bright); background: rgba(255, 255, 255, 0.1); }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick #fsBtn { order: 4; width: auto; padding: 0 12px; margin-left: auto; }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick.ab-on #fsBtn { width: auto; padding: 0 12px; }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick.ab-on .fs-label { display: inline; }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick #ctlMoreBtn { order: 5; flex: 0 0 auto; padding: 0 12px; }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick.ab-on .mc-label { display: inline; }
|
||||
html[data-layout="glass-stage"] #controls .dk-more .mc-rest { display: none; }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick .dk-more span { font: 600 11px var(--ui); }
|
||||
html[data-layout="glass-stage"] #controls .deck-vol #modeBtn::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 6px var(--accent); flex: none; order: 3; }
|
||||
html[data-layout="glass-stage"] #controls .deck-vol #modeBtn { justify-content: flex-start; }
|
||||
html[data-layout="glass-stage"] #controls .deck-vol #modeBtn svg { margin-left: auto; order: -1; color: var(--text-dim); }
|
||||
html[data-layout="glass-stage"] #controls .deck-vol #modeBtn .mode-name { order: 4; }
|
||||
|
||||
/* now playing: verified-style channel line */
|
||||
html[data-layout="glass-stage"] #nowPlayingMeta .np-channel { font-weight: 500; }
|
||||
|
||||
/* lyrics: compact single-row toolbar, bracketed section labels */
|
||||
html[data-layout="glass-stage"] #lyricsPane .lyrics-toolbar { display: flex; flex-wrap: nowrap; overflow-x: auto; gap: 6px; scrollbar-width: none; }
|
||||
html[data-layout="glass-stage"] #lyricsPane .lyrics-toolbar > * { flex: none; }
|
||||
html[data-layout="glass-stage"] #lyricsPane .lyrics-toolbar .np-btn { height: 30px; padding: 0 10px; font-size: 11px; border-radius: 10px; }
|
||||
html[data-layout="glass-stage"] #lyricsPane .lyrics-toolbar .lyr-offset { height: 30px; border-radius: 10px; padding: 0 4px; }
|
||||
html[data-layout="glass-stage"] #lyricsPane .lyr-off-btn { height: 24px; padding: 0 6px; background: transparent; color: var(--accent-bright); font-size: 11px; }
|
||||
html[data-layout="glass-stage"] #lyricsPane .lyr-off-val { font-size: 11px; flex: none; }
|
||||
html[data-layout="glass-stage"] #lyricsPane .lyr-auto { height: 30px; border: 0; background: transparent; grid-column: auto; }
|
||||
html[data-layout="glass-stage"] #lyricsPane .lyr-flag { grid-column: auto; height: 30px; padding: 0 10px; font-size: 11px; border-radius: 10px; white-space: nowrap; }
|
||||
html[data-layout="glass-stage"] #lyricsPane .lyr-flag span { font-size: 11px; }
|
||||
html[data-layout="glass-stage"] .lyr-section::before { content: "[ "; }
|
||||
html[data-layout="glass-stage"] .lyr-section::after { content: " ]"; }
|
||||
|
||||
/* up next */
|
||||
html[data-layout="glass-stage"] .upnext { padding: 16px; }
|
||||
html[data-layout="glass-stage"] .upnext-header { display: flex; align-items: center; gap: 8px; font: 700 16px var(--display); color: var(--text); }
|
||||
html[data-layout="glass-stage"] .upnext-count { background: rgba(255, 255, 255, 0.06); border: 1px solid var(--glass-line); color: var(--accent-bright); font: 600 10px var(--mono); border-radius: 99px; padding: 2px 10px; }
|
||||
html[data-layout="glass-stage"] .upnext-clear { display: inline; margin-left: auto; background: none; border: 0; color: var(--accent-bright); font: 500 12px var(--ui); cursor: pointer; }
|
||||
html[data-layout="glass-stage"] .upnext-item { background: var(--tile); border: 1px solid var(--glass-line); border-radius: 18px; padding: 10px; }
|
||||
html[data-layout="glass-stage"] .upnext-item img { border-radius: 12px; }
|
||||
html[data-layout="glass-stage"] .related-panel { padding: 0; overflow: hidden; }
|
||||
|
||||
/* list header banner: eyebrow, title + Play all, three tiles with sub-labels */
|
||||
html[data-layout="glass-stage"] .list-header { display: grid; grid-template-columns: repeat(6, 1fr); gap: 10px; padding: 0 0 12px; align-items: start; }
|
||||
html[data-layout="glass-stage"] .list-header::before { grid-column: 1 / -1; content: "Current list"; }
|
||||
html[data-layout="glass-stage"] .list-header h2 { grid-column: 1 / 5; font: 700 20px var(--display); margin: 0; }
|
||||
html[data-layout="glass-stage"] .list-sub { display: block; grid-column: 1 / 5; margin: -6px 0 0; font: 400 11px var(--ui); color: var(--text-dim); }
|
||||
html[data-layout="glass-stage"] .list-sub:empty { display: none; }
|
||||
html[data-layout="glass-stage"] #listActions { display: contents; }
|
||||
html[data-layout="glass-stage"] #listActions button.la-primary { grid-column: 5 / -1; grid-row: 2 / span 2; align-self: start; flex: none; height: 44px; padding: 0 14px; border-radius: 16px; font-size: 13px; white-space: nowrap; }
|
||||
html[data-layout="glass-stage"] #listActions button.la-primary.la-inline { grid-row: 2; }
|
||||
html[data-layout="glass-stage"] #listActions button.la-main { grid-column: span 2; flex: none; height: auto; min-height: 56px; padding: 8px 4px; border-radius: 18px; flex-direction: column; gap: 2px; font: 600 11px var(--ui); }
|
||||
html[data-layout="glass-stage"] #listActions button.la-main::after { content: attr(data-sub); font: 500 9px var(--mono); color: var(--text-dim); }
|
||||
html[data-layout="glass-stage"] #listActions button:not(.la-primary):not(.la-main):not(.la-icon) { grid-column: span 2; flex: none; height: 34px; border-radius: 12px; font-size: 11px; padding: 0 6px; }
|
||||
html[data-layout="glass-stage"] #listActions button.la-icon { grid-column: span 1; }
|
||||
html[data-layout="glass-stage"] .list-filter-bar input { border-radius: 14px; background: var(--tile); border: 1px solid var(--glass-line); height: 38px; }
|
||||
|
||||
/* P2P strip under a playlist */
|
||||
html[data-layout="glass-stage"] .p2p-strip { display: block; margin-top: 16px; padding-top: 14px; border-top: 1px solid var(--glass-line); }
|
||||
html[data-layout="glass-stage"] .p2p-strip.hidden { display: none; }
|
||||
html[data-layout="glass-stage"] .ps-head { display: flex; align-items: center; justify-content: space-between; font: 700 13px var(--ui); color: var(--text); }
|
||||
html[data-layout="glass-stage"] .ps-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-dim); }
|
||||
html[data-layout="glass-stage"] .ps-dot.on { background: var(--accent); box-shadow: 0 0 8px var(--accent); }
|
||||
html[data-layout="glass-stage"] .ps-sub { margin: 4px 0 10px; font: 400 11px var(--ui); color: var(--text-dim); }
|
||||
html[data-layout="glass-stage"] .ps-row { display: flex; align-items: center; gap: 10px; padding: 10px 12px; margin-bottom: 8px; border-radius: 18px; background: var(--tile); border: 1px solid var(--glass-line); }
|
||||
html[data-layout="glass-stage"] .ps-ic { width: 32px; height: 32px; border-radius: 12px; display: grid; place-items: center; background: rgba(255, 255, 255, 0.06); flex: none; font-size: 15px; }
|
||||
html[data-layout="glass-stage"] .ps-txt { flex: 1; min-width: 0; display: grid; cursor: pointer; }
|
||||
html[data-layout="glass-stage"] .ps-txt b { font: 500 12px var(--ui); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||
html[data-layout="glass-stage"] .ps-txt small { font: 400 10px var(--mono); color: var(--text-dim); }
|
||||
html[data-layout="glass-stage"] .ps-dl { width: 34px; height: 34px; border-radius: 12px; border: 0; background: rgba(255, 255, 255, 0.07); color: var(--accent-bright); font-size: 16px; cursor: pointer; }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick { align-items: center; }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick .ctrl, html[data-layout="glass-stage"] #controls .dk-quick .dk-more { height: 40px !important; box-shadow: none !important; white-space: nowrap; }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick #fsBtn { flex-direction: row; gap: 6px; }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick #fsBtn svg { width: 16px; height: 16px; }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick .fs-label { font: 600 11px var(--ui); }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick #abBBtn, html[data-layout="glass-stage"] #controls .dk-quick #abClearBtn { margin-left: -8px; }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick .ctrl.active { background: rgba(255, 255, 255, 0.12) !important; color: var(--accent-bright); }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick #fsBtn { min-width: 112px; padding: 0 12px; }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick #fsBtn svg { flex: none; display: block; }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick { gap: 6px; }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick #abABtn, html[data-layout="glass-stage"] #controls .dk-quick #abBBtn { padding: 0 7px !important; font-size: 10px; }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick #abClearBtn:not(.hidden) { padding: 0 8px !important; }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick #fsBtn { min-width: 0; margin-left: auto; padding: 0 10px; }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick #ctlMoreBtn { flex: 0 1 auto; min-width: 0; padding: 0 10px; }
|
||||
html[data-layout="glass-stage"] #controls .dk-quick #fsBtn { width: auto !important; flex: 0 0 auto !important; }
|
||||
|
||||
Reference in New Issue
Block a user