/* ── Persian type ───────────────────────────────────────────────────────
   Vazirmatn for every Persian/Arabic glyph in the app. Declared HERE rather than in fonts.css on
   purpose: the server rewrites the ?v= on avify.css for each build (server.js), so a font change can
   never be served from a stale cache, while /fonts/fonts.css carries no version at all.

   One variable file covers 100–900, which is what the app actually needs — six distinct weights are
   used across the stylesheet, so static cuts would have meant six downloads instead of one 111KB file.

   unicode-range confines it to the Arabic blocks, and that does three things at once: the file is only
   fetched when Persian is on screen, Latin text keeps Inter/Sora, and Vazirmatn's own Latin glyphs can
   never quietly take over the app's type. U+200C is listed explicitly — the zero-width non-joiner is
   what makes Persian half-spaces render, and it sits outside the Arabic block. */
@font-face{
  font-family:'Vazirmatn';
  font-style:normal;
  font-weight:100 900;
  font-display:swap;
  src:url(/fonts/vazirmatn-var.woff2) format('woff2');
  unicode-range:U+0600-06FF,U+0750-077F,U+0870-088F,U+08A0-08FF,U+200C-200D,U+FB50-FDFF,U+FE70-FEFF;
}

/* =====================================================================
   AVIFY · Immersive Player-First — total redesign (staging)
   Framework-free. Responsive: desktop · laptop · tablet · car · mobile.
   ===================================================================== */

:root{
  --bg:#07060f; --bg2:#0c0a18;
  --violet:#8b5cf6; --cyan:#22d3ee; --magenta:#d946ef;
  --grad:linear-gradient(135deg,#8b5cf6 0%,#22d3ee 100%);
  --glass:rgba(255,255,255,.05); --glass2:rgba(255,255,255,.08);
  --line:rgba(255,255,255,.10); --line2:rgba(255,255,255,.16);
  --txt:#f4f2ff; --txt2:#b9b4cf; --muted:#7b7595;
  --glow-v:rgba(139,92,246,.45); --glow-c:rgba(34,211,238,.40);
  --r:18px; --r-sm:12px; --r-lg:26px;
  /* ambient colors (overwritten from artwork) */
  --c1:#6d28d9; --c2:#0e7490;
  --topbar-h:64px; --dock-h:0px;
  font-synthesis:none;
}
*{margin:0;padding:0;box-sizing:border-box;-webkit-tap-highlight-color:transparent}
[hidden]{display:none!important}
html,body{height:100%}
/* themed scrollbars — replace the browser default to match the Midnight-Glass look */
*{scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.2) transparent}
::-webkit-scrollbar{width:11px;height:11px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:rgba(255,255,255,.16);border:3px solid transparent;border-radius:10px;background-clip:padding-box}
::-webkit-scrollbar-thumb:hover{background:rgba(139,92,246,.6);background-clip:padding-box}
::-webkit-scrollbar-thumb:active{background:rgba(34,211,238,.65);background-clip:padding-box}
::-webkit-scrollbar-corner{background:transparent}
/* image holders get a gradient base so loading/missing art looks intentional */
.rimg,.mini-art,.art,.rail-card img,.detail-head img,.card .thumb{
  background:linear-gradient(135deg,#241f47,#16324a)}
body{
  font-family:'Inter','Vazirmatn',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;
  color:var(--txt); background:var(--bg); overflow:hidden;
  -webkit-font-smoothing:antialiased; line-height:1.5;
}
button{font-family:inherit;color:inherit;cursor:pointer;border:none;background:none}
img{display:block;max-width:100%}
input{font-family:inherit}
h1,h2,h3,.brand-name,.now-title{font-family:'Sora','Vazirmatn',sans-serif}

/* ── Ambient backdrop ─────────────────────────────────────────────── */
.ambient{
  position:fixed;inset:-20% ;z-index:0;pointer-events:none;
  background:
    radial-gradient(60% 60% at 18% 12%, var(--c1), transparent 60%),
    radial-gradient(60% 70% at 88% 18%, var(--c2), transparent 60%),
    radial-gradient(80% 80% at 50% 120%, #5b21b6, transparent 60%),
    linear-gradient(180deg,#0b0a16,#060410);
  filter:saturate(135%) blur(20px);
  transition:background 1.2s ease;
  opacity:.85;
}
.grain{position:fixed;inset:0;z-index:1;pointer-events:none;opacity:.035;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");}

/* ── App grid ─────────────────────────────────────────────────────── */
.app{position:relative;z-index:2;height:100%;display:grid;
  grid-template-rows:var(--topbar-h) 1fr;
  /* keep content out of the notch / home-indicator on iOS (env() is 0 on Android/desktop) */
  padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);}

/* ── Top bar ──────────────────────────────────────────────────────── */
.topbar{display:flex;align-items:center;gap:18px;padding:0 22px;
  background:rgba(10,8,20,.5);backdrop-filter:blur(22px) saturate(150%);
  -webkit-backdrop-filter:blur(22px) saturate(150%);
  border-bottom:1px solid var(--line);}
.brand{display:flex;align-items:center;gap:10px}
.brand-mark{width:34px;height:34px;border-radius:11px;overflow:hidden;box-shadow:0 2px 10px rgba(0,0,0,.4)}
.brand-mark img{width:100%;height:100%;object-fit:cover;display:block}
.brand-name{font-weight:800;letter-spacing:3px;font-size:18px;
  background:var(--grad);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.top-nav{display:flex;gap:6px;margin-left:8px}
.top-link{display:flex;align-items:center;gap:8px;padding:9px 16px;border-radius:12px;color:var(--txt2);
  font-weight:600;font-size:14px;transition:.2s}
.top-link i{font-size:14px}
.top-link:hover{background:var(--glass2);color:var(--txt)}
.top-link.active{color:#fff;background:linear-gradient(90deg,rgba(139,92,246,.30),rgba(34,211,238,.12));
  box-shadow:inset 0 0 0 1px var(--line2)}
.top-actions{margin-left:auto;display:flex;gap:10px;align-items:center}
/* The moon is the one button here people press while driving. Its box stays 34x33 so the header is
   unchanged, but the area that responds to a tap grows (measured 34x33 -> 41x42) — on a
   pseudo-element, so nothing moves. Sideways it cannot grow further: the gap to the next button is
   10px, and claiming more than half of it would start stealing taps meant for the sleep timer. The
   real fix for reaching this while driving is the labelled button on the now-playing screen. */
#oledBtn{position:relative}
#oledBtn::after{content:"";position:absolute;top:-6px;bottom:-6px;left:-5px;right:-5px;border-radius:14px}
.ghost-btn{display:flex;align-items:center;gap:8px;padding:9px 14px;border-radius:12px;
  background:var(--glass);border:1px solid var(--line);color:var(--txt2);font-weight:600;font-size:13px;transition:.2s}
.ghost-btn:hover{background:var(--glass2);color:var(--txt);border-color:var(--line2)}
#sleepBtn.active{background:var(--grad);color:#0a0a14;border-color:transparent;box-shadow:0 0 18px var(--glow-c)}   /* sleep timer running */
.offline-pill{display:none;align-items:center;gap:7px;padding:7px 13px;border-radius:11px;background:rgba(251,113,133,.14);border:1px solid rgba(251,113,133,.4);color:#fb7185;font-size:12px;font-weight:700;white-space:nowrap}
body.offline .offline-pill{display:inline-flex}
/* storage readout on Downloaded page */
.storage-bar{margin:0 0 16px}
.sb-top{display:flex;justify-content:space-between;align-items:center;gap:10px;font-size:12px;color:var(--txt2);margin-bottom:7px;flex-wrap:wrap}
.sb-top b{color:var(--txt)}.sb-top i{margin-right:6px;color:var(--cyan)}.sb-dev{color:var(--muted)}
.sb-track{height:7px;border-radius:5px;background:rgba(255,255,255,.1);overflow:hidden}
.sb-fill{height:100%;border-radius:5px;background:var(--grad);box-shadow:0 0 12px var(--glow-v)}
.sb-fill.warn{background:linear-gradient(90deg,#f59e0b,#ef4444);box-shadow:0 0 12px rgba(239,68,68,.5)}
.sb-warn{display:flex;align-items:center;gap:7px;color:#fbbf24;font-size:11.5px;margin-top:8px}
.gate-list{list-style:none;margin:2px 0 18px;padding:0;display:flex;flex-direction:column;gap:10px}
.gate-list li{display:flex;align-items:center;gap:11px;font-size:14px;color:var(--txt2)}
.gate-list li.ok{color:var(--txt)} .gate-list li.ok i{color:#34d399} .gate-list li.todo i{color:var(--muted)}

/* ── Stage + hero ─────────────────────────────────────────────────── */
.stage{position:relative;overflow:hidden;display:flex;justify-content:center;align-items:stretch;padding:clamp(14px,2.4vw,34px)}
.hero{width:100%;max-width:1180px;min-width:0;display:flex;flex-direction:column;justify-content:center;gap:clamp(14px,2vw,24px);min-height:0}
.hero-empty{margin:auto;display:grid;place-items:center;gap:14px;text-align:center;color:var(--txt2);padding:40px}
.hero-empty-art{width:120px;height:120px;border-radius:50%;display:grid;place-items:center;font-size:46px;
  background:var(--glass);border:1px solid var(--line);color:var(--violet);animation:spin 8s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.inline-link,.text-btn{background:var(--grad);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent;font-weight:700}

.hero-now{display:grid;grid-template-columns:auto minmax(0,1fr);gap:clamp(20px,3.5vw,52px);align-items:center;min-width:0;width:100%;flex:0 0 auto}

/* artwork */
.art-wrap,.lyr-stage{position:relative;aspect-ratio:1;width:min(42vh,40vw,440px);justify-self:center;flex:0 0 auto}
.art{width:100%;height:100%;object-fit:cover;border-radius:var(--r-lg);
  box-shadow:0 30px 80px rgba(0,0,0,.6);position:relative;z-index:2;background:var(--glass)}
.art-glow{position:absolute;inset:-8% ;border-radius:50%;z-index:1;filter:blur(46px);opacity:.85;
  background:radial-gradient(circle,var(--c1),var(--c2) 60%,transparent 72%)}   /* pulse removed: animating a 46px blur re-rasterised every frame = CPU sink on low-end; static glow kept */
@keyframes pulse{0%,100%{transform:scale(1);opacity:.7}50%{transform:scale(1.06);opacity:.95}}
/* Now-playing action rail: a vertical bar of like / add-to-playlist / download in the space to the
   RIGHT of the album art (Instagram-style, but beside the art rather than over it). art-stage lays the
   square art and the rail out in one centred row; the rail sits in the empty space next to the art. */
.art-stage{position:relative;display:flex;align-items:center;justify-content:center;gap:14px}
.art-actions{display:flex;flex-direction:column;gap:12px;flex:0 0 auto}
.art-actions .act-btn,.art-actions .dl-btn{width:46px;height:46px;border-radius:50%;display:grid;place-items:center;
  font-size:17px;background:rgba(8,6,16,.55);backdrop-filter:blur(10px);border:1px solid var(--line2);
  color:#fff;transition:transform .15s,color .2s,box-shadow .2s;flex:0 0 auto;cursor:pointer}
.art-actions .act-btn:hover,.art-actions .dl-btn:hover{transform:scale(1.08);box-shadow:0 0 20px var(--glow-v)}
#favBtn.on{background:var(--grad);color:#0a0a14;border-color:transparent}
#playerLyrics.on{background:var(--grad);color:#0a0a14;border-color:transparent}

/* The genre family, under the style's own name — present for orientation, not competing with it. */
.gc-fam{display:block;font-size:11px;font-weight:600;opacity:.62;margin-top:1px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* Romanised title kept under the Persian one. Deliberately quiet — it is there to recognise the song
   by, not to compete with the title. */
.now-sub{font-size:13px;font-weight:600;color:rgba(255,255,255,.46);margin:-4px 0 2px;letter-spacing:.01em}
.rlatin{font-size:11.5px;font-weight:600;color:rgba(255,255,255,.4);margin-top:1px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* Search mode chips + the matched lyric line under each result row. */
.search-modes{display:flex;gap:8px;flex-wrap:wrap;margin:0 0 16px}
.lyr-snip{margin:-4px 0 12px;padding-inline-start:56px;padding-inline-end:14px;
  font-size:13px;line-height:1.65;color:rgba(255,255,255,.58);font-style:italic}

/* ── Lyrics panel ───────────────────────────────────────────────────────
   Sits in the album-art slot (sizing shared with .art-wrap above, so the two
   are always the same box). Lines are ordinary selectable text as well as seek
   targets — avify.js only reads a click as a seek when nothing is selected, so
   copying a line never jumps the track. The tall vertical padding lets the
   first and last lines reach the vertical centre when auto-scrolled. */
.lyr-stage{display:none;flex-direction:column;border-radius:18px;overflow:hidden;
  background:rgba(8,6,16,.45);border:1px solid var(--line2);backdrop-filter:blur(12px)}
body.lyr-on .lyr-stage{display:flex}
body.lyr-on .art-wrap{display:none}
.lyr-body{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  padding:42% 16px;scrollbar-width:thin;-webkit-overflow-scrolling:touch}
.lyr-line{margin:0;padding:7px 4px;border-radius:8px;font-size:17px;line-height:1.5;font-weight:600;
  color:rgba(255,255,255,.4);cursor:pointer;user-select:text;-webkit-user-select:text;
  transition:color .25s,font-size .2s}
.lyr-line:hover{color:rgba(255,255,255,.72)}
.lyr-line.done{color:rgba(255,255,255,.26)}
.lyr-line.on{color:#fff;font-size:19px;text-shadow:0 0 18px var(--glow-v)}
.lyr-line.gap{min-height:12px;padding:0}
/* Unsynced lyrics have no timings, so they are readable text and nothing more. */
.lyr-line.plainline{cursor:default;color:rgba(255,255,255,.74);font-weight:500}
.lyr-line.plainline:hover{color:rgba(255,255,255,.74)}
.lyr-note{margin:0;padding:0 18px;text-align:center;font-size:14px;line-height:1.7;
  color:rgba(255,255,255,.58)}
.lyr-foot{flex:0 0 auto;padding:7px 10px;font-size:10px;letter-spacing:.05em;text-transform:uppercase;
  color:rgba(255,255,255,.34);border-top:1px solid var(--line2);text-align:center;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Weak devices: no blur, no glow, no size animation (matches the rest of lite mode). */
body.lite .lyr-stage{backdrop-filter:none;background:rgba(8,6,16,.82)}
body.lite .lyr-line{transition:none}
body.lite .lyr-line.on{text-shadow:none}

/* Now-playing art gestures (wired in avify.js):
   • double-tap → like/unlike (heart-pop overlay below)
   • swipe left/right → next/prev (JS drives .art transform; pan-y keeps vertical scroll,
     user-drag off so the image isn't ghost-dragged on desktop). */
.art{touch-action:pan-y;user-select:none;-webkit-user-select:none;-webkit-user-drag:none;will-change:transform,opacity}
.art-heart{position:absolute;inset:0;z-index:4;display:grid;place-items:center;pointer-events:none}
.art-heart i{font-size:clamp(64px,26vmin,120px);color:#ff5d8f;
  filter:drop-shadow(0 8px 26px rgba(255,93,143,.55));animation:heartPop .7s cubic-bezier(.2,.7,.2,1) forwards}
.art-heart.un i{color:var(--txt2);filter:drop-shadow(0 8px 22px rgba(0,0,0,.5))}
@keyframes heartPop{0%{transform:scale(.3);opacity:0}15%{transform:scale(1.15);opacity:1}
  40%{transform:scale(.94)}60%{transform:scale(1.04)}100%{transform:scale(1.35);opacity:0}}

/* now meta */
.now-meta{min-width:0}
.now-kicker{letter-spacing:3px;font-size:12px;font-weight:700;color:var(--cyan);margin-bottom:10px}
.now-title{font-size:clamp(28px,4.4vw,52px);font-weight:800;line-height:1.16;letter-spacing:-.5px;padding-bottom:2px;
  overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.now-artist{font-size:clamp(15px,1.8vw,20px);color:var(--txt2);font-weight:600;margin-top:8px;text-align:left}
.now-artist:hover{color:var(--cyan)}
.now-album{display:block;font-size:clamp(13px,1.5vw,16px);color:var(--muted);font-weight:500;margin-top:4px;text-align:left}
.now-album:hover{color:var(--cyan)}
.now-album i{font-size:.82em;margin-right:6px;opacity:.75}

/* scrubber */
.scrubber{display:flex;align-items:center;gap:12px;margin:clamp(20px,3vw,34px) 0 18px}
.scrubber .t{font-size:12px;color:var(--muted);font-variant-numeric:tabular-nums;min-width:38px}
.scrubber .t.dur{text-align:right}
.track{position:relative;flex:1;height:8px;border-radius:6px;background:rgba(255,255,255,.10);cursor:pointer}
.buffered{position:absolute;left:0;top:0;height:100%;border-radius:6px;background:rgba(255,255,255,.26);width:0;transition:width .25s linear}
.fill{position:absolute;left:0;top:0;height:100%;border-radius:6px;background:var(--grad);width:0;box-shadow:0 0 14px var(--glow-v)}
.fill .knob{position:absolute;right:-7px;top:50%;transform:translateY(-50%);width:14px;height:14px;border-radius:50%;
  background:#fff;box-shadow:0 0 12px var(--glow-c);opacity:0;transition:opacity .2s}
.track:hover .knob{opacity:1}

/* transport */
.transport{display:flex;align-items:center;gap:clamp(10px,2vw,22px)}
.t-btn{width:52px;height:52px;border-radius:50%;display:grid;place-items:center;font-size:19px;color:var(--txt2);transition:.18s}
.t-btn:hover{color:#fff;background:var(--glass2);transform:scale(1.06)}
.t-btn.active{color:var(--cyan)}
/* Repeat-one: fa-repeat glyph stays visible; a small "1" badge marks the one-track mode */
#repeatBtn{position:relative}
#repeatBtn.repeat-one::after{content:'1';position:absolute;top:2px;right:6px;min-width:15px;height:15px;padding:0 3px;border-radius:8px;background:var(--cyan);color:#0a0a14;font:800 10px/15px 'Sora','Vazirmatn',sans-serif;text-align:center;box-shadow:0 0 0 2px var(--bg,#07060f)}
.t-btn.play{width:74px;height:74px;font-size:26px;background:var(--grad);color:#0a0a14;
  box-shadow:0 0 34px var(--glow-v),0 10px 26px rgba(0,0,0,.4)}
.t-btn.play:hover{transform:scale(1.05);box-shadow:0 0 46px var(--glow-c)}
.t-btn.sm{width:42px;height:42px;font-size:15px}

/* sub controls */
.sub-controls{display:flex;align-items:center;gap:18px;margin-top:clamp(18px,3vw,30px);flex-wrap:wrap}
/* Both pills in this row are things you reach for one-handed, often without looking straight at the
   screen, so they get the 44px minimum rather than the 40 they inherited. */
.sub-controls .ghost-btn{min-height:44px}
/* Nightstand is normally found while driving, so it is tinted instead of neutral — enough to pick
   out of the corner of your eye without turning it into a call to action. */
.night-btn{color:var(--txt);border-color:var(--line2)}
.night-btn i{color:#a78bfa}
.night-btn:hover i{color:#c4b5fd}
.volume{display:flex;align-items:center;gap:8px;min-width:150px}
.volume input[type=range]{flex:1;accent-color:var(--cyan);height:4px}
.quality{display:flex;gap:6px;background:var(--glass);padding:4px;border-radius:12px;border:1px solid var(--line)}
.chip{padding:7px 12px;border-radius:9px;font-size:12px;font-weight:600;color:var(--txt2);transition:.2s}
.chip:hover{color:var(--txt)}
.chip.active{background:var(--grad);color:#0a0a14}

/* up next rail */
/* Up Next — horizontal "filmstrip": numbered covers, next-track highlighted, faded edges,
   hidden scrollbar, snap-scroll. Fixed (compact) height so the whole player fits one screen. */
.upnext-rail{flex:0 0 auto;min-width:0;margin-top:2px}
.rail-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;font-weight:700;color:var(--txt2);font-size:13px;letter-spacing:.4px}
.rail-head .text-btn{font-size:12px}
.rail-items{display:flex;gap:14px;overflow-x:auto;overflow-y:hidden;padding:6px 2px 8px 8px;scroll-padding-left:8px;scroll-snap-type:x proximity;scrollbar-width:none;
  -webkit-mask-image:linear-gradient(90deg,#000 0,#000 calc(100% - 52px),transparent 100%);
          mask-image:linear-gradient(90deg,#000 0,#000 calc(100% - 52px),transparent 100%)}
.rail-items::-webkit-scrollbar{display:none}
.rail-card{flex:0 0 auto;width:clamp(76px,11.5vh,108px);cursor:pointer;scroll-snap-align:start}
.rail-card .rc-img{position:relative;width:100%;aspect-ratio:1;border-radius:14px;overflow:hidden;
  border:1px solid var(--line2);box-shadow:0 8px 20px rgba(0,0,0,.42);transition:transform .25s cubic-bezier(.2,.7,.2,1),box-shadow .25s,border-color .25s}
.rail-card .rc-img img{width:100%;height:100%;object-fit:cover}
.rail-card .rc-num{position:absolute;top:6px;left:6px;min-width:20px;height:20px;padding:0 5px;border-radius:7px;display:grid;place-items:center;
  font-size:11px;font-weight:800;color:#fff;background:rgba(8,6,16,.55);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);border:1px solid var(--line2)}
.rail-card:hover .rc-img{transform:translateY(-5px);box-shadow:0 16px 32px rgba(0,0,0,.5),0 0 26px var(--glow-v);border-color:rgba(167,139,250,.6)}
.rail-card:first-child .rc-img{box-shadow:0 0 0 2px var(--cyan),0 0 22px var(--glow-c),0 8px 20px rgba(0,0,0,.42)}
.rail-card:first-child .rc-num{background:var(--grad);color:#06040d;border-color:transparent}
.rail-card .rt{font-size:12px;font-weight:600;margin-top:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rail-card .ra{font-size:11px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* ── Browse drawer ────────────────────────────────────────────────── */
.scrim{position:fixed;top:calc(var(--topbar-h) + env(safe-area-inset-top));left:0;right:0;bottom:0;z-index:36;display:none;background:rgba(5,4,12,.32);opacity:0;transition:opacity .25s}
.scrim.show{display:block;opacity:1}
.browse{position:fixed;top:0;right:0;height:100%;width:min(520px,92vw);z-index:40;
  padding-top:env(safe-area-inset-top);
  background:linear-gradient(180deg,rgba(16,12,32,.92),rgba(9,7,18,.95));
  backdrop-filter:blur(26px) saturate(150%);-webkit-backdrop-filter:blur(26px) saturate(150%);
  border-left:1px solid var(--line2);box-shadow:-20px 0 60px rgba(0,0,0,.5);
  transform:translateX(100%);transition:transform .38s cubic-bezier(.2,.7,.2,1);display:grid;grid-template-rows:auto 1fr auto}
.browse.open{transform:translateX(0)}
/* Admin panel opens full-width on desktop (a real full page, not a side drawer) */
/* Admin panel: a proper desktop dashboard — full-width drawer, left tab rail, centered
   readable content column (instead of the phone layout stretched across the screen). */
@media(min-width:1024px){
  .browse.admin-full{width:100%;max-width:100%}
  .browse.admin-full .browse-body{padding:30px 36px}
  .browse.admin-full .admin-page{
    display:grid; grid-template-columns:224px minmax(0,1fr); column-gap:34px;
    align-content:start; max-width:1160px; margin-inline:auto;
  }
  .browse.admin-full .admin-page > *{grid-column:1 / -1}          /* headers / scan bar span full width */
  .browse.admin-full .adtabs{
    grid-column:1; grid-row:2; align-self:start; position:sticky; top:6px;
    flex-direction:column; overflow:visible; gap:6px; margin:0; padding:0;
    background:rgba(255,255,255,.03); border:1px solid var(--line2); border-radius:16px; padding:8px;
  }
  .browse.admin-full .adtab{width:100%; justify-content:flex-start; padding:11px 14px}
  .browse.admin-full .adpanel.active{grid-column:2; grid-row:2; min-width:0}
  .browse.admin-full .adpanel .admin-sec:first-child{margin-top:0}
  /* keep form controls a comfortable width; lists/grids still use the whole column */
  .browse.admin-full .adpanel .field input,
  .browse.admin-full .adpanel .field select{max-width:580px}
  .browse.admin-full .adpanel > .btn{max-width:580px}
}
.head-btn{width:38px;height:38px;border-radius:11px;display:grid;place-items:center;color:var(--txt2);background:var(--glass);border:1px solid var(--line);transition:.2s}
.head-btn:hover{background:var(--glass2);color:#fff}
body.select-mode #selBtn{background:var(--grad);color:#08060f;border-color:transparent}
/* selection visuals */
body.select-mode .play-fab,body.select-mode .ractions,body.select-mode .rdur{display:none}
/* card checkbox (uses FA solid \f00c — the regular font isn't bundled). On the CARD (not .thumb) so a
   circular artist thumb's overflow:hidden can't clip it. */
body.select-mode .card{position:relative}
body.select-mode .card:hover .thumb{transform:none}   /* no hover-lift in select mode (keeps the checkbox aligned) */
body.select-mode .card::after{content:"";position:absolute;top:8px;left:8px;width:24px;height:24px;border-radius:50%;border:2px solid rgba(255,255,255,.9);background:rgba(8,6,16,.6);z-index:3;display:grid;place-items:center;font:900 13px/1 'Font Awesome 6 Free';color:transparent;transition:.15s}
body.select-mode .card.artist::after{top:14px;left:14px}   /* nudge onto the round artist art so it reads as fully on the circle */
body.select-mode .card.selected::after{content:"\f00c";background:var(--grad);border-color:transparent;box-shadow:0 0 14px var(--glow-c);color:#08060f}
/* protected card (Liked Songs): show a lock instead of a selectable checkbox */
body.select-mode .card[data-locked]::after{content:"\f023";color:rgba(255,255,255,.92);border-color:transparent;font-size:11px}
body.select-mode .card[data-locked]{opacity:.65}
.card.selected .thumb{box-shadow:0 0 0 3px var(--cyan),0 10px 26px rgba(0,0,0,.5)}
.card.selected .ct{color:var(--cyan)}
/* row checkbox — sits on the right where the more/download buttons are hidden in select mode */
body.select-mode .row{position:relative;padding-right:52px}
body.select-mode .ractions,body.select-mode .qrow-actions,body.select-mode .ra-plays{display:none}
body.select-mode .row::after{content:"";position:absolute;right:16px;top:50%;transform:translateY(-50%);width:24px;height:24px;border-radius:50%;border:2px solid rgba(255,255,255,.9);background:rgba(8,6,16,.6);display:grid;place-items:center;font:900 13px/1 'Font Awesome 6 Free';color:transparent;z-index:2}
body.select-mode .row.selected::after{content:"\f00c";background:var(--grad);border-color:transparent;box-shadow:0 0 14px var(--glow-c);color:#08060f}
.row.selected{background:linear-gradient(90deg,rgba(34,211,238,.28),rgba(139,92,246,.16))!important;box-shadow:inset 3px 0 0 var(--cyan)}
/* bulk action bar */
/* Floating pill (styled like the mini player); sits at the mini's spot, or above it when it's showing */
.sel-bar{position:fixed;left:10px;right:10px;bottom:calc(var(--dock-h) + 10px);z-index:49;
  display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;padding:10px 12px;border-radius:16px;
  background:rgba(14,11,28,.94);-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);
  border:1px solid var(--line2);box-shadow:0 12px 30px rgba(0,0,0,.55)}
.sel-bar[hidden]{display:none}
body.mini-on .sel-bar{bottom:calc(var(--dock-h) + 84px)}   /* stack above the mini now-playing bar */
.sel-count{font-weight:700;font-size:14px;white-space:nowrap;padding-left:4px}
.sel-acts{display:flex;gap:7px;flex-wrap:wrap;justify-content:flex-end}
.sel-acts button{padding:8px 11px;border-radius:11px;background:var(--glass);border:1px solid var(--line);color:var(--txt);font-weight:600;font-size:12.5px;transition:.2s}
.sel-acts button:hover{background:var(--glass2)}
.sel-acts button[data-sa=queue]{background:var(--grad);color:#08060f;border-color:transparent}
.sel-acts button.danger{color:#fb7185;border-color:rgba(251,113,133,.4)}
/* keep the last list items above the floating select bar (its height varies with wrapped buttons →
   JS sets --selbar-h). 22px = 10 offset + 12 gap; 96px = 84 offset (above the mini bar) + 12 gap. */
body.select-mode .browse-body{padding-bottom:calc(22px + var(--selbar-h,72px))}
body.select-mode.mini-on .browse-body{padding-bottom:calc(96px + var(--selbar-h,72px))}
.prog-msg{margin-top:14px;font-weight:600;color:var(--txt2)}
.browse-head{display:flex;align-items:center;gap:12px;padding:18px 20px;border-bottom:1px solid var(--line);min-width:0}
.browse-title{font-size:20px;font-weight:700}
.back-btn,.close-btn{width:38px;height:38px;border-radius:11px;display:grid;place-items:center;color:var(--txt2);background:var(--glass);border:1px solid var(--line);transition:.2s}
.back-btn:hover,.close-btn:hover{background:var(--glass2);color:#fff}
.close-btn{margin-left:auto}
.searchbar{flex:1;min-width:0;display:flex;align-items:center;gap:10px;padding:11px 14px;border-radius:14px;
  background:rgba(255,255,255,.06);border:1px solid var(--line)}
.searchbar i{color:var(--muted)}
.searchbar input{flex:1;min-width:0;background:none;border:none;outline:none;color:var(--txt);font-size:15px}
.searchbar input[type=search]::-webkit-search-cancel-button{-webkit-appearance:none;appearance:none}  /* hide tiny native ✕; use our own */
.searchbar:focus-within{border-color:rgba(34,211,238,.6);box-shadow:0 0 0 3px rgba(34,211,238,.16)}
.search-clear{flex:0 0 auto;width:34px;height:34px;border-radius:50%;display:grid;place-items:center;font-size:15px;color:var(--txt2);background:rgba(255,255,255,.1);transition:.15s;margin:-4px -6px -4px 0}
.search-clear:hover{color:#fff;background:var(--glass2);transform:scale(1.06)}
.inline-search{display:flex;align-items:center;gap:10px;padding:10px 14px;border-radius:14px;margin:4px 0 22px;background:rgba(255,255,255,.06);border:1px solid var(--line)}
.inline-search i{color:var(--muted);font-size:13px}
.inline-search input{flex:1;background:none;border:none;outline:none;color:var(--txt);font-size:14px}
.inline-search:focus-within{border-color:rgba(34,211,238,.6);box-shadow:0 0 0 3px rgba(34,211,238,.16)}
.browse-body{overflow-y:auto;padding:20px;scrollbar-width:thin}

/* sections / grids / cards */
.section{margin-bottom:30px}
.section h3,.section-title{font-size:16px;font-weight:700;margin-bottom:14px;display:flex;align-items:center;gap:10px}
.section-title::before{content:"";width:4px;height:18px;border-radius:3px;background:var(--grad);box-shadow:0 0 12px var(--glow-v)}
.grid{display:grid;gap:16px;grid-template-columns:repeat(auto-fill,minmax(140px,1fr))}
.card{cursor:pointer;transition:.25s}
.card .thumb{position:relative;aspect-ratio:1;border-radius:16px;overflow:hidden;border:1px solid var(--line);
  box-shadow:0 8px 22px rgba(0,0,0,.4);background:var(--glass)}
.card.artist .thumb{border-radius:50%}
.card .thumb img{width:100%;height:100%;object-fit:cover}
/* playlist mosaic cover (up to 4 track covers) */
.pl-cover{position:absolute;inset:0}
.pl-cover.mosaic{display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr 1fr;gap:1px}
.pl-cover .plm-cell{width:100%;height:100%;object-fit:cover;display:block}
.pl-cover .plm-cell.ph{display:grid;place-items:center;font-size:15px;color:rgba(255,255,255,.45);background:linear-gradient(135deg,rgba(139,92,246,.28),rgba(34,211,238,.2))}
.pl-cover.empty{display:grid;place-items:center;font-size:38px;color:rgba(255,255,255,.6);background:linear-gradient(135deg,rgba(139,92,246,.32),rgba(34,211,238,.22))}
/* Artist-collage playlist thumbnail (diagonal panels of the top artists) */
.pl-cover.collage{overflow:hidden;background:#0a0a12}
.pl-cover.collage .pcl{position:absolute;top:0;bottom:0;overflow:hidden}
.pl-cover.collage .pcl img{width:100%;height:100%;object-fit:cover;object-position:center;display:block;filter:saturate(.92) brightness(.99)}
.pl-cover.collage .pcl.solo{inset:0;clip-path:none}
/* angled panels via clip-path: each image centered in its own strip; adjacent strips share the exact diagonal seam -> no gaps at any aspect */
.pl-cover.collage .p3-0{left:0;width:38.33%;clip-path:polygon(0 0,100% 0,73.9% 100%,0 100%)}
.pl-cover.collage .p3-1{left:28.33%;width:43.33%;clip-path:polygon(23.1% 0,100% 0,76.9% 100%,0 100%)}
.pl-cover.collage .p3-2{left:61.66%;width:38.33%;clip-path:polygon(26.1% 0,100% 0,100% 100%,0 100%)}
.pl-cover.collage .p2-0{left:0;width:55%;clip-path:polygon(0 0,100% 0,81.8% 100%,0 100%)}
.pl-cover.collage .p2-1{left:45%;width:55%;clip-path:polygon(18.2% 0,100% 0,100% 100%,0 100%)}
.pl-cover.collage .plc-tint{position:absolute;inset:0;background:linear-gradient(155deg,hsla(var(--plh),72%,55%,.32),transparent 55%)}
.pl-cover.collage .plc-scrim{position:absolute;inset:0;background:linear-gradient(to top,rgba(0,0,0,.42),transparent 42%)}
/* Featured (RadioJavan discovery) — horizontal filmstrip, distinct from the section grid: larger
   square art, hover play button, edge fade + snap-scroll like the Up Next rail; mouse-wheel scrolls
   it horizontally (bound in bindFeaturedRail). */
.section-title .feat-viewall{margin-left:auto;font-size:13px}
.feat-rail{display:flex;gap:16px;overflow-x:auto;overflow-y:hidden;padding:4px 2px 10px 2px;
  scroll-padding-left:2px;scroll-snap-type:x proximity;scrollbar-width:none;
  -webkit-mask-image:linear-gradient(90deg,#000 0,#000 calc(100% - 40px),transparent 100%);
          mask-image:linear-gradient(90deg,#000 0,#000 calc(100% - 40px),transparent 100%)}
.feat-rail::-webkit-scrollbar{display:none}
.feat-card{flex:0 0 auto;width:clamp(128px,15vw,160px);cursor:pointer;scroll-snap-align:start}
.feat-img{position:relative;width:100%;aspect-ratio:1;border-radius:16px;overflow:hidden;
  border:1px solid var(--line);box-shadow:0 8px 22px rgba(0,0,0,.4);background:var(--glass);
  transition:transform .22s cubic-bezier(.2,.7,.2,1),box-shadow .22s,border-color .22s}
.feat-img img{width:100%;height:100%;object-fit:cover;display:block}
.feat-play{position:absolute;right:8px;bottom:8px;width:36px;height:36px;border-radius:50%;border:0;
  display:grid;place-items:center;color:#06040d;background:var(--grad);box-shadow:0 6px 16px rgba(0,0,0,.45);
  opacity:0;transform:translateY(6px) scale(.9);transition:opacity .18s,transform .18s;cursor:pointer}
.feat-card:hover .feat-img{transform:translateY(-4px);box-shadow:0 16px 30px rgba(0,0,0,.5),0 0 24px var(--glow-v);border-color:rgba(167,139,250,.55)}
.feat-card:hover .feat-play{opacity:1;transform:translateY(0) scale(1)}
.feat-t{font-size:13px;font-weight:700;margin-top:9px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.feat-a{font-size:12px;color:var(--muted);margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* "What are you doing?" activity strip */
.act-sec{margin:2px 0 22px}
.act-head{font-size:15px;font-weight:800;color:#fff;margin:0 2px 12px}
.act-strip{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;padding:2px}
.act-chip{position:relative;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:18px 8px;border-radius:16px;overflow:hidden;cursor:pointer;border:0;background:linear-gradient(158deg, var(--hc-accent,#8b5cf6), #16131f);box-shadow:inset 0 0 0 1px rgba(255,255,255,.07);transition:transform .16s cubic-bezier(.2,.7,.2,1),box-shadow .16s,border-color .16s}
.act-chip:hover{transform:translateY(-3px);border-color:rgba(255,255,255,.26);box-shadow:0 12px 28px rgba(0,0,0,.5)}
.act-chip .ac-ic{width:54px;height:54px;border-radius:50%;display:grid;place-items:center;background:rgba(255,255,255,.18);font-size:24px;color:#fff;z-index:2}
.act-chip .ac-lb{font-size:13px;font-weight:700;color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.35);z-index:2;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
/* now-playing report/flag button (subtle: clear but out of the way) */
.art-actions .act-btn.report{opacity:.5}
.art-actions .act-btn.report:hover{opacity:1;color:#fb7185}
.rpt-note{width:100%;margin-top:12px;background:rgba(255,255,255,.06);border:1px solid var(--line2,rgba(255,255,255,.14));border-radius:12px;color:#fff;padding:10px 12px;font:inherit;resize:vertical;box-sizing:border-box}
.pop-sep{height:1px;background:var(--line,rgba(255,255,255,.1));margin:8px 6px}
.pop-norm{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:4px 12px 6px;font-size:13px;color:#fff}
.pop-norm i{color:#22d3ee;margin-right:7px}
.card .thumb .play-fab{position:absolute;right:10px;bottom:10px;width:44px;height:44px;border-radius:50%;display:grid;place-items:center;
  background:var(--grad);color:#0a0a14;font-size:15px;box-shadow:0 6px 18px rgba(0,0,0,.4),0 0 18px var(--glow-v);
  transform:translateY(8px) scale(.8);opacity:0;transition:.25s}
.card:hover .play-fab{transform:none;opacity:1}
.card:hover .thumb{transform:translateY(-5px);box-shadow:0 18px 38px rgba(0,0,0,.5),0 0 28px var(--glow-v)}
.card .ct{font-size:14px;font-weight:600;margin-top:10px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.card.artist .ct{text-align:center}
.card .cs{font-size:12px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.card.artist .cs{text-align:center}

/* track rows */
.rows{display:flex;flex-direction:column;gap:4px}
.row{display:flex;align-items:center;gap:14px;padding:10px 12px;border-radius:12px;cursor:pointer;transition:.18s}
.row:hover{background:var(--glass2)}
.row.playing{background:linear-gradient(90deg,rgba(34,211,238,.16),rgba(139,92,246,.10));box-shadow:inset 3px 0 0 var(--cyan)}
.row .rnum{width:24px;text-align:center;color:var(--muted);font-size:13px;font-variant-numeric:tabular-nums}
.row .rimg{width:46px;height:46px;border-radius:10px;object-fit:cover;border:1px solid var(--line);flex:0 0 auto}
.row .rinfo{min-width:0;flex:1}
.row .rtitle{font-size:14px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.row .rartist{font-size:12px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.row .rdur{color:var(--muted);font-size:12px;font-variant-numeric:tabular-nums}
.ractions{display:flex;align-items:center;gap:2px;flex:0 0 auto}
.row .rbtn{width:32px;height:32px;border-radius:9px;display:grid;place-items:center;color:var(--txt2);opacity:0;transition:.2s}
.row:hover .rbtn{opacity:1}
.row .rbtn:hover{background:var(--glass2);color:#fff}
.row .rbtn[data-qn]:hover,.row .rbtn[data-qq]:hover{color:var(--cyan)}
@media (hover:none){.row .rbtn{opacity:1}}   /* touch devices: quick actions always visible */

/* artist/album header */
.detail-head{display:flex;gap:20px;align-items:flex-end;margin-bottom:24px}
.detail-head img{width:140px;height:140px;border-radius:20px;object-fit:cover;box-shadow:0 18px 44px rgba(0,0,0,.55),0 0 36px var(--glow-v)}
.detail-head.artist img{border-radius:50%}
.detail-head .dh-kicker{font-size:12px;letter-spacing:2px;color:var(--cyan);font-weight:700}
.detail-head h2{font-size:clamp(24px,3vw,38px);font-weight:800;line-height:1.05;margin:6px 0}
.detail-head .dh-sub{color:var(--txt2);font-size:14px}
.play-all{margin-bottom:18px;display:inline-flex;gap:10px;align-items:center;padding:12px 22px;border-radius:14px;
  background:var(--grad);color:#0a0a14;font-weight:700;box-shadow:0 0 26px var(--glow-v);transition:.2s}
.play-all:hover{transform:translateY(-2px);box-shadow:0 0 38px var(--glow-c)}

/* ── Queue panel ──────────────────────────────────────────────────── */
.queue-panel{position:fixed;top:0;right:0;height:100%;width:min(420px,92vw);z-index:45;
  padding-top:env(safe-area-inset-top);
  background:linear-gradient(180deg,rgba(16,12,32,.94),rgba(9,7,18,.96));backdrop-filter:blur(26px);
  border-left:1px solid var(--line2);box-shadow:-20px 0 60px rgba(0,0,0,.5);
  transform:translateX(100%);transition:transform .38s cubic-bezier(.2,.7,.2,1);display:grid;grid-template-rows:auto 1fr}
.queue-panel.open{transform:translateX(0)}
.qp-head{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:16px 18px;border-bottom:1px solid var(--line)}
.qp-head h3{font-size:18px;display:flex;align-items:baseline;gap:8px}
.qp-count{font-size:12px;color:var(--muted);font-weight:500}
.qp-actions{display:flex;align-items:center;gap:6px}
.qh-btn{width:36px;height:36px;border-radius:10px;display:grid;place-items:center;color:var(--txt2);background:var(--glass);border:1px solid var(--line);font-size:14px;transition:.2s}
.qh-btn:hover{background:var(--glass2);color:#fff}
#queueClear:hover{color:#fb7185;border-color:rgba(251,113,133,.4)}
.qp-list{overflow-y:auto;padding:12px}
.qrow-actions{display:flex;align-items:center;gap:4px;flex:0 0 auto;opacity:0;transition:opacity .15s}
.row:hover .qrow-actions{opacity:1}
.qbtn{width:36px;height:36px;border-radius:9px;display:grid;place-items:center;color:var(--txt2);font-size:14px;transition:.15s}
.qbtn:hover{background:var(--glass2);color:#fff}
.qbtn[data-qrem]{color:#fb7185}
.qbtn[data-qrem]:hover,.qbtn[data-qrem]:active{background:rgba(251,113,133,.18);color:#fb7185}
@media (hover:none){.qrow-actions{opacity:1}}

/* ── Dock + mini (mobile/car) ─────────────────────────────────────── */
.dock{display:none;position:fixed;bottom:0;left:0;right:0;z-index:50;height:var(--dock-h);
  grid-template-columns:repeat(5,1fr);align-items:center;
  background:rgba(8,6,16,.72);backdrop-filter:blur(24px);-webkit-backdrop-filter:blur(24px);border-top:1px solid var(--line2);
  padding-bottom:env(safe-area-inset-bottom)}
.dock-btn{display:grid;justify-items:center;gap:4px;color:var(--muted);font-size:10px;font-weight:600}
.dock-btn i{font-size:18px}
.dock-btn.active{color:var(--cyan)}
/* dock "More" overflow sheet (mobile/tablet only) */
.more-backdrop{position:fixed;inset:0;z-index:48;background:rgba(0,0,0,.4)}
.more-sheet{position:fixed;left:0;right:0;bottom:var(--dock-h);z-index:49;
  display:grid;grid-template-columns:repeat(3,1fr);gap:8px;padding:12px 12px 16px;
  background:rgba(12,9,24,.97);-webkit-backdrop-filter:blur(24px);backdrop-filter:blur(24px);
  border-top:1px solid var(--line2);box-shadow:0 -14px 34px rgba(0,0,0,.5);animation:moreUp .18s cubic-bezier(.2,.7,.2,1)}
@keyframes moreUp{from{transform:translateY(14px);opacity:0}to{transform:translateY(0);opacity:1}}
.more-item{display:grid;justify-items:center;gap:7px;padding:14px 6px;border-radius:14px;
  color:var(--txt2);font-size:12px;font-weight:600;background:var(--glass);border:1px solid var(--line);transition:.18s}
.more-item i{font-size:21px}
.more-item:hover,.more-item:active{color:var(--txt);background:var(--glass2);border-color:var(--line2)}
.mini{display:none;position:fixed;left:10px;width:calc(100% - 20px);bottom:calc(var(--dock-h) + 10px);z-index:48;align-items:center;gap:11px;padding:8px 8px 8px 8px;border-radius:16px;overflow:hidden;cursor:pointer;transition:width .26s cubic-bezier(.4,0,.2,1),transform .2s ease,opacity .2s ease;
  background:rgba(14,11,28,.92);backdrop-filter:blur(20px);-webkit-backdrop-filter:blur(20px);border:1px solid var(--line2);box-shadow:0 12px 30px rgba(0,0,0,.5)}
.mini-art{width:46px;height:46px;border-radius:10px;object-fit:cover;flex:none}
.mini-meta{flex:1;min-width:0}
.mini-title{font-size:13.5px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.mini-artist{font-size:11.5px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:1px}
/* When the mini now-playing bar is showing, pad the scrollable content so the last rows/cards aren't
   hidden under it (the bar is ~64px tall, sitting 10px above the dock). */
body.mini-on .browse-body{padding-bottom:88px}
body.mini-on .qp-list{padding-bottom:88px}
.mini-btn{width:40px;height:40px;flex:none;display:grid;place-items:center;border-radius:50%;color:var(--txt2);font-size:17px;background:transparent;border:none;transition:transform .12s}
.mini-btn:active{transform:scale(.88)}
#miniPlay{color:#0a0a14;background:var(--grad);box-shadow:0 4px 14px var(--glow-v);font-size:15px}
.mini-prog{position:absolute;left:0;right:0;top:0;height:2.5px;background:rgba(255,255,255,.09)}
.mini-prog-fill{height:100%;width:0;background:var(--cyan);transition:width .25s linear}

/* ── Modals + toasts ──────────────────────────────────────────────── */
.modal-root{position:fixed;inset:0;z-index:66;display:none;place-items:center;padding:20px;
  background:rgba(4,3,12,.6);backdrop-filter:blur(8px)}   /* above the OLED overlay (65) so the add-to-playlist modal is usable in lockscreen mode */
.modal-root.open{display:grid}
.modal{position:relative;width:min(420px,100%);max-height:88vh;overflow-y:auto;background:linear-gradient(180deg,rgba(24,19,44,.96),rgba(14,11,28,.96));
  border:1px solid var(--line2);border-radius:22px;box-shadow:0 30px 80px rgba(0,0,0,.6),0 0 50px rgba(139,92,246,.2);padding:26px}
.modal-x{position:absolute;top:14px;right:14px;width:36px;height:36px;border-radius:10px;display:grid;place-items:center;
  color:var(--txt2);background:var(--glass);border:1px solid var(--line);font-size:22px;line-height:1;transition:.2s}
.modal-x:hover{background:var(--glass2);color:#fff}
.modal h3{font-size:22px;margin-bottom:6px}
.modal p.sub{color:var(--txt2);font-size:14px;margin-bottom:18px}
.field{margin-bottom:14px}
.field label{display:block;font-size:13px;color:var(--txt2);margin-bottom:6px}
.field input{width:100%;padding:13px 15px;border-radius:13px;background:rgba(255,255,255,.06);border:1px solid var(--line);color:var(--txt);font-size:15px;outline:none}
.field input:focus{border-color:rgba(34,211,238,.6);box-shadow:0 0 0 3px rgba(34,211,238,.16)}
.btn{width:100%;padding:14px;border-radius:14px;font-weight:700;font-size:15px;transition:.2s}
.btn.primary{background:var(--grad);color:#0a0a14;box-shadow:0 0 24px var(--glow-v)}
.btn.primary:hover{transform:translateY(-2px);box-shadow:0 0 34px var(--glow-c)}
.btn.ghost{background:var(--glass);border:1px solid var(--line);color:var(--txt)}
.btn.danger{background:rgba(251,113,133,.1);border:1px solid rgba(251,113,133,.4);color:#fb7185}
.btn.danger:hover{background:rgba(251,113,133,.18)}
.admin-hint{font-size:11.5px;color:var(--muted);line-height:1.45;margin:7px 4px 2px}
.ad-fb{font-size:12px;color:var(--cyan);line-height:1.4;margin:5px 4px 4px}
.ad-fb:empty{display:none}
.scan-prog{background:var(--glass);border:1px solid var(--line2);border-radius:14px;padding:13px 14px;margin:2px 0 16px}
.scan-prog-top{display:flex;justify-content:space-between;align-items:center;font-size:13px;font-weight:700;color:var(--txt);margin-bottom:9px}
.scan-prog-top span:last-child{color:var(--cyan);font-variant-numeric:tabular-nums;font-size:14px}
.scan-prog-track{height:8px;border-radius:6px;background:rgba(255,255,255,.1);overflow:hidden}
.scan-prog-fill{height:100%;border-radius:6px;background:var(--grad);box-shadow:0 0 12px var(--glow-v);width:0;transition:width .45s ease}
.scan-prog-fill.indet{width:30%!important;transition:none;animation:scanIndet 1.15s ease-in-out infinite}
@keyframes scanIndet{0%{margin-left:-32%}100%{margin-left:100%}}
.scan-prog-sub{font-size:11.5px;color:var(--muted);margin-top:8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.modal .switch{text-align:center;margin-top:16px;font-size:14px;color:var(--txt2)}
.modal .switch button{color:var(--cyan);font-weight:700}
.modal .err{color:#fb7185;font-size:13px;margin-bottom:10px;min-height:18px}
.toast-root{position:fixed;bottom:24px;left:50%;transform:translateX(-50%);z-index:70;display:flex;flex-direction:column;gap:10px;align-items:center}
.toast{padding:12px 20px;border-radius:14px;background:rgba(20,16,38,.96);border:1px solid var(--line2);
  box-shadow:0 14px 36px rgba(0,0,0,.5);font-size:14px;font-weight:600;animation:rise .3s ease}
.toast.ok{box-shadow:0 0 26px var(--glow-c),0 14px 36px rgba(0,0,0,.5)}
@keyframes rise{from{opacity:0;transform:translateY(12px)}}

/* ── Browse handle (reopen affordance) ────────────────────────────── */
.browse-handle{position:fixed;right:0;top:50%;transform:translateY(-50%);z-index:38;
  display:flex;flex-direction:column;align-items:center;gap:10px;padding:18px 9px;
  background:var(--grad);color:#08060f;font-weight:800;font-size:11px;letter-spacing:2px;
  border-radius:16px 0 0 16px;box-shadow:-6px 0 26px var(--glow-v);
  transition:transform .35s cubic-bezier(.2,.7,.2,1),opacity .25s}
.browse-handle i{font-size:13px}
.browse-handle span{writing-mode:vertical-rl;text-orientation:mixed}
.browse-handle:hover{padding-right:13px}
body.drawer-open .browse-handle,body.queue-open .browse-handle{transform:translate(120%,-50%);opacity:0;pointer-events:none}

/* ── Popover (quality) ────────────────────────────────────────────── */
.popover{position:fixed;top:calc(var(--topbar-h) + env(safe-area-inset-top) + 8px);right:14px;z-index:56;width:236px;
  background:rgba(18,14,36,.98);-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px);
  border:1px solid var(--line2);border-radius:16px;box-shadow:0 24px 60px rgba(0,0,0,.6),0 0 40px rgba(139,92,246,.18);
  padding:10px;animation:rise .18s ease}
.pop-title{font-size:11px;color:var(--muted);font-weight:700;letter-spacing:1.5px;padding:6px 10px 8px}
.pop-opt{display:flex;justify-content:space-between;align-items:center;width:100%;padding:11px 12px;border-radius:11px;color:var(--txt);font-size:14px;transition:.15s}
.pop-opt span{display:flex;gap:10px;align-items:center;font-weight:600}
.pop-opt span i{width:18px;text-align:center;color:var(--txt2)}
.pop-opt small{color:var(--muted);font-size:11px}
.pop-opt:hover{background:var(--glass2)}
.pop-opt.active{background:linear-gradient(90deg,rgba(139,92,246,.30),rgba(34,211,238,.12))}
.pop-opt.active small{color:var(--cyan)}
.pop-opt.active span i{color:var(--cyan)}
.pop-note{font-size:11px;color:var(--cyan);padding:8px 10px 4px;line-height:1.4}

/* ── Action sheet / playlist picker rows ──────────────────────────── */
.sheet{display:flex;flex-direction:column;gap:4px;margin-top:6px;max-height:340px;overflow-y:auto}
.sheet-btn{display:flex;justify-content:space-between;align-items:center;width:100%;padding:13px 14px;border-radius:12px;
  color:var(--txt);font-size:15px;font-weight:600;transition:.15s;text-align:left}
.sheet-btn span{display:flex;gap:12px;align-items:center}
.sheet-btn span i{width:18px;text-align:center;color:var(--txt2)}
.sheet-btn small{color:var(--muted);font-size:12px}
.sheet-btn:hover{background:var(--glass2)}
.sheet-btn.danger{color:#fb7185}
.sheet-btn.danger span i{color:#fb7185}
.sheet-btn.liked span i{color:#ff5d8f}
/* Playlist-membership toggle rows (addToPlaylistFlow): check shows when the track is a member */
.sheet-btn.plrow .chk{opacity:0;color:var(--cyan);transition:opacity .15s}
.sheet-btn.plrow.on .chk{opacity:1}
.sheet-btn.plrow.on span i{color:var(--cyan)}
/* Now-playing "add to playlist" button when the track is already saved: cyan (matching the other active
   icons); the distinct fa-list-check glyph — set in JS — is what sets it apart from the download button's
   fa-circle-check "done" state, so they no longer read as the same icon. */
#playerPl.saved{background:var(--grad);color:#0a0a14;border-color:transparent}
#playerPl.saved i{filter:none}

/* Playlist sharing-state panel (private vs unlisted-link) + action chips */
.share-state{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:10px 14px;
  margin:14px 0 4px;padding:11px 14px;border-radius:14px;border:1px solid var(--line2);background:rgba(255,255,255,.03)}
.share-state.on{border-color:rgba(34,211,238,.35);background:rgba(34,211,238,.06)}
.share-state .ss-label{display:flex;align-items:center;gap:8px;font-size:13px;font-weight:600;color:var(--txt2)}
.share-state.on .ss-label{color:var(--cyan)}
.share-state .ss-btns{display:flex;flex-wrap:wrap;gap:8px}
.chip{display:inline-flex;align-items:center;gap:6px;padding:7px 12px;border-radius:999px;font-size:12.5px;font-weight:600;
  cursor:pointer;color:var(--txt);border:1px solid var(--line2);background:rgba(255,255,255,.05);
  transition:background .15s,transform .1s,color .15s,border-color .15s}
.chip:hover{background:rgba(255,255,255,.1);transform:translateY(-1px)}
.chip.primary{background:var(--grad);color:#0a0a14;border-color:transparent}
.chip.danger:hover{color:#ff6b8a;border-color:rgba(255,107,138,.4)}
.chip i{font-size:12px}

/* Playlist header share-status badge + the link row inside the share-manager modal */
.sh-badge{display:inline-flex;align-items:center;gap:5px;padding:2px 9px;border-radius:999px;font-size:11.5px;font-weight:700;
  cursor:pointer;vertical-align:middle;border:1px solid var(--line2);background:rgba(255,255,255,.06);color:var(--txt2);
  transition:background .15s,color .15s,border-color .15s}
.sh-badge:hover{background:rgba(255,255,255,.12)}
.sh-badge.on{color:var(--cyan);border-color:rgba(34,211,238,.4);background:rgba(34,211,238,.1)}
.sh-badge i{font-size:10px}
.share-link{display:flex;gap:8px;align-items:center;margin:12px 0}
.share-link input{flex:1;min-width:0;padding:9px 11px;border-radius:10px;border:1px solid var(--line2);
  background:rgba(0,0,0,.25);color:var(--txt);font-size:12.5px}
.share-link .chip{flex:0 0 auto;padding:9px 12px}

/* Visibility picker inside the playlist share manager */
.vis-list{display:flex;flex-direction:column;gap:8px;margin:4px 0 14px}
.vis-opt{display:flex;align-items:center;gap:12px;width:100%;text-align:left;padding:11px 13px;border-radius:13px;
  border:1px solid var(--line2);background:rgba(255,255,255,.04);color:var(--txt);cursor:pointer;transition:border-color .15s,background .15s}
.vis-opt:hover{background:rgba(255,255,255,.08)}
.vis-opt.on{border-color:rgba(34,211,238,.5);background:rgba(34,211,238,.08)}
.vis-opt .vo-ic{flex:0 0 auto;width:30px;height:30px;border-radius:50%;display:grid;place-items:center;
  background:rgba(255,255,255,.07);font-size:13px;color:var(--txt2)}
.vis-opt.on .vo-ic{background:rgba(34,211,238,.16);color:var(--cyan)}
.vis-opt .vo-tx{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.vis-opt .vo-tx b{font-size:13.5px;font-weight:700}
.vis-opt .vo-tx small{font-size:11.5px;color:var(--txt2)}
.vis-opt .vo-ck{opacity:0;color:var(--cyan);font-size:13px}
.vis-opt.on .vo-ck{opacity:1}

/* Admin → Playlists (official Avify playlist curation) */
.ad-pl-list{display:flex;flex-direction:column;gap:8px}
.ad-pl{display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding:11px 13px;border-radius:13px;
  border:1px solid var(--line2);background:rgba(255,255,255,.03)}
.ad-pl-tx{flex:1;min-width:140px;display:flex;flex-direction:column;gap:2px}
.ad-pl-tx b{font-size:13.5px}
.ad-pl-tx small{font-size:11.5px;color:var(--txt2)}
.ad-pl-ac{display:flex;align-items:center;gap:8px;flex-wrap:wrap}

/* Music requests — no-results prompt, request list, status badges */
.nr-req{margin-top:18px}
.req-list{display:flex;flex-direction:column;gap:8px;max-height:52vh;overflow:auto}
.req-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:10px 13px;border-radius:12px;
  border:1px solid var(--line2);background:rgba(255,255,255,.03)}
.req-tx{min-width:0;font-size:13.5px;overflow:hidden;text-overflow:ellipsis}
.req-tx b{font-weight:600}
.req-link{color:var(--cyan);margin-left:6px;font-size:12px}
.req-meta{display:flex;align-items:center;gap:8px;flex:0 0 auto}
.req-badge{display:inline-flex;align-items:center;gap:5px;padding:3px 10px;border-radius:999px;font-size:11.5px;font-weight:700;
  color:var(--txt2);border:1px solid var(--line2);background:rgba(255,255,255,.05)}
.req-badge.ok{color:#39d98a;border-color:rgba(57,217,138,.4);background:rgba(57,217,138,.1)}
.req-badge.no{color:#ff6b8a;border-color:rgba(255,107,138,.4);background:rgba(255,107,138,.1)}
.req-del{background:none;border:0;color:var(--txt2);cursor:pointer;font-size:14px;padding:4px}
.req-del:hover{color:#ff6b8a}
/* admin requests tab */
.ad-req-list{display:flex;flex-direction:column;gap:8px}
.ad-req{display:flex;align-items:center;gap:12px;flex-wrap:wrap;padding:11px 13px;border-radius:13px;
  border:1px solid var(--line2);background:rgba(255,255,255,.03)}
.ad-req .arq-tx{flex:1;min-width:160px;display:flex;flex-direction:column;gap:2px}
.ad-req .arq-tx b{font-size:13.5px}
.ad-req .arq-tx small{font-size:11.5px;color:var(--txt2)}
.ad-req .arq-ac{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.tab-badge{display:inline-grid;place-items:center;min-width:18px;height:18px;padding:0 5px;border-radius:999px;
  background:var(--grad);color:#0a0a14;font-size:10.5px;font-weight:800;margin-left:4px}

/* Admin → Import zip progress */
.zip-prog{margin-top:16px;padding:14px;border-radius:14px;border:1px solid var(--line2);background:rgba(255,255,255,.03)}
.zp-phase{font-size:13px;font-weight:700;color:var(--txt);margin-bottom:8px}
.zp-track{height:8px;border-radius:99px;background:rgba(255,255,255,.08);overflow:hidden}
.zp-fill{height:100%;background:var(--grad);border-radius:99px;width:0;transition:width .4s}
.zp-fill.indet{width:35%!important;animation:zpIndet 1.1s ease-in-out infinite}
@keyframes zpIndet{0%{margin-left:-35%}100%{margin-left:100%}}
.zp-msg{font-size:12px;color:var(--txt2);margin-top:8px}

/* Track-row YouTube play count */
.rplays{display:flex;align-items:center;gap:5px;font-size:12px;color:var(--txt2);flex:0 0 auto;white-space:nowrap;margin-right:2px}
.rplays i{font-size:9px;opacity:.7}
.now-plays{margin-top:8px;display:flex;align-items:center;gap:6px;font-size:12.5px;color:var(--txt2)}
.now-plays i{font-size:9px;opacity:.7}
.qplays{flex:0 0 auto;font-size:11.5px;color:var(--txt2);white-space:nowrap;font-variant-numeric:tabular-nums;margin-left:2px}
.rp-ic{font-size:9px;opacity:.7}
.rartist.has-plays{display:flex;align-items:center;min-width:0}
.rartist.has-plays .ra-name{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rartist.has-plays .ra-plays{flex:0 0 auto;white-space:nowrap;padding-left:8px}
.ra-name-in{display:inline-block;white-space:nowrap}
.ra-name.marquee{text-overflow:clip}
.ra-name.marquee .ra-name-in{animation:raMarq var(--marq-dur,8s) ease-in-out infinite alternate}
@keyframes raMarq{0%,12%{transform:translateX(0)}88%,100%{transform:translateX(var(--marq-shift,0))}}
@media (prefers-reduced-motion:reduce){.ra-name.marquee .ra-name-in{animation:none}}
.rinfo{min-width:0}
.srow .rartist{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Queue rows: tighter gaps + smaller controls so title/artist have room */
#queueList .row{gap:10px}
#queueList .rimg{width:44px;height:44px}
#queueList .qbtn{width:32px;height:32px;font-size:13px}
#queueList .qrow-actions{gap:2px}
.qgrip{touch-action:none;cursor:grab}
.qgrip:active{cursor:grabbing}
.row.qdrag{transition:none;position:relative;z-index:6;opacity:.96;background:var(--glass2);box-shadow:0 10px 26px rgba(0,0,0,.45)}
body.q-dragging{user-select:none;-webkit-user-select:none}
@media(max-width:560px){.rplays{font-size:11px}}
/* Admin YouTube-plays picker */
.yt-scope{display:flex;gap:8px;flex-wrap:wrap}
.yt-refresh{display:flex;align-items:center;gap:8px;margin-top:12px;font-size:13px;color:var(--txt2);cursor:pointer;user-select:none}
.yt-refresh input{width:16px;height:16px;accent-color:var(--cyan)}
.yt-results{margin-top:10px}
.yt-list{display:flex;flex-direction:column;gap:6px;max-height:44vh;overflow:auto}
.yt-item{display:flex;flex-direction:column;gap:2px;align-items:flex-start;text-align:left;width:100%;
  padding:10px 12px;border-radius:11px;border:1px solid var(--line2);background:rgba(255,255,255,.03);cursor:pointer}
.yt-item:hover{background:rgba(34,211,238,.08);border-color:rgba(34,211,238,.35)}
.yti-n{font-size:13.5px;font-weight:600;color:var(--txt)}
.yti-s{font-size:11.5px;color:var(--txt2)}


/* Import-zip history list */
.zip-hist{margin-top:14px}
.zh-head{display:flex;align-items:center;justify-content:space-between;font-size:11px;letter-spacing:1.2px;
  text-transform:uppercase;color:var(--muted);font-weight:700;margin:0 2px 8px}
.zh-head .text-btn{font-size:11px;text-transform:none;letter-spacing:0}
.zh-list{display:flex;flex-direction:column;gap:8px}
.zh-row{display:flex;align-items:center;gap:11px;padding:10px 12px;border-radius:12px;
  border:1px solid var(--line2);background:rgba(255,255,255,.03)}
.zh-ic{font-size:16px;flex:0 0 auto}
.zh-ic.ok{color:#39d98a}.zh-ic.no{color:#ff6b8a}
.zh-tx{flex:1;min-width:0}
.zh-msg{font-size:13px;color:var(--txt);overflow-wrap:anywhere}
.zh-meta{font-size:11px;color:var(--txt2);margin-top:2px}
.zh-x{flex:0 0 auto;background:none;border:0;color:var(--txt2);cursor:pointer;font-size:15px;padding:4px 6px;border-radius:8px}
.zh-x:hover{color:#ff6b8a;background:rgba(255,107,138,.1)}



/* subscribed state for the playlist Subscribe button */
#plSub.on,#followBtn.on{color:var(--cyan);background:rgba(34,211,238,.12);border-color:rgba(34,211,238,.4)}
.vis-opt.collab{margin-top:2px}
.sub-count{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;
  margin:12px 0 4px;padding:10px 13px;border-radius:12px;border:1px solid var(--line2);background:rgba(255,255,255,.04)}
.sub-count span{display:flex;align-items:center;gap:7px;font-size:13px;font-weight:600;color:var(--txt2)}
.vis-opt.collab .vo-ck{opacity:0}
.vis-opt.collab.on .vo-ck{opacity:1}





/* ── Detail action row (play / rename / delete) ───────────────────── */
.detail-actions{display:flex;align-items:center;gap:10px;margin-bottom:18px;flex-wrap:wrap}
.detail-actions .play-all{margin-bottom:0}
.icon-action{width:46px;height:46px;border-radius:13px;display:grid;place-items:center;font-size:16px;
  color:var(--txt2);background:var(--glass);border:1px solid var(--line);transition:.2s}
.icon-action:hover{background:var(--glass2);color:#fff;border-color:var(--line2)}
.icon-action.danger:hover{color:#fb7185;border-color:rgba(251,113,133,.5)}
.lib-quick{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:18px}
.play-all.alt{background:var(--glass);color:var(--txt);border:1px solid var(--line);box-shadow:none}
.play-all.alt:hover{background:var(--glass2);box-shadow:none;transform:translateY(-2px)}
/* per-row download button: idle ↓ · progress ring · done ✓ */
.dl-btn{flex:0 0 auto;width:30px;height:30px;border-radius:50%;display:grid;place-items:center;font-size:15px;color:var(--muted);background:transparent;transition:color .2s,transform .15s}
.dl-btn:hover{color:var(--txt);transform:scale(1.12)}
/* download control inside the player (id so applyDlBtn's className rewrite keeps the sizing) */
#playerDl{width:42px;height:42px;font-size:18px;background:var(--glass);border:1px solid var(--line);color:var(--txt2)}
#playerDl:hover{transform:none;color:var(--txt);border-color:var(--line2);background:var(--glass2)}
#playerDl.done{background:var(--grad);color:#0a0a14;border-color:transparent}
#playerDl.done i{filter:none}
#playerDl .dl-pct{width:24px;height:24px;font-size:10px}
.dl-btn.done{color:var(--cyan)}
.dl-btn.done i{filter:drop-shadow(0 0 6px var(--glow-c))}
.dl-btn.loading{color:#fff}
.dl-btn .dl-pct{width:22px;height:22px;border-radius:50%;background:var(--bg2);display:grid;place-items:center;font-size:9px;font-weight:800;color:#fff}
.icon-action.busy .dl-badge{position:absolute;top:-4px;right:-4px;min-width:16px;height:16px;padding:0 4px;border-radius:8px;background:var(--cyan);color:#06040d;font-size:10px;font-weight:800;display:grid;place-items:center}
.icon-action{position:relative}

/* ── Admin stats grid ─────────────────────────────────────────────── */
.admin-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:10px;margin:6px 0 18px}
.admin-cell{background:var(--glass);border:1px solid var(--line);border-radius:14px;padding:14px;text-align:center}
.admin-cell b{display:block;font-size:22px;font-weight:800;background:var(--grad);-webkit-background-clip:text;background-clip:text;-webkit-text-fill-color:transparent}
.admin-cell span{font-size:11px;color:var(--muted);text-transform:capitalize}
/* Storage: media-drive usage bar */
.disk-bar-wrap{margin:4px 0 16px}
.disk-bar{height:12px;border-radius:7px;background:rgba(255,255,255,.1);overflow:hidden}
.disk-bar-fill{height:100%;border-radius:7px;background:var(--grad);box-shadow:0 0 12px var(--glow-v)}
.disk-bar-legend{display:flex;justify-content:space-between;margin-top:8px;font-size:12px;color:var(--txt2)}
.disk-bar-legend b{color:var(--txt);font-weight:700}
.disk-free b{color:var(--cyan)}
.admin-sec{font-size:11px;letter-spacing:1.5px;text-transform:uppercase;color:var(--muted);font-weight:700;margin:18px 0 8px}
.admin-btn-row{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:10px}
.admin-btn-row .btn{margin-top:0;font-size:13px;padding:12px}

/* update-available banner */
.update-banner{position:fixed;top:calc(var(--topbar-h) + env(safe-area-inset-top) + 12px);left:50%;transform:translateX(-50%);z-index:80;display:flex;align-items:center;gap:14px;
  padding:11px 16px;border-radius:14px;background:var(--grad);color:#08060f;font-weight:700;font-size:14px;box-shadow:0 12px 36px rgba(0,0,0,.5),0 0 30px var(--glow-v);animation:rise .3s ease}
.update-banner button{background:rgba(8,6,16,.22);border:1px solid rgba(8,6,16,.3);color:#08060f;padding:6px 14px;border-radius:10px;font-weight:800;cursor:pointer}
.update-banner button:hover{background:rgba(8,6,16,.4)}

/* in-player ±15s seek */
.seek-group{display:flex;gap:4px}

/* ── Dev-mode toggle row ──────────────────────────────────────────── */
.dev-row{display:flex;align-items:center;justify-content:space-between;gap:14px;margin-top:14px;padding:14px;
  border:1px solid var(--line);border-radius:14px;background:var(--glass)}
.dev-label{display:flex;flex-direction:column;gap:3px;font-size:14px;font-weight:600;color:var(--txt)}
.dev-label i{margin-right:6px;color:var(--cyan)}
.dev-label small{font-weight:400;color:var(--muted);font-size:11px}
.dev-sw{flex:0 0 auto;width:48px;height:28px;border-radius:999px;background:rgba(255,255,255,.12);position:relative;transition:.25s}
.dev-sw::after{content:"";position:absolute;top:3px;left:3px;width:22px;height:22px;border-radius:50%;background:#fff;transition:.25s}
.dev-sw.on{background:var(--grad);box-shadow:0 0 18px var(--glow-v)}
.dev-sw.on::after{transform:translateX(20px)}

.spinner{width:34px;height:34px;border-radius:50%;border:3px solid var(--line2);border-top-color:var(--cyan);animation:spin .8s linear infinite;margin:40px auto}
.empty-note{color:var(--muted);text-align:center;padding:40px;font-size:14px}
.offline-note{display:flex;flex-direction:column;align-items:center;gap:6px;padding:54px 22px}
.offline-note i{font-size:30px;color:rgba(255,255,255,.45);margin-bottom:8px}
.offline-note .ttl{font-size:18px;font-weight:800;color:#fff;letter-spacing:.2px}
.offline-note .sub{font-size:13.5px;color:var(--muted);max-width:300px;line-height:1.5}
.offline-note .play-all{margin-top:14px}

/* ════════ RESPONSIVE ════════════════════════════════════════════── */

/* The browse drawer / queue panel OVERLAY the player (they float on top); the
   player keeps its size and position. */

/* tablet & below: stack hero, show dock, browse fuller */
@media (max-width:1023px){
  /* dock height includes the home-indicator inset so its buttons aren't squished on iPhone */
  :root{--dock-h:calc(68px + env(safe-area-inset-bottom))}
  .top-nav{display:none}
  .dock{display:grid}
  .stage{padding:16px 16px calc(var(--dock-h) + 16px);overflow-y:auto;align-items:flex-start}
  /* vertically centre the now-playing content; margin-block:auto centres when it fits and collapses to
     0 (scrolls from the top) when it's taller than the screen — no clipping */
  .hero{justify-content:flex-start;margin-block:auto}
  .hero-now{grid-template-columns:1fr;justify-items:center;text-align:center;gap:18px}
  .now-meta{justify-self:stretch}   /* full-width meta so the scrubber/transport don't resize with the title length */
  .art-wrap,.lyr-stage{width:min(68vw,40vh,330px)}
  /* Stacked layout: keep the ART itself centred on screen (art-stage shrinks to the art because the
     rail is taken out of flow), and float the action rail in the empty space to the art's RIGHT. */
  .art-stage{display:block}
  .art-actions{position:absolute;top:0;bottom:0;justify-content:center;gap:12px}
  .art-actions-r{left:100%;margin-left:12px}
  .art-actions-l{right:100%;margin-right:12px}
  .now-artist,.now-album{text-align:center}
  /* let long titles wrap to full multi-line (no truncation/clip), without affecting other styles */
  .now-title{display:block;overflow:visible;-webkit-line-clamp:unset;white-space:normal;overflow-wrap:anywhere}
  .scrubber{margin:22px 0 16px}
  .transport{justify-content:center}
  .sub-controls{justify-content:center}
  .browse{width:100vw;border-left:none;padding-bottom:var(--dock-h)}   /* keep sel-bar + list above the dock */
  .queue-panel{padding-bottom:var(--dock-h)}
  .mini.show{display:flex}
  .browse-handle{display:none}   /* dock provides navigation at this size */
}

/* mobile */
@media (max-width:560px){
  .topbar{padding:0 10px;gap:6px}
  .brand-name{display:none}
  /* 5 dock items — comfortable tap targets; label ellipsis as a safety net */
  .dock-btn{font-size:10.5px;gap:4px;padding:0 2px;min-width:0}
  .dock-btn i{font-size:19px}
  .dock-btn span{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .auth-label,#qualityLabel,.offline-pill span{display:none}
  #fsBtn{display:none}                 /* fullscreen rarely used on a phone */
  .ghost-btn{padding:9px 11px}
  .browse-handle{padding:14px 7px;font-size:10px}
  .browse-head{padding:14px 12px;gap:8px}
  .browse-head .head-btn,.browse-head .back-btn,.browse-head .close-btn{flex:0 0 auto}
  .qp-head{padding:14px 12px}
  .qp-actions{gap:4px}
  .qh-btn{width:32px;height:32px}
  .qp-head h3{min-width:0;overflow:hidden;white-space:nowrap}
  .t-btn{width:46px;height:46px}
  .t-btn.play{width:64px;height:64px;font-size:22px}
  .volume{display:none}
  .sub-controls{gap:12px;justify-content:center}
  .grid{grid-template-columns:repeat(auto-fill,minmax(110px,1fr))}
  .upnext-rail{display:none}      /* phones use the dock's Queue button instead */
  .art-wrap,.lyr-stage{max-width:min(300px,64vw,calc(100vw - 140px))}
  .now-title{font-size:clamp(24px,7vw,34px)}
  /* narrower right gap on phones → smaller rail so it fits beside the centred art */
  .art-actions{gap:10px}
  .art-actions-r{margin-left:7px}
  .art-actions-l{margin-right:7px}
  .art-actions .act-btn,.art-actions .dl-btn{width:42px;height:42px;font-size:16px}
}

/* Six header buttons do not fit a 320px-wide phone at the normal spacing. */
@media (max-width:360px){
  .top-actions{gap:6px}
  .top-actions .ghost-btn{padding:7px 8px}
}

/* short landscape (phones in car cradle) */
@media (max-height:560px) and (orientation:landscape){
  .hero-now{grid-template-columns:auto minmax(0,1fr);text-align:left;justify-items:start}   /* auto so the art + action rail both fit */
  .now-artist,.now-album,.now-title{text-align:left}
  .art-wrap,.lyr-stage{max-width:230px}
  .art-stage{display:flex;align-items:center}   /* 2-col car layout: keep the rail in-flow beside the art */
  .art-actions{position:static;margin-left:0;margin-right:0;gap:10px}
  .upnext-rail{display:none}
}


/* ░░ Curated home cards ░░ */
.home-cards{display:grid;gap:16px;grid-template-columns:var(--hc-cols-d,repeat(auto-fill,minmax(160px,1fr)));margin-top:6px}
.hcard{position:relative;display:flex;flex-direction:column;text-align:left;border-radius:18px;overflow:hidden;border:1px solid var(--line);background:var(--glass);cursor:pointer;aspect-ratio:1/1;transition:transform .22s cubic-bezier(.2,.7,.2,1),box-shadow .22s,border-color .22s}
.hcard:hover{transform:translateY(-3px);border-color:var(--line2);box-shadow:0 16px 36px rgba(0,0,0,.5),0 0 26px var(--glow-v)}
.hcard .hc-img,.hcard .hc-grad{position:absolute;inset:0}
.hcard .hc-img img{width:100%;height:100%;object-fit:cover;display:block}
.hcard .hc-img .hc-fall{display:none}
.hcard .hc-img.noimg{display:grid;place-items:center;background:linear-gradient(135deg,rgba(139,92,246,.42),rgba(34,211,238,.3))}
.hcard .hc-img.noimg .hc-fall{display:block;font-size:34px;color:rgba(255,255,255,.85)}
.hcard.text .hc-grad{display:grid;place-items:center;background:linear-gradient(135deg,var(--hc-accent,rgba(139,92,246,.52)),rgba(34,211,238,.32))}
.hcard.text .hc-grad i{font-size:38px;color:rgba(255,255,255,.92)}
.hcard .hc-meta{position:relative;margin-top:auto;z-index:2;padding:12px 13px;background:linear-gradient(transparent,rgba(6,5,14,.55) 38%,rgba(6,5,14,.92))}
.hcard .hc-title{font-weight:800;font-size:15px;color:#fff;line-height:1.2;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical}
.hcard .hc-sub{font-size:12px;color:rgba(255,255,255,.72);margin-top:2px;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;line-height:1.3}
.hcard .hc-kind{position:absolute;top:9px;right:9px;z-index:3;width:28px;height:28px;border-radius:9px;display:grid;place-items:center;font-size:12px;color:#fff;background:rgba(8,6,16,.5);-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);border:1px solid var(--line2)}
.home-shortcuts{margin-top:18px;max-width:280px}
.detail-head.genre{align-items:center}
.detail-head.genre .dh-genreart{width:120px;height:120px;border-radius:20px;display:grid;place-items:center;font-size:48px;color:#fff;background:linear-gradient(135deg,rgba(139,92,246,.5),rgba(34,211,238,.32));box-shadow:0 18px 44px rgba(0,0,0,.55)}

/* ░░ Genres page ░░ */
.genre-grid{display:grid;gap:14px;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));margin-top:4px}
.gcard{position:relative;display:flex;flex-direction:column;justify-content:flex-end;gap:2px;text-align:left;height:108px;padding:14px;border-radius:16px;border:1px solid rgba(255,255,255,.12);overflow:hidden;cursor:pointer;
  background:linear-gradient(135deg,hsl(var(--gh,260),68%,44%),hsl(calc(var(--gh,260) + 38),72%,28%));
  background-size:cover;background-position:center;
  transition:transform .2s cubic-bezier(.2,.7,.2,1),box-shadow .2s}
.gcard:hover{transform:translateY(-3px);box-shadow:0 16px 32px rgba(0,0,0,.5)}
.gcard.hasbg::before{content:"";position:absolute;inset:0;z-index:1;background:linear-gradient(160deg,hsla(var(--gh,260),65%,52%,.30),rgba(8,6,16,.5) 42%,rgba(6,5,14,.9))}
.gcard.hasbg .gc-name,.gcard.hasbg .gc-count{position:relative;z-index:2}
.gcard.hasbg .gc-ic{z-index:2;opacity:.4}
.gcard .gc-ic{position:absolute;top:11px;right:13px;font-size:30px;color:rgba(255,255,255,.26)}
.gcard .gc-name{font-weight:800;font-size:16px;color:#fff;line-height:1.15;z-index:1;max-width:88%}
.gcard .gc-count{font-size:12px;color:rgba(255,255,255,.82);z-index:1}

/* ░░ Admin: full page, tabs ░░ */
.admin-page{padding-bottom:24px}
.adtabs{display:flex;gap:8px;overflow-x:auto;margin:4px 0 18px;padding-bottom:4px;-webkit-overflow-scrolling:touch}
.adtabs::-webkit-scrollbar{height:0}
.adtab{flex:0 0 auto;padding:9px 14px;border-radius:11px;font-size:13px;font-weight:700;color:var(--txt2);background:var(--glass);border:1px solid var(--line);white-space:nowrap;transition:.2s}
.adtab i{margin-right:6px;font-size:12px;opacity:.85}
.adtab:hover{color:var(--txt);border-color:var(--line2)}
.adtab.active{color:#0a0a14;background:var(--grad);border-color:transparent;box-shadow:0 0 20px var(--glow-v)}
.adtab.active i{opacity:1}
.adpanel{display:none}
.adpanel.active{display:block}
.adpanel .btn{margin-top:10px}
.adpanel .admin-sec:first-child{margin-top:2px}

/* ░░ Admin: home-cards manager ░░ */
.hc-admin-list{margin-top:14px;display:flex;flex-direction:column;gap:8px}
.hc-admin-row{display:flex;align-items:center;gap:12px;padding:10px 12px;border-radius:13px;background:var(--glass);border:1px solid var(--line)}
.hc-admin-row.off{opacity:.5}
.hcar-ic{flex:0 0 auto;width:38px;height:38px;border-radius:10px;display:grid;place-items:center;color:#fff;background:linear-gradient(135deg,rgba(139,92,246,.45),rgba(34,211,238,.3));font-size:15px}
.hcar-main{flex:1;min-width:0}
.hcar-title{font-weight:700;font-size:14px;color:var(--txt);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.hcar-sub{font-size:11.5px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:1px}
.hcar-kind{text-transform:capitalize;color:var(--cyan);font-weight:600}
.hcar-actions{flex:0 0 auto;display:flex;gap:4px}
.iconbtn{width:32px;height:32px;border-radius:9px;display:grid;place-items:center;color:var(--txt2);background:rgba(255,255,255,.05);border:1px solid var(--line);font-size:12px;transition:.18s}
.iconbtn:hover{color:var(--txt);border-color:var(--line2);background:var(--glass2)}
.iconbtn:disabled{opacity:.3;pointer-events:none}
.iconbtn.danger:hover{color:#fb7185;border-color:rgba(251,113,133,.4)}
.hc-editor{margin-top:14px}
.hc-form{background:var(--glass);border:1px solid var(--line2);border-radius:16px;padding:16px}
.hcf-head{font-weight:800;font-size:16px;color:var(--txt);margin-bottom:14px}
.field .opt{color:var(--muted);font-weight:400;font-size:11px}
.field select{width:100%;padding:13px 15px;border-radius:13px;background:rgba(255,255,255,.06);border:1px solid var(--line);color:var(--txt);font-size:15px;outline:none}
.field select:focus{border-color:rgba(34,211,238,.6);box-shadow:0 0 0 3px rgba(34,211,238,.16)}
.field select option{color:#111}
.hc-target{position:relative}
#hcfTarget.hc-has-caret{padding-right:36px;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='%237b7595' stroke-width='2'><path d='M4 6l4 4 4-4'/></svg>");background-repeat:no-repeat;background-position:right 13px center;background-size:13px}
.hc-lookup{position:absolute;left:0;right:0;top:100%;margin-top:4px;z-index:20;max-height:240px;overflow-y:auto;background:#100d1f;border:1px solid var(--line2);border-radius:12px;box-shadow:0 18px 40px rgba(0,0,0,.55)}
.hc-lk{display:block;width:100%;text-align:left;padding:11px 14px;font-size:14px;color:var(--txt);border-bottom:1px solid var(--line);transition:.15s}
.hc-lk:last-child{border-bottom:0}
.hc-lk:hover{background:var(--glass2);color:#fff}
.hc-lk small{color:var(--muted);font-size:12px;margin-left:6px}
.hc-lk.none{color:var(--muted);cursor:default}

/* ══════ OLED LOCKSCREEN (pure-black now-playing overlay for AMOLED battery saving) ══════
   Background is true #000 so those pixels switch OFF entirely on OLED panels. Everything is monochrome
   grey — the album art is the only colour — and there are NO glow/pulse animations (they'd keep pixels
   lit). The look still reads premium: art floating on black, a thin lockscreen clock, hairline progress. */
.oled{position:fixed;inset:0;z-index:65;background:#000;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:clamp(16px,3.6vh,34px);padding:calc(env(safe-area-inset-top) + 46px) 24px calc(env(safe-area-inset-bottom) + 28px);
  color:#8a8a8a;-webkit-tap-highlight-color:transparent;user-select:none;-webkit-user-select:none;
  touch-action:none;overscroll-behavior:none;will-change:transform}
.oled,.oled *{touch-action:none}   /* JS owns all overlay gestures (swipe-down dismiss + art swipe) — no native scroll fighting it */
.oled[hidden]{display:none}
.oled-x{position:absolute;top:calc(env(safe-area-inset-top) + 12px);left:50%;transform:translateX(-50%);
  background:none;border:none;color:#4a4a4a;font-size:19px;padding:10px 22px;cursor:pointer}
.oled-x:active{color:#9a9a9a}
.oled-clock{font:300 clamp(38px,11vw,60px)/1 'Sora','Vazirmatn',sans-serif;color:#d0d0d0;letter-spacing:2px;font-variant-numeric:tabular-nums}
.oled-artwrap{position:relative;width:min(60vw,40vh,320px);aspect-ratio:1;border-radius:20px;overflow:hidden;box-shadow:0 0 0 1px rgba(255,255,255,.05)}
.oled-art{width:100%;height:100%;object-fit:cover;filter:brightness(.9);-webkit-user-drag:none;user-select:none;-webkit-user-select:none}
.oled-meta{text-align:center;max-width:82vw}
.oled-title{font:700 clamp(18px,5vw,25px)/1.25 'Sora','Vazirmatn',sans-serif;color:#e6e6e6;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.oled-artist{margin-top:6px;font-size:clamp(13px,3.6vw,16px);color:#787878}
/* Romanised title under the Persian one on the nightstand. Dimmer than anywhere else on purpose —
   this screen is meant to be readable in a dark room without lighting it up. */
.oled-sub{margin-top:3px;font-size:clamp(11px,2.9vw,13px);color:#5a5a5a;font-weight:600}
.oled-seek{width:min(82vw,360px)}
/* Nightstand mode gets used on a dock/in a car, so the scrubber is sized to be hit at a glance without
   aiming: a thick bar plus a tall transparent grab area around it. touch-action:none keeps the browser
   from claiming the drag for panning, which would swallow the scrub gesture. */
.oled-barhit{padding:15px 0;touch-action:none;cursor:pointer}
.oled-bar{height:12px;border-radius:99px;background:#141414;position:relative}
.oled-fill{height:100%;width:0;border-radius:99px;background:rgba(34,211,238,.5);position:relative}   /* dim cyan: a hint of brand, few lit pixels */
/* Knob only while scrubbing — keeps the idle nightstand as dark as possible, then gives a clear
   handle the moment a finger is down. */
.oled-bar.scrub .oled-fill{background:rgba(34,211,238,.9)}
.oled-bar.scrub .oled-fill::after{content:'';position:absolute;right:0;top:50%;transform:translate(50%,-50%);
  width:26px;height:26px;border-radius:50%;background:#22d3ee;box-shadow:0 0 0 4px rgba(0,0,0,.6)}
.oled-times{display:flex;justify-content:space-between;margin-top:9px;font-size:11px;color:#555;font-variant-numeric:tabular-nums}
.oled-ctrls{display:flex;align-items:center;gap:clamp(26px,9vw,46px)}
.oled-ctrls button{background:none;border:none;color:#c8c8c8;font-size:21px;padding:10px;cursor:pointer;transition:transform .12s}
.oled-ctrls button:active{transform:scale(.88)}
.oled-ctrls .oled-play{width:66px;height:66px;border-radius:50%;border:1.5px solid #333;color:#e9e9e9;font-size:23px;display:grid;place-items:center}
/* OLED action rail (like / add-to-playlist / download) — mirrors the main rail's state via JS */

/* ── LISTENING ROOMS ─────────────────────────────────────────────────────
   Full-screen overlay, same z-index family as the OLED lockscreen. Member chips -> now-playing
   stage -> queue, top to bottom; the transport row only appears for whoever currently holds control. */
.room-ov{position:fixed;inset:0;z-index:64;background:linear-gradient(180deg,var(--bg2),var(--bg));
  display:flex;flex-direction:column;overflow:hidden}
.room-top{display:flex;align-items:center;gap:10px;padding:16px 16px 10px}
.room-x{background:none;border:none;color:var(--txt2);font-size:18px;padding:8px;cursor:pointer;line-height:1}
.room-top-name{flex:1;font-weight:800;font-size:15px;color:var(--txt);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.room-invite{background:var(--glass);border:1px solid var(--line);color:var(--txt2);width:36px;height:36px;
  border-radius:50%;display:grid;place-items:center;cursor:pointer;font-size:14px}
.room-invite:hover{color:var(--txt);border-color:var(--line2)}

.room-members{display:flex;gap:8px;flex-wrap:wrap;padding:0 16px 14px;overflow-x:auto}
.room-chip{display:inline-flex;align-items:center;gap:5px;padding:6px 12px;border-radius:999px;
  background:var(--glass);border:1px solid var(--line);font-size:12.5px;font-weight:600;color:var(--txt2);white-space:nowrap}
.room-chip i{color:#f5c344;font-size:11px}
.room-chip.off{opacity:.4}

.room-stage{flex:1 1 auto;min-height:0;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:6px;padding:10px 24px;text-align:center}
.room-art-wrap{width:min(56vw,46vh,300px);aspect-ratio:1;border-radius:20px;overflow:hidden;
  background:var(--glass);box-shadow:0 20px 60px rgba(0,0,0,.5);margin-bottom:14px}
.room-art{width:100%;height:100%;object-fit:cover;display:block}
.room-title{font-weight:800;font-size:19px;color:var(--txt);max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.room-artist{font-size:14px;color:var(--txt2);margin-top:2px}
.room-sync{display:inline-flex;align-items:center;gap:6px;margin-top:12px;font-size:11.5px;
  font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}
.room-sync i{font-size:7px;color:var(--muted)}
.room-sync.live i{color:#34d399}
.room-sync.live{color:#34d399}
.room-transport{display:flex;align-items:center;gap:18px;margin-top:18px}
.room-tbtn{width:52px;height:52px;border-radius:50%;background:var(--grad);border:none;color:#fff;
  font-size:18px;display:grid;place-items:center;cursor:pointer;box-shadow:0 10px 26px var(--glow-v)}
.room-tbtn:active{transform:scale(.94)}
#roomSkipBtn{width:44px;height:44px;background:var(--glass);box-shadow:none;border:1px solid var(--line2);font-size:15px}

.room-queue-wrap{flex:0 0 auto;max-height:38vh;display:flex;flex-direction:column;
  border-top:1px solid var(--line);background:rgba(0,0,0,.18)}
.room-queue-head{display:flex;align-items:center;justify-content:space-between;padding:12px 16px 8px;
  font-size:12px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}
.room-add-btn{display:inline-flex;align-items:center;gap:6px;background:var(--glass);border:1px solid var(--line2);
  color:var(--txt);font-size:12.5px;font-weight:700;padding:7px 12px;border-radius:999px;cursor:pointer}
.room-queue-list{flex:1;min-height:0;overflow-y:auto;padding:0 16px 14px;display:flex;flex-direction:column;gap:2px}
.room-q-row{display:flex;align-items:center;gap:10px;padding:9px 6px;border-radius:10px}
.room-q-row.playing{background:var(--glass)}
.room-q-row.playing .rqr-t{color:#22d3ee}
.room-q-row.played{opacity:.4}
.rqr-n{width:18px;flex:0 0 auto;font-size:11px;color:var(--muted);text-align:center}
.rqr-t{flex:1;min-width:0;font-size:13.5px;font-weight:600;color:var(--txt);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rqr-a{flex:0 0 auto;max-width:30%;font-size:12px;color:var(--txt2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rqr-play{background:none;border:none;color:var(--txt2);font-size:13px;padding:6px;cursor:pointer;flex:0 0 auto}
.rqr-play:hover{color:var(--txt)}

.room-add-results{display:flex;flex-direction:column;gap:2px;max-height:50vh;overflow-y:auto;margin-top:10px}
.room-add-row{display:flex;align-items:center;gap:10px;width:100%;padding:8px 6px;border-radius:10px;
  background:none;border:none;cursor:pointer;text-align:left}
.room-add-row:hover{background:var(--glass)}
.room-add-row img{width:36px;height:36px;border-radius:7px;object-fit:cover;flex:0 0 auto}
.room-add-row .ct{flex:1;min-width:0;font-size:13.5px;font-weight:600;color:var(--txt);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.room-add-row .cs{flex:0 0 auto;max-width:34%;font-size:11.5px;color:var(--txt2);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.room-hub-row{display:flex;align-items:center;gap:10px;width:100%;padding:11px 10px;border-radius:12px;
  background:var(--glass);border:1px solid var(--line);cursor:pointer;text-align:left;margin-bottom:8px}
.room-hub-row:hover{border-color:var(--line2)}
.room-hub-row i.fa-users-line,.room-hub-row .rh-ic{width:34px;height:34px;border-radius:50%;background:var(--grad);
  display:grid;place-items:center;color:#fff;font-size:13px;flex:0 0 auto}
.room-hub-row .rh-name{flex:1;min-width:0;font-size:14px;font-weight:700;color:var(--txt);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.room-hub-row .rh-sub{font-size:11.5px;color:var(--txt2)}
.oled-actions{display:flex;align-items:center;justify-content:center;flex-wrap:wrap;
  gap:clamp(10px,5vw,46px);margin-top:2px;padding:0 10px;max-width:100%}
/* The 12vw gap was sized for the four buttons this row had; the lyrics button made six, and
   six at that spacing ran off both edges of a phone. Wrapping is the backstop for a seventh. */
/* Nightstand lyrics: the artwork's slot, but sized for reading rather than for a square. No panel
   chrome — no border, no blur, no glow — because this screen exists to stay dark, and every line is
   held below pure white for the same reason. */
.oled-lyr{display:none;flex-direction:column;width:min(88vw,540px);height:min(48vh,380px);min-height:0}
body.oled-lyr-on .oled-lyr{display:flex}
body.oled-lyr-on .oled-artwrap{display:none}
.oled-lyr .lyr-body{padding:38% 14px}
.oled-lyr .lyr-line{color:rgba(255,255,255,.3);font-size:16px}
.oled-lyr .lyr-line:hover{color:rgba(255,255,255,.55)}
.oled-lyr .lyr-line.done{color:rgba(255,255,255,.16)}
.oled-lyr .lyr-line.on{color:rgba(255,255,255,.93);font-size:18px;text-shadow:none}
.oled-lyr .lyr-line.plainline,.oled-lyr .lyr-line.plainline:hover{color:rgba(255,255,255,.55)}
.oled-lyr .lyr-note{color:rgba(255,255,255,.4)}
.oled-lyr .lyr-foot{border-top:1px solid rgba(255,255,255,.07);color:rgba(255,255,255,.22)}
.oled-act.on{color:#fff;opacity:1}
.oled-act{background:none;border:none;color:#8a8a8a;font-size:20px;padding:8px;cursor:pointer;transition:transform .12s,color .2s;line-height:1;display:grid;place-items:center}
.oled-act:active{transform:scale(.85)}
.oled-act.on{color:#ff5d8f}          /* liked */
.oled-act.saved{color:var(--cyan)}   /* already in a playlist */
.oled-act.done{color:var(--cyan)}    /* downloaded for offline */
.oled-act .dl-pct{width:20px;height:20px;border-radius:50%;background:#151515;display:grid;place-items:center;font-size:9px;font-weight:800;color:#ddd}
/* under the opaque overlay: stop the ambient wash / grain / art-glow so they don't burn CPU while hidden */
body.oled-on .ambient,body.oled-on .grain{display:none}
body.oled-on .art-glow{animation:none}
/* Nightstand: the black overlay covers everything, so stop ALL animation/blur/GPU work on the app
   underneath — keeps low-end devices smooth. #oled overlay is a sibling of .app, so it's untouched. */
body.oled-on .app,body.oled-on .app *{animation:none!important;transition:none!important;backdrop-filter:none!important;-webkit-backdrop-filter:none!important;will-change:auto!important}

/* seek bar: let the browser hand drag gestures to us instead of scrolling */
#seekTrack{touch-action:none}
#seekTrack *{pointer-events:none}

.confirm-btns{display:flex;gap:10px;margin-top:16px}
.confirm-btns .btn{flex:1}

.mini-x{color:var(--muted)}
.mini-x:hover{color:#fb7185}

/* --- swipe-to-dismiss: mini collapses to a resume square --- */
.mini.collapsed{width:62px;padding:8px;gap:0;justify-content:center;cursor:pointer}
.mini.collapsed.collapse-right{left:auto;right:10px}
.mini.collapsed .mini-prog,.mini.collapsed .mini-meta,.mini.collapsed .mini-btn{display:none}
.mini-resume{position:absolute;left:0;top:0;width:100%;height:100%;display:none;align-items:center;justify-content:center;color:#fff;font-size:18px;background:rgba(0,0,0,.42);border-radius:16px;z-index:3}
.mini.collapsed .mini-resume{display:flex;animation:miniResumePulse 2.2s ease-in-out infinite}
@keyframes miniResumePulse{0%,100%{box-shadow:inset 0 0 0 0 rgba(255,255,255,0)}50%{box-shadow:inset 0 0 0 2px rgba(255,255,255,.28)}}
.mini-title.marquee{text-overflow:clip}
.mini-title.marquee .mini-title-in{display:inline-block;animation:raMarq var(--marq-dur,8s) ease-in-out infinite alternate}
/* --- storage: stacked device bar with downloads highlighted --- */
.sb-track.sb-stack{display:flex}
.sb-seg{height:100%}
.sb-seg.sb-other{background:rgba(255,255,255,.16)}
.sb-seg.sb-dl{background:var(--grad);box-shadow:0 0 10px var(--glow-v)}
.sb-legend{display:flex;flex-wrap:wrap;gap:12px;margin-top:8px;font-size:11px;color:var(--muted)}
.sb-lg{display:inline-flex;align-items:center;gap:5px}
.sb-dot{width:9px;height:9px;border-radius:3px;display:inline-block}
.sb-dot.dot-dl{background:var(--grad)}
.sb-dot.dot-other{background:rgba(255,255,255,.16)}
.sb-dot.dot-free{background:transparent;border:1px solid var(--line2)}

/* --- admin: user management --- */
.ad-user-list{display:flex;flex-direction:column;gap:8px}
.ad-user{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;padding:11px 13px;border:1px solid var(--line2);border-radius:14px;background:rgba(255,255,255,.03)}
.au-main{display:flex;align-items:center;gap:11px;min-width:0;flex:1 1 220px}
.au-avatar{width:38px;height:38px;flex:none;border-radius:50%;display:grid;place-items:center;font-weight:700;color:#fff;background:var(--grad)}
.au-tx{min-width:0}
.au-tx b{font-size:14px}
.au-tx small{display:block;color:var(--muted);font-size:11.5px;margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.au-you{font-size:9.5px;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);border:1px solid var(--line2);border-radius:6px;padding:1px 5px;vertical-align:middle}
.au-badge{display:inline-flex;align-items:center;gap:4px;font-size:10.5px;font-weight:600;padding:2px 7px;border-radius:20px;margin-left:5px;vertical-align:middle}
.au-badge.admin{background:rgba(139,92,246,.18);color:#c4b5fd}
.au-badge.ok{background:rgba(34,197,94,.15);color:#4ade80}
.au-badge.warn{background:rgba(245,158,11,.15);color:#fbbf24}
.au-ac{display:flex;align-items:center;gap:6px;flex-wrap:wrap;justify-content:flex-end}
.au-ac .chip[disabled]{opacity:.4;pointer-events:none}

/* mini swipe: reserve only the vertical axis for the browser so horizontal drags follow the finger */
.mini,.mini *{touch-action:pan-y;-webkit-user-select:none;user-select:none}

/* --- admin users: select + edit --- */
.ad-user.selected{border-color:#8b5cf6;background:rgba(139,92,246,.10)}
.au-check{width:26px;height:26px;flex:none;border-radius:50%;border:2px solid var(--line2);background:transparent;color:transparent;display:grid;place-items:center;font-size:11px;cursor:pointer;transition:.15s}
.ad-user.selected .au-check{background:var(--grad);border-color:transparent;color:#fff}
.au-edit{flex:none}
.au-bulk{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;margin:0 0 12px;padding:10px 12px;border-radius:12px;background:rgba(139,92,246,.12);border:1px solid var(--line2)}
.aub-count{font-weight:700;font-size:13px}
.aub-ac{display:flex;gap:6px;flex-wrap:wrap}

/* native app: drop continuously-recompositing effects to save battery/heat (PWA keeps them) */
body.native .art-glow{animation:none}
body.native .hero-empty-art{animation:none}

/* delete-tab results: artwork beside each match */
.del-item{display:flex;align-items:center;gap:11px;text-align:left}
.yti-art{width:42px;height:42px;border-radius:8px;object-fit:cover;flex:none;background:var(--line2)}
.yti-art.round{border-radius:50%}
.del-item .yti-tx{display:flex;flex-direction:column;min-width:0}
.del-item .yti-n,.del-item .yti-s{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}

/* admin Library tab: group each tool in its own card */
.lib-card{border:1px solid var(--line2);border-radius:16px;padding:14px 16px 16px;margin-bottom:16px;background:rgba(255,255,255,.02)}
.lib-card>.admin-sec:first-child{margin-top:0}
.lib-card.danger-card{border-color:rgba(251,113,133,.35)}
.lib-card.danger-card>.admin-sec{color:#fb7185}

/* collapsed square captures vertical gestures (swipe up = clear); full bar keeps pan-y */
.mini.collapsed,.mini.collapsed *{touch-action:none}
/* gesture hint pill — tells the user exactly what the swipe will do */
.swipe-hint{position:fixed;left:50%;transform:translateX(-50%);bottom:calc(var(--dock-h) + 84px);z-index:60;padding:8px 15px;border-radius:999px;background:rgba(20,16,34,.96);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border:1px solid var(--line2);color:var(--muted);font-size:12.5px;font-weight:700;opacity:0;pointer-events:none;transition:opacity .15s;white-space:nowrap}
.swipe-hint.show{opacity:1}
.swipe-hint.armed{color:#fff;border-color:#8b5cf6;background:rgba(139,92,246,.35)}
.swipe-hint.danger.armed{border-color:#fb7185;background:rgba(251,113,133,.4)}
/* Floating X target for the clear-queue drag; fills red as the square is lifted */
.mini-clear-x{position:fixed;left:50%;bottom:calc(var(--dock-h) + 96px);transform:translateX(-50%) scale(1);z-index:60;width:64px;height:64px;border-radius:50%;display:grid;place-items:center;font-size:30px;color:#fff;background:rgba(20,16,34,.92);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);border:2px solid var(--line2);opacity:0;pointer-events:none;transition:opacity .16s,box-shadow .16s,transform .06s;overflow:visible}
.mini-clear-x::before{content:"";position:absolute;inset:-2px;border-radius:50%;background:rgba(251,113,133,.55);border:2px solid #fb7185;opacity:var(--xp,0);transition:opacity .08s}
.mini-clear-x i{position:relative;z-index:1}
.mini-clear-x.show{opacity:1}
.mini-clear-x.armed{box-shadow:0 0 26px rgba(251,113,133,.6)}

/* delete/rename search results — standard list rows (thumb + name/artist) */
.cg-list{display:flex;flex-direction:column;gap:8px;margin-top:8px}
.cg-item{display:flex;flex-direction:row;align-items:center;gap:12px;width:100%;padding:8px 11px;border:1px solid var(--line2);border-radius:12px;background:rgba(255,255,255,.02);cursor:pointer;text-align:left;transition:border-color .15s,background .15s}
.cg-item:hover{border-color:#8b5cf6;background:rgba(139,92,246,.08)}
.cg-thumb{width:46px;height:46px;flex:none;object-fit:cover;border-radius:9px;background:var(--line2)}
.cg-thumb.round{border-radius:50%}
.cg-tx{display:flex;flex-direction:column;min-width:0;flex:1}
.cg-n{font-size:13.5px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}
.cg-s{font-size:11.5px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%;margin-top:1px}

/* in-app update prompt */
.upd-prog{margin:12px 0}
.upd-bar{height:7px;border-radius:5px;background:rgba(255,255,255,.12);overflow:hidden}
.upd-fill{height:100%;width:0;border-radius:5px;background:var(--grad);box-shadow:0 0 12px var(--glow-v);transition:width .2s}
.upd-msg{font-size:12px;color:var(--muted);margin-top:7px}

/* Android-app download promo (shown to Android web users) */
.app-promo{display:flex;align-items:center;gap:14px;padding:13px 15px;margin:0 0 16px;border-radius:16px;background:linear-gradient(135deg,rgba(99,102,241,.16),rgba(45,212,191,.10));border:1px solid var(--line2)}
.ap-logo{width:48px;height:48px;flex:none;border-radius:12px;object-fit:cover}
.ap-tx{flex:1;min-width:0}
.ap-ttl{font-weight:700;font-size:14.5px;flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ap-sub{font-size:12px;color:var(--muted);margin-top:2px;line-height:1.35}
.ap-btn{flex:none;display:inline-flex;align-items:center;gap:7px;padding:10px 16px;border-radius:11px;background:var(--grad);color:#0a0a14;font-weight:700;font-size:13px;text-decoration:none;white-space:nowrap}
.ap-btn:active{transform:scale(.97)}
@media(max-width:560px){.app-promo{flex-wrap:wrap}.ap-tx{flex:1 1 60%}.ap-btn{width:100%;justify-content:center;margin-top:2px}}
/* phone: force 2-up home/genre cards — placed AFTER the base .home-cards/.genre-grid rules so it actually wins (media queries add no specificity; equal-specificity later rule wins) */
@media(max-width:560px){.home-cards{grid-template-columns:var(--hc-cols-m,repeat(2,1fr))}.genre-grid{grid-template-columns:repeat(2,1fr)}}
.hc-cols-ctrl{border:1px solid var(--line);background:var(--glass);border-radius:14px;padding:12px 14px;margin:0 0 14px}
.hc-cols-ctrl .hcc-title{font-weight:700;font-size:13px;margin-bottom:9px;display:flex;align-items:center;gap:7px;color:#fff}
.hc-cols-ctrl .hcc-row{display:flex;flex-wrap:wrap;align-items:center;gap:12px}
.hc-cols-ctrl label{font-size:12.5px;color:rgba(255,255,255,.72);display:flex;align-items:center;gap:6px}
.hc-cols-ctrl select{background:#1c1830;color:#fff;border:1px solid var(--line2);border-radius:9px;padding:5px 8px;font-size:13px}
.hc-cols-ctrl select option{background:#1c1830;color:#fff}
/* ── Equalizer popover ── */
.eq-pop{width:min(340px,88vw);padding:16px}
.eq-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:12px}
.eq-head .pop-title{margin:0}
.eq-switch{position:relative;display:inline-block;width:42px;height:24px;flex:0 0 auto}
.eq-switch input{opacity:0;width:0;height:0}
.eq-sw{position:absolute;inset:0;background:rgba(255,255,255,.16);border-radius:999px;transition:.2s;cursor:pointer}
.eq-sw::before{content:"";position:absolute;height:18px;width:18px;left:3px;top:3px;background:#fff;border-radius:50%;transition:.2s}
.eq-switch input:checked+.eq-sw{background:#22d3ee}
.eq-switch input:checked+.eq-sw::before{transform:translateX(18px)}
.eq-presets{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:16px}
.eq-chip{font-size:12px;padding:5px 11px;border-radius:999px;border:1px solid var(--line2);background:rgba(255,255,255,.05);color:#fff;cursor:pointer;transition:.15s}
.eq-chip.active{background:#22d3ee;color:#06121a;border-color:#22d3ee;font-weight:700}
.eq-bands{display:flex;justify-content:space-between;gap:4px;padding-top:2px}
.eq-band{display:flex;flex-direction:column;align-items:center;gap:8px;flex:1}
.eq-range{writing-mode:vertical-lr;direction:rtl;width:22px;height:120px;accent-color:#22d3ee;cursor:pointer}
.eq-val{font-size:11px;color:#22d3ee;min-height:13px;font-variant-numeric:tabular-nums}
.eq-flabel{font-size:10px;color:rgba(255,255,255,.5)}
body.eq-on #eqBtn{color:#22d3ee}
.hc-cols-ctrl #hccSave{margin-left:auto}

/* trim-artist preview */
.trim-list{max-height:320px;overflow-y:auto;margin:12px 0;display:flex;flex-direction:column;gap:6px;border:1px solid var(--line2);border-radius:12px;padding:10px}
.trim-row{display:flex;align-items:center;gap:9px;font-size:12.5px}
.trim-row i{color:var(--muted);font-size:11px;flex:none}
.trim-old{color:var(--muted);text-decoration:line-through;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}
.trim-new{color:var(--txt);font-weight:600;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}
.trim-more{color:var(--muted);font-size:11.5px;padding-top:5px;text-align:center}

/* trim scan — affected-artist list */
.trim-scan-list{display:flex;flex-direction:column;gap:7px;margin-top:10px}
.trim-scan-row{display:flex;align-items:center;gap:11px;width:100%;padding:8px 11px;border:1px solid var(--line2);border-radius:11px;background:rgba(255,255,255,.02);cursor:pointer;text-align:left;transition:border-color .15s,background .15s}
.trim-scan-row:hover{border-color:#8b5cf6;background:rgba(139,92,246,.08)}
.ts-art{width:38px;height:38px;flex:none;border-radius:50%;object-fit:cover;background:var(--line2)}
.ts-name{flex:1;min-width:0;font-weight:600;font-size:13.5px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ts-count{flex:none;font-size:11.5px;font-weight:700;color:#0a0a14;background:var(--grad);border-radius:20px;padding:3px 10px}

/* ==== BETA: desktop 3-column layout (opt-in via ?lay3=1). Revertible: delete this block + the nava_lay3 flag at top of avify.js. ==== */
@media(min-width:1024px){
  body.lay3 .app{height:100%;overflow:hidden;grid-template-columns:240px minmax(0,1fr) clamp(340px,27vw,440px);grid-template-rows:minmax(0,1fr);grid-template-areas:"nav content now"}
  body.lay3 .topbar,body.lay3 .browse,body.lay3 .stage{min-height:0;max-height:100%}
  body.lay3 .browse{grid-template-rows:auto minmax(0,1fr) auto}
  body.lay3 .browse-body{overflow-y:auto;min-height:0}
  body.lay3 .topbar{grid-area:nav;flex-direction:column;align-items:stretch;justify-content:flex-start;height:100%;padding:18px 14px 16px;gap:8px;border-bottom:none;border-right:1px solid var(--line);overflow-y:auto;background:rgba(10,8,20,.4)}
  body.lay3 .brand{margin:2px 4px 16px}
  body.lay3 .top-nav{flex-direction:column;gap:4px;margin-left:0}
  body.lay3 .top-link{justify-content:flex-start;width:100%;padding:11px 14px}
  body.lay3 .top-actions{margin-left:0;margin-top:auto;flex-direction:column;align-items:stretch;gap:8px;padding-top:12px;border-top:1px solid var(--line)}
  body.lay3 .top-actions .ghost-btn{justify-content:flex-start;width:100%}
  body.lay3 .browse{grid-area:content;position:relative;inset:auto;height:100%;width:auto;max-width:none;transform:none!important;box-shadow:none;border-left:none;border-radius:0;background:transparent;-webkit-backdrop-filter:none;backdrop-filter:none;padding-top:0}
  body.lay3 .browse-head{padding-inline:24px}
  body.lay3 .browse-body{padding-inline:24px}
  body.lay3 #browseClose{display:none}
  body.lay3 .scrim,body.lay3 #browseHandle{display:none!important}
  body.lay3 .stage{grid-area:now;border-left:1px solid var(--line);padding:22px 20px;overflow-y:auto;background:rgba(10,8,20,.25)}
  body.lay3 .hero{max-width:none;justify-content:flex-start;gap:16px}
  body.lay3 .hero-now{grid-template-columns:1fr;gap:16px;text-align:center;align-items:stretch}
  /* Two rails in a column would stack as two rows with the art between them, so the stage wraps
     instead: the art takes a full line and both rails land side by side on the next one, which is
     what the single row looked like before the split. */
  body.lay3 .art-stage{flex-direction:row;flex-wrap:wrap;justify-content:center;gap:12px}
  body.lay3 .art-wrap,body.lay3 .lyr-stage{flex:0 0 100%;order:1}
  /* Keep/like first in the panel row, as it was before the split — only the fullscreen and phone
     layouts actually put one group on each side. */
  body.lay3 .art-actions-r{order:2}
  body.lay3 .art-actions-l{order:3}
  body.lay3 .art-wrap,body.lay3 .lyr-stage{max-width:260px;margin:0 auto;width:100%}
  /* Here the rail is a horizontal row under the art, so its width is capped by the now-playing
     column (clamp(340px,27vw,440px) → ~332px of usable space). At the base 46px it needed 336px for
     six buttons and 394px for seven, so the row ran off the edge the moment another action was added.
     Sized to fit seven in 328px, and allowed to wrap so an eighth degrades onto a second line instead
     of overflowing again. */
  /* nowrap on purpose: with wrapping allowed the browser breaks the row BEFORE it shrinks anything,
     which put a lone button on a second line. Shrinking is what we actually want here. */
  /* width:100% + min-width:0 is what actually makes the shrinking work: the rail inherits flex:0 0 auto
     from the base rule, so without being tied to the column it just took its content width and hung off
     the panel edge — and its children were never asked to give any ground. */
  body.lay3 .art-actions{flex-direction:row;justify-content:center;flex-wrap:nowrap;gap:8px;width:auto;min-width:0}
  /* Let the buttons shrink to fit instead of pinning a size to today's button count: they start at the
     normal 46px and only give ground when the row would overflow, down to a still-tappable 32px. That
     keeps one tidy row whatever the column width, and keeps working if another action is added later. */
  body.lay3 .art-actions .act-btn,body.lay3 .art-actions .dl-btn{
    flex:0 1 46px;width:auto;height:auto;aspect-ratio:1;min-width:32px;font-size:16px}
  /* #playerDl is deliberately a little smaller than its neighbours AND sets its size with an ID, which
     outranks the rule above. Letting that rule widen it while the ID kept height:42px is what made it
     render as an oval — so its shrink behaviour is restated here at its own intended size. */
  /* align-self:center matters: the rail is a flex ROW, so with height:auto this button would otherwise
     stretch to the line height set by its taller neighbours and come out 42 wide by 46 tall. */
  body.lay3 .art-actions #playerDl{flex:0 1 42px;width:auto;height:auto;aspect-ratio:1;min-width:30px;align-self:center}
  body.lay3 .art-actions .act-btn{align-self:center}
  body.lay3 .now-meta{text-align:center}
  /* The base gap is clamp(10px,2vw,22px) — sized against the VIEWPORT. In this layout the transport
     sits inside a ~340px panel, so on a wide screen the row was spaced for a width it does not have:
     the buttons overflowed, flex shrank their WIDTH while their fixed height stayed, and the play
     button rendered as an oval. A panel-appropriate gap plus aspect-ratio keeps every button round
     however much it still has to give. */
  body.lay3 .transport{justify-content:center;gap:clamp(6px,1vw,14px)}
  body.lay3 .t-btn{height:auto;aspect-ratio:1;min-width:38px}
  body.lay3 .t-btn.play{height:auto;aspect-ratio:1;min-width:54px}
  body.lay3 .sub-controls{justify-content:center;flex-wrap:wrap}
  body.lay3 .now-title{font-size:22px}
  body.lay3 .mini{display:none!important}
}

@media(min-width:1024px){
  /* sidebar footer actions: compact icon row pinned to bottom */
  body.lay3 .top-actions{flex-direction:row;flex-wrap:wrap;align-items:center;gap:6px}
  body.lay3 .top-actions .ghost-btn{width:auto;justify-content:center;padding:9px 11px}
  body.lay3 #qualityBtn,body.lay3 #authBtn{flex:1 1 100%;justify-content:flex-start}
  /* idle now-playing column: centered placeholder */
  body.lay3 .stage{justify-content:center}
  body.lay3 .hero-empty{margin:auto;padding:24px;text-align:center}
  body.lay3 .hero-empty-art{width:96px;height:96px;font-size:38px}
}

@media(min-width:1024px){
  /* home content adapts like library/other grids (ignore the fixed --hc-cols-d in the wider centre column) */
  body.lay3 .home-cards{grid-template-columns:repeat(auto-fill,minmax(160px,1fr))}
}

/* ==== lay3 extras: queue-as-modal + full-page now-playing (Task1/Task2) ==== */
@media(min-width:1024px){
  /* Task 1: desktop queue = centered modal (over a scrim) instead of a side drawer */
  body.lay3 .queue-panel{position:fixed;top:50%;left:50%;right:auto;height:auto;max-height:78vh;width:min(540px,92vw);border-radius:20px;border:1px solid var(--line2);box-shadow:0 30px 90px rgba(0,0,0,.6);background:linear-gradient(180deg,rgba(20,16,40,.98),rgba(11,8,22,.99));-webkit-backdrop-filter:blur(30px) saturate(150%);backdrop-filter:blur(30px) saturate(150%);display:flex;flex-direction:column;transform:translate(-50%,-46%) scale(.97);opacity:0;pointer-events:none;transition:opacity .2s,transform .2s}
  body.lay3 .queue-panel.open{transform:translate(-50%,-50%) scale(1);opacity:1;pointer-events:auto}
  body.lay3 .qp-list{flex:1;min-height:0}
  body.lay3.queue-open .scrim{display:block!important}
  /* Task 2: fullscreen button = immersive full-page now-playing overlay (pre-C look) */
  body.lay3.np-full .stage{position:fixed;inset:0;z-index:60;width:auto;max-height:none;border-left:none;overflow-y:auto;padding:clamp(20px,4vw,52px);background:linear-gradient(180deg,#0e0a20,#070510);justify-content:center}
  body.lay3.np-full .hero{max-width:1100px;justify-content:center;margin:auto;gap:clamp(14px,2vw,24px)}
  body.lay3.np-full .hero-now{grid-template-columns:auto minmax(0,1fr);gap:clamp(24px,4vw,56px);text-align:left;align-items:center}
  body.lay3.np-full .art-stage{flex-direction:row;flex-wrap:nowrap;gap:16px}
  body.lay3.np-full .art-wrap,body.lay3.np-full .lyr-stage{width:min(46vh,440px);max-width:none;margin:0;flex:0 0 auto;order:0}
  body.lay3.np-full .art-actions-l,body.lay3.np-full .art-actions-r{order:0}
  body.lay3.np-full .art-actions{flex-direction:column;width:auto}
  /* The rail is a COLUMN again here, so the lay3 row rules above are upside down: `flex:0 1 46px`
     puts the basis on the HEIGHT and `width:auto` + aspect-ratio then has nothing to resolve
     against, which collapsed the buttons to their 32px min-width. Pin both axes back. */
  body.lay3.np-full .art-actions .act-btn,
  body.lay3.np-full .art-actions .dl-btn,
  body.lay3.np-full .art-actions #playerDl{flex:0 0 auto;width:46px;height:46px;aspect-ratio:auto;min-width:0}
  body.lay3.np-full .now-meta{text-align:left}
  body.lay3.np-full .transport,body.lay3.np-full .sub-controls{justify-content:flex-start}
}
.np-exit{display:none;position:fixed;top:20px;right:24px;z-index:62;width:44px;height:44px;border-radius:50%;place-items:center;background:rgba(20,16,40,.72);border:1px solid var(--line2);color:#fff;font-size:17px;cursor:pointer;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px)}
body.np-full .np-exit{display:grid}

/* ==== lay3: anchor popovers/queue near their buttons + fit the select bar (msg 539) ==== */
@media(min-width:1024px){
  /* Task 2: quality/sleep/eq popovers fly out from their sidebar-footer buttons (bottom-left) */
  body.lay3 .popover{top:auto;right:auto;left:248px;bottom:16px;transform-origin:bottom left}
  /* Task 1: queue opens as a popover beside the now-playing panel, next to the Queue button */
  body.lay3 .queue-panel{top:auto;left:auto;right:calc(clamp(340px,27vw,440px) + 14px);bottom:16px;width:min(380px,30vw);max-height:min(72vh,640px);transform:translateY(10px) scale(.98);transform-origin:bottom right}
  body.lay3 .queue-panel.open{transform:translateY(0) scale(1)}
  body.lay3.queue-open .scrim{display:block!important;background:transparent}
  /* Task 3: multi-select bar fits the content column, sized to content (not screen-wide) */
  body.lay3 .sel-bar{left:240px;right:clamp(340px,27vw,440px);width:fit-content;max-width:calc(100% - 40px);margin-inline:auto;bottom:20px}
}

/* ==== "Show selected" popover (msg 540) ==== */
.sel-count{cursor:pointer;background:none;border:0;color:inherit;font:inherit;display:inline-flex;align-items:center}
.sel-count i{font-size:10px;margin-left:6px;opacity:.7}
.sel-list{position:fixed;z-index:50;background:linear-gradient(180deg,rgba(22,17,42,.98),rgba(12,9,24,.99));border:1px solid var(--line2);border-radius:16px;box-shadow:0 24px 60px rgba(0,0,0,.55);padding:8px;max-height:min(52vh,440px);overflow-y:auto;-webkit-backdrop-filter:blur(24px);backdrop-filter:blur(24px)}
.sel-list[hidden]{display:none}
.sel-list .sl-head{font-size:11px;letter-spacing:1.2px;text-transform:uppercase;color:var(--muted);font-weight:700;padding:6px 8px 8px}
.sel-list .sl-item{display:flex;align-items:center;gap:10px;padding:6px;border-radius:10px}
.sel-list .sl-item:hover{background:var(--glass2)}
.sel-list .sl-item img{width:38px;height:38px;border-radius:8px;object-fit:cover;flex:0 0 auto}
.sel-list .sl-tx{display:flex;flex-direction:column;min-width:0;flex:1}
.sel-list .sl-t{font-size:13px;color:#fff;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sel-list .sl-s{font-size:11px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;text-transform:capitalize}
.sel-list .sl-x{flex:0 0 auto;width:28px;height:28px;border-radius:50%;display:grid;place-items:center;color:#fb7185;background:rgba(251,113,133,.12);border:1px solid rgba(251,113,133,.3);transition:.15s}
.sel-list .sl-x:hover{background:rgba(251,113,133,.25)}

@media(min-width:1024px){
  /* sidebar footer: Install full-width, utility icons row, then Hi-Fi + profile(icon) on one line (msg 552) */
  body.lay3 #installBtn{order:0;flex:1 1 100%}
  body.lay3 #oledBtn,body.lay3 #sleepBtn,body.lay3 #eqBtn,body.lay3 #fsBtn{order:1}
  body.lay3 #qualityBtn{order:2;flex:1 1 auto;justify-content:flex-start}
  body.lay3 #authBtn{order:3;flex:0 0 auto;justify-content:center;width:auto}
  body.lay3 #authBtn .auth-label{display:none}
}

@media(min-width:1024px){
  /* dim the gradient behind the search input so its text is readable (msg 555) */
  body.lay3 .searchbar{background:rgba(9,7,18,.62);border-color:var(--line2);-webkit-backdrop-filter:blur(14px) saturate(150%);backdrop-filter:blur(14px) saturate(150%)}
}

/* artist page: "See all songs" button + back link */
.art-allsongs{margin:8px 0 10px}
.art-allsongs button{width:100%;display:flex;align-items:center;justify-content:center;gap:9px;padding:12px;border-radius:12px;background:var(--glass);border:1px solid var(--line);color:var(--txt);font-weight:600;font-size:14px;transition:.18s}
.art-allsongs button:hover{background:var(--glass2);border-color:var(--line2)}
.art-back{margin-bottom:8px;color:var(--txt2);display:inline-flex;align-items:center;gap:6px}

/* head search shortcut button — hidden on the search page itself (searchbar visible) */
.searchbar:not([hidden]) ~ #headSearchBtn{display:none!important}

/* queue rows are drag-to-reorder anywhere on mouse — hint with a grab cursor */
@media(hover:hover) and (pointer:fine){.qp-list .row{cursor:grab}body.q-dragging .qp-list .row.qdrag{cursor:grabbing}}

/* playlist manual drag-reorder mode */
.plre-bar{display:flex;gap:10px;justify-content:flex-end;margin:6px 0 12px}
.plre-list .plre-row .qgrip{margin-left:auto}
@media(hover:hover) and (pointer:fine){.plre-list .plre-row{cursor:grab}body.q-dragging .plre-list .plre-row.qdrag{cursor:grabbing}}

@media(min-width:1024px){
  body.lay3 .browse.admin-full{position:fixed;inset:0;z-index:52;width:100%;max-width:100%;height:100%;border-radius:0;background:linear-gradient(180deg,rgba(16,12,32,.98),rgba(9,7,18,.99));-webkit-backdrop-filter:blur(30px);backdrop-filter:blur(30px)}
  body.lay3 .browse.admin-full #browseClose{display:grid}
}

/* email-verification gate + grace banner */
.verify-gate{position:fixed;inset:0;z-index:9999;background:rgba(5,4,12,.93);-webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);display:grid;place-items:center;padding:24px}
.verify-gate .vg-card{max-width:430px;width:100%;text-align:center;background:linear-gradient(180deg,rgba(22,17,42,.98),rgba(12,9,24,.99));border:1px solid var(--line2);border-radius:22px;padding:34px 26px;box-shadow:0 30px 90px rgba(0,0,0,.6)}
.verify-gate .vg-ic{font-size:46px;color:var(--violet);margin-bottom:14px}
.verify-gate h2{font-size:22px;margin-bottom:12px;color:#fff}
.verify-gate p{color:var(--txt2);font-size:14px;line-height:1.55;margin-bottom:8px}
.verify-gate .vg-sub{font-size:12.5px;color:var(--muted)}
.verify-gate .vg-btns{display:flex;gap:10px;justify-content:center;margin:20px 0 10px;flex-wrap:wrap}
.verify-gate .vg-logout{background:none;border:0;color:var(--muted);font-size:12.5px;text-decoration:underline;cursor:pointer;margin-top:6px}
.verify-banner{position:fixed;top:0;left:0;right:0;z-index:900;background:linear-gradient(90deg,#8b5cf6,#22d3ee);color:#07060f;font-weight:600;font-size:13px;padding:9px 40px 9px 14px;display:flex;align-items:center;justify-content:center;gap:8px;text-align:center}
.verify-banner .vb-link{background:rgba(0,0,0,.16);border:0;color:#07060f;font-weight:700;padding:3px 11px;border-radius:8px;cursor:pointer}
.verify-banner .vb-x{background:none;border:0;color:#07060f;cursor:pointer;position:absolute;right:10px;font-size:16px;display:grid;place-items:center}


/* == Card-stack album art (React-Bits "Stack" look, vanilla, no deps) ===============
   heroArt/oledArt = top card; .art-peek fan behind it; .art-fly = the thrown card. */
.art-wrap,.oled-artwrap{perspective:1100px}
.oled-artwrap{overflow:visible}
.oled-art{position:relative;z-index:3;border-radius:20px}
.art-peek{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;border-radius:var(--r-lg);
  transform-origin:100% 100%;pointer-events:none;-webkit-user-drag:none;user-select:none;
  will-change:transform,opacity;box-shadow:0 20px 55px rgba(0,0,0,.45);
  transition:transform .42s cubic-bezier(.2,.75,.25,1),opacity .42s}
.oled-artwrap .art-peek{border-radius:20px;filter:brightness(.8)}
.art-peek.p1{z-index:1;transform:rotate(6deg) scale(.965)}
.art-peek.p2{z-index:1;transform:rotate(12deg) scale(.93)}
.art-peek.hide{opacity:0}
.art-fly{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;border-radius:var(--r-lg);
  z-index:5;transform-origin:100% 100%;pointer-events:none;will-change:transform,opacity;
  box-shadow:0 26px 70px rgba(0,0,0,.6)}
.oled-artwrap .art-fly{border-radius:20px}

/* previous-cover peek: hidden at rest, slid in from the left while dragging right (prev cue) */
.art-peek.pv{z-index:2;transform-origin:100% 100%;transform:translateX(-52%) rotate(-10deg) scale(.9);opacity:0}
.art-peek.noprev{display:none}

/* == AnimatedList entrance (React-Bits look, vanilla, no deps): track rows pop in on view ==
   Gated by body.animlist so rows stay fully visible if the JS observer never runs. */
@keyframes avifyRowIn{from{opacity:0;transform:translateY(10px) scale(.92)}to{opacity:1;transform:none}}
body.animlist .srow{opacity:0}
body.animlist .srow.in{animation:avifyRowIn .4s cubic-bezier(.2,.75,.25,1) both}
@media(prefers-reduced-motion:reduce){body.animlist .srow{opacity:1}body.animlist .srow.in{animation:none}}

/* == MoltenMetal WebGL background (replaces .ambient when body.bg-molten; revertible) == */
#moltenBg{position:fixed;inset:0;width:100%;height:100%;z-index:0;pointer-events:none;display:block}
body.bg-molten .ambient,body.bg-molten .grain{display:none}

/* immersive fullscreen: canvas is reparented into .stage; z-index:-1 puts molten above the
   stage's opaque mask background but below the now-playing content (no UI bleed-through) */
@media(min-width:1024px){body.bg-molten.lay3.np-full #moltenBg{z-index:-1}}

/* readability scrim: dims the molten bg behind the UI (z between canvas z0 and app z2) so text/buttons stay legible */
body.bg-molten::before{content:"";position:fixed;inset:0;z-index:1;pointer-events:none;background:rgba(7,6,15,.4)}

/* add-to-playlist chooser: search box + admin group headers (Your playlists / Avify playlists) */
.pl-search{width:100%;box-sizing:border-box;margin:2px 0 10px;padding:9px 12px;border-radius:10px;border:1px solid var(--line);background:var(--glass);color:var(--txt);font-size:14px}
.pl-search:focus{outline:none;border-color:var(--line2)}
.pl-group{margin-bottom:4px}
.pl-group-h{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.06em;color:var(--muted);margin:10px 4px 6px}

/* add-to-playlist chooser tabs (admin: Your playlists / Avify playlists) */
.pl-tabs{display:flex;gap:6px;margin:4px 0 10px}
.pl-tab{flex:1;padding:9px 10px;border-radius:10px;border:1px solid var(--line);background:var(--glass);color:var(--txt2);font-weight:600;font-size:13px;cursor:pointer;transition:.15s}
.pl-tab:hover{color:var(--txt)}
.pl-tab.active{background:var(--grad);color:#0a0a14;border-color:transparent}
.pl-tabpane[hidden]{display:none}

/* == Lite mode: strip GPU/CPU-heavy effects for weak devices (body.lite; auto or forced) == */
body.lite .ambient,body.lite .grain{display:none}
body.lite{background:var(--bg)}
body.lite .art-glow{display:none!important}
body.lite .art-peek,body.lite .art-fly{display:none!important}
body.lite *{backdrop-filter:none!important;-webkit-backdrop-filter:none!important}
body.lite .art{box-shadow:0 6px 20px rgba(0,0,0,.55)}
body.lite .marquee .ra-name-in{animation:none!important;transform:none!important}
.rows-more{display:block;width:100%;margin:8px 0 2px;padding:12px;border-radius:12px;border:1px solid var(--line);background:var(--glass);color:var(--txt2);font-weight:600;font-size:13px;cursor:pointer}
.rows-more:hover{background:var(--glass2);color:var(--txt)}

/* Performance (lite) toggle in the quality popover */
.pop-lite{display:flex;gap:6px;padding:4px 14px 2px}
.lite-opt{flex:1;padding:8px 6px;border-radius:9px;border:1px solid var(--line);background:var(--glass);color:var(--txt2);font-weight:600;font-size:12px;cursor:pointer;transition:.15s}
.lite-opt:hover{color:var(--txt)}
.lite-opt.active{background:var(--grad);color:#0a0a14;border-color:transparent}

.pl-cover.img{position:relative;overflow:hidden}.pl-cover.img img{width:100%;height:100%;object-fit:cover;display:block}

/* category (folder) home cards */
.hcard.cat .hc-grad{background:linear-gradient(150deg,#3b3350,#211b2e)}
.hcard.cat .hc-img.noimg,.hcard.cat .hc-grad{position:relative}
.hcard.cat .hc-kind{background:rgba(255,255,255,.16)}
.hcard.cat .hc-grad>i{opacity:.9}

/* pinned home card */
.hc-admin-row .iconbtn.pinned{color:#8b5cf6}
.hcar-pin{color:#8b5cf6;font-size:.8em;margin-right:2px}

/* home-cards admin groups */
.hc-group{margin-top:6px}
.hc-group-head{font-size:12px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;opacity:.55;margin:16px 4px 6px;display:flex;align-items:center;gap:8px}
.hcg-count,.hcar-kids{display:inline-block;background:rgba(255,255,255,.12);border-radius:10px;padding:0 7px;font-size:11px;font-weight:600;vertical-align:middle}
.hc-admin-row.is-cat{background:rgba(139,92,246,.08)}
.hc-admin-row.is-cat.open{border-bottom-left-radius:0;border-bottom-right-radius:0}
.hc-admin-row.nested{margin-left:20px}
.hc-children{border-left:2px solid rgba(139,92,246,.28);margin:0 0 8px 10px}
.hc-child-empty{opacity:.55;font-size:12.5px;padding:10px 14px;margin-left:10px}
.hc-expand{flex:0 0 auto}

/* home-cards bulk add */
.hc-lookup.multi{position:static;max-height:230px;overflow:auto;margin-top:6px;border-radius:10px}
.hc-lk.picked{background:rgba(139,92,246,.22)}
.hc-lk.picked::after{content:"✓";float:right;color:#8b5cf6;font-weight:700}
.hcb-chosen{display:flex;flex-wrap:wrap;gap:6px;margin:2px 0 8px}
.hcb-chosen:empty{display:none}
.hcb-chip{display:inline-flex;align-items:center;gap:6px;background:rgba(139,92,246,.16);border:1px solid rgba(139,92,246,.35);border-radius:14px;padding:3px 6px 3px 11px;font-size:13px;line-height:1.3}
.hcb-chip button{background:none;border:0;color:inherit;cursor:pointer;font-size:16px;line-height:1;opacity:.7}
.hcb-chip button:hover{opacity:1}

/* home-cards paste list */
.hcb-paste{margin:4px 0 10px;border:1px solid rgba(255,255,255,.10);border-radius:10px;padding:6px 10px}
.hcb-paste>summary{cursor:pointer;font-size:13px;opacity:.85;list-style:none;display:flex;align-items:center;gap:7px;padding:4px 0}
.hcb-paste>summary::-webkit-details-marker{display:none}
.hcb-paste textarea{width:100%;box-sizing:border-box;margin:8px 0;min-height:96px;resize:vertical;border-radius:8px;padding:8px 10px;font:inherit}
.hcb-report{margin-top:8px;font-size:13px;line-height:1.5}
.hcb-report .hcr-ok{color:#22c55e}
.hcb-report .hcr-miss{color:#f59e0b;margin-top:3px}
.hcb-report .hcr-warn{color:#f59e0b}

/* home-cards sections */
.hc-sec{border:1px solid var(--line);border-radius:16px;margin:14px 0;background:rgba(255,255,255,.02);overflow:hidden}
.hc-sec-act{border-color:rgba(139,92,246,.30);background:rgba(139,92,246,.06)}
.hc-sec-head{width:100%;text-align:left;display:flex;align-items:center;gap:9px;font-size:12px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;opacity:.85;padding:13px 15px;background:none;border:0;color:var(--txt);cursor:pointer;font-family:inherit}
.hc-sec-head.static{cursor:default;opacity:.6}
.hc-sec-head .hcs-title{opacity:.92}
.hc-sec-head .hcs-hint{margin-left:auto;text-transform:none;letter-spacing:0;font-weight:500;opacity:.5;font-size:11px}
.hc-sec-act .hc-sec-head:hover{opacity:1}
.hcs-caret{width:11px;font-size:11px;opacity:.6}
.hc-sec-body{display:flex;flex-direction:column;gap:8px;padding:2px 10px 12px}
.hc-sec-body:empty{display:none}

.hc-sec-cat{border-color:rgba(34,211,238,.28);background:rgba(34,211,238,.05)}

/* media library picker */
.media-modal{max-width:640px;width:calc(100vw - 32px)}
.media-upl{display:flex;align-items:center;gap:12px;margin:6px 0 12px}
.media-upl-btn{display:inline-flex;align-items:center;gap:8px;cursor:pointer;background:linear-gradient(135deg,rgba(139,92,246,.9),rgba(34,211,238,.75));color:#fff;font-weight:700;font-size:13px;padding:9px 14px;border-radius:10px}
.media-upl-hint{font-size:12px;opacity:.55}
.media-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(96px,1fr));gap:10px;max-height:46vh;overflow-y:auto;padding:2px;margin-bottom:12px}
.media-empty{grid-column:1/-1;opacity:.55;font-size:13px;text-align:center;padding:24px 0}
.media-item{position:relative;aspect-ratio:1;border-radius:10px;overflow:hidden;cursor:pointer;border:2px solid transparent;background:rgba(255,255,255,.04)}
.media-item img{width:100%;height:100%;object-fit:cover;display:block}
.media-item.sel{border-color:var(--cyan);box-shadow:0 0 0 2px rgba(34,211,238,.35)}
.media-item.sel::after{content:"\f00c";font-family:"Font Awesome 6 Free";font-weight:900;position:absolute;top:5px;right:5px;width:20px;height:20px;display:grid;place-items:center;border-radius:50%;background:var(--cyan);color:#04121a;font-size:11px}
.media-del{position:absolute;bottom:5px;right:5px;width:26px;height:26px;border:0;border-radius:8px;background:rgba(0,0,0,.6);color:#fff;cursor:pointer;opacity:0;transition:opacity .12s;font-size:12px}
.media-item:hover .media-del{opacity:1}
.media-del:hover{background:#f43f5e}
/* card editor thumbnail field */
.hcf-img-row{display:flex;gap:12px;align-items:stretch}
.hcf-img-prev{flex:0 0 auto;width:64px;height:64px;border-radius:12px;overflow:hidden;background:rgba(255,255,255,.05);display:grid;place-items:center;color:var(--muted)}
.hcf-img-prev img{width:100%;height:100%;object-fit:cover;display:block}
.hcf-img-prev.empty{border:1px dashed var(--line)}
.hcf-img-ctl{flex:1;min-width:0;display:flex;flex-direction:column;gap:8px;justify-content:center}
/* playlist cover edit */
.pl-cover-edit{display:flex;gap:12px;align-items:center}
.pl-cover-prev{flex:0 0 auto;width:72px;height:72px;border-radius:12px;overflow:hidden;background:rgba(255,255,255,.05);display:grid;place-items:center}
.pl-cover-prev img{width:100%;height:100%;object-fit:cover;display:block}
.pl-cover-ctl{display:flex;flex-direction:column;gap:8px}
.ghost-btn.danger{color:#f87ea0}

/* media picker tabs */
.media-tabs{display:flex;gap:6px;flex-wrap:wrap;margin:2px 0 10px}
.media-tab{background:rgba(255,255,255,.05);border:1px solid var(--line);color:var(--txt);border-radius:999px;padding:6px 12px;font-size:12.5px;font-weight:600;cursor:pointer;display:inline-flex;align-items:center;gap:6px}
.media-tab.active{background:linear-gradient(135deg,rgba(139,92,246,.9),rgba(34,211,238,.7));border-color:transparent;color:#fff}
.media-tab .mt-n{font-size:11px;opacity:.7;background:rgba(0,0,0,.2);border-radius:8px;padding:0 6px}
.media-tab.active .mt-n{background:rgba(255,255,255,.2);opacity:.95}
.media-search{width:100%;box-sizing:border-box;margin:0 0 10px;border-radius:10px;padding:9px 12px;font:inherit;background:rgba(255,255,255,.05);border:1px solid var(--line);color:var(--txt)}
.media-cap{position:absolute;left:0;right:0;bottom:0;padding:3px 6px;font-size:10.5px;line-height:1.2;color:#fff;background:linear-gradient(180deg,transparent,rgba(0,0,0,.72));white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.media-item.bad{display:none}

.zp-name{font-weight:700;font-size:14px;color:var(--txt);margin-bottom:4px;display:flex;align-items:center;gap:7px}
.zp-name:empty{display:none}

/* ── RTL: directional icons ─────────────────────────────────────────────
   "Back" points the other way in a right-to-left reading order, and the same holds for every chevron,
   angle and arrow used as a navigation affordance. Mirroring the glyph covers both the static shell
   and anything JS builds later, which a per-icon class swap would not.
   MEDIA controls are deliberately left alone: previous/next are not mirrored in RTL players by
   convention, and they live inside the now-playing island, which stays left-to-right anyway. */
html[dir="rtl"] .fa-chevron-left,html[dir="rtl"] .fa-chevron-right,
html[dir="rtl"] .fa-angle-left,html[dir="rtl"] .fa-angle-right,
html[dir="rtl"] .fa-arrow-left,html[dir="rtl"] .fa-arrow-right,
html[dir="rtl"] .fa-arrow-right-from-bracket,html[dir="rtl"] .fa-arrow-left-long{transform:scaleX(-1)}
/* ...except inside the surfaces that stay left-to-right, where nothing is mirrored. */
html[dir="rtl"] #hero [class*="fa-chevron-"],html[dir="rtl"] #hero [class*="fa-arrow-"],
html[dir="rtl"] #oled [class*="fa-chevron-"],html[dir="rtl"] #oled [class*="fa-arrow-"]{transform:none}

/* ── RTL: rail edge fade ────────────────────────────────────────────────
   A horizontal rail fades out at the edge its content scrolls TOWARD, hinting there is more. In a
   right-to-left layout the row starts at the right, so the fade belongs on the LEFT — the gradient
   runs the other way, and the scroll padding that keeps the first card off the edge moves with it.
   .rail-items is deliberately absent: it is the Up Next rail inside the now-playing section, which
   stays left-to-right, so its fade should not move either. */
html[dir="rtl"] .feat-rail{
  -webkit-mask-image:linear-gradient(270deg,#000 0,#000 calc(100% - 40px),transparent 100%);
          mask-image:linear-gradient(270deg,#000 0,#000 calc(100% - 40px),transparent 100%);
  scroll-padding-left:0;scroll-padding-right:2px}

/* ── RTL mirror layer ───────────────────────────────────────────────────
   Generated (scratchpad/rtlgen2.py). Flex and grid mirror themselves under
   dir="rtl"; physical geometry does not, and this stylesheet had 173 such
   declarations against 6 logical ones. Each flip also NEUTRALISES the side it
   came from — without that, both sides end up set at once and the element
   collapses (which is exactly what broke the now-playing action rail).
   RTL-only: with dir="ltr" not one of these rules matches. */
html[dir="rtl"] .app{padding:env(safe-area-inset-top) env(safe-area-inset-left) env(safe-area-inset-bottom) env(safe-area-inset-right)}
html[dir="rtl"] .top-nav{margin-right:8px;margin-left:0}
html[dir="rtl"] .top-actions{margin-right:auto;margin-left:0}
html[dir="rtl"] .sb-top i{margin-left:6px;margin-right:0}
html[dir="rtl"] #repeatBtn.repeat-one::after{left:6px;right:auto}
html[dir="rtl"] .rail-items{padding:6px 8px 8px 2px}
html[dir="rtl"] .rail-card .rc-num{right:6px;left:auto}
html[dir="rtl"] .scrim{right:0;left:0}
html[dir="rtl"] .browse{left:0;right:auto;border-right:1px solid var(--line2);border-left:0}
html[dir="rtl"] body.select-mode .card::after{right:8px;left:auto}
html[dir="rtl"] body.select-mode .card.artist::after{right:14px;left:auto}
html[dir="rtl"] body.select-mode .row{padding-left:52px;padding-right:0}
html[dir="rtl"] body.select-mode .row::after{left:16px;right:auto}
html[dir="rtl"] .sel-bar{right:10px;left:10px}
html[dir="rtl"] .sel-count{padding-right:4px;padding-left:0}
html[dir="rtl"] .close-btn{margin-right:auto;margin-left:0}
html[dir="rtl"] .search-clear{margin:-4px 0 -4px -6px}
html[dir="rtl"] .pl-cover.collage .p3-0{right:0;left:auto}
html[dir="rtl"] .pl-cover.collage .p3-1{right:28.33%;left:auto}
html[dir="rtl"] .pl-cover.collage .p3-2{right:61.66%;left:auto}
html[dir="rtl"] .pl-cover.collage .p2-0{right:0;left:auto}
html[dir="rtl"] .pl-cover.collage .p2-1{right:45%;left:auto}
html[dir="rtl"] .section-title .feat-viewall{margin-right:auto;margin-left:0}
html[dir="rtl"] .feat-rail{padding:4px 2px 10px 2px}
html[dir="rtl"] .feat-play{left:8px;right:auto}
html[dir="rtl"] .pop-norm i{margin-left:7px;margin-right:0}
html[dir="rtl"] .card .thumb .play-fab{left:10px;right:auto}
html[dir="rtl"] .queue-panel{left:0;right:auto;border-right:1px solid var(--line2);border-left:0}
html[dir="rtl"] .dock{right:0;left:0}
html[dir="rtl"] .more-sheet{right:0;left:0}
html[dir="rtl"] .mini{right:10px;left:auto;padding:8px 8px 8px 8px}
html[dir="rtl"] .mini-prog{right:0;left:0}
html[dir="rtl"] .modal-x{left:14px;right:auto}
html[dir="rtl"] 0%{margin-right:-32%;margin-left:0}
html[dir="rtl"] 100%{margin-right:100%;margin-left:0}
html[dir="rtl"] .browse-handle{left:0;right:auto;border-radius:0 16px 16px 0}
html[dir="rtl"] .browse-handle:hover{padding-left:13px;padding-right:0}
html[dir="rtl"] .popover{left:14px;right:auto}
html[dir="rtl"] .sheet-btn{text-align:right}
html[dir="rtl"] .vis-opt{text-align:right}
html[dir="rtl"] .req-link{margin-right:6px;margin-left:0}
html[dir="rtl"] .tab-badge{margin-right:4px;margin-left:0}
html[dir="rtl"] 0%{margin-right:-35%;margin-left:0}
html[dir="rtl"] 100%{margin-right:100%;margin-left:0}
html[dir="rtl"] .rplays{margin-left:2px;margin-right:0}
html[dir="rtl"] .qplays{margin-right:2px;margin-left:0}
html[dir="rtl"] .rartist.has-plays .ra-plays{padding-right:8px;padding-left:0}
html[dir="rtl"] .yt-item{text-align:right}
html[dir="rtl"] .icon-action.busy .dl-badge{left:-4px;right:auto}
html[dir="rtl"] .dev-label i{margin-left:6px;margin-right:0}
html[dir="rtl"] .dev-sw::after{right:3px;left:auto}
@media (max-width:1023px){
  html[dir="rtl"] .browse{border-right:none;border-left:0}
  html[dir="rtl"] .au-badge{margin-right:5px;margin-left:0}
  html[dir="rtl"] .del-item{text-align:right}
  html[dir="rtl"] .cg-item{text-align:right}
}
html[dir="rtl"] .hcard{text-align:right}
html[dir="rtl"] .hcard .hc-kind{left:9px;right:auto}
html[dir="rtl"] .gcard{text-align:right}
html[dir="rtl"] .gcard .gc-ic{left:13px;right:auto}
html[dir="rtl"] .adtab i{margin-left:6px;margin-right:0}
html[dir="rtl"] #hcfTarget.hc-has-caret{padding-left:36px;padding-right:0}
html[dir="rtl"] .hc-lookup{right:0;left:0}
html[dir="rtl"] .hc-lk{text-align:right}
html[dir="rtl"] .hc-lk small{margin-right:6px;margin-left:0}
html[dir="rtl"] .mini.collapsed.collapse-right{right:auto;left:10px}
html[dir="rtl"] .mini-resume{right:0;left:auto}
html[dir="rtl"] .eq-sw::before{right:3px;left:auto}
html[dir="rtl"] .hc-cols-ctrl #hccSave{margin-right:auto;margin-left:0}
html[dir="rtl"] .trim-scan-row{text-align:right}
html[dir="rtl"] .plre-list .plre-row .qgrip{margin-right:auto;margin-left:0}
html[dir="rtl"] .hcar-pin{margin-left:2px;margin-right:0}
html[dir="rtl"] .hc-admin-row.is-cat.open{border-bottom-right-radius:0;border-bottom-left-radius:0}
html[dir="rtl"] .hc-admin-row.nested{margin-right:20px;margin-left:0}
html[dir="rtl"] .hc-children{border-right:2px solid rgba(139,92,246,.28);border-left:0;margin:0 10px 8px 0}
html[dir="rtl"] .hc-child-empty{margin-right:10px;margin-left:0}
html[dir="rtl"] .hc-lk.picked::after{float:left}
html[dir="rtl"] .hcb-chip{padding:3px 11px 3px 6px}
html[dir="rtl"] .hc-sec-head{text-align:right}
html[dir="rtl"] .hc-sec-head .hcs-hint{margin-right:auto;margin-left:0}
html[dir="rtl"] .media-item.sel::after{left:5px;right:auto}
html[dir="rtl"] .media-del{left:5px;right:auto}
html[dir="rtl"] .media-cap{right:0;left:0}
html[dir="rtl"] .sel-count i{margin-right:6px;margin-left:0}
html[dir="rtl"] .verify-banner{right:0;left:0;padding:9px 14px 9px 40px}
html[dir="rtl"] .verify-banner .vb-x{left:10px;right:auto}
@media(min-width:1024px){
  html[dir="rtl"] body.lay3 .topbar{border-left:1px solid var(--line);border-right:0}
  html[dir="rtl"] body.lay3 .top-nav{margin-right:0;margin-left:0}
  html[dir="rtl"] body.lay3 .top-actions{margin-right:0;margin-left:0}
  html[dir="rtl"] body.lay3 .browse{border-right:none;border-left:0}
  html[dir="rtl"] body.lay3 .stage{border-right:1px solid var(--line);border-left:0}
  html[dir="rtl"] body.lay3 .queue-panel{left:auto}
  html[dir="rtl"] body.lay3 .popover{left:auto;right:248px}
  html[dir="rtl"] body.lay3 .queue-panel{right:auto;left:calc(clamp(340px,27vw,440px) + 14px)}
  html[dir="rtl"] body.lay3 .sel-bar{right:240px;left:clamp(340px,27vw,440px)}
}

/* Drawers slide in from the opposite edge in RTL, so their closed position is the other way too. */
html[dir="rtl"] .browse{transform:translateX(-100%)}
html[dir="rtl"] .browse.open{transform:translateX(0)}
html[dir="rtl"] .queue-panel{transform:translateX(-100%)}
html[dir="rtl"] .queue-panel.open{transform:translateX(0)}
/* Switch knobs travel the other way. */
html[dir="rtl"] .dev-sw.on::after{transform:translateX(-20px)}
html[dir="rtl"] .eq-switch input:checked+.eq-sw::before{transform:translateX(-18px)}

