Run 1: bug fixes and CSS polish

- Fix keyboard shortcuts breaking after +/- channel change (window.focus on PLAYING)
- Fix + and gear buttons not staying open (document close handler exclusions)
- Remove hotkey hint bar (moved to settings panel later)
- Title truncation: 2-line clamp for playlist and channel list titles
- sizePW: 4% buffer ensures YouTube native title never bleeds into viewport
- Mobile: hide pop-out button on ≤600px

Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
Aaron
2026-05-23 11:10:46 -04:00
parent fa63f4d956
commit 04fffb11d6
+9 -13
View File
@@ -148,8 +148,8 @@ html,body{width:100%;height:100%;overflow:hidden;background:var(--bg);font-famil
.pl-card{display:flex;gap:9px;padding:9px;background:rgba(255,255,255,.025);border:1px solid transparent;margin-bottom:7px;cursor:default;transition:.15s} .pl-card{display:flex;gap:9px;padding:9px;background:rgba(255,255,255,.025);border:1px solid transparent;margin-bottom:7px;cursor:default;transition:.15s}
.pl-card:hover{background:rgba(255,255,255,.06);border-color:var(--border)} .pl-card:hover{background:rgba(255,255,255,.06);border-color:var(--border)}
.pl-thumb{width:78px;height:44px;object-fit:cover;flex-shrink:0;background:var(--panel2)} .pl-thumb{width:78px;height:44px;object-fit:cover;flex-shrink:0;background:var(--panel2)}
.pl-info{flex:1;overflow:hidden;display:flex;flex-direction:column;justify-content:center;gap:3px} .pl-info{flex:1;min-width:0;overflow:hidden;display:flex;flex-direction:column;justify-content:center;gap:3px}
.pl-title{font-size:12px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;line-height:1.2} .pl-title{font-size:12px;font-weight:700;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;line-height:1.35}
.pl-meta{font-size:10px;color:var(--dim);letter-spacing:.3px} .pl-meta{font-size:10px;color:var(--dim);letter-spacing:.3px}
.pl-acts{display:flex;flex-direction:column;gap:4px;justify-content:center;flex-shrink:0} .pl-acts{display:flex;flex-direction:column;gap:4px;justify-content:center;flex-shrink:0}
.pl-ab,.pl-pb{font-family:var(--font-d);font-size:11px;letter-spacing:1px;padding:4px 8px;border:none;cursor:pointer;transition:.15s;white-space:nowrap} .pl-ab,.pl-pb{font-family:var(--font-d);font-size:11px;letter-spacing:1px;padding:4px 8px;border:none;cursor:pointer;transition:.15s;white-space:nowrap}
@@ -165,7 +165,7 @@ html,body{width:100%;height:100%;overflow:hidden;background:var(--bg);font-famil
.ch-n{font-family:var(--font-d);font-size:20px;color:var(--accent);flex-shrink:0;width:30px;text-align:center;line-height:1} .ch-n{font-family:var(--font-d);font-size:20px;color:var(--accent);flex-shrink:0;width:30px;text-align:center;line-height:1}
.ch-ithumb{width:58px;height:33px;object-fit:cover;flex-shrink:0;background:var(--panel2)} .ch-ithumb{width:58px;height:33px;object-fit:cover;flex-shrink:0;background:var(--panel2)}
.ch-ii{flex:1;overflow:hidden} .ch-ii{flex:1;overflow:hidden}
.ch-ititle{font-size:12px;font-weight:700;white-space:nowrap;overflow:hidden;text-overflow:ellipsis} .ch-ititle{font-size:12px;font-weight:700;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;line-height:1.35}
.ch-imeta{font-size:10px;color:var(--dim);margin-top:2px} .ch-imeta{font-size:10px;color:var(--dim);margin-top:2px}
.ch-del{background:transparent;border:none;color:var(--dim);cursor:pointer;padding:5px;font-size:13px;transition:.15s;flex-shrink:0} .ch-del{background:transparent;border:none;color:var(--dim);cursor:pointer;padding:5px;font-size:13px;transition:.15s;flex-shrink:0}
.ch-del:hover{color:var(--accent)} .ch-del:hover{color:var(--accent)}
@@ -195,9 +195,6 @@ html,body{width:100%;height:100%;overflow:hidden;background:var(--bg);font-famil
#toast{position:absolute;top:64px;left:50%;transform:translateX(-50%) translateY(-8px);background:var(--panel2);border:1px solid var(--border);border-left:3px solid var(--accent2);padding:9px 18px;font-size:12px;letter-spacing:.5px;z-index:25;opacity:0;transition:opacity .2s,transform .2s;white-space:nowrap;pointer-events:none;font-weight:600} #toast{position:absolute;top:64px;left:50%;transform:translateX(-50%) translateY(-8px);background:var(--panel2);border:1px solid var(--border);border-left:3px solid var(--accent2);padding:9px 18px;font-size:12px;letter-spacing:.5px;z-index:25;opacity:0;transition:opacity .2s,transform .2s;white-space:nowrap;pointer-events:none;font-weight:600}
#toast.on{opacity:1;transform:translateX(-50%) translateY(0)} #toast.on{opacity:1;transform:translateX(-50%) translateY(0)}
/* Keyboard hint */
.kh{position:absolute;bottom:68px;right:14px;z-index:5;font-size:9px;color:rgba(255,255,255,.11);letter-spacing:1.5px;pointer-events:none;font-weight:600}
/* Demo banner */ /* Demo banner */
#demo-banner{position:absolute;top:var(--top-h);left:0;right:0;z-index:4;text-align:center;padding:4px;background:rgba(255,34,0,.12);border-bottom:1px solid rgba(255,34,0,.2);font-size:10px;letter-spacing:2px;color:rgba(255,100,80,.8);font-weight:700;pointer-events:none} #demo-banner{position:absolute;top:var(--top-h);left:0;right:0;z-index:4;text-align:center;padding:4px;background:rgba(255,34,0,.12);border-bottom:1px solid rgba(255,34,0,.2);font-size:10px;letter-spacing:2px;color:rgba(255,100,80,.8);font-weight:700;pointer-events:none}
@@ -205,7 +202,7 @@ html,body{width:100%;height:100%;overflow:hidden;background:var(--bg);font-famil
@media(max-width:600px){ @media(max-width:600px){
#sb{width:100vw} #sb{width:100vw}
.np-lbl span:not(.np-lbl-dot){display:none} .np-lbl span:not(.np-lbl-dot){display:none}
.kh{display:none} #po-btn{display:none}
} }
@media(max-width:420px){ @media(max-width:420px){
.c-btn{width:30px;height:30px;font-size:13px} .c-btn{width:30px;height:30px;font-size:13px}
@@ -225,7 +222,7 @@ html,body{width:100%;height:100%;overflow:hidden;background:var(--bg);font-famil
} }
/* ── Idle / broadcast mode ── */ /* ── Idle / broadcast mode ── */
#tb,#bb,#pb-wrap,.kh{ #tb,#bb,#pb-wrap{
will-change:transform,opacity; will-change:transform,opacity;
transition:transform .5s cubic-bezier(.4,0,.15,1), opacity .5s ease; transition:transform .5s cubic-bezier(.4,0,.15,1), opacity .5s ease;
} }
@@ -235,7 +232,6 @@ body.idle{cursor:none}
body.idle #tb{transform:translateY(-120%) scaleY(0.5);transform-origin:top center;opacity:0} body.idle #tb{transform:translateY(-120%) scaleY(0.5);transform-origin:top center;opacity:0}
body.idle #bb{transform:translateY(120%) scaleY(0.5);transform-origin:bottom center;opacity:0} body.idle #bb{transform:translateY(120%) scaleY(0.5);transform-origin:bottom center;opacity:0}
body.idle #pb-wrap{opacity:0} body.idle #pb-wrap{opacity:0}
body.idle .kh{opacity:0}
body.idle #scanlines{opacity:.68} body.idle #scanlines{opacity:.68}
body.idle #ch-bug{opacity:1} body.idle #ch-bug{opacity:1}
body.idle #tc{bottom:20px} body.idle #tc{bottom:20px}
@@ -342,7 +338,6 @@ body.idle .gt,body.idle .gb,body.idle .gr,body.idle .gl{opacity:0;transition:opa
<div id="lo"><div class="ldr"><div class="lb"></div><div class="lb"></div><div class="lb"></div><div class="lb"></div></div></div> <div id="lo"><div class="ldr"><div class="lb"></div><div class="lb"></div><div class="lb"></div><div class="lb"></div></div></div>
<div id="toast"></div> <div id="toast"></div>
<div class="kh">SPACE &middot; &larr;&rarr; &middot; &uarr;&darr; vol &middot; +/- ch &middot; S shuffle &middot; C channels &middot; P pop-out &middot; ESC</div>
<div id="sb"> <div id="sb">
<div class="sb-hd"> <div class="sb-hd">
@@ -392,8 +387,8 @@ window.onYouTubeIframeAPIReady = function(){
function sizePW(){ function sizePW(){
const el = qs('#pw iframe'); if(!el) return; const el = qs('#pw iframe'); if(!el) return;
const vw=window.innerWidth, vh=window.innerHeight; const vw=window.innerWidth, vh=window.innerHeight;
const w = Math.max(vw, vh*1.7778); const w = Math.max(vw * 1.04, vh * 1.7778);
const h = Math.max(vh, vw*0.5625); const h = Math.max(vh * 1.04, vw * 0.5625);
el.style.width=w+'px'; el.style.height=h+'px'; el.style.width=w+'px'; el.style.height=h+'px';
} }
@@ -420,6 +415,7 @@ function onPState(e){
if(e.data===S.PLAYING){ if(e.data===S.PLAYING){
pb.textContent='⏸'; A.playing=true; pb.textContent='⏸'; A.playing=true;
updateNP(); startPB(); hideTap(); hideNCO(); updateNP(); startPB(); hideTap(); hideNCO();
try{ window.focus(); }catch(err){}
} else if(e.data===S.PAUSED){ } else if(e.data===S.PAUSED){
pb.textContent='▶'; A.playing=false; pb.textContent='▶'; A.playing=false;
} else if(e.data===S.CUED||e.data===-1){ } else if(e.data===S.CUED||e.data===-1){
@@ -874,7 +870,7 @@ function wireControls(){
document.addEventListener('click',e=>{ document.addEventListener('click',e=>{
if(!document.contains(e.target)) return; // guard: element may have been removed by innerHTML replacement if(!document.contains(e.target)) return; // guard: element may have been removed by innerHTML replacement
const sb=qs('#sb'); const sb=qs('#sb');
if(sb.classList.contains('on')&&!sb.contains(e.target)&&!qs('#b-sb').contains(e.target)) closeSB(); if(sb.classList.contains('on')&&!sb.contains(e.target)&&!qs('#b-sb').contains(e.target)&&!e.target.closest('#add-ch-btn')&&!e.target.closest('#cfg-btn')) closeSB();
}); });
document.addEventListener('keydown',e=>{ document.addEventListener('keydown',e=>{
if(['INPUT','TEXTAREA'].includes(e.target.tagName)) return; if(['INPUT','TEXTAREA'].includes(e.target.tagName)) return;