@import url('fonts.css');

/* =========================================================================
   Aurelune — design tokens
   A black-and-green palette in the mold of the streaming apps everyone
   already knows: near-black sidebar, dark grey panels, one bright green
   accent for interactive/active states. Generative cover art (server-
   rendered SVG) supplies the rest of the color variety, so the chrome
   itself stays disciplined and the accent isn't diluted.
   ========================================================================= */
:root {
  --bg: #000000;
  --bg-1: #121212;
  --panel: #12121280;
  --panel-solid: #121212;
  --raised: #181818;
  --hover: #282828;
  --hairline: rgba(255, 255, 255, 0.08);
  --hairline-2: rgba(255, 255, 255, 0.14);

  --gold: #1ed760;
  --gold-hi: #3be47a;
  --gold-ink: #000000;
  --violet: #0a3d1f;
  --teal: #17a84a;
  --pink: #e2637a;

  --text: #ffffff;
  --text-dim: #b3b3b3;
  --text-faint: #6a6a6a;

  --aurora: linear-gradient(115deg, #0a3d1f 0%, var(--gold) 60%, var(--gold-hi) 100%);

  --font-display: 'Hanken Grotesk Variable', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-ui: 'Hanken Grotesk Variable', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;

  --radius-s: 4px;
  --radius-m: 8px;
  --radius-l: 8px;
  --radius-round: 999px;

  --nav-w: 232px;
  --player-h: 90px;
  --topbar-h: 64px;
  --shadow-lift: 0 12px 34px rgba(0,0,0,0.6);
}

@media (prefers-color-scheme: light) {
  /* Aurelune is designed as a night-listening app; we keep the palette
     fixed rather than flipping to a washed-out "light mode" of it. */
}

* { box-sizing: border-box; }
html, body { height: 100%; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-ui);
  font-size: 15px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  overflow: hidden;
}
h1, h2, h3, h4 { margin: 0; font-family: var(--font-display); font-weight: 500; letter-spacing: -0.01em; }
p { margin: 0; }
a { color: inherit; text-decoration: none; }
button { font-family: inherit; cursor: pointer; }
input, textarea, select { font-family: inherit; color: inherit; }
img { display: block; max-width: 100%; }
::selection { background: var(--gold); color: var(--gold-ink); }

/* Nothing in the app is selectable text unless it's meant to be: double-clicking a track, dragging across a list or
   Ctrl+A shouldn't highlight (and let you copy) titles, buttons and labels. Text boxes and anything marked .selectable keep it. */
html, body {
  -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none; /* iOS long-press "Copy / Look up" bubble */
  -webkit-tap-highlight-color: transparent;
}
input, textarea, [contenteditable]:not([contenteditable="false"]), .selectable, .selectable * {
  -webkit-user-select: text; user-select: text;
}
/* Safari/WebKit won't let you type in an input that sits under user-select:none unless it opts back in itself. */
input, textarea { -webkit-user-select: text; user-select: text; }
/* Not-a-text-box inputs have nothing to select. */
input[type="range"], input[type="checkbox"], input[type="radio"], input[type="file"], input[type="button"], input[type="submit"] { -webkit-user-select: none; user-select: none; }
/* Images and links can't be picked up and dragged out as a file/URL either. */
img, svg, a { -webkit-user-drag: none; }

*:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Animations are on by default and follow the account setting (Settings → Appearance), NOT the OS "reduce motion" switch. */
html.no-anim *, html.no-anim *::before, html.no-anim *::after {
  animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; animation-delay: 0s !important;
  transition-duration: 0.001ms !important; transition-delay: 0s !important; scroll-behavior: auto !important;
}

.scrollbar, .shelf-row, .modal-body, .panel-scroll { scrollbar-width: thin; scrollbar-color: var(--hairline-2) transparent; }
.scrollbar::-webkit-scrollbar, .shelf-row::-webkit-scrollbar, .modal-body::-webkit-scrollbar, .panel-scroll::-webkit-scrollbar { width: 8px; height: 8px; }
.scrollbar::-webkit-scrollbar-thumb, .modal-body::-webkit-scrollbar-thumb, .panel-scroll::-webkit-scrollbar-thumb { background: var(--hairline-2); border-radius: 8px; }

/* ---------------------------------------------------------------------
   App shell
   --------------------------------------------------------------------- */
#app {
  position: relative; z-index: 2;
  display: grid;
  grid-template-columns: var(--nav-w) 1fr;
  grid-template-rows: minmax(0, 1fr);
  height: 100vh; height: calc(100dvh / var(--ui-scale, 1)); /* dvh = the visible height on phones (100vh ignores the address bar and pushed the page end under the player) */
  padding: 8px;
  gap: 8px;
}
#app.no-auth { display: block; padding: 0; height: 100vh; height: calc(100dvh / var(--ui-scale, 1)); }

.nav {
  min-height: 0;
  position: relative;
  background: var(--bg-1);
  border-radius: var(--radius-l);
  display: flex;
  flex-direction: column;
  padding: 20px 14px;
  gap: 4px;
}
.nav-brand {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 10px 22px;
  position: relative;
}
.nav-brand > svg { width: 30px; height: 30px; flex: none; }
.nav-brand span { font-family: var(--font-display); font-size: 19px; font-weight: 600; letter-spacing: -0.01em; flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; }
.nav-collapse-btn {
  border: none; background: var(--hover); color: var(--text-dim); width: 26px; height: 26px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; flex: none; opacity: 0; transition: opacity 0.15s;
}
.nav:hover .nav-collapse-btn { opacity: 1; }
.nav-brand .nav-collapse-btn svg { width: 15px; height: 15px; }
.nav-resize-handle {
  position: absolute; top: 0; right: -5px; bottom: 0; width: 10px; cursor: ew-resize; z-index: 5;
}
.nav-resize-handle:hover, .nav-resize-handle.dragging { background: linear-gradient(90deg, transparent, rgba(255,255,255,0.08)); }

.nav.collapsed { align-items: center; }
.nav.collapsed .nav-brand { justify-content: center; padding: 6px 0 22px; }
.nav.collapsed .brand-text, .nav.collapsed .nav-item .nav-label, .nav.collapsed .nav-section-label { display: none; }
.nav.collapsed .nav-collapse-btn { position: static; opacity: 1; transform: rotate(180deg); }
.nav.collapsed .nav-item { justify-content: center; padding: 12px; width: auto; }
.nav.collapsed .nav-resize-handle { display: none; }

.nav-item {
  display: flex; align-items: center; gap: 13px;
  padding: 10px 12px;
  border-radius: var(--radius-m);
  color: var(--text-dim);
  background: none; border: none; width: 100%; text-align: left;
  font-size: 14.5px; font-weight: 660;
  transition: color 0.15s;
}
.nav-item svg { width: 22px; height: 22px; flex: none; }
.nav-item:hover { color: var(--text); }
.nav-item.active { color: var(--text); }
.nav-item .nav-icon-filled { display: none; }
.nav-item.active .nav-icon-outline { display: none; }
.nav-item.active .nav-icon-filled { display: inline-flex; }
.nav-sep { height: 1px; background: var(--hairline); margin: 12px 4px; }
.nav-section-label { font-size: 12px; color: var(--text-faint); padding: 4px 12px 6px; font-weight: 700; }
.nav-playlists { overflow-y: auto; flex: 1; display: flex; flex-direction: column; gap: 1px; }
.nav-playlists .nav-item { font-size: 13.5px; padding: 7px 12px; font-weight: 560; border-radius: var(--radius-s); }
.nav-playlists .nav-item:hover { background: var(--hover); }

.avatar-btn { display: flex; align-items: center; gap: 8px; border: none; background: var(--raised); border-radius: var(--radius-round); padding: 4px 8px 4px 4px; }
.avatar-btn:hover { background: var(--hover); }
.avatar-btn .avatar { width: 28px; height: 28px; border-radius: 50%; background: var(--gold); display: flex; align-items: center; justify-content: center; font-weight: 700; font-size: 12.5px; color: var(--gold-ink); flex: none; }
.avatar-btn .name { font-size: 13px; font-weight: 660; color: var(--text); max-width: 120px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.avatar-menu { position: absolute; top: calc(100% + 8px); right: 0; min-width: 200px; background: #282828; border-radius: var(--radius-s); box-shadow: var(--shadow-lift); padding: 6px; z-index: 70; }
.avatar-menu button, .avatar-menu a { display: block; width: 100%; text-align: left; background: none; border: none; color: var(--text); font-size: 13.5px; font-weight: 600; padding: 10px 12px; border-radius: var(--radius-s); }
.avatar-menu button:hover, .avatar-menu a:hover { background: var(--hover); }
.avatar-menu .sep { height: 1px; background: var(--hairline); margin: 6px 4px; }
.topbar-nav { display: flex; align-items: center; gap: 6px; }
.avatar-menu.above { top: auto; bottom: calc(100% + 8px); }

.ctx-menu { position: fixed; min-width: 220px; background: #282828; border-radius: 6px; box-shadow: var(--shadow-lift); padding: 6px; z-index: 300; }
.ctx-item {
  display: flex; align-items: center; gap: 11px; width: 100%; text-align: left;
  background: none; border: none; color: var(--text); font-size: 13.5px; font-weight: 570;
  padding: 9px 12px; border-radius: 4px;
}
.ctx-item svg { width: 16px; height: 16px; color: var(--text-dim); flex: none; }
.ctx-item:hover { background: var(--hover); }
.ctx-item.danger { color: var(--pink); }
.ctx-item.danger svg { color: var(--pink); }
.ctx-sep { height: 1px; background: var(--hairline); margin: 6px 8px; }

.eq-band { display: flex; flex-direction: column; align-items: center; gap: 8px; flex: 1; }
.eq-val { font-size: 11px; color: var(--text-faint); font-variant-numeric: tabular-nums; min-width: 22px; text-align: center; }
.eq-slider-wrap { height: 130px; display: flex; align-items: center; justify-content: center; width: 100%; }
.eq-slider {
  width: 120px; height: 4px; transform: rotate(-90deg); appearance: none; -webkit-appearance: none;
  background: var(--raised); border-radius: 2px; outline: none; cursor: pointer;
}
.eq-slider::-webkit-slider-thumb { appearance: none; -webkit-appearance: none; width: 14px; height: 14px; border-radius: 50%; background: var(--gold); cursor: pointer; }
.eq-slider::-moz-range-thumb { width: 14px; height: 14px; border-radius: 50%; background: var(--gold); border: none; cursor: pointer; }
.eq-freq { font-size: 11px; color: var(--text-faint); }

/* ---------------------------------------------------------------------
   Full-page lyrics
   --------------------------------------------------------------------- */
.lyrics-page {
  position: relative; margin: -28px -30px calc(-1 * (var(--player-h) + 24px));
  min-height: calc(100vh - var(--topbar-h) - 24px); min-height: calc(100dvh / var(--ui-scale, 1) - var(--topbar-h) - 24px);
  display: flex; flex-direction: column; align-items: center;
  overflow: hidden; color: #fff;
}
.lyrics-page-bg {
  position: absolute; inset: 0; background-size: cover; background-position: center;
  filter: blur(60px) brightness(0.5) saturate(140%); transform: scale(1.3); z-index: 0;
}
.lyrics-page-bg::after { content: ''; position: absolute; inset: 0; background: linear-gradient(180deg, rgba(0,0,0,0.35), rgba(0,0,0,0.75)); }
.lp-close { position: absolute; top: 20px; right: 20px; z-index: 3; background: rgba(0,0,0,0.4); }
.lyrics-page-head { position: relative; z-index: 2; display: flex; align-items: center; gap: 18px; padding: 40px 30px 20px; width: 100%; max-width: 720px; }
.lp-cover { width: 84px; height: 84px; border-radius: 8px; overflow: hidden; flex: none; box-shadow: 0 12px 30px rgba(0,0,0,0.5); }
.lp-cover img { width: 100%; height: 100%; object-fit: cover; }
.lp-title { font-size: 22px; font-weight: 800; }
.lp-artist { font-size: 14.5px; color: rgba(255,255,255,0.7); margin-top: 4px; }
.lp-artist a { color: inherit; }
.lp-artist a:hover { text-decoration: underline; }
.lyrics-page-body {
  position: relative; z-index: 2; flex: 1; width: 100%; max-width: 720px; overflow-y: auto;
  padding: 20px 30px 45vh; scroll-behavior: smooth; -webkit-mask-image: linear-gradient(180deg, transparent, #000 40px, #000 calc(100% - 60px), transparent);
}
.lp-line {
  font-family: var(--font-display); font-size: 26px; font-weight: 800; line-height: 1.5;
  color: rgba(255,255,255,0.38); margin: 0 0 6px; cursor: pointer; transition: color 0.25s, transform 0.25s; transform-origin: left center;
}
.lp-line:hover { color: rgba(255,255,255,0.7); }
.lp-line.active { color: #fff; transform: scale(1.04); }
.lp-plain { white-space: pre-line; font-family: var(--font-display); font-size: 19px; line-height: 1.9; color: rgba(255,255,255,0.85); }
.lp-status { color: rgba(255,255,255,0.6); font-size: 14px; }
.lp-sync-btn { position: absolute; z-index: 4; bottom: 30px; left: 50%; transform: translateX(-50%); display: flex; gap: 8px; box-shadow: var(--shadow-lift); }
.lp-sync-btn svg { width: 15px; height: 15px; }

#ambient-bar {
  position: fixed; top: 0; left: 0; right: 0; height: 340px; pointer-events: none; z-index: 1;
  opacity: 0; transition: opacity 1s ease, background-color 1.4s ease;
  background: radial-gradient(120% 100% at 50% 0%, var(--ambient, #1ed760) 0%, transparent 68%);
  filter: saturate(150%); /* (was blur(55px) saturate(150%): the gradient is already soft, and a 55px blur over a full-width slab is the costliest thing the GPU of a phone does while a song plays) */
  will-change: transform;
  animation: ambient-pulse 7s ease-in-out infinite;
}
#ambient-bar.on { opacity: 0.6; }
@keyframes ambient-pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.06); } }

.pnow-mobile-controls { display: none; }

.mobile-tabbar {
  display: none;
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 61;
  height: var(--tabbar-h, 58px);
  padding-bottom: env(safe-area-inset-bottom, 0px);
  background: #000000; border-top: 1px solid var(--hairline);
  align-items: stretch; justify-content: space-around;
}
.mtab {
  flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  border: none; background: none; color: var(--text-faint); font-size: 10.5px; font-weight: 620;
  padding: 6px 0 0;
}
.mtab svg { width: 22px; height: 22px; }
.mtab.active { color: var(--text); }
.mtab .nav-icon-filled { display: none; }
.mtab.active .nav-icon-outline { display: none; }
.mtab.active .nav-icon-filled { display: inline-flex; }

.main-col { display: flex; flex-direction: column; min-width: 0; min-height: 0; gap: 8px; height: 100%; }
.topbar {
  height: var(--topbar-h); flex: none;
  background: var(--bg-1); border-radius: var(--radius-l);
  display: flex; align-items: center; gap: 14px; padding: 0 20px;
}
.search-box {
  flex: 1; max-width: 480px; position: relative;
  display: flex; align-items: center; gap: 10px;
  background: var(--raised); border-radius: var(--radius-round);
  padding: 0 16px; height: 42px;
}
.search-box svg { width: 17px; height: 17px; color: var(--text-faint); flex: none; }
.search-box input { background: none; border: none; color: var(--text); font-size: 14.5px; width: 100%; outline: none; }
.search-box input::placeholder { color: var(--text-faint); }
.topbar-spacer { flex: 1; }
.icon-btn {
  width: 38px; height: 38px; border-radius: 50%; border: none; background: var(--raised);
  color: var(--text-dim); display: flex; align-items: center; justify-content: center;
  transition: background 0.15s, color 0.15s, transform 0.1s;
}
.icon-btn svg { width: 18px; height: 18px; }
.icon-btn:hover { background: var(--hover); color: var(--text); }
.icon-btn:active { transform: scale(0.94); }
.icon-btn.on { color: var(--gold); background: rgba(30,215,96,0.14); }

.content {
  flex: 1; min-height: 0; overflow-y: auto;
  background: var(--bg-1); border-radius: var(--radius-l);
  padding: 28px 30px calc(var(--player-h) + 24px);
}
.content.tight { padding: 0; }
#view { display: block; }

/* ---------------------------------------------------------------------
   Type + generic bits
   --------------------------------------------------------------------- */
.eyebrow-none {} /* intentionally: we do not use tracked-out all-caps eyebrows anywhere */
.page-title { font-size: 32px; font-weight: 800; letter-spacing: -0.02em; margin-bottom: 4px; }
.page-sub { color: var(--text-dim); font-size: 14.5px; margin-bottom: 22px; }
.section-title { font-size: 22px; font-weight: 800; letter-spacing: -0.01em; margin: 0; }
.section-head { display: flex; align-items: baseline; justify-content: space-between; margin: 30px 0 14px; }
.section-head:first-child { margin-top: 0; }
.link-more { font-size: 13px; color: var(--text-dim); font-weight: 600; }
.link-more:hover { color: var(--text); }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  border: none; border-radius: var(--radius-round);
  padding: 11px 22px; font-size: 14px; font-weight: 640;
  transition: transform 0.1s, filter 0.15s, background 0.15s;
  white-space: nowrap;
}
.btn:active { transform: scale(0.97); }
.btn-primary { background: var(--gold); color: var(--gold-ink); }
.btn-primary:hover { filter: brightness(1.08); }
.btn-ghost { background: var(--raised); color: var(--text); }
.btn-ghost:hover { background: var(--hover); }
.btn-outline { background: none; color: var(--text); border: 1px solid var(--hairline-2); }
.btn-outline:hover { background: var(--raised); }
.btn-danger { background: rgba(226,99,122,0.16); color: var(--pink); }
.btn-danger:hover { background: rgba(226,99,122,0.26); }
.btn-sm { padding: 7px 15px; font-size: 13px; }
.btn:disabled { opacity: 0.5; pointer-events: none; }
.btn svg { width: 16px; height: 16px; }

.play-btn {
  width: 56px; height: 56px; border-radius: 50%; border: none;
  background: var(--gold); color: var(--gold-ink);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 10px 24px rgba(30,215,96,0.28);
  transition: transform 0.12s, filter 0.15s;
}
.play-btn:hover { filter: brightness(1.06); }
.play-btn:active { transform: scale(0.95); }
.play-btn svg { width: 22px; height: 22px; }
.play-btn.sm { width: 40px; height: 40px; }
.play-btn.sm svg { width: 16px; height: 16px; }
.play-btn.white { background: #fff; color: #000; box-shadow: 0 6px 14px rgba(0,0,0,0.4); }
.play-btn.white:hover { filter: none; transform: scale(1.06); }

.chip {
  display: inline-flex; align-items: center; padding: 8px 16px; border-radius: var(--radius-round);
  background: var(--raised); color: var(--text-dim); font-size: 13.5px; font-weight: 580;
  border: 1px solid transparent;
}
.chip:hover { color: var(--text); background: var(--hover); }
.chip.active { background: rgba(30,215,96,0.15); color: var(--gold-hi); border-color: rgba(30,215,96,0.35); }
.chip-row { display: flex; gap: 9px; flex-wrap: wrap; }

.field { display: flex; flex-direction: column; gap: 7px; margin-bottom: 16px; }
.field label { font-size: 13px; font-weight: 620; color: var(--text-dim); }
.field .hint { font-size: 12px; color: var(--text-faint); }
.field input[type=text], .field input[type=email], .field input[type=password], .field input[type=number],
.field input[type=date], .field textarea, .field select {
  background: var(--raised); border: 1px solid var(--hairline-2); border-radius: var(--radius-s);
  padding: 11px 13px; font-size: 14.5px; color: var(--text); outline: none;
}
.field input:focus, .field textarea:focus, .field select:focus { border-color: var(--gold); }
.field textarea { resize: vertical; min-height: 84px; }
.field-row { display: flex; gap: 14px; }
.field-row .field { flex: 1; }
.switch-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 4px 0; }
.switch-row .copy { max-width: 380px; }
.switch-row .title { font-size: 14px; font-weight: 620; }
.switch-row .desc { font-size: 12.5px; color: var(--text-faint); margin-top: 2px; }
.switch { position: relative; width: 42px; height: 24px; border-radius: var(--radius-round); background: var(--raised); border: 1px solid var(--hairline-2); flex: none; transition: background 0.15s; }
.switch::after { content: ''; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%; background: var(--text-dim); transition: transform 0.15s, background 0.15s; }
.switch.on { background: rgba(30,215,96,0.28); border-color: rgba(30,215,96,0.5); }
.switch.on::after { transform: translateX(18px); background: var(--gold); }

.file-drop {
  border: 1.5px dashed var(--hairline-2); border-radius: var(--radius-m); padding: 20px;
  display: flex; align-items: center; gap: 14px; cursor: pointer; background: var(--raised);
  transition: border-color 0.15s, background 0.15s;
}
.file-drop:hover, .file-drop.over { border-color: var(--gold); }
.file-drop.over { background: rgba(30,215,96,0.08); }
.file-drop .drop-over { display: none; color: var(--gold); font-weight: 650; }
.file-drop.over .drop-hint { display: none; }
.file-drop.over .drop-over { display: inline; }
.drop-target { outline: 2px dashed var(--gold); outline-offset: -6px; border-radius: var(--radius-m); background: rgba(30,215,96,0.05); }
.file-drop input { display: none; }
.file-drop .icon { width: 40px; height: 40px; border-radius: 50%; background: var(--hover); display: flex; align-items: center; justify-content: center; flex: none; }
.file-drop .icon svg { width: 18px; height: 18px; color: var(--text-dim); }
.file-drop .txt { font-size: 13.5px; color: var(--text-dim); }
.file-drop .txt b { color: var(--text); }

.callout {
  border-radius: var(--radius-m); padding: 16px 18px; font-size: 13.5px; line-height: 1.55;
  border: 1px solid var(--hairline-2); background: var(--raised); color: var(--text-dim);
}
.callout.warn { border-color: rgba(30,215,96,0.35); background: rgba(30,215,96,0.08); color: var(--gold-hi); }
.callout.err { border-color: rgba(226,99,122,0.35); background: rgba(226,99,122,0.08); color: var(--pink); }
.callout.ok { border-color: rgba(23,168,74,0.35); background: rgba(23,168,74,0.08); color: var(--teal); }

/* The shimmer sweeps a lighter band across a base tone. The base must differ from what the placeholder sits on: on a card (which is
   --raised) a --raised base is invisible, so only the moving band showed. Cards get their own, lighter pair of tones. */
.skeleton { --sk-a: #1d1d1d; --sk-b: #2c2c2c; background: linear-gradient(100deg, var(--sk-a) 30%, var(--sk-b) 50%, var(--sk-a) 70%); background-size: 200% 100%; animation: shimmer 1.4s infinite; border-radius: var(--radius-s); }
.card .skeleton { --sk-a: #262626; --sk-b: #383838; }
.card .art-wrap.skeleton { background: linear-gradient(100deg, var(--sk-a) 30%, var(--sk-b) 50%, var(--sk-a) 70%); background-size: 200% 100%; box-shadow: none; } /* .card .art-wrap paints a flat #282828 */
#search-results { transition: opacity .15s ease; }
#search-results.busy { opacity: 0.5; pointer-events: none; } /* last results stay up, dimmed, while new ones load */
@keyframes shimmer { to { background-position: -200% 0; } }
/* Page-shaped loading placeholders (see skeletonPage in components.js): same boxes as the real page */
.sk-line { border-radius: 4px; max-width: 100%; }
.sk-pill { border-radius: 999px; }
.sk-round { border-radius: 50%; }
.sk-header { display: flex; gap: 26px; align-items: flex-end; margin-bottom: 26px; }
.sk-cover { width: 190px; height: 190px; border-radius: var(--radius-m); flex: none; box-shadow: var(--shadow-lift); }
.sk-cover.round { border-radius: 50%; }
.sk-meta { flex: 1; min-width: 0; }
.sk-actions { display: flex; align-items: center; gap: 14px; margin-bottom: 26px; }
.sk-play { width: 56px; height: 56px; border-radius: 50%; }
.sk-trow { display: grid; grid-template-columns: 28px 1fr auto; align-items: center; gap: 14px; padding: 9px 10px; }
.sk-idx { display: flex; justify-content: center; }
.sk-main { display: flex; align-items: center; gap: 12px; min-width: 0; }
.sk-cover-s { width: 42px; height: 42px; border-radius: 6px; flex: none; }
.sk-ecover { width: 108px; height: 108px; border-radius: var(--radius-s); flex: none; }

.empty { text-align: center; padding: 70px 20px; color: var(--text-dim); }
.empty .icon { width: 56px; height: 56px; margin: 0 auto 18px; color: var(--text-faint); }
.empty .icon svg { width: 100%; height: 100%; }
.empty h3 { font-size: 18px; margin-bottom: 8px; color: var(--text); }
.empty p { font-size: 13.5px; max-width: 360px; margin: 0 auto; }

/* ---------------------------------------------------------------------
   Shelves & cards
   --------------------------------------------------------------------- */
.shelf-row { display: flex; gap: 16px; overflow-x: auto; padding-bottom: 6px; scroll-snap-type: x proximity; }
.card {
  width: 180px; flex: none; scroll-snap-align: start;
  background: var(--raised); border-radius: var(--radius-m); padding: 12px;
  transition: background 0.2s;
}
.card:hover { background: var(--hover); }
.card .art-wrap { position: relative; width: 100%; aspect-ratio: 1; border-radius: var(--radius-s); overflow: hidden; background: #282828; box-shadow: 0 8px 24px rgba(0,0,0,0.4); }
.card.round .art-wrap { border-radius: 50%; }
.card .art-wrap img { width: 100%; height: 100%; object-fit: cover; }
.card .art-wrap .play-overlay {
  position: absolute; right: 8px; bottom: 8px; opacity: 0; transform: translateY(8px);
  transition: opacity 0.2s, transform 0.2s;
  box-shadow: 0 8px 16px rgba(0,0,0,0.5);
}
.card:hover .art-wrap .play-overlay { opacity: 1; transform: translateY(0); }
.card .title { margin-top: 14px; font-size: 14.5px; font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.card .sub { font-size: 13px; color: var(--text-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 5px; line-height: 1.4; }
.card a.title-link:hover { text-decoration: underline; }
.card.hero { width: 216px; }

.collage { display: grid; grid-template-columns: 1fr 1fr; grid-template-rows: 1fr 1fr; width: 100%; height: 100%; }
.collage img { width: 100%; height: 100%; object-fit: cover; }
.collage.n1 { grid-template-columns: 1fr; grid-template-rows: 1fr; }

.hero-band {
  padding: 8px 0 4px; margin-bottom: 4px;
}
.hero-band h1 { font-size: 32px; font-weight: 800; margin-bottom: 4px; letter-spacing: -0.02em; }
.hero-band p { color: var(--text-dim); font-size: 14.5px; }

.detail-header { display: flex; gap: 26px; align-items: flex-end; margin-bottom: 26px; }
.detail-header .cover { width: 190px; height: 190px; border-radius: var(--radius-m); overflow: hidden; background: var(--raised); flex: none; box-shadow: var(--shadow-lift); }
.detail-header .cover img { width: 100%; height: 100%; object-fit: cover; }
.detail-header.artist .cover { border-radius: 50%; }
.detail-header .meta { min-width: 0; }
.detail-header .kind { font-size: 13px; color: var(--text-dim); font-weight: 620; margin-bottom: 8px; }
.detail-header h1 { font-size: 42px; line-height: 1.05; margin-bottom: 12px; word-break: break-word; }
.detail-header .facts { display: flex; align-items: center; gap: 8px; font-size: 13.5px; color: var(--text-dim); flex-wrap: wrap; }
.detail-header .facts .dot { width: 3px; height: 3px; border-radius: 50%; background: var(--text-faint); }
.detail-actions { display: flex; align-items: center; gap: 14px; margin-bottom: 26px; }

.verified-badge { display: inline-flex; color: var(--teal); }
.verified-badge svg { width: 16px; height: 16px; }
.verified-inline { display: inline-flex; color: var(--teal); vertical-align: middle; margin-left: 1px; }
.verified-inline svg { width: 0.72em; height: 0.72em; }
.tlink { color: inherit; }
.tlink:hover { text-decoration: underline; }
.shelf { margin-bottom: 6px; }

/* ---------------------------------------------------------------------
   Track / episode rows
   --------------------------------------------------------------------- */
.row-list { display: flex; flex-direction: column; }
.trow {
  display: grid; grid-template-columns: 28px 1fr auto; align-items: center; gap: 14px;
  padding: 9px 10px; border-radius: var(--radius-s); cursor: default;
}
.trow:hover { background: var(--raised); }
.trow.playing { background: rgba(30,215,96,0.09); }
.trow .idx { color: var(--text-faint); font-size: 13.5px; text-align: center; font-variant-numeric: tabular-nums; }
.single-row .trow { grid-template-columns: 1fr auto; } /* a lone song has no track number, so no number column */
.single-row .trow .idx { display: none; }
.trow .idx .eq { display: none; }
.trow.playing .idx .num { display: none; }
.trow.playing .idx .eq { display: flex; }
.trow .idx .play-hover { display: none; }
.trow:hover .idx .num, .trow:hover .idx .eq { display: none; }
.trow:hover .idx .play-hover { display: flex; }
.trow-main { display: flex; align-items: center; gap: 12px; min-width: 0; }
.trow-cover { width: 42px; height: 42px; border-radius: 6px; overflow: hidden; background: var(--raised); flex: none; }
.trow-cover img { width: 100%; height: 100%; object-fit: cover; }
.trow-text { min-width: 0; }
.trow-text .t { font-size: 14.5px; font-weight: 580; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.trow.playing .trow-text .t { color: var(--gold-hi); }
.trow-text .s { font-size: 12.5px; color: var(--text-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-top: 2px; }
.trow-text .s a:hover { text-decoration: underline; color: var(--text-dim); }
.trow-right { display: flex; align-items: center; gap: 16px; color: var(--text-faint); font-size: 13px; font-variant-numeric: tabular-nums; }
.trow-actions { display: flex; align-items: center; gap: 6px; opacity: 0; transition: opacity 0.12s; }
.trow:hover .trow-actions { opacity: 1; }
.like-btn { background: none; border: none; color: var(--text-faint); width: 30px; height: 30px; border-radius: 50%; display: flex; align-items: center; justify-content: center; }
.like-btn:hover { color: var(--text); background: var(--hover); }
.like-btn.on { color: var(--gold); }
.like-btn svg { width: 16px; height: 16px; }
.trow-explicit { font-size: 10px; font-weight: 700; color: var(--text-faint); border: 1px solid var(--text-faint); border-radius: 3px; padding: 0 3px; line-height: 1.4; }

.erow { display: flex; gap: 16px; padding: 16px 8px; border-bottom: 1px solid var(--hairline); }
.erow:last-child { border-bottom: none; }
.erow .cover { width: 108px; height: 108px; border-radius: var(--radius-s); overflow: hidden; background: var(--raised); flex: none; }
.erow .cover img { width: 100%; height: 100%; object-fit: cover; }
.erow .body { flex: 1; min-width: 0; }
.erow .date { font-size: 12.5px; color: var(--text-faint); margin-bottom: 6px; }
.erow .title { font-size: 16px; font-weight: 620; margin-bottom: 6px; }
.erow .desc { font-size: 13.5px; color: var(--text-dim); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; margin-bottom: 12px; }
.erow .foot { display: flex; align-items: center; gap: 14px; }
.erow .foot .progress-mini { flex: 1; height: 4px; border-radius: 2px; background: var(--raised); position: relative; max-width: 220px; }
.erow .foot .progress-mini i { position: absolute; inset: 0; border-radius: 2px; background: var(--gold); }
.erow .foot .dur { font-size: 12px; color: var(--text-faint); }

.equalizer { display: flex; align-items: flex-end; gap: 2px; width: 14px; height: 14px; margin: 0 auto; }
/* The bars animate transform (scaleY), not height: animating height re-ran layout and style 60 times a second for as long as a song played, work a busy phone
   can't spare. A transform is handled by the compositor and costs the main thread nothing. */
.equalizer i { width: 3px; height: 13px; transform-origin: 50% 100%; will-change: transform; background: var(--gold); border-radius: 1px; animation: eq 0.9s ease-in-out infinite; }
.equalizer i:nth-child(1) { animation-delay: -0.6s; }
.equalizer i:nth-child(2) { animation-delay: -0.3s; }
.equalizer i:nth-child(3) { animation-delay: 0s; }
@keyframes eq { 0%, 100% { transform: scaleY(0.23); } 50% { transform: scaleY(1); } }
.equalizer.paused i { animation-play-state: paused; transform: scaleY(0.3); }

/* ---------------------------------------------------------------------
   Grids (albums/artists/playlists in library etc.)
   --------------------------------------------------------------------- */
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(168px, 1fr)); gap: 20px 18px; }
.grid .card { width: auto; }
.grid .card .art-wrap { width: 100%; height: auto; aspect-ratio: 1; }

/* ---------------------------------------------------------------------
   Now playing bar
   --------------------------------------------------------------------- */
.player-bar {
  position: fixed; left: 8px; right: 8px; bottom: 8px; height: var(--player-h);
  background: var(--bg-1); border-radius: var(--radius-l); z-index: 60;
  display: grid; grid-template-columns: minmax(180px, 1fr) minmax(360px, 640px) minmax(180px, 1fr); align-items: center;
  padding: 0 18px; gap: 16px; border: 1px solid var(--hairline);
}
.player-bar.empty { background: transparent; border-color: transparent; }
.pnow { display: flex; align-items: center; gap: 12px; min-width: 0; }
.pnow-cover { width: 56px; height: 56px; border-radius: 8px; overflow: hidden; background: var(--raised); flex: none; position: relative; }
.pnow-cover img { width: 100%; height: 100%; object-fit: cover; }
.pnow-cover .equalizer { position: absolute; right: 5px; bottom: 5px; background: rgba(10,11,20,0.55); padding: 3px 4px; border-radius: 4px; }
/* Now-playing indicator laid over the cover in the player bar: always there while something is loaded, dancing while it plays. */
.pnow-cover .equalizer.eq-lg { inset: 0; right: auto; bottom: auto; width: 100%; height: 100%; margin: 0; padding: 0 17px; box-sizing: border-box; gap: 3px; align-items: flex-end; justify-content: center; padding-bottom: 14px; border-radius: 0; background: linear-gradient(to top, rgba(10,11,20,0.72), rgba(10,11,20,0.12) 70%, transparent); }
.pnow-cover .equalizer.eq-lg i { width: 4px; flex: none; height: 22px; animation-name: eq-lg; }
@keyframes eq-lg { 0%, 100% { transform: scaleY(0.23); } 50% { transform: scaleY(1); } }
.pnow-cover .equalizer.eq-lg i:nth-child(4) { animation-delay: -0.45s; }
.pnow-cover .equalizer.eq-lg.paused i { animation: none; transform: scaleY(0.23); opacity: 0.8; }
.pnow-text { min-width: 0; flex: 1 1 auto; }
.pnow .like-btn { flex: none; }
.pnow-acts { display: flex; align-items: center; flex: none; }
.pnow-acts .like-btn { width: 28px; height: 28px; }

/* Download button (next to the heart): arrow -> progress ring -> green "downloaded" disc */
.dl-btn { flex: none; position: relative; }
.dl-btn svg { width: 17px; height: 17px; }
.dl-btn.dl-done { color: var(--gold); --dl-ink: var(--gold-ink, #000); }
.dl-btn.dl-locked { color: var(--text-dim); }
.dl-btn.dl-downloading { color: var(--gold); }
.dl-ring.spin { animation: dl-spin 1s linear infinite; }
@keyframes dl-spin { to { transform: rotate(360deg); } }
html.no-anim .dl-ring.spin { animation: none; }
.trow-actions .dl-btn { opacity: 0; }
.trow:hover .trow-actions .dl-btn, .trow:focus-within .trow-actions .dl-btn, .trow-actions .dl-btn.dl-done, .trow-actions .dl-btn.dl-downloading, .trow-actions .dl-btn.dl-locked { opacity: 1; }
@media (hover: none) { .trow-actions .dl-btn { opacity: 1; } }
.erow .foot .dl-btn { margin-left: 2px; }
@media (max-width: 720px) { .pnow .bar-dl { display: none; } } /* the phone mini bar is tight: the full-screen player has the button */
.fp-meta .dl-btn { width: 44px; height: 44px; }
.fp-meta .dl-btn svg { width: 24px; height: 24px; }
.offline-pill { font-size: 11.5px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; padding: 4px 10px; border-radius: 99px; background: rgba(255,170,60,0.16); color: #ffb347; margin-right: 6px; white-space: nowrap; }
.pnow-text .t { font-size: 14px; font-weight: 620; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pnow-text .s { font-size: 12.5px; color: var(--text-faint); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pcenter { display: flex; flex-direction: column; align-items: center; gap: 8px; min-width: 0; }
.ptransport { display: flex; align-items: center; gap: 18px; }
.ptransport .icon-btn { background: none; }
.ptransport .icon-btn:hover { background: var(--raised); }
.ptransport .icon-btn.on { color: var(--gold); }
.pseek { display: flex; align-items: center; gap: 10px; width: 100%; }
.pseek .time { font-size: 11.5px; color: var(--text-faint); font-variant-numeric: tabular-nums; width: 36px; text-align: center; }
.pbar { flex: 1; height: 4px; border-radius: 2px; background: rgba(255,255,255,0.28); position: relative; cursor: pointer; touch-action: none; outline: none; }
.pbar::before { content: ''; position: absolute; left: 0; right: 0; top: -9px; bottom: -9px; } /* a 4px bar is too thin to grab: make the clickable area taller */
.pbar .fill { position: absolute; top: 0; bottom: 0; left: 0; border-radius: 2px; background: var(--text); width: 0%; }
.pbar:hover .fill, .pbar.dragging .fill, .pbar:focus-visible .fill { background: var(--gold); }
.pbar:focus-visible { box-shadow: 0 0 0 3px rgba(30,215,96,0.35); }
.pbar.dragging .knob { opacity: 1; }
.pmini { display: none; }
.pbar .knob { position: absolute; top: 50%; width: 11px; height: 11px; border-radius: 50%; background: var(--text); transform: translate(-50%, -50%); left: 0%; opacity: 0; transition: opacity 0.1s; }
.pbar:hover .knob { opacity: 1; }
.pright { display: flex; align-items: center; justify-content: flex-end; gap: 8px; }
.pvol { display: flex; align-items: center; gap: 8px; width: 100px; }
.pvol .pbar { height: 4px; }

/* ---------------------------------------------------------------------
   Lyrics + queue side panels
   --------------------------------------------------------------------- */
.side-panel {
  position: fixed; top: 8px; right: 8px; bottom: calc(var(--player-h) + 16px); width: 380px;
  background: var(--bg-1); border-radius: var(--radius-l); z-index: 55; display: flex; flex-direction: column;
  transform: translateX(115%); transition: transform 0.22s ease; border: 1px solid var(--hairline);
}
.side-panel.open { transform: translateX(0); }
.side-panel .sp-head { display: flex; align-items: center; justify-content: space-between; padding: 14px 14px 12px 20px; }
.side-panel .sp-head h3 { font-size: 16px; }
.side-panel .sp-body { flex: 1; overflow-y: auto; padding: 0 20px 20px; }
.sp-tabs { display: flex; gap: 18px; }
.sp-tab { background: none; border: none; color: var(--text-faint); font-size: 14.5px; font-weight: 700; padding: 6px 0; border-bottom: 2px solid transparent; }
.sp-tab.active { color: var(--text); border-color: var(--gold); }

.np-cover { width: 100%; aspect-ratio: 1; border-radius: 8px; overflow: hidden; margin-bottom: 18px; box-shadow: var(--shadow-lift); }
.np-cover img { width: 100%; height: 100%; object-fit: cover; }
.np-title { font-size: 20px; font-weight: 800; }
.np-artist { font-size: 14px; color: var(--text-dim); margin-top: 4px; }
.np-artist a:hover { text-decoration: underline; }
.np-credits { font-size: 12.5px; color: var(--text-faint); margin-top: 10px; line-height: 1.5; }
.np-section-head { display: flex; align-items: center; justify-content: space-between; margin: 26px 0 10px; }
.np-section-head span { font-size: 13px; font-weight: 700; color: var(--text-dim); }
.np-section-head a, .np-section-head button { font-size: 12px; color: var(--text-faint); font-weight: 600; }
.np-section-head a:hover, .np-section-head button:hover { color: var(--text); }
.np-lyrics-preview { display: flex; flex-direction: column; gap: 4px; }
.np-dim { color: var(--text-faint); font-size: 13.5px; }

.lyrics-line { font-family: var(--font-display); font-size: 19px; line-height: 1.6; color: var(--text-faint); padding: 5px 0; transition: color 0.2s; }
.np-lyrics-preview .lyrics-line { cursor: pointer; }
.np-lyrics-preview .lyrics-line:hover { color: var(--text); }
.lyrics-line.active { color: var(--gold-hi); font-weight: 560; }
.lyrics-plain { white-space: pre-line; font-family: var(--font-display); font-size: 17px; line-height: 1.8; color: var(--text-dim); }

.queue-list .trow { grid-template-columns: 1fr auto; }
.queue-section-label { font-size: 12px; color: var(--text-faint); padding: 12px 10px 4px; }

/* ---------------------------------------------------------------------
   Auth screen — the one place the aurora gradient runs loose
   --------------------------------------------------------------------- */
.auth-screen { min-height: 100vh; min-height: calc(100dvh / var(--ui-scale, 1)); display: flex; align-items: center; justify-content: center; position: relative; overflow: hidden; background: var(--bg); }
.auth-aurora { position: absolute; inset: -20%; filter: blur(60px) saturate(120%); opacity: 0.55; animation: drift 22s ease-in-out infinite alternate; }
.auth-aurora div { position: absolute; border-radius: 50%; }
.auth-aurora .a1 { width: 46vw; height: 46vw; left: -8%; top: -12%; background: radial-gradient(circle, var(--teal), transparent 65%); }
.auth-aurora .a2 { width: 50vw; height: 50vw; right: -10%; top: -6%; background: radial-gradient(circle, var(--violet), transparent 65%); }
.auth-aurora .a3 { width: 42vw; height: 42vw; left: 20%; bottom: -18%; background: radial-gradient(circle, var(--gold), transparent 65%); }
@keyframes drift { from { transform: translate(0,0) scale(1); } to { transform: translate(-2%, 3%) scale(1.06); } }
.auth-card { position: relative; z-index: 2; width: 400px; max-width: calc(100vw / var(--ui-scale, 1) - 40px); background: rgba(19,21,38,0.82); backdrop-filter: blur(18px); border: 1px solid var(--hairline-2); border-radius: var(--radius-l); padding: 36px 32px; box-shadow: var(--shadow-lift); }
.auth-brand { display: flex; align-items: center; gap: 11px; margin-bottom: 26px; }
.auth-brand svg { width: 34px; height: 34px; }
.auth-brand span { font-family: var(--font-display); font-size: 22px; font-weight: 600; }
.auth-card h1 { font-size: 24px; margin-bottom: 6px; }
.auth-card .sub { color: var(--text-dim); font-size: 13.5px; margin-bottom: 24px; }
.auth-tabs { display: flex; gap: 4px; background: var(--raised); border-radius: var(--radius-round); padding: 4px; margin-bottom: 24px; }
.auth-tabs button { flex: 1; border: none; background: none; color: var(--text-dim); padding: 9px; border-radius: var(--radius-round); font-size: 13.5px; font-weight: 620; }
.auth-tabs button.active { background: var(--gold); color: var(--gold-ink); }
.auth-card .btn { width: 100%; margin-top: 6px; }
.auth-foot { text-align: center; font-size: 12.5px; color: var(--text-faint); margin-top: 18px; }

/* ---------------------------------------------------------------------
   Stats / history charts (hand-built SVG, no chart library)
   --------------------------------------------------------------------- */
.stat-cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 14px; margin-bottom: 30px; }
.stat-card { background: var(--panel-solid); border: 1px solid var(--hairline); border-radius: var(--radius-m); padding: 18px; }
.stat-card .n { font-family: var(--font-display); font-size: 30px; font-weight: 560; }
.stat-card .l { font-size: 12.5px; color: var(--text-faint); margin-top: 4px; }
.bars-chart { display: flex; align-items: flex-end; gap: 4px; height: 140px; }
.bars-chart .bar-col { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; height: 100%; gap: 6px; }
.bars-chart .bar { width: 100%; max-width: 22px; border-radius: 3px 3px 0 0; background: var(--gold); opacity: 0.85; min-height: 2px; }
.bars-chart .lbl { font-size: 10px; color: var(--text-faint); white-space: nowrap; }
.hour-chart { display: flex; align-items: flex-end; gap: 3px; height: 90px; }
.hour-chart .bar { flex: 1; background: var(--violet); border-radius: 2px 2px 0 0; opacity: 0.8; min-height: 2px; }
.top-list { display: flex; flex-direction: column; gap: 2px; }
.top-list .trow-right .rank { width: 22px; text-align: right; color: var(--text-faint); }

/* ---------------------------------------------------------------------
   Studio / admin
   --------------------------------------------------------------------- */
.tabs { display: flex; gap: 6px; border-bottom: 1px solid var(--hairline); margin-bottom: 24px; }
.tabs button { background: none; border: none; color: var(--text-faint); padding: 11px 4px; margin-right: 22px; font-size: 14.5px; font-weight: 610; border-bottom: 2px solid transparent; }
.tabs button.active { color: var(--text); border-color: var(--gold); }
.data-table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.data-table th { text-align: left; color: var(--text-faint); font-weight: 610; font-size: 12px; padding: 10px 12px; border-bottom: 1px solid var(--hairline); }
.data-table td { padding: 11px 12px; border-bottom: 1px solid var(--hairline); vertical-align: middle; }
.data-table tr:last-child td { border-bottom: none; }
.status-pill { display: inline-flex; padding: 3px 10px; border-radius: var(--radius-round); font-size: 11.5px; font-weight: 640; }
.status-pill.pending { background: rgba(30,215,96,0.15); color: var(--gold-hi); }
.status-pill.approved { background: rgba(23,168,74,0.15); color: var(--teal); }
.status-pill.rejected, .status-pill.suspended { background: rgba(226,99,122,0.15); color: var(--pink); }
.mini-cover { width: 34px; height: 34px; border-radius: 6px; overflow: hidden; background: var(--raised); flex: none; }
.mini-cover img { width: 100%; height: 100%; object-fit: cover; }

.token-row { display: flex; align-items: center; justify-content: space-between; padding: 14px; border: 1px solid var(--hairline); border-radius: var(--radius-m); margin-bottom: 10px; }
.token-row .name { font-weight: 620; font-size: 14px; }
.token-row .meta { font-size: 12px; color: var(--text-faint); margin-top: 3px; }
.token-secret { font-family: ui-monospace, 'SF Mono', Menlo, monospace; background: var(--raised); border-radius: var(--radius-s); padding: 12px 14px; font-size: 13px; word-break: break-all; -webkit-user-select: all; user-select: all; }
.scope-grid { display: flex; flex-direction: column; gap: 8px; }
.scope-opt { display: flex; align-items: flex-start; gap: 10px; padding: 10px; border-radius: var(--radius-s); border: 1px solid var(--hairline); cursor: pointer; }
.scope-opt input { margin-top: 3px; }
.scope-opt .t { font-size: 13.5px; font-weight: 620; }
.scope-opt .d { font-size: 12px; color: var(--text-faint); }

.docs-endpoint { border-bottom: 1px solid var(--hairline); padding: 14px 0; }
.docs-endpoint:last-child { border-bottom: none; }
.docs-endpoint .row1 { display: flex; align-items: center; gap: 10px; margin-bottom: 5px; }
.docs-method { font-family: ui-monospace, monospace; font-size: 11.5px; font-weight: 700; padding: 2px 7px; border-radius: 4px; background: var(--raised); color: var(--teal); }
.docs-path { font-family: ui-monospace, monospace; font-size: 13px; }
.docs-scope { font-size: 11px; color: var(--text-faint); background: var(--raised); padding: 1px 8px; border-radius: var(--radius-round); }
.docs-desc { font-size: 13px; color: var(--text-dim); }

/* ---------------------------------------------------------------------
   Modal + toast
   --------------------------------------------------------------------- */
.modal-backdrop { position: fixed; inset: 0; background: rgba(6,7,13,0.6); backdrop-filter: blur(3px); z-index: 100; display: flex; align-items: center; justify-content: center; padding: 20px; }
.modal { width: 480px; max-width: 100%; max-height: 86vh; display: flex; flex-direction: column; background: var(--panel-solid); border: 1px solid var(--hairline-2); border-radius: var(--radius-l); box-shadow: var(--shadow-lift); }
.modal.wide { width: 640px; }
.modal-head { display: flex; align-items: center; justify-content: space-between; padding: 20px 24px; border-bottom: 1px solid var(--hairline); flex: none; }
.modal-head h3 { font-size: 17px; }
.modal-body { padding: 22px 24px; overflow-y: auto; }
.modal-foot { display: flex; justify-content: flex-end; gap: 10px; padding: 16px 24px; border-top: 1px solid var(--hairline); flex: none; }

.toast-stack { position: fixed; bottom: calc(var(--player-h) + 24px); left: 50%; transform: translateX(-50%); z-index: 200; display: flex; flex-direction: column; gap: 8px; align-items: center; }
.toast { background: var(--raised); border: 1px solid var(--hairline-2); color: var(--text); padding: 11px 20px; border-radius: var(--radius-round); font-size: 13.5px; box-shadow: var(--shadow-lift); animation: toast-in 0.18s ease; }
.toast.err { border-color: rgba(226,99,122,0.4); color: var(--pink); }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } }

/* ---------------------------------------------------------------------
   Responsive
   --------------------------------------------------------------------- */
@media (max-width: 980px) {
  /* !important so this wins over the width the sidebar resizer stores as an inline style */
  :root { --nav-w: 84px !important; }
  .nav { padding: 16px 8px; align-items: center; }
  /* hide only the text labels. The icons live in <span>s too, so a blanket "span" rule would hide them */
  .nav-brand .brand-text, .nav-item .nav-label, .nav-section-label, .nav-collapse-btn, .nav-resize-handle { display: none; }
  .nav-brand { justify-content: center; padding: 6px 0 22px; }
  .nav-item { justify-content: center; padding: 12px; width: auto; }
  .side-panel { width: calc(100vw / var(--ui-scale, 1) - 16px); }
}
@media (max-width: 720px) {
  :root { --player-h: 64px; --tabbar-h: 58px; }
  #app { grid-template-columns: 1fr; grid-template-rows: minmax(0, 1fr); padding: 0; gap: 0; height: var(--app-h, 100dvh); } /* --app-h = the truly visible height (set in app.js), for phones without dvh */
  .nav { display: none; }
  .main-col { border-radius: 0; gap: 0; }
  .topbar, .content { border-radius: 0; }
  .topbar { padding: 0 12px; gap: 8px; }
  .topbar-nav { display: none; }
  .topbar-spacer { display: none; }
  .search-box { max-width: none; height: 40px; padding: 0 12px; }
  .ts-panel { position: fixed; left: 8px; right: 8px; top: calc(var(--topbar-h) + 10px); max-height: calc(100dvh / var(--ui-scale, 1) - var(--topbar-h) - var(--player-h) - var(--tabbar-h) - 28px); }
  .avatar-btn .name, .avatar-btn svg { display: none; }
  .avatar-btn { padding: 0; background: none; }
  /* leave room for the fixed player bar + tab bar (+ the iPhone home-indicator inset) so the last shelf is never covered */
  .content { padding: 18px 14px calc(var(--player-h) + var(--tabbar-h) + env(safe-area-inset-bottom, 0px) + 28px); }
  .content.tight { padding: 0 0 calc(var(--player-h) + var(--tabbar-h) + env(safe-area-inset-bottom, 0px) + 12px); }

  .mobile-tabbar { display: flex; }
  .player-bar {
    left: 0; right: 0; bottom: calc(var(--tabbar-h) + env(safe-area-inset-bottom, 0px)); border-radius: 0;
    grid-template-columns: 1fr; padding: 0 14px; height: var(--player-h); border-left: none; border-right: none; border-bottom: none;
  }
  .pcenter, .pright { display: none; }
  .pmini { display: block; position: absolute; left: 0; right: 0; top: 0; height: 3px; border-radius: 0; flex: none; }
  .pmini::before { top: -14px; bottom: -8px; }
  .pmini .fill { border-radius: 0; background: var(--gold); }
  .pnow { width: 100%; }
  .pnow-text .s { display: none; }
  .pnow-mobile-controls { display: flex; align-items: center; gap: 6px; margin-left: auto; }

  .detail-header, .sk-header { flex-direction: column; align-items: flex-start; }
  .sk-cover { width: 140px; height: 140px; }
  .sk-meta { width: 100%; }
  .detail-header .cover { width: 140px; height: 140px; }
  .detail-header h1 { font-size: 28px; }
  .side-panel { top: auto; bottom: calc(var(--player-h) + var(--tabbar-h) + 4px); height: 65vh; right: 0; width: 100%; border-radius: var(--radius-l) var(--radius-l) 0 0; }
  .modal { width: 100%; }
  .tabs { overflow-x: auto; flex-wrap: nowrap; }
  .tabs button { flex: none; }
  .data-table { display: block; overflow-x: auto; white-space: nowrap; }
  .field-row { flex-direction: column; gap: 0; }
  .stat-cards { grid-template-columns: repeat(2, 1fr); }
}

/* --------------------------------------------------------------------- Top bar search --------------------------------------------------------------------- */
.search-box { background: var(--hover); border: 1px solid transparent; transition: border-color 0.15s, background 0.15s; }
.search-box:hover { background: #2f2f2f; }
.search-box:focus-within { border-color: rgba(255,255,255,0.85); background: #2a2a2a; }
.search-box input { min-width: 0; flex: 1; -webkit-appearance: none; appearance: none; }
.search-box input::-webkit-search-cancel-button, .search-box input::-webkit-search-decoration { -webkit-appearance: none; display: none; }
.ts-clear { flex: none; width: 24px; height: 24px; border: none; background: none; color: var(--text-dim); display: flex; align-items: center; justify-content: center; border-radius: 50%; padding: 0; cursor: pointer; }
.ts-clear:hover { color: var(--text); background: rgba(255,255,255,0.1); }
.ts-clear svg { width: 14px; height: 14px; }
.ts-panel {
  position: absolute; top: calc(100% + 8px); left: 0; right: 0; z-index: 90;
  background: #1f1f1f; border-radius: 10px; box-shadow: var(--shadow-lift); border: 1px solid var(--hairline);
  padding: 6px; max-height: min(70vh, 560px); overflow-y: auto; overscroll-behavior: contain; text-align: left;
}
.ts-panel[hidden] { display: none; }
.ts-head { display: flex; align-items: center; justify-content: space-between; font-size: 12px; font-weight: 700; color: var(--text-faint); padding: 10px 10px 4px; letter-spacing: 0.02em; }
.ts-link { background: none; border: none; color: var(--text-dim); font-size: 12px; font-weight: 600; cursor: pointer; padding: 0; }
.ts-link:hover { color: var(--text); text-decoration: underline; }
.ts-empty { padding: 18px 12px; color: var(--text-dim); font-size: 13.5px; }
.ts-row { display: flex; align-items: center; gap: 12px; width: 100%; padding: 7px 10px; border: none; background: none; color: var(--text); border-radius: 6px; text-align: left; cursor: pointer; font: inherit; }
.ts-row.active, .ts-row:hover { background: var(--hover); }
.ts-row img { width: 40px; height: 40px; border-radius: 4px; object-fit: cover; flex: none; background: var(--raised); }
.ts-row img.round { border-radius: 50%; }
.ts-row > svg { width: 18px; height: 18px; flex: none; color: var(--text-dim); margin: 0 11px; }
.ts-text { display: flex; flex-direction: column; min-width: 0; }
.ts-title { font-size: 14px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ts-sub { font-size: 12.5px; color: var(--text-dim); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ts-all { margin-top: 4px; border-top: 1px solid var(--hairline); border-radius: 0 0 6px 6px; }
.ts-clear[hidden] { display: none; }

/* --------------------------------------------------------------------- Creator page switcher (Studio) --------------------------------------------------------------------- */
.page-switch { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; margin: 0 0 22px; }
.ps-list { display: flex; flex-wrap: wrap; gap: 8px; }
.ps-item { display: inline-flex; align-items: center; gap: 8px; max-width: 220px; padding: 5px 14px 5px 5px; border-radius: 999px; border: 1px solid var(--hairline-2); background: var(--raised); color: var(--text); font: inherit; font-size: 13.5px; font-weight: 600; cursor: pointer; transition: background 0.12s, border-color 0.12s; }
.ps-item:hover { background: var(--hover); }
.ps-item.active { background: var(--text); color: #000; border-color: var(--text); }
.ps-item img { width: 26px; height: 26px; border-radius: 50%; object-fit: cover; flex: none; background: var(--hover); }
.ps-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ps-dot { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--text-faint); }
.ps-dot.approved { background: var(--gold); }
.ps-dot.pending { background: #f5b942; }
.ps-dot.rejected, .ps-dot.suspended { background: var(--pink, #e2637a); }
.ps-add { padding-left: 12px; color: var(--text-dim); border-style: dashed; }
.ps-add svg { width: 16px; height: 16px; flex: none; }
.ps-add.active { color: #000; }
.ps-note { font-size: 12.5px; color: var(--text-faint); }

/* --------------------------------------------------------------------- Private tracks --------------------------------------------------------------------- */
.lock-badge { display: inline-flex; vertical-align: -2px; margin-right: 5px; color: #ffb547; }
.lock-badge svg { width: 13px; height: 13px; }
.vis-pill { display: inline-flex; align-items: center; gap: 5px; border: 0; cursor: pointer; font: inherit; font-size: 12px; font-weight: 700; padding: 4px 11px; border-radius: 999px; transition: filter 0.15s, transform 0.1s; }
.vis-pill:hover { filter: brightness(1.2); }
.vis-pill:active { transform: scale(0.96); }
.vis-pill:disabled { opacity: 0.5; cursor: progress; }
.vis-pill svg { width: 12px; height: 12px; }
.vis-pill.public { background: rgba(30,215,96,0.16); color: var(--gold); }
.vis-pill.private { background: rgba(255,181,71,0.16); color: #ffb547; }

/* --------------------------------------------------------------------- Playlist pictures --------------------------------------------------------------------- */
.collage { overflow: hidden; background: var(--raised); }
.pl-thumb { width: 36px; height: 36px; border-radius: 4px; overflow: hidden; flex: none; display: block; background: var(--raised); }
.pl-thumb .collage { width: 100%; height: 100%; border-radius: 0; }
.nav-playlists .nav-item.pl-nav { gap: 11px; padding: 5px 8px; align-items: center; }
.pl-nav-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.nav-item.pick-row { gap: 12px; text-align: left; align-items: center; padding: 6px 8px; }
.pick-text { display: flex; flex-direction: column; min-width: 0; line-height: 1.3; }
.pick-text b { font-weight: 600; font-size: 14px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pick-text small { color: var(--text-faint); font-size: 12px; }

/* Collapsed / narrow sidebar: playlists stay visible as a column of just their pictures (name on hover). */
.nav.collapsed .nav-playlists { width: 100%; align-items: center; gap: 6px; padding-top: 10px; margin-top: 4px; border-top: 1px solid var(--hairline); }
.nav.collapsed .nav-playlists .nav-item.pl-nav { padding: 4px; width: auto; justify-content: center; border-radius: 8px; }
.nav.collapsed .nav-playlists .pl-nav-text, .nav.collapsed .nav-playlists > .nav-section-label { display: none; }
.nav.collapsed .nav-playlists .pl-thumb { width: 44px; height: 44px; border-radius: 6px; }
.nav.collapsed .nav-playlists .nav-item.pl-nav.active { background: var(--hover); }
@media (max-width: 980px) and (min-width: 721px) {
  .nav-playlists { width: 100%; align-items: center; gap: 6px; padding-top: 10px; margin-top: 4px; border-top: 1px solid var(--hairline); }
  .nav-playlists .nav-item.pl-nav { padding: 4px; width: auto; justify-content: center; border-radius: 8px; }
  .nav-playlists .pl-nav-text, .nav-playlists > .nav-section-label { display: none; }
  .nav-playlists .pl-thumb { width: 44px; height: 44px; border-radius: 6px; }
}

/* --------------------------------------------------------------------- Pinned playlists & Liked Songs --------------------------------------------------------------------- */
.liked-tile { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; color: #fff; }
.liked-tile > span { display: flex; width: 34%; height: 34%; }  /* icon() wraps the svg in a span, so size the span and let the svg fill it */
/* three classes deep on purpose: generic "svg inside a nav item / button" size rules must never win here, or the icon spills out of its box and sits off-centre */
.liked-tile > span > svg { width: 100%; height: 100%; flex: none; filter: drop-shadow(0 0 2px rgba(0,0,0,0.25)); }
.liked-tile.big { aspect-ratio: 1; border-radius: inherit; }
.liked-tile.big > span { width: 32%; height: 32%; }
/* the glyph's svg box IS its ink (see GLYPH_BOX in components.js), so centring the box centres what you see; the shadow is symmetric on purpose */
.detail-header .cover.liked-cover { position: relative; border: 0; padding: 0; cursor: pointer; overflow: hidden; }
.liked-edit { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: rgba(0,0,0,0.55); opacity: 0; transition: opacity 0.15s; color: #fff; }
.liked-edit svg { width: 34px; height: 34px; }
.liked-cover:hover .liked-edit, .liked-cover:focus-visible .liked-edit { opacity: 1; }
.liked-preview { width: 120px; height: 120px; border-radius: 10px; overflow: hidden; margin: 0 auto 18px; box-shadow: var(--shadow-lift); }
.lk-grid { display: flex; flex-wrap: wrap; gap: 10px; }
#lk-icons { max-width: calc(4 * 48px + 3 * 10px); } /* 8 icons = two even rows of 4 */
.lk-opt { width: 48px; height: 48px; border-radius: 10px; border: 2px solid transparent; background: var(--raised); color: var(--text); display: flex; align-items: center; justify-content: center; cursor: pointer; transition: transform 0.1s, border-color 0.15s; }
.lk-opt svg { width: 22px; height: 22px; }
.lk-opt:hover { transform: scale(1.06); }
.lk-opt.on { border-color: var(--text); }
.lk-color { border-radius: 50%; }

.nav-playlists .nav-item.pl-nav { position: relative; }
.pl-nav-text { display: flex; flex-direction: column; min-width: 0; flex: 1; line-height: 1.25; }
.pl-nav-text b { font-weight: 600; font-size: 13.5px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pl-nav-text small { display: flex; align-items: center; gap: 4px; font-size: 11.5px; color: var(--text-faint); font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pl-nav-text small svg { width: 11px; height: 11px; color: var(--gold); flex: none; }
.pl-pin { flex: none; width: 26px; height: 26px; border-radius: 50%; border: 0; background: none; color: var(--text-dim); display: flex; align-items: center; justify-content: center; opacity: 0; cursor: pointer; padding: 0; }
.pl-pin svg { width: 15px; height: 15px; }
.pl-nav:hover .pl-pin, .pl-pin:focus-visible { opacity: 1; }
.pl-pin:hover { color: var(--text); background: var(--hover); }
.pl-nav.pinned .pl-pin { color: var(--gold); }
.pin-toggle.on { color: var(--gold); }
.nav.collapsed .pl-pin, .nav.collapsed .pl-nav-text { display: none; }
@media (max-width: 980px) and (min-width: 721px) { .pl-pin { display: none; } }

/* ---------------------------------------------------------------------
   Desktop layout: the player bar is its own row at the bottom of the app grid (like Spotify), so the sidebar and the
   page end above it instead of running underneath. With nothing loaded the row collapses to nothing and slides in
   when something starts playing. Phones keep the fixed bar above the tab bar (see the max-width: 720px block).
   --------------------------------------------------------------------- */
@media (min-width: 721px) {
  #app:not(.no-auth) { grid-template-rows: minmax(0, 1fr) auto; row-gap: 0; }
  #app > .nav { grid-column: 1; grid-row: 1; }
  #app > .main-col { grid-column: 2; grid-row: 1; }
  #app > .player-bar {
    position: static; grid-column: 1 / -1; grid-row: 2; width: auto; margin-top: 8px;
    height: var(--player-h); overflow: hidden; transition: height 0.22s ease, margin 0.22s ease, padding 0.22s ease;
  }
  #app > .player-bar.empty { height: 0; margin-top: 0; padding-top: 0; padding-bottom: 0; border-width: 0; }
  .content { padding: 28px 30px 28px; }
  .lyrics-page { margin: -28px -30px -28px; min-height: 0; height: calc(100vh - var(--topbar-h) - var(--player-h) - 40px); height: calc(100dvh / var(--ui-scale, 1) - var(--topbar-h) - var(--player-h) - 40px); } /* fixed height: the lyrics scroll inside the page, not the whole page */
}

.private-note { margin-left: 10px; color: #ffb547; font-weight: 600; text-transform: none; letter-spacing: 0; font-size: 12.5px; }
.private-note .lock-badge { margin-right: 4px; }
.ps-name .lock-badge { margin-right: 4px; }
.ps-name .lock-badge svg { width: 11px; height: 11px; }

/* ---- Collaborations ---- */
.tab-badge { display: inline-block; min-width: 18px; padding: 0 6px; margin-left: 6px; border-radius: 9px; background: var(--gold); color: #0b0c14; font-size: 11px; font-weight: 700; line-height: 18px; text-align: center; }
.collab-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
.collab-chips:empty { display: none; }
.collab-chip { display: inline-flex; align-items: center; gap: 6px; }
.collab-chip em { font-style: normal; font-size: 11px; color: var(--text-faint); }
.collab-chip button { background: none; border: 0; color: inherit; cursor: pointer; font-size: 16px; line-height: 1; padding: 0 2px; opacity: 0.7; }
.collab-chip button:hover { opacity: 1; }
.collab-search { position: relative; }
.collab-results { position: absolute; z-index: 20; left: 0; right: 0; top: calc(100% + 4px); max-height: 240px; overflow-y: auto; background: var(--raised, #1c1e2e); border: 1px solid var(--line, rgba(255,255,255,0.1)); border-radius: 10px; padding: 4px; box-shadow: 0 12px 30px rgba(0,0,0,0.45); }
.collab-results[hidden] { display: none; }
.collab-opt { display: flex; align-items: center; gap: 10px; width: 100%; padding: 7px 8px; background: none; border: 0; border-radius: 8px; color: inherit; cursor: pointer; text-align: left; font: inherit; }
.collab-opt:hover { background: rgba(255,255,255,0.07); }
.collab-opt img { width: 28px; height: 28px; border-radius: 50%; object-fit: cover; flex: none; }
.collab-opt span { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.collab-opt small { color: var(--text-faint); font-size: 11px; }
.collab-none { padding: 10px; color: var(--text-faint); font-size: 13px; }

/* ---------------------------------------------------------------------
   Seek-bar hover box: the time under the pointer, shown above the bar
   --------------------------------------------------------------------- */
.seek-tip {
  position: fixed; z-index: 400; pointer-events: none; left: 0; top: 0;
  transform: translate(-50%, -100%); padding: 4px 8px; border-radius: 6px;
  background: #fff; color: #111; font-size: 12px; font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1.2;
  box-shadow: 0 4px 14px rgba(0,0,0,0.45); opacity: 0; visibility: hidden; transition: opacity 0.1s;
}
.seek-tip.show { opacity: 1; visibility: visible; }
.seek-tip::after { content: ''; position: absolute; left: 50%; bottom: -4px; width: 8px; height: 8px; background: inherit; transform: translateX(-50%) rotate(45deg); border-radius: 1px; }

/* ---------------------------------------------------------------------
   Full-screen player (phones only; opened by tapping the mini player)
   --------------------------------------------------------------------- */
.full-player { display: none; }
@media (max-width: 720px) {
  .full-player {
    display: flex; flex-direction: column; position: fixed; left: 0; right: 0; top: 0; z-index: 80;
    height: var(--app-h, 100dvh); background: var(--bg-1); overflow: hidden;
    padding: calc(env(safe-area-inset-top, 0px) + 6px) 22px calc(env(safe-area-inset-bottom, 0px) + 16px);
    animation: fp-in 0.26s cubic-bezier(0.2, 0.8, 0.2, 1);
  }
  .full-player.swiping { transition: none; }
  @keyframes fp-in { from { transform: translateY(100%); } to { transform: none; } }
  body.fp-open { overflow: hidden; }
  .fp-bg { position: absolute; inset: -40px; width: calc(100% + 80px); height: calc(100% + 80px); object-fit: cover; filter: blur(64px) saturate(1.4); opacity: 0.34; z-index: 0; pointer-events: none; }
  .full-player > *:not(.fp-bg) { position: relative; z-index: 1; }
  .fp-top { display: flex; align-items: center; justify-content: space-between; flex: none; height: 48px; }
  .fp-top .icon-btn, .fp-top-spacer { width: 40px; height: 40px; flex: none; }
  .fp-top .icon-btn { background: none; }
  .fp-top .icon-btn svg { width: 26px; height: 26px; }
  .fp-label { font-size: 13px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--text-dim); }
  .fp-art { flex: 1 1 auto; min-height: 0; display: flex; align-items: center; justify-content: center; padding: 10px 0 14px; }
  .fp-art img { width: min(100%, 52dvh); max-height: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 14px; background: var(--raised); box-shadow: 0 18px 50px rgba(0,0,0,0.55); }
  .fp-meta { display: flex; align-items: center; gap: 12px; flex: none; margin-top: 4px; }
  .fp-meta-text { flex: 1; min-width: 0; }
  .fp-title { font-size: 22px; font-weight: 750; line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .fp-by { font-size: 15px; color: var(--text-dim); margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .fp-by a { color: inherit; }
  .fp-meta .like-btn { flex: none; width: 44px; height: 44px; }
  .fp-meta .like-btn svg { width: 26px; height: 26px; }
  .fp-seek { flex: none; margin-top: 18px; }
  .fp-bar { height: 5px; width: 100%; flex: none; }
  .fp-bar::before { top: -16px; bottom: -16px; }
  .fp-bar .knob { opacity: 1; width: 14px; height: 14px; }
  .fp-bar .fill { background: var(--gold); }
  .fp-times { display: flex; justify-content: space-between; margin-top: 8px; font-size: 12px; color: var(--text-faint); font-variant-numeric: tabular-nums; }
  .fp-transport { flex: none; display: flex; align-items: center; justify-content: space-between; margin: 10px 0 6px; }
  .fp-transport .icon-btn { background: none; width: 48px; height: 48px; }
  .fp-transport .icon-btn svg { width: 24px; height: 24px; }
  .fp-transport .fp-skip svg { width: 32px; height: 32px; }
  .fp-transport .icon-btn.on { color: var(--gold); }
  .fp-play { width: 68px; height: 68px; border-radius: 50%; display: flex; align-items: center; justify-content: center; }
  .fp-play svg { width: 32px; height: 32px; }
  .fp-extras { flex: none; display: flex; justify-content: space-around; gap: 8px; margin-top: 8px; padding-top: 10px; border-top: 1px solid var(--hairline); }
  .fp-extra { display: flex; flex-direction: column; align-items: center; gap: 4px; background: none; border: none; color: var(--text-dim); font: inherit; font-size: 11.5px; font-weight: 600; padding: 6px 14px; cursor: pointer; border-radius: 10px; }
  .fp-extra svg { width: 22px; height: 22px; }
  .fp-extra:active { background: var(--hover); color: var(--text); }
}
@media (max-width: 720px) and (max-height: 640px) {
  .fp-art img { width: min(100%, 36dvh); }
  .fp-title { font-size: 19px; }
  .fp-transport { margin: 4px 0 2px; }
}

/* ---------------------------------------------------------------------
   Wide screens: the Now Playing / Queue panel is a real column of the app, like the player bar is a real row. Opening it makes the
   page narrower instead of covering it (and closing gives the room back). Below 1100px there isn't the room to give up, so the panel
   stays an overlay there (see .side-panel above).
   --------------------------------------------------------------------- */
@media (min-width: 1100px) {
  #app:not(.no-auth) {
    --sp-w: clamp(320px, 26vw, 400px);
    grid-template-columns: var(--nav-w) minmax(0, 1fr) 0px;
    transition: grid-template-columns 0.22s ease;
  }
  #app.np-open:not(.no-auth) { grid-template-columns: var(--nav-w) minmax(0, 1fr) var(--sp-w); }
  #app > .side-panel {
    position: static; grid-column: 3; grid-row: 1; width: auto; min-width: 0; height: auto; overflow: hidden;
    transform: none; transition: margin 0.22s ease, opacity 0.22s ease, visibility 0.22s;
    margin-left: -8px; /* cancels the grid gap while the column is 0 wide */
    opacity: 0; visibility: hidden; pointer-events: none;
  }
  #app.np-open > .side-panel { margin-left: 0; opacity: 1; visibility: visible; pointer-events: auto; }
  /* keep the content at full width while the column grows/shrinks, so it is clipped rather than squeezed */
  #app > .side-panel > .sp-head, #app > .side-panel > .sp-body { min-width: var(--sp-w); box-sizing: border-box; }
}


/* ---------------------------------------------------------------------
   Player bar, all sizes. Podcast episodes get back-15 / forward-15 next to play, and shuffle/repeat like songs do.
   Tablets (721-1099 px) used to keep the desktop 3-column grid, whose middle column wanted 360 px: the sides collapsed, so the title
   vanished and the cover ran over the time. Here the columns share the width instead, and the volume slider gives way to mute.
   --------------------------------------------------------------------- */
.ptransport.ep { gap: 12px; }
.ptransport .skip15 svg { width: 22px; height: 22px; }
.pright { min-width: 0; flex-wrap: nowrap; }
.pnow-text .t, .pnow-text .s { max-width: 100%; }
@media (min-width: 721px) and (max-width: 1099px) {
  .player-bar { grid-template-columns: minmax(0, 1fr) minmax(312px, 1.3fr) auto; gap: 12px; padding: 0 14px; }
  .pnow-cover { width: 52px; height: 52px; }
  .pnow-text .t { font-size: 14px; }
  .pnow-text .s { display: block; }
  .ptransport { gap: 12px; }
  .ptransport.ep { gap: 4px; }
  .pright { gap: 4px; }
  .pvol { width: auto; }
  .pvol .pbar { display: none; }
}
@media (min-width: 721px) and (max-width: 899px) {
  /* the right-hand cluster gained the sleep timer: on a narrow tablet the mute button goes (volume is on the device, and the M key still mutes) so the title keeps its room */
  .pvol { display: none; }
  .pright { gap: 2px; }
  .pright .icon-btn { width: 36px; height: 36px; }
}
@media (min-width: 900px) and (max-width: 1099px) {
  .pvol { width: 92px; }
  .pvol .pbar { display: block; }
}
@media (max-width: 720px) {
  .fp-skiprow { flex: none; display: flex; justify-content: center; gap: 12px; margin: 0 0 4px; }
  .fp-jump { display: flex; align-items: center; gap: 8px; background: var(--raised); border: none; color: var(--text); font: inherit; font-size: 13px; font-weight: 650; padding: 10px 16px; border-radius: 999px; cursor: pointer; }
  .fp-jump svg { width: 22px; height: 22px; }
  .fp-jump:active { background: var(--hover); }
}


/* ---------------------------------------------------------------------
   Names in the player bar are links, and a name too long for its space glides sideways (see marquee.js)
   --------------------------------------------------------------------- */
.mq { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.mq-run { text-overflow: clip; -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 18px), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 18px), transparent); }
.mq-in { display: inline-block; white-space: nowrap; animation: mq-slide var(--mq-dur, 9s) ease-in-out infinite alternate; will-change: transform; }
.mq-run:hover .mq-in, .mq-run:focus-within .mq-in { animation-play-state: paused; }
@keyframes mq-slide { 0%, 16% { transform: translateX(0); } 84%, 100% { transform: translateX(var(--mq-dist, 0px)); } }
.pnow-text a, .fp-meta-text a { color: inherit; }
.pnow-text .s a:hover, .pnow-text .t a:hover, .fp-by a:hover { text-decoration: underline; color: var(--text); }
.pnow-text .s a { color: var(--text-faint); }
.pnow-text .s a:hover { color: var(--text); }
.fp-title { text-overflow: ellipsis; }
@media (max-width: 720px) {
  .pnow-text .s { display: block; font-size: 12px; }
  .pnow-text .t { font-size: 14px; }
}


/* ---------------------------------------------------------------------
   Interface scale (Settings → Appearance)
   --------------------------------------------------------------------- */
.scale-block { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--hairline); }
.scale-block .title { font-weight: 650; margin-bottom: 4px; }
.scale-block .desc { color: var(--text-faint); font-size: 12.5px; line-height: 1.5; max-width: 560px; margin-bottom: 14px; }
.scale-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 14px; }
.scale-chip { min-width: 62px; padding: 9px 14px; border-radius: 999px; border: 1px solid var(--hairline-2, var(--hairline)); background: var(--raised); color: var(--text-dim); font: inherit; font-size: 13.5px; font-weight: 650; font-variant-numeric: tabular-nums; cursor: pointer; transition: background 0.15s, color 0.15s, border-color 0.15s; }
.scale-chip:hover { background: var(--hover); color: var(--text); }
.scale-chip.on { background: var(--gold); border-color: var(--gold); color: var(--gold-ink, #000); }
.scale-chip:focus-visible { outline: 2px solid var(--gold-hi); outline-offset: 2px; }

/* ---------------------------------------------------------------------
   Icon sizes: one step bigger than the first version (the outline icons read small next to the text)
   --------------------------------------------------------------------- */
.icon-btn { width: 42px; height: 42px; }
.icon-btn svg { width: 22px; height: 22px; }
.like-btn { width: 34px; height: 34px; }
.like-btn svg { width: 20px; height: 20px; }
.dl-btn svg { width: 20px; height: 20px; }
.nav-item svg { width: 25px; height: 25px; }
.nav-brand > svg { width: 32px; height: 32px; } /* only the logo: this used to match the collapse button's chevron too, blowing it up to 32px inside a 26px circle (off-centre) */
.nav-brand .nav-collapse-btn svg { width: 17px; height: 17px; }
.mtab svg { width: 26px; height: 26px; }
.search-box svg { width: 20px; height: 20px; }
.play-btn svg { width: 26px; height: 26px; }
.play-btn.sm svg { width: 19px; height: 19px; }
.btn svg { width: 18px; height: 18px; }
.ctx-item svg { width: 19px; height: 19px; }
.lp-sync-btn svg { width: 17px; height: 17px; }
.verified-badge svg { width: 18px; height: 18px; }
.trow-actions { gap: 4px; }
/* The player bar is tight (the tablet layouts have to fit seven transport buttons): bigger icons, but the same button boxes as before. */
.ptransport .icon-btn, .pright .icon-btn { width: 38px; height: 38px; }
.ptransport .icon-btn svg, .pright .icon-btn svg { width: 21px; height: 21px; }
.pnow-acts .like-btn { width: 30px; height: 30px; }
@media (min-width: 721px) { .pnow { gap: 9px; } }

/* ----------------------------------------------------------------- Playback speed and sleep timer ----------------------------------------------------------------- */
[data-speed-btn][hidden] { display: none !important; }
.spd-chip { flex: none; min-width: 40px; height: 26px; padding: 0 9px; border-radius: 999px; border: 1px solid var(--hairline); background: none; color: var(--text-dim); font: inherit; font-size: 11.5px; font-weight: 700; font-variant-numeric: tabular-nums; cursor: pointer; display: inline-flex; align-items: center; justify-content: center; }
.spd-chip:hover { color: var(--text); border-color: var(--text-faint); }
.spd-chip.on { color: var(--gold); border-color: var(--gold); }
.pseek .spd-chip { margin-right: 2px; }
.sleep-btn { position: relative; }
.sleep-btn.on { color: var(--gold); }
.sl-left { font-style: normal; font-size: 9.5px; font-weight: 800; line-height: 1; letter-spacing: 0.01em; font-variant-numeric: tabular-nums; color: #000; background: var(--gold); padding: 2px 4px; border-radius: 6px; position: absolute; left: 50%; bottom: 0; transform: translateX(-50%); white-space: nowrap; pointer-events: none; }
.sl-left:empty { display: none; }
.sp-tools { display: flex; align-items: center; gap: 6px; }
.fp-extra.sleep-btn .sl-left { top: 0; bottom: auto; left: auto; right: 6px; transform: none; }
.fp-spd { font-size: 16px; line-height: 22px; height: 22px; font-weight: 800; font-variant-numeric: tabular-nums; }
.fp-extra.spd-btn.on, .fp-extra.sleep-btn.on { color: var(--gold); }
@media (max-width: 720px) { .fp-extra { padding-left: 9px; padding-right: 9px; } }
.opt-menu { min-width: 240px; }
.opt-head { font-size: 11.5px; font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--text-faint); padding: 8px 10px 6px; }
.rate-grid { display: grid; grid-template-columns: repeat(8, 1fr); gap: 4px; padding: 2px 4px 6px; width: 392px; max-width: calc(100vw - 40px); box-sizing: border-box; }
.rate-opt { background: var(--raised); color: var(--text); border: none; border-radius: 6px; padding: 8px 0; font: inherit; font-size: 12.5px; font-weight: 650; font-variant-numeric: tabular-nums; cursor: pointer; }
.rate-opt:hover { background: var(--hover); }
.rate-opt.on { background: var(--gold); color: #000; }
.sl-status { padding: 2px 10px 8px; font-size: 12.5px; color: var(--text-dim); }
.sl-status b { color: var(--gold); font-variant-numeric: tabular-nums; }
.sleep-menu .ctx-item { width: 100%; justify-content: space-between; }
.sleep-menu .ctx-item.sel { color: var(--gold); }
.sleep-menu .ctx-item.sel svg { color: var(--gold); }

/* icon() wraps each svg in <span class="ic">. As a plain inline span it kept a line box around the svg (room for descenders below it), so every icon sat about 2px above the
   centre of its button. As an inline-flex box it is exactly as tall as the svg, so centring a button's icon centres the icon. */
.ic { display: inline-flex; }

/* Cover pictures appear only when completely loaded (imgfallback.js adds .ld), fading in over the tile's grey, so they never paint
   half-way down while the bytes arrive. The tile itself is always there, so nothing jumps. */
.pnow-cover img, .np-cover img, .fp-art img, .fp-bg, .trow-cover img, .detail-header .cover img, .card .art-wrap img,
.erow .cover img, .mini-cover img, .lp-cover img, .collage img { opacity: 0; transition: opacity .25s ease; }
.fp-bg.ld { opacity: 0.34; } /* its resting opacity (the blurred backdrop) */
.pnow-cover img.ld, .np-cover img.ld, .fp-art img.ld, .trow-cover img.ld, .detail-header .cover img.ld, .card .art-wrap img.ld,
.erow .cover img.ld, .mini-cover img.ld, .lp-cover img.ld, .collage img.ld { opacity: 1; }
.np-cover, .lp-cover { background: var(--raised); }
