/* ==========================================================================
   SoundBox — design system
   --------------------------------------------------------------------------
   One stylesheet for every page. nav.js swaps only <main> on a soft
   navigation, so anything a page needs must live here rather than in a
   per-page <style> block: the incoming page's <head> never arrives.

   Token tiers (per the design-system guidance):
     1. primitives   — raw scales: the warm neutral ramp, accents, spacing,
                       type, radius, motion. Never referenced by components.
     2. semantic     — purpose names: --bg, --surface, --line, --fg, --accent.
                       Components consume these only.
     3. component    — per-component decisions (control heights, row padding,
                       art sizes) so a size can change in one place.

   Visual language: flat border-separated panels, tracked uppercase mono
   labels, an amber "studio" accent with red for ON AIR / destructive. No
   drop shadows doing layout work — 1px rules do that.

   Mobile-first: the base rules are the small screen, then min-width
   queries add columns and shrink nothing below its tap target.
   ========================================================================== */

/* ==========================================================================
   1. PRIMITIVES
   ========================================================================== */
:root {
  color-scheme: dark;

  /* --- warm neutral ramp --- */
  --c-1000: #0a0908;
  --c-950:  #0e0d0b;
  --c-900:  #141311;
  --c-850:  #1a1815;
  --c-800:  #221f1b;
  --c-750:  #2a2723;
  --c-700:  #332f29;
  --c-600:  #423d35;
  --c-500:  #5a544a;
  --c-400:  #7d766b;
  --c-300:  #9a9287;
  --c-200:  #c9c2b6;
  --c-100:  #ebe6dd;

  /* --- accents --- */
  --amber-300: #ffd694;
  --amber-400: #ffc46a;
  --amber-500: #f0a13c;
  --amber-700: #a86818;
  --red-400:   #ff7b71;
  --red-500:   #ff5f56;
  --red-700:   #a5322a;
  --green-500: #7fd88f;
  --green-700: #2f7a41;

  /* --- translucent accents (pre-mixed; no color-mix dependency) --- */
  --amber-10: rgba(240, 161, 60, .10);
  --amber-16: rgba(240, 161, 60, .16);
  --amber-45: rgba(240, 161, 60, .45);
  --red-12:   rgba(255, 95, 86, .12);
  --red-16:   rgba(255, 95, 86, .16);
  --red-45:   rgba(255, 95, 86, .45);
  --green-12: rgba(127, 216, 143, .12);
  --green-45: rgba(127, 216, 143, .45);
  --ink-06:   rgba(10, 9, 8, .06);
  --ink-60:   rgba(10, 9, 8, .60);

  /* --- typography --- */
  --font-sans: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
               Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
               "Liberation Mono", monospace;

  --fs-2xs: .68rem;
  --fs-xs:  .72rem;
  --fs-sm:  .78rem;
  --fs-md:  .875rem;
  --fs-lg:  1rem;
  --fs-xl:  1.125rem;
  --fs-title: clamp(1.45rem, 1.9vw + .75rem, 2.1rem);

  /* --- spacing (4px scale) --- */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 20px; --sp-6: 24px; --sp-7: 32px; --sp-8: 40px;
  --sp-9: 48px; --sp-10: 64px;

  /* --- radius --- */
  --r-flat: 0px;
  --r-ctl:  3px;
  --r-pill: 999px;

  /* --- motion --- */
  --dur-1: 110ms;
  --dur-2: 190ms;
  --dur-3: 320ms;
  --ease-out: cubic-bezier(.22, .61, .36, 1);
  --ease-std: cubic-bezier(.4, 0, .2, 1);

  /* --- elevation (used sparingly) --- */
  --shadow-1: 0 1px 2px rgba(0, 0, 0, .45);
  --shadow-2: 0 14px 34px -14px rgba(0, 0, 0, .8);

  /* ==========================================================================
     2. SEMANTIC
     ========================================================================== */
  --bg: var(--c-950);
  --surface: var(--c-900);
  --surface-2: var(--c-850);
  --surface-3: var(--c-800);
  --line: var(--c-750);
  --line-strong: var(--c-600);

  --fg: var(--c-100);
  --fg-2: var(--c-200);
  --fg-3: var(--c-300);
  --fg-faint: var(--c-400);

  --accent: var(--amber-500);
  --accent-hi: var(--amber-400);
  --accent-soft: var(--amber-300);
  --on-accent: var(--c-1000);

  --live: var(--red-500);
  --live-soft: var(--red-400);
  --danger: var(--red-500);
  --ok: var(--green-500);

  --focus: var(--amber-400);

  /* ==========================================================================
     3. COMPONENT
     ========================================================================== */
  --shell-max: 1140px;
  --topbar-h: 56px;
  --pad-body: 16px;

  --ctl-h-sm: 28px;
  --ctl-h: 34px;
  --ctl-h-lg: 44px;

  --art-sm: 42px;
  --art-hero: clamp(150px, 21vw, 244px);
  --art-compact: 92px;

  --row-py: 9px;
  --row-px: var(--pad-body);
}

/* ==========================================================================
   BASE
   ========================================================================== */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  background: var(--bg);
}

body {
  margin: 0;
  min-height: 100vh;
  background-color: var(--bg);
  /* a faint amber wash where the header sits — the studio-lamp look */
  background-image: radial-gradient(760px 300px at 50% -60px, var(--amber-10), transparent 72%);
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: var(--fs-lg);
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* signature rule across the very top of the document */
body::before {
  content: "";
  display: block;
  height: 3px;
  background: var(--accent);
}

h1, h2, h3, h4, p, dl, dd, figure { margin: 0; }
ul, ol { margin: 0; padding: 0; }
li { list-style: none; }

img { max-width: 100%; display: block; }

a {
  color: var(--accent-hi);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
a:hover { color: var(--accent-soft); }

button, input, select, textarea {
  font: inherit;
  color: inherit;
}
button { cursor: pointer; }

/* the hidden attribute is load-bearing here: components below set display,
   and an element that is display:flex cannot go away without this */
[hidden] { display: none !important; }

::selection { background: var(--amber-45); color: var(--c-1000); }

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

* { scrollbar-width: thin; scrollbar-color: var(--c-600) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb {
  background: var(--c-600);
  background-clip: content-box;
  border: 3px solid transparent;
  border-radius: var(--r-pill);
}
::-webkit-scrollbar-thumb:hover { background-color: var(--c-500); background-clip: content-box; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

/* ==========================================================================
   UTILITIES
   ========================================================================== */
.shell {
  width: min(100% - var(--sp-6), var(--shell-max));
  margin-inline: auto;
}
@media (max-width: 560px) {
  .shell { width: min(100% - var(--sp-4), var(--shell-max)); }
}

.mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
.muted { color: var(--fg-3); }

/* ==========================================================================
   TOPBAR
   ========================================================================== */
.topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  background: rgba(14, 13, 11, .88);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--line);
}

.topbar-inner {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-height: var(--topbar-h);
  /* Tabs and badges share this row at every width — the bar must never be
     two lines thick. Overflowing content gives ground instead (see .chip-btn). */
  flex-wrap: nowrap;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  color: var(--fg);
  text-decoration: none;
}
.brand-mark {
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  background: var(--accent);
  color: var(--on-accent);
  border-radius: var(--r-ctl);
  flex: 0 0 auto;
}
.brand-mark .material-symbols-outlined { font-size: 19px; }
.brand-name {
  font-family: var(--font-mono);
  font-size: var(--fs-md);
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
}

.nav-links { display: flex; gap: 2px; }
.nav-links a {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--fg-3);
  text-decoration: none;
  padding: var(--sp-2) 10px;
  border-bottom: 2px solid transparent;
  transition: color var(--dur-1) var(--ease-std);
}
.nav-links a:hover { color: var(--fg); }
.nav-links a[aria-current="page"] {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.topbar-tools {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  margin-left: auto;
  min-width: 0;
}

/* ==========================================================================
   PILLS — status chips
   ========================================================================== */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 25px;
  padding: 0 10px;
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  color: var(--fg-2);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  white-space: nowrap;
}
.pill .material-symbols-outlined { font-size: 15px; }
/* a pill that is actually a button (the header name chip) */
button.pill { cursor: pointer; }
button.pill:hover,
button.pill:focus-visible {
  border-color: var(--accent);
  color: var(--accent-hi);
}

.pill-live {
  color: var(--live-soft);
  background: var(--red-12);
  border-color: var(--red-45);
}
.pill-live .dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--live);
  box-shadow: 0 0 0 0 var(--red-45);
  animation: pulse-dot 2.2s var(--ease-std) infinite;
}
@keyframes pulse-dot {
  0%   { box-shadow: 0 0 0 0 var(--red-45); }
  70%  { box-shadow: 0 0 0 6px rgba(255, 95, 86, 0); }
  100% { box-shadow: 0 0 0 0 rgba(255, 95, 86, 0); }
}

.pill-warn {
  color: var(--live-soft);
  background: var(--red-12);
  border-color: var(--red-45);
}
.pill-accent {
  color: var(--accent-hi);
  background: var(--amber-10);
  border-color: var(--amber-45);
}
.pill-quiet {
  color: var(--fg-3);
  background: transparent;
  border-color: var(--line);
}

/* ==========================================================================
   PANELS
   ========================================================================== */
.panel {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-flat);
}

.panel-head {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 13px var(--pad-body);
  border-bottom: 1px solid var(--line);
}
.panel-title {
  display: flex;
  align-items: center;
  gap: 9px;
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--fg-2);
}
.panel-title::before {
  content: "";
  width: 7px;
  height: 7px;
  background: var(--accent);
  flex: 0 0 auto;
}
.panel-note {
  margin-left: auto;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--fg-faint);
  letter-spacing: .06em;
}

.panel-body { padding: var(--pad-body); }

.eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--fg-3);
}

.sub-head {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--fg-3);
  margin: var(--sp-6) 0 var(--sp-2);
}
.panel-body .sub-head:first-child { margin-top: 0; }

.hint {
  font-size: var(--fs-sm);
  color: var(--fg-3);
  line-height: 1.6;
}

/* ==========================================================================
   BUTTONS — variant × size
   ========================================================================== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  height: var(--ctl-h);
  padding: 0 14px;
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-ctl);
  color: var(--fg);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color var(--dur-1) var(--ease-std),
              border-color var(--dur-1) var(--ease-std),
              color var(--dur-1) var(--ease-std),
              transform var(--dur-1) var(--ease-std);
}
.btn:hover { border-color: var(--accent); color: var(--accent-hi); }
.btn:active { transform: translateY(1px); }
.btn:disabled {
  opacity: .45;
  cursor: not-allowed;
  transform: none;
}
.btn .material-symbols-outlined { font-size: 17px; }

.btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}
.btn-primary:hover {
  background: var(--accent-hi);
  border-color: var(--accent-hi);
  color: var(--on-accent);
}
.btn-primary:disabled:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}

.btn-danger {
  color: var(--danger);
  border-color: var(--red-45);
}
.btn-danger:hover {
  background: var(--red-16);
  border-color: var(--danger);
  color: var(--danger);
}

.btn-quiet {
  border-color: transparent;
  color: var(--fg-3);
}
.btn-quiet:hover { background: var(--surface-3); border-color: transparent; color: var(--fg); }

.btn-sm { height: var(--ctl-h-sm); padding: 0 10px; font-size: var(--fs-2xs); gap: 5px; }
.btn-sm .material-symbols-outlined { font-size: 15px; }
.btn-lg { height: var(--ctl-h-lg); padding: 0 22px; font-size: var(--fs-sm); gap: 9px; }
.btn-lg .material-symbols-outlined { font-size: 21px; }
.btn-block { width: 100%; }

.icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--ctl-h);
  height: var(--ctl-h);
  padding: 0;
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r-ctl);
  color: var(--fg-3);
  transition: background-color var(--dur-1) var(--ease-std),
              color var(--dur-1) var(--ease-std),
              border-color var(--dur-1) var(--ease-std);
}
.icon-btn:hover {
  background: var(--surface-3);
  color: var(--fg);
}
.icon-btn:disabled { opacity: .4; cursor: not-allowed; }
.icon-btn .material-symbols-outlined { font-size: 21px; }

/* hearts: red once liked, for everyone who can see the state */
.heart-btn[aria-pressed="true"] { color: var(--danger); }
.heart-btn[aria-pressed="true"]:hover { background: var(--red-12); color: var(--danger); }

/* the number next to a heart: reserves its own width so it never nudges
   the row when a count arrives */
.like-count {
  min-width: 2ch;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--fg-3);
  user-select: none;
}

/* ==========================================================================
   TABS & FILTER CHIPS
   ========================================================================== */
.tabs {
  display: flex;
  gap: 2px;
  border-bottom: 1px solid var(--line);
  margin-bottom: var(--sp-4);
  overflow-x: auto;
}
.tab {
  appearance: none;
  background: none;
  border: 0;
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
  padding: 10px 14px;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--fg-3);
  white-space: nowrap;
  transition: color var(--dur-1) var(--ease-std);
}
.tab:hover { color: var(--fg); }
.tab.active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
.tab-panel { display: none; }
.tab-panel.active { display: block; }

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-bottom: var(--sp-3);
}
.chip-filter {
  height: var(--ctl-h-sm);
  padding: 0 12px;
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-pill);
  color: var(--fg-3);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  transition: background-color var(--dur-1) var(--ease-std),
              border-color var(--dur-1) var(--ease-std),
              color var(--dur-1) var(--ease-std);
}
.chip-filter:hover { border-color: var(--accent); color: var(--accent-hi); }
.chip-filter.active {
  background: var(--amber-16);
  border-color: var(--accent);
  color: var(--accent-hi);
}

/* ==========================================================================
   FORMS
   ========================================================================== */
input[type="text"],
input[type="password"],
input[type="search"],
input[type="url"],
select {
  height: var(--ctl-h);
  padding: 0 12px;
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-ctl);
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: var(--fs-md);
  min-width: 0;
  transition: border-color var(--dur-1) var(--ease-std);
}
input::placeholder { color: var(--fg-faint); }
input[type="text"]:hover,
input[type="password"]:hover,
input[type="search"]:hover,
input[type="url"]:hover,
select:hover { border-color: var(--c-500); }

input[type="text"]:focus-visible,
input[type="password"]:focus-visible,
input[type="search"]:focus-visible,
input[type="url"]:focus-visible,
select:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 1px;
  border-color: var(--accent);
}

select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 32px;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%239a9287' stroke-width='1.7'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
}
option { background: var(--surface); color: var(--fg); }

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: var(--sp-3);
}
.field-label {
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--fg-3);
}

.searchbar {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 5px 6px 5px 12px;
  background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-ctl);
  margin-bottom: var(--sp-3);
  transition: border-color var(--dur-1) var(--ease-std);
}
.searchbar:focus-within { border-color: var(--accent); }
.searchbar-icon {
  color: var(--fg-faint);
  font-size: 20px;
  flex: 0 0 auto;
}
.searchbar input {
  flex: 1 1 auto;
  min-width: 0;
  height: 30px;
  padding: 0;
  background: transparent;
  border: 0;
  font-size: var(--fs-lg);
}
.searchbar input:focus,
.searchbar input:focus-visible {
  outline: none;
  border-color: transparent;
  box-shadow: none;
}
.searchbar .btn { flex: 0 0 auto; }

.file-field {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 14px;
  background: var(--surface-2);
  border: 1px dashed var(--line-strong);
  border-radius: var(--r-ctl);
  color: var(--fg-3);
}
.file-field .material-symbols-outlined { font-size: 22px; flex: 0 0 auto; }
input[type="file"] {
  border: 0;
  background: none;
  padding: 0;
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--fg-2);
  max-width: 100%;
  min-width: 0;
}
input[type="file"]::file-selector-button {
  height: var(--ctl-h-sm);
  margin-right: 10px;
  padding: 0 11px;
  background: transparent;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-ctl);
  color: var(--fg);
  font-family: var(--font-mono);
  font-size: var(--fs-2xs);
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  cursor: pointer;
}
input[type="file"]::file-selector-button:hover {
  border-color: var(--accent);
  color: var(--accent-hi);
}

.row-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
}
.actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-2);
  margin-top: var(--sp-3);
}

.error {
  display: none;
  padding: 10px 12px;
  background: var(--red-12);
  border: 1px solid var(--red-45);
  border-radius: var(--r-ctl);
  color: var(--live-soft);
  font-size: var(--fs-sm);
}
.error.show { display: block; }

.spinner {
  display: none;
  width: 14px;
  height: 14px;
  border: 2px solid rgba(10, 9, 8, .35);
  border-top-color: rgba(10, 9, 8, .95);
  border-radius: 50%;
  animation: spin .8s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.btn.loading .spinner { display: inline-block; }

/* ==========================================================================
   ARTWORK
   ========================================================================== */
.art {
  position: relative;
  display: block;
  width: var(--art-sm);
  aspect-ratio: 1;
  flex: 0 0 auto;
  background: var(--surface-2);
  border: 1px solid var(--line);
  overflow: hidden;
}
.art img {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.art-fallback {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 22px;
  color: var(--c-500);
}

/* ==========================================================================
   TRACK LISTS
   ========================================================================== */
.track-list {
  border-top: 1px solid var(--line);
  /* full-bleed inside the panel body */
  margin-inline: calc(var(--pad-body) * -1);
  max-height: min(58vh, 540px);
  overflow-y: auto;
  overscroll-behavior: contain;
}

.track-row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--row-py) var(--row-px);
  border-bottom: 1px solid var(--line);
  transition: background-color var(--dur-1) var(--ease-std);
}
.track-row:hover { background: var(--surface-2); }
.track-row:focus-within { background: var(--surface-2); }

.track-main { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.track-title {
  font-size: var(--fs-md);
  font-weight: 600;
  color: var(--fg);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.track-sub {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--fg-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.track-actions {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
}
.track-actions .pill {
  height: 22px;
  padding: 0 8px;
  max-width: 130px;
  overflow: hidden;
  text-overflow: ellipsis;
}
@media (max-width: 620px) {
  .track-actions .pill { display: none; }
}

.empty {
  padding: var(--sp-6) var(--sp-4);
  text-align: center;
  font-family: var(--font-mono);
  font-size: var(--fs-sm);
  color: var(--fg-3);
}
.empty::before {
  content: "> ";
  color: var(--accent);
}

/* ==========================================================================
   GENERIC LIST ROWS (account / admin)
   ========================================================================== */
.rows {
  margin-inline: calc(var(--pad-body) * -1);
}
.list-row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: 10px var(--row-px);
  border-bottom: 1px solid var(--line);
  transition: background-color var(--dur-1) var(--ease-std);
}
.list-row:hover { background: var(--surface-2); }
.list-row .grow { flex: 1 1 auto; min-width: 0; }
.list-row .nm {
  font-size: var(--fs-md);
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.list-row .sub {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--fg-3);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.list-row .btn { flex: 0 0 auto; }

.kv {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: var(--sp-2) var(--sp-4);
  font-size: var(--fs-md);
}
.kv dt {
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--fg-3);
  align-self: center;
}
.kv dd {
  margin: 0;
  font-weight: 600;
  overflow-wrap: anywhere;
}

.stat-line {
  padding: 9px 12px;
  margin-bottom: var(--sp-3);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-ctl);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  font-variant-numeric: tabular-nums;
  color: var(--fg-2);
  overflow-wrap: anywhere;
}

/* ==========================================================================
   NOW PLAYING (hero)
   ========================================================================== */
.hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-5);
  padding: var(--pad-body);
}
.hero-art .art-lg { width: var(--art-hero); }

.hero-body { min-width: 0; }

.hero-top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2) var(--sp-3);
  margin-bottom: var(--sp-3);
}

.hero h1,
.hero h2 {
  font-size: var(--fs-title);
  font-weight: 680;
  line-height: 1.14;
  letter-spacing: -.015em;
  overflow-wrap: anywhere;
  margin-bottom: 6px;
}
.hero-byline {
  font-size: var(--fs-lg);
  color: var(--fg-2);
  overflow-wrap: anywhere;
}
.hero-byline:empty { display: none; }

.hero-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-2);
  margin-top: var(--sp-4);
}
.hero-meta .mono {
  font-size: var(--fs-xs);
  color: var(--fg-3);
}

.hero-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-3);
  margin-top: var(--sp-5);
}
.controls-end {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
  margin-left: auto;
}

/* equalizer */
.eq {
  display: flex;
  align-items: flex-end;
  gap: 4px;
  height: 26px;
  flex: 0 0 auto;
}
.eq i {
  display: block;
  width: 4px;
  height: 30%;
  background: var(--accent);
  border-radius: var(--r-ctl);
}
.eq.playing i { animation: eq-bar 1.15s var(--ease-std) infinite; }
.eq.playing i:nth-child(1) { animation-delay: 0s; }
.eq.playing i:nth-child(2) { animation-delay: .15s; }
.eq.playing i:nth-child(3) { animation-delay: .3s; }
.eq.playing i:nth-child(4) { animation-delay: .45s; }
.eq.paused i { background: var(--c-600); }
@keyframes eq-bar {
  0%, 100% { height: 26%; }
  50%      { height: 96%; }
}

/* volume */
.vol {
  display: flex;
  align-items: center;
  gap: var(--sp-1);
}
.vol input[type="range"] {
  width: 96px;
  height: 20px;
  padding: 0;
  border: 0;
  background: none;
  accent-color: var(--accent);
  cursor: pointer;
}
.vol input[type="range"]:focus-visible { outline-offset: 3px; }

/* compact variant (account page) */
.hero-compact { align-items: center; }
.hero-compact .art-lg { width: var(--art-compact); }
.hero-compact h1,
.hero-compact h2 { font-size: clamp(1.05rem, 1vw + .8rem, 1.3rem); }
.hero-compact .hero-byline { font-size: var(--fs-md); }
.hero-compact .hero-top { margin-bottom: var(--sp-2); }
.hero-compact .hero-meta { margin-top: var(--sp-3); }
.hero-compact .hero-controls { margin-top: var(--sp-4); }

@media (min-width: 720px) {
  .hero {
    grid-template-columns: auto minmax(0, 1fr);
    padding: clamp(var(--pad-body), 2.4vw, var(--sp-7));
  }
  .hero-compact { gap: var(--sp-5); }
}

/* ==========================================================================
   LAYOUT: page scaffolding
   ========================================================================== */
/* The page body is a vertical column — but the topbar's inner div carries
   .shell too (for the shared max-width centering), and it must stay a
   horizontal flex row. Without the :not() this rule matched it (specificity
   2 > the topbar rule's 1), stacked brand / tabs / badges onto three lines
   and smothered the bar in this padding and gap — the topbar's align-items
   and margin-left:auto were dead letters. */
.page-player .shell:not(.topbar-inner),
.page-account .shell:not(.topbar-inner) {
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
  padding-block: var(--sp-5) var(--sp-8);
}

.player-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-5);
  align-items: start;
}

.acct-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--sp-5);
  align-items: start;
}
/* two panels side by side when both fit; collapses to one when the admin
   panel is hidden (a display:none element is not a grid item) */
@media (min-width: 980px) {
  .acct-grid {
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 380px), 1fr));
  }
}

.page-head { display: flex; flex-direction: column; gap: 6px; }
.page-title {
  font-size: clamp(1.3rem, 1.4vw + .9rem, 1.7rem);
  font-weight: 680;
  letter-spacing: -.01em;
}

.foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--sp-2) var(--sp-5);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: var(--fs-xs);
  color: var(--fg-faint);
}
.foot a { color: var(--fg-3); }
.foot a:hover { color: var(--accent-hi); }

/* add-music panel: search results list follows the controls */
.tab-panel .track-list { border-top: 1px solid var(--line); }

/* the queue is the point of the page — keep its body tall enough that the
   layout does not collapse to a stub when nothing is queued */
.queue-panel .panel-body { min-height: 132px; }

/* ==========================================================================
   AUTH PAGE (login / register)
   ========================================================================== */
.page-auth {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: var(--sp-7) var(--sp-4);
}
.auth-card {
  width: min(100%, 430px);
  padding: clamp(22px, 4vw, 34px);
  display: flex;
  flex-direction: column;
  gap: var(--sp-3);
}
.auth-card .brand {
  align-self: center;
  margin-bottom: var(--sp-2);
}
.auth-card .brand-name { font-size: var(--fs-xl); }
.auth-card .brand-mark { width: 34px; height: 34px; }
.auth-card .brand-mark .material-symbols-outlined { font-size: 21px; }
.auth-card .tabs { margin-bottom: var(--sp-2); }
.auth-card .field { margin-bottom: 0; }
.auth-card .btn-block { margin-top: var(--sp-2); }
.auth-card .hint {
  text-align: center;
  font-size: var(--fs-xs);
  font-family: var(--font-mono);
}
.auth-card .hint a {
  color: var(--accent-hi);
  cursor: pointer;
  text-decoration: none;
}
.auth-card .hint a:hover { text-decoration: underline; }

/* inline rename input in the header */
.chip-input {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 30px;
  padding: 0 8px 0 10px;
  background: var(--surface-3);
  border: 1px solid var(--accent);
  border-radius: var(--r-pill);
  color: var(--fg-2);
}
.chip-input .material-symbols-outlined { font-size: 17px; color: var(--fg-3); }
.chip-input input {
  width: 108px;
  min-width: 0;
  height: 22px;
  padding: 0;
  background: none;
  border: 0;
  font-size: var(--fs-md);
}
.chip-input input:focus,
.chip-input input:focus-visible {
  outline: none;
  border: 0;
  box-shadow: none;
}

/* header chip button (anonymous name / signed-in name) */
.chip-btn {
  max-width: 190px;
  /* A flex item's automatic minimum is its content width, which would force
     the topbar onto a second row on a narrow window. 0 lets the name below
     ellipsize instead, so the bar always fits. */
  min-width: 0;
}
.chip-btn #user-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ==========================================================================
   SNACKBAR
   ========================================================================== */
.snackbar {
  position: fixed;
  left: 50%;
  bottom: var(--sp-5);
  z-index: 90;
  max-width: min(92vw, 460px);
  padding: 11px 16px;
  background: var(--surface-3);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-ctl);
  box-shadow: var(--shadow-2);
  color: var(--fg);
  font-size: var(--fs-md);
  opacity: 0;
  transform: translate(-50%, 96px);
  transition: transform var(--dur-3) var(--ease-out),
              opacity var(--dur-2) var(--ease-out);
  pointer-events: none;
}
.snackbar.show {
  opacity: 1;
  transform: translate(-50%, 0);
}

/* ==========================================================================
   RESPONSIVE — base is the phone; scale up
   ========================================================================== */
@media (max-width: 700px) {
  .hero-art .art-lg { width: clamp(128px, 34vw, 180px); }
  /* No wrap in the topbar: wrapping here put the badges on their own line and
     doubled the bar's height. The word "listening" drops instead, and the name
     chip ellipsizes when space runs out (both rules live with their styles). */
  .pill-word { display: none; }
}
@media (max-width: 400px) {
  .topbar-inner { gap: var(--sp-2); }
}
@media (max-width: 340px) {
  /* Last resort for very narrow windows: the tabs and badges keep the whole bar. */
  .brand { display: none; }
}

@media (max-width: 520px) {
  .brand-name { display: none; }
  .hero-controls { gap: var(--sp-2); }
  .vol input[type="range"] { display: none; }
  .controls-end { margin-left: auto; }
}

@media (min-width: 1040px) {
  .player-grid {
    grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  }
}
