*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { overflow-x: hidden; }

/* Per-field × clear button — appears inside text inputs when they
   have content. Wrapper is added programmatically by app.js so the
   existing label > input HTML doesn't need changing. */
.input-clear-wrap {
  position: relative;
  display: inline-block;
  width: 100%;
}
.input-clear-wrap > input {
  width: 100%;
  padding-right: 1.6rem;
}
.input-clear-btn {
  position: absolute;
  right: 0.35rem;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: none;
  color: var(--muted);
  font-size: 1.05rem;
  line-height: 1;
  padding: 0.05rem 0.35rem;
  cursor: pointer;
  display: none;
  border-radius: 3px;
  z-index: 2;
}
.input-clear-wrap.has-text .input-clear-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.input-clear-btn:hover { color: var(--text); background: var(--border); }
/* When the wrapped input contains text, tint its border with the
   theme's catno (off-spectrum accent) so users can see at a glance
   which fields are populated. Wins over the input's own focus state
   only when it actually has content. */
.input-clear-wrap.has-text > input,
.input-clear-wrap.has-text > input:focus {
  border-color: var(--catno, var(--accent)) !important;
}

/* Results type + sort row */
.type-sort-row {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin-bottom: 0.2rem;
  margin-top: 0.5rem;
  font-size: 0.78rem;
  color: var(--muted);
  flex-wrap: wrap;
}
.type-radios {
  display: flex;
  gap: 0.5rem;
  align-items: center;
}
.sort-label {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  color: var(--muted);
}
/* ══════════════════════════════════════════════
   RESPONSIVE / MOBILE
   ══════════════════════════════════════════════ */

/* ── Tablet (≤ 860px) ── */
@media (max-width: 860px) {
  #site-header { padding: 0.5rem 1rem; }
  #site-header img { height: 40px; }
}

/* ── Mobile (≤ 640px) ── */
@media (max-width: 640px) {
  #site-header { padding: 0.4rem 0.75rem; margin-bottom: 0; }
  #site-header img { height: 22px; }
  /* Mobile logo trimmed ~35% (1.4rem → 0.9rem) so it leaves more
     room next to the hamburger and doesn't dominate above-the-fold
     on small phones. */
  .text-logo { font-size: 0.9rem; }
  .header-version { font-size: 0.55rem; }

  #header-bar {
    flex-direction: column;
    align-items: center;
    gap: 0.2rem;
    text-align: center;
    margin-bottom: 0.5rem;
  }
  #auth-bar { text-align: center; }

  #collection-tabs { padding: 0 0.4rem 1.25rem; }

  main { padding: 0.4rem 0.4rem 1rem; overflow-x: hidden; }

  /* Search row — allow button to flex so it never clips in narrow viewports */
  .search-row { width: 100%; }
  #search-btn {
    width: auto;
    min-width: 70px;
    flex: 0 0 auto;
  }

  /* Type/sort row — radios on top, Advanced+Sort+Clear+Hide on bottom */
  .type-sort-row {
    flex-wrap: wrap;
    gap: 0.4rem;
    row-gap: 0.5rem;
    padding: 0 0.2rem;
  }
  .type-sort-row > span { display: none; }
  .type-radios     { order: 1; flex-basis: 100%; justify-content: center; gap: 0.3rem; flex-wrap: wrap; }
  #advanced-toggle { order: 10; }
  .sort-label      { order: 10; }
  #hide-owned-label { order: 10; font-size: 0.72rem; }
  #clear-btn       { order: 10; }
  .type-radios label { font-size: 0.72rem; }

  /* Collection controls: radios + sort on same line */
  #cw-controls-row .type-radios { flex-basis: auto; }
  #cw-controls-row .sort-label  { order: 1; }

  /* Advanced filters — 2 per row on mobile */
  .filters {
    row-gap: 0.75rem;
    margin-bottom: 0.75rem;
  }
  .filters label { min-width: 80px; flex: 1 1 45%; }

  /* Card grids — tighter on mobile */
  .card-grid {
    grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
    gap: 0.65rem;
  }

  /* Card body — tighter padding on small cards */
  .card-body { padding: 0.5rem 0.6rem 0.6rem; }
  .card-title { font-size: 0.76rem; }

  /* Collection controls row — allow wrapping */
  #cw-controls-row { flex-wrap: wrap !important; row-gap: 0.3rem !important; }

  /* Collection tabs */
  .result-tab {
    padding: 0.4rem 0.75rem;
    font-size: 0.76rem;
  }

  /* Album popup — stack cover + meta vertically */
  #album-info .album-header,
  #version-info .album-header {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 0.75rem;
  }
  #album-info .album-cover,
  #version-info .album-cover,
  #album-info .album-cover-placeholder,
  #version-info .album-cover-placeholder {
    width: 100px;
    height: 100px;
  }

  /* Modal boxes — full width with breathing room */
  #modal-box,
  #bio-full-box,
  #version-box,
  #series-box {
    max-width: 100%;
    margin: 0;
    max-height: 92vh;
    border-radius: var(--radius) var(--radius) 0 0;
  }
  #modal-overlay,
  #bio-full-overlay,
  #version-overlay,
  #series-overlay,
  #wiki-overlay {
    padding: 0.5rem;
    align-items: flex-end;  /* slide up from bottom on mobile */
  }

  /* Video overlay */
  #video-overlay { padding: 0.5rem; }
  #video-wrap { padding: 0.4rem; }

  /* Lightbox overlay */
  #lightbox-overlay { padding: 0.5rem; }
  #lightbox-img { max-width: 95vw; max-height: 75vh; }
  #lightbox-prev { left: 0.4rem; font-size: 1.1rem; width: 2.2rem; height: 2.2rem; }
  #lightbox-next { right: 0.4rem; font-size: 1.1rem; width: 2.2rem; height: 2.2rem; }
  #lightbox-close { top: 0.5rem; right: 0.5rem; }

  /* Pagination */
  #pagination { gap: 0.3rem; }
  #pagination .pag-arrow { padding: 0.4rem 0.7rem; font-size: 0.8rem; }
  #pagination .pag-num { padding: 0.35rem 0.55rem; min-width: 2rem; font-size: 0.8rem; }

  /* Modal actions — larger touch targets on mobile (not smaller) */
  .modal-actions { gap: 0.35rem; flex-wrap: wrap; }
  .modal-act-btn { font-size: 0.75rem; padding: 0.4rem 0.65rem; min-height: 36px; }
  .price-sparkline-row { flex-wrap: wrap; }

  /* Mini-player — stack info + controls on mobile when collapsed.
     Mobile bars are taller because controls wrap; loc bar stays single
     row so it gets the same treatment as desktop. */
  body.player-open { padding-bottom: 140px; }
  .mini-player-bar {
    flex-wrap: wrap;
    padding: 0.3rem 0.5rem;
    gap: 0.15rem 0.4rem;
  }
  .mini-player-info {
    flex: 1 1 100%;
    justify-content: center;
  }
  .mini-player-title {
    text-align: center;
    white-space: normal;
    font-size: 0.74rem;
    line-height: 1.3;
  }
  .mini-player-controls {
    flex: 1 1 100%;
    justify-content: center;
  }
  .mini-player-controls button { padding: 0.4rem 0.55rem; font-size: 1rem; min-width: 40px; min-height: 40px; }
  .mini-player #video-nav button { padding: 0.45rem 0.8rem; min-height: 40px; font-size: 0.9rem; }

  /* Account page — tighter padding */
  .account-box { padding: 1rem; margin: 1rem auto; }
}

/* ── Small phone (≤ 400px) ── */
@media (max-width: 400px) {
  #site-header img { height: 28px; }
  #site-header { padding: 0.3rem 0.5rem; }

  .type-sort-row { font-size: 0.7rem; }

  /* Force 2-column grid so cards aren't tiny */
  .card-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 0.5rem;
  }

  .result-tab {
    padding: 0.35rem 0.4rem;
    font-size: 0.7rem;
    letter-spacing: 0;
  }

  /* Tighten blurb/bio padding */
  #blurb { padding: 0.65rem 0.85rem; font-size: 0.85rem; }
}


/* ══════════════════════════════════════════════════════════════════════
   THEME SYSTEM
   ══════════════════════════════════════════════════════════════════════

   Every theme defines the same set of semantic CSS variables. Switching
   themes means re-defining the :root block (or a [data-theme="..."]
   variant) with different values. The rest of the stylesheet only
   references var(--name) — no hardcoded colors should appear outside
   these blocks.

   Semantic variables:
     Surfaces:   --bg, --surface, --surface-raised, --surface-sunken,
                 --bg-elevated, --bg-hover
     Borders:    --border, --border-strong, --border-soft
     Text:       --fg, --text, --muted, --muted-dim, --text-disabled
     Accents:    --accent, --accent-hover, --accent-dim, --accent2,
                 --accent-hi, --accent-soft
     States:     --success, --success-bg, --success-border
                 --warning, --warning-bg, --warning-border
                 --danger,  --danger-bg,  --danger-border, --danger-bright
                 --inventory, --inventory-bg, --inventory-border
                 --favorite (star color)
     Aliases:    --link, --panel   (legacy hooks)
     Misc:       --radius, --input-h, --color-scheme

   Themes available (user picks via /admin → Theme):
     ── Standard ─────────────────────────────────────────────────
     amber-dark      SeaDisco signature — warm amber on black (default)
     dark-default    GitHub-dark — neutral dark + blue link + green hi
     light-default   GitHub-light — white + blue link, clean minimal
     ── Designer classics ────────────────────────────────────────
     solarized-dark  Ethan Schoonover's teal-base + blue + yellow dark
     solarized-light Solarized's sister palette on sepia cream
     monokai         Wimer Hazenberg's classic — magenta + green + yellow
     ── Themed ──────────────────────────────────────────────────
     slate-dark      Cool steel neutrals with teal accent
     mossy-dark      Deep forest green primary, warm gold highlights
     vinyl-black     Jukebox red on near-black — turntable mood
     neon-wax        Synthwave violet/cyan/magenta dark
     tape-cream      Sepia paper light — vintage typewriter / liner notes
     paperback       Sage / dusty rose / off-white light — book design
     ── Neutral-bg + accent + font ────────────────────────────────
     paper-ink       White + grey accent + system sans
     paper-blue      White + deep blue + classic serif (Georgia)
     paper-rose      Cream + dusty rose + modern serif (Iowan/Charter)
     paper-forest    Soft white + forest green + slab serif (Rockwell)
     stone-violet    Warm grey + violet + humanist sans (Verdana)
     stone-sun       Light grey + sun gold + geometric sans (Avenir/Futura)
     noir-white      Pure black + white-only + monospace
     graphite-amber  Charcoal + amber + system sans
     graphite-cyan   Charcoal + electric cyan + monospace
     graphite-coral  Charcoal + coral + classic serif
     slate-violet    Cool slate + electric violet + geometric sans
     slate-emerald   Cool slate + emerald + slab serif
   ══════════════════════════════════════════════════════════════════════ */

:root,
:root[data-theme="amber-dark"] {
  color-scheme: dark;
  --bg:              #080706;
  --bg-elevated:     #1a1610;
  --bg-hover:        #1f1a12;
  --surface:         #15120e;
  --surface-raised:  #221814;
  --surface-sunken:  #0e0c08;
  --border:          #2e2518;
  --border-strong:   #3d3225;
  --border-soft:     #221814;
  --fg:              #f5eed8;
  --text:            #e8dcc8;
  --muted:           #a89880;
  --muted-dim:       #8a7d6b;
  --text-disabled:   #555555;
  --accent:          #ff6b35;
  --accent-hover:    #ff8c5a;
  --accent-dim:      #a34420;
  --accent2:         #ff8c5a;
  --accent-hi:       #e8d44d;
  --accent-soft:     #3a2a0d;
  --success:         #6bcf8e;
  --success-bg:      #1a3a1a;
  --success-border:  #2a5a2a;
  --warning:         #d4a843;
  --warning-bg:      #2a2510;
  --warning-border:  #4a3f20;
  --danger:          #e05050;
  --danger-bright:   #ff6b6b;
  --danger-bg:       #2a1010;
  --danger-border:   #5a2828;
  --inventory:       #e8a84a;
  --inventory-bg:    #3a2a0d;
  --inventory-border:#6b4a18;
  --favorite:        #e8d44d;
  --catno:           #5fd4d0;          /* cyan against orange accent */
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
}

/* ── Theme: Slate Dark (cool steel with teal accent) ────────────────── */
:root[data-theme="slate-dark"] {
  color-scheme: dark;
  --bg:              #0f1418;
  --bg-elevated:     #1a2028;
  --bg-hover:        #232a35;
  --surface:         #161c24;
  --surface-raised:  #1e2530;
  --surface-sunken:  #0a0e12;
  --border:          #2a3340;
  --border-strong:   #3a4555;
  --border-soft:     #1e2530;
  --fg:              #e8edf5;
  --text:            #c8d0dc;
  --muted:           #7a8595;
  --muted-dim:       #5a6575;
  --text-disabled:   #45505a;
  --accent:          #2fa8a0;   /* teal */
  --accent-hover:    #44c0b8;
  --accent-dim:      #1a605c;
  --accent2:         #44c0b8;
  --accent-hi:       #d4b84a;
  --accent-soft:     #0f2a28;
  --success:         #5ac87a;
  --success-bg:      #122a18;
  --success-border:  #2a5a3a;
  --warning:         #d4b84a;
  --warning-bg:      #2a2510;
  --warning-border:  #4a4020;
  --danger:          #e05050;
  --danger-bright:   #ff6b6b;
  --danger-bg:       #2a1010;
  --danger-border:   #5a2828;
  --inventory:       #d4894a;
  --inventory-bg:    #2a1a10;
  --inventory-border:#6b4a20;
  --favorite:        #d4b84a;
  --catno:           #e06090;
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
}

/* ── Theme: Mossy Dark (deep forest green with warm gold highlights) ── */
:root[data-theme="mossy-dark"] {
  color-scheme: dark;
  --bg:              #0d140e;
  --bg-elevated:     #162017;
  --bg-hover:        #1e2a1f;
  --surface:         #121c13;
  --surface-raised:  #1a241b;
  --surface-sunken:  #080f08;
  --border:          #263028;
  --border-strong:   #384438;
  --border-soft:     #1a241b;
  --fg:              #e5ecd8;
  --text:            #c8d4b8;
  --muted:           #7f8a70;
  --muted-dim:       #5f6a52;
  --text-disabled:   #444d3a;
  --accent:          #6b9248;   /* deep moss green */
  --accent-hover:    #7fa858;
  --accent-dim:      #385020;
  --accent2:         #7fa858;
  --accent-hi:       #d4a843;   /* warm gold */
  --accent-soft:     #15241a;
  --success:         #88c270;
  --success-bg:      #1a2a15;
  --success-border:  #385a28;
  --warning:         #c49a3a;
  --warning-bg:      #2a2410;
  --warning-border:  #4a3f20;
  --danger:          #a84030;
  --danger-bright:   #c45040;
  --danger-bg:       #2a1410;
  --danger-border:   #5a2420;
  --inventory:       #c49a3a;
  --inventory-bg:    #2a2410;
  --inventory-border:#5a4620;
  --favorite:        #d4a843;
  --catno:           #b070a0;
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
}

/* ── Theme: Vinyl Black (jukebox red on near-black) ───────────────── */
:root[data-theme="vinyl-black"] {
  color-scheme: dark;
  --bg:              #0a0a0a;
  --bg-elevated:     #161616;
  --bg-hover:        #1d1d1d;
  --surface:         #141414;
  --surface-raised:  #1f1f1f;
  --surface-sunken:  #050505;
  --border:          #262626;
  --border-strong:   #363636;
  --border-soft:     #1c1c1c;
  --fg:              #f0f0f0;
  --text:            #e0e0e0;
  --muted:           #888888;
  --muted-dim:       #666666;
  --text-disabled:   #444444;
  --accent:          #d63333;          /* vinyl wax red */
  --accent-hover:    #ec5050;
  --accent-dim:      #7a1818;
  --accent2:         #ec5050;
  --accent-hi:       #f0c95c;          /* needle gold */
  --accent-soft:     #2a0d0d;
  --success:         #6dd49b;
  --success-bg:      #122a1c;
  --success-border:  #2a5a3a;
  --warning:         #e8b34a;
  --warning-bg:      #2a230f;
  --warning-border:  #4a3f20;
  --danger:          #d63333;
  --danger-bright:   #ff4848;
  --danger-bg:       #2a0e0e;
  --danger-border:   #5a1818;
  --inventory:       #f0c95c;
  --inventory-bg:    #2a230f;
  --inventory-border:#5a4818;
  --favorite:        #f0c95c;
  --catno:           #5fd4d0;
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
}

/* ── Theme: Tape Cream (sepia paper light) ────────────────────────── */
:root[data-theme="tape-cream"] {
  color-scheme: light;
  --bg:              #f4ecd8;
  --bg-elevated:     #ece2c8;
  --bg-hover:        #e2d6b8;
  --surface:         #faf5e4;
  --surface-raised:  #fcf9ed;
  --surface-sunken:  #ece2c8;
  --border:          #c9b88d;
  --border-strong:   #a8946a;
  --border-soft:     #ddd0a4;
  --fg:              #2a1d0e;
  --text:            #3a2a16;
  --muted:           #6b5840;
  --muted-dim:       #8c7c60;
  --text-disabled:   #a89878;
  --accent:          #8b3a1f;          /* sepia rust */
  --accent-hover:    #a44a28;
  --accent-dim:      #5a2410;
  --accent2:         #a44a28;
  --accent-hi:       #a87832;          /* aged gold */
  --accent-soft:     #ead5b8;
  --success:         #4a7a3a;
  --success-bg:      #d8e2c4;
  --success-border:  #95a878;
  --warning:         #a87832;
  --warning-bg:      #ead5b8;
  --warning-border:  #c9a868;
  --danger:          #8b3a1f;
  --danger-bright:   #a44a28;
  --danger-bg:       #ead5b8;
  --danger-border:   #c98870;
  --inventory:       #a87832;
  --inventory-bg:    #ead5b8;
  --inventory-border:#c9a868;
  --favorite:        #a87832;
  --catno:           #3d4a8a;
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
}

/* ── Theme: Neon Wax (synthwave violet/cyan dark) ─────────────────── */
:root[data-theme="neon-wax"] {
  color-scheme: dark;
  --bg:              #0d0a18;
  --bg-elevated:     #1a1430;
  --bg-hover:        #221a3a;
  --surface:         #18142a;
  --surface-raised:  #221a3a;
  --surface-sunken:  #08061a;
  --border:          #2e2348;
  --border-strong:   #423462;
  --border-soft:     #1d1735;
  --fg:              #ece8ff;
  --text:            #d8d4ff;
  --muted:           #8a82b8;
  --muted-dim:       #685e95;
  --text-disabled:   #4a4170;
  --accent:          #c060f0;          /* electric violet */
  --accent-hover:    #d480ff;
  --accent-dim:      #6a3088;
  --accent2:         #ff5dde;          /* hot magenta */
  --accent-hi:       #00e5ff;          /* cyan */
  --accent-soft:     #2a1845;
  --success:         #50f5b8;
  --success-bg:      #0e2a1f;
  --success-border:  #1f5a40;
  --warning:         #ffd84a;
  --warning-bg:      #2a2510;
  --warning-border:  #5a4f20;
  --danger:          #ff5dde;
  --danger-bright:   #ff8df0;
  --danger-bg:       #2a0e22;
  --danger-border:   #5a1f48;
  --inventory:       #00e5ff;
  --inventory-bg:    #0a2a32;
  --inventory-border:#1f5a68;
  --favorite:        #00e5ff;
  --catno:           #9aff5a;
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
}

/* ── Theme: Paperback (sage / dusty rose / off-white light) ───────── */
:root[data-theme="paperback"] {
  color-scheme: light;
  --bg:              #f0ebe1;
  --bg-elevated:     #e6e0d2;
  --bg-hover:        #d8d0bc;
  --surface:         #f8f4ea;
  --surface-raised:  #fcfaf2;
  --surface-sunken:  #e6e0d2;
  --border:          #c2b8a0;
  --border-strong:   #9c917a;
  --border-soft:     #d4cab2;
  --fg:              #322a22;
  --text:            #423832;
  --muted:           #6b5e52;
  --muted-dim:       #8c8074;
  --text-disabled:   #a89e90;
  --accent:          #6b8068;          /* sage */
  --accent-hover:    #7d957a;
  --accent-dim:      #3e4d3c;
  --accent2:         #8a9d87;
  --accent-hi:       #c1716e;          /* dusty rose */
  --accent-soft:     #d8e0d4;
  --success:         #6b8068;
  --success-bg:      #d8e0d4;
  --success-border:  #98a895;
  --warning:         #c1956e;
  --warning-bg:      #ead8c0;
  --warning-border:  #c9a888;
  --danger:          #c1716e;
  --danger-bright:   #d4827f;
  --danger-bg:       #ead0d0;
  --danger-border:   #c98a88;
  --inventory:       #c1956e;
  --inventory-bg:    #ead8c0;
  --inventory-border:#c9a888;
  --favorite:        #c1716e;
  --catno:           #2a6a78;
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
}

/* ── Theme: Dark Default (GitHub-dark — neutral dark + blue) ─────────
   The clean, unsurprising tech-default. If a user just wants a "dark
   mode" without any aesthetic, this is it. Palette derived from
   github.com's dark theme so it reads instantly familiar. */
:root[data-theme="dark-default"] {
  color-scheme: dark;
  --bg:              #0d1117;
  --bg-elevated:     #161b22;
  --bg-hover:        #21262d;
  --surface:         #161b22;
  --surface-raised:  #1c2128;
  --surface-sunken:  #010409;
  --border:          #30363d;
  --border-strong:   #484f58;
  --border-soft:     #21262d;
  --fg:              #f0f6fc;
  --text:            #c9d1d9;
  --muted:           #8b949e;
  --muted-dim:       #6e7681;
  --text-disabled:   #484f58;
  --accent:          #58a6ff;          /* link blue */
  --accent-hover:    #79b8ff;
  --accent-dim:      #1f6feb;
  --accent2:         #79b8ff;
  --accent-hi:       #7ee787;          /* highlight green */
  --accent-soft:     #0c2d6b;
  --success:         #3fb950;
  --success-bg:      #0d3217;
  --success-border:  #196c2e;
  --warning:         #d29922;
  --warning-bg:      #2e2200;
  --warning-border:  #5a4500;
  --danger:          #f85149;
  --danger-bright:   #ff7b72;
  --danger-bg:       #3c0d0d;
  --danger-border:   #6e2222;
  --inventory:       #d29922;
  --inventory-bg:    #2e2200;
  --inventory-border:#5a4500;
  --favorite:        #d29922;
  --catno:           #ff79c6;
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
}

/* ── Theme: Light Default (GitHub-light — white + blue) ──────────────
   The companion to dark-default — clean, high-contrast, no aesthetic.
   For users who want a basic light mode that just gets out of the way.
*/
:root[data-theme="light-default"] {
  color-scheme: light;
  --bg:              #ffffff;
  --bg-elevated:     #f6f8fa;
  --bg-hover:        #eaeef2;
  --surface:         #f6f8fa;
  --surface-raised:  #ffffff;
  --surface-sunken:  #eaeef2;
  --border:          #d0d7de;
  --border-strong:   #afb8c1;
  --border-soft:     #eaeef2;
  --fg:              #1f2328;
  --text:            #1f2328;
  --muted:           #656d76;
  --muted-dim:       #8c959f;
  --text-disabled:   #afb8c1;
  --accent:          #0969da;          /* link blue */
  --accent-hover:    #218bff;
  --accent-dim:      #0550ae;
  --accent2:         #218bff;
  --accent-hi:       #1a7f37;          /* green highlight */
  --accent-soft:     #ddf4ff;
  --success:         #1a7f37;
  --success-bg:      #dafbe1;
  --success-border:  #4ac26b;
  --warning:         #9a6700;
  --warning-bg:      #fff8c5;
  --warning-border:  #d4a72c;
  --danger:          #cf222e;
  --danger-bright:   #d1242f;
  --danger-bg:       #ffebe9;
  --danger-border:   #ff8182;
  --inventory:       #9a6700;
  --inventory-bg:    #fff8c5;
  --inventory-border:#d4a72c;
  --favorite:        #9a6700;
  --catno:           #a8328a;
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
}

/* ── Theme: Solarized Dark (Ethan Schoonover's classic) ──────────────
   The designer-classic palette: scientifically-tuned to maintain even
   contrast across all 16 colors. Recognizable to anyone who's used a
   text editor in the last decade. Teal-dark base, blue link, yellow hi. */
:root[data-theme="solarized-dark"] {
  color-scheme: dark;
  --bg:              #002b36;          /* base03 */
  --bg-elevated:     #073642;          /* base02 */
  --bg-hover:        #094352;
  --surface:         #073642;          /* base02 */
  --surface-raised:  #094352;
  --surface-sunken:  #001f27;
  --border:          #1d4956;
  --border-strong:   #586e75;          /* base01 */
  --border-soft:     #073642;
  --fg:              #eee8d5;          /* base2 */
  --text:            #93a1a1;          /* base1 */
  --muted:           #586e75;          /* base01 */
  --muted-dim:       #4d6168;
  --text-disabled:   #3a4a50;
  --accent:          #268bd2;          /* blue */
  --accent-hover:    #4ca3da;
  --accent-dim:      #1a5d8e;
  --accent2:         #2aa198;          /* cyan */
  --accent-hi:       #b58900;          /* yellow */
  --accent-soft:     #093d52;
  --success:         #859900;          /* green */
  --success-bg:      #1a2c00;
  --success-border:  #4d5a00;
  --warning:         #b58900;          /* yellow */
  --warning-bg:      #2c2200;
  --warning-border:  #5a4500;
  --danger:          #dc322f;          /* red */
  --danger-bright:   #ec5552;
  --danger-bg:       #350d0d;
  --danger-border:   #7a1f1f;
  --inventory:       #cb4b16;          /* orange */
  --inventory-bg:    #3a1808;
  --inventory-border:#7a3010;
  --favorite:        #b58900;          /* yellow */
  --catno:           #d33682;
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
}

/* ── Theme: Solarized Light (Solarized's sister palette) ─────────────
   Cream-paper base from the same color science. Pairs with solarized-
   dark for a cohesive day/night look. */
:root[data-theme="solarized-light"] {
  color-scheme: light;
  --bg:              #fdf6e3;          /* base3 */
  --bg-elevated:     #eee8d5;          /* base2 */
  --bg-hover:        #ddd5b8;
  --surface:         #eee8d5;          /* base2 */
  --surface-raised:  #f5f0dc;
  --surface-sunken:  #ddd5b8;
  --border:          #ccc5a8;
  --border-strong:   #93a1a1;          /* base1 */
  --border-soft:     #ddd5b8;
  --fg:              #073642;          /* base02 */
  --text:            #586e75;          /* base01 */
  --muted:           #93a1a1;          /* base1 */
  --muted-dim:       #a0a99a;
  --text-disabled:   #c0c0a0;
  --accent:          #268bd2;          /* blue */
  --accent-hover:    #4ca3da;
  --accent-dim:      #195e92;
  --accent2:         #2aa198;          /* cyan */
  --accent-hi:       #b58900;          /* yellow */
  --accent-soft:     #d8e8f0;
  --success:         #859900;
  --success-bg:      #e6e8c4;
  --success-border:  #aab084;
  --warning:         #b58900;
  --warning-bg:      #f0e8c0;
  --warning-border:  #c4a84e;
  --danger:          #dc322f;
  --danger-bright:   #ec5552;
  --danger-bg:       #f5d0d0;
  --danger-border:   #d09090;
  --inventory:       #cb4b16;          /* orange */
  --inventory-bg:    #f0d8c0;
  --inventory-border:#c49060;
  --favorite:        #b58900;
  --catno:           #d33682;
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
}

/* ── Theme: Monokai (Wimer Hazenberg's editor classic) ───────────────
   Cult-classic editor palette — warm dark green base, magenta primary,
   green secondary, yellow highlight. Anyone who's used Sublime Text,
   TextMate, or VS Code's Monokai recognizes this on sight. */
:root[data-theme="monokai"] {
  color-scheme: dark;
  --bg:              #272822;
  --bg-elevated:     #34352f;
  --bg-hover:        #49483e;
  --surface:         #2d2e27;
  --surface-raised:  #34352f;
  --surface-sunken:  #1e1f1a;
  --border:          #3e3d32;
  --border-strong:   #75715e;
  --border-soft:     #2d2e27;
  --fg:              #ffffff;
  --text:            #f8f8f2;
  --muted:           #75715e;
  --muted-dim:       #5a5749;
  --text-disabled:   #3e3d32;
  --accent:          #f92672;          /* magenta — primary */
  --accent-hover:    #ff5599;
  --accent-dim:      #a01640;
  --accent2:         #fd971f;          /* orange */
  --accent-hi:       #a6e22e;          /* green highlight */
  --accent-soft:     #3e1828;
  --success:         #a6e22e;
  --success-bg:      #2a3a14;
  --success-border:  #5a8020;
  --warning:         #e6db74;          /* yellow */
  --warning-bg:      #36321c;
  --warning-border:  #75715e;
  --danger:          #f92672;
  --danger-bright:   #ff5599;
  --danger-bg:       #3e1828;
  --danger-border:   #75204a;
  --inventory:       #fd971f;          /* orange */
  --inventory-bg:    #3a2410;
  --inventory-border:#7a5018;
  --favorite:        #e6db74;          /* yellow */
  --catno:           #66d9ef;
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
}

/* ══════════════════════════════════════════════════════════════════════
   NEUTRAL-BG THEMES — restrained backgrounds (white/cream/grey/black/
   charcoal), with personality coming from the accent color + a distinct
   typeface set via --font. Six lights + six darks paired with serif,
   slab serif, mono, geometric, humanist, and system sans fonts.
   ══════════════════════════════════════════════════════════════════════ */

/* ── Light: Paper Ink (white + grey accent + system sans) ─────────── */
:root[data-theme="paper-ink"] {
  color-scheme: light;
  --bg:              #ffffff;
  --bg-elevated:     #f5f5f5;
  --bg-hover:        #ececec;
  --surface:         #fafafa;
  --surface-raised:  #ffffff;
  --surface-sunken:  #ececec;
  --border:          #d8d8d8;
  --border-strong:   #aaaaaa;
  --border-soft:     #e8e8e8;
  --fg:              #0a0a0a;
  --text:            #1a1a1a;
  --muted:           #6a6a6a;
  --muted-dim:       #909090;
  --text-disabled:   #b8b8b8;
  --accent:          #1a1a1a;
  --accent-hover:    #4a4a4a;
  --accent-dim:      #555555;
  --accent2:         #4a4a4a;
  --accent-hi:       #6a6a6a;
  --accent-soft:     #ececec;
  --success:         #2a6a30;
  --success-bg:      #d8e8d8;
  --success-border:  #a8c8a0;
  --warning:         #6a4a18;
  --warning-bg:      #f0e0c0;
  --warning-border:  #c0a070;
  --danger:          #6a1a1a;
  --danger-bright:   #8a2a2a;
  --danger-bg:       #f0d0d0;
  --danger-border:   #c89090;
  --inventory:       #4a4a4a;
  --inventory-bg:    #ececec;
  --inventory-border:#b8b8b8;
  --favorite:        #1a1a1a;
  --catno:           #0d8a8a;
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
  --font:            system-ui, -apple-system, "Segoe UI", sans-serif;
}

/* ── Light: Paper Blue (white + deep blue + classic serif) ────────── */
:root[data-theme="paper-blue"] {
  color-scheme: light;
  --bg:              #ffffff;
  --bg-elevated:     #f4f5f8;
  --bg-hover:        #ebedf0;
  --surface:         #fafbfd;
  --surface-raised:  #ffffff;
  --surface-sunken:  #ebedf0;
  --border:          #d4d8de;
  --border-strong:   #aab0b8;
  --border-soft:     #e4e6ea;
  --fg:              #0a0a0a;
  --text:            #1a1a1a;
  --muted:           #5a6470;
  --muted-dim:       #8590a0;
  --text-disabled:   #b0b8c0;
  --accent:          #0050a0;
  --accent-hover:    #0070d0;
  --accent-dim:      #003570;
  --accent2:         #0070d0;
  --accent-hi:       #b8000a;
  --accent-soft:     #d8e4f0;
  --success:         #1a6a2a;
  --success-bg:      #d8e8d8;
  --success-border:  #a8c8a0;
  --warning:         #8a5a18;
  --warning-bg:      #f0e0c0;
  --warning-border:  #c0a070;
  --danger:          #b8000a;
  --danger-bright:   #d02030;
  --danger-bg:       #f0d4d4;
  --danger-border:   #c89090;
  --inventory:       #8a5a18;
  --inventory-bg:    #f0e0c0;
  --inventory-border:#c0a070;
  --favorite:        #b8000a;
  --catno:           #1a7a3a;
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
  --font:            Georgia, "Iowan Old Style", "Times New Roman", serif;
}

/* ── Light: Paper Rose (cream + dusty rose + modern serif) ────────── */
:root[data-theme="paper-rose"] {
  color-scheme: light;
  --bg:              #faf8f4;
  --bg-elevated:     #f0eee8;
  --bg-hover:        #e6e2d8;
  --surface:         #fdfcf8;
  --surface-raised:  #ffffff;
  --surface-sunken:  #ece8de;
  --border:          #d8d2c4;
  --border-strong:   #aaa498;
  --border-soft:     #e6e2d4;
  --fg:              #1a1410;
  --text:            #2a2418;
  --muted:           #6a604e;
  --muted-dim:       #8a7e6a;
  --text-disabled:   #b0a890;
  --accent:          #b04d6a;
  --accent-hover:    #c66880;
  --accent-dim:      #802a48;
  --accent2:         #c66880;
  --accent-hi:       #5a7d4a;
  --accent-soft:     #f0d8de;
  --success:         #5a7d4a;
  --success-bg:      #dee4d0;
  --success-border:  #a8b890;
  --warning:         #a07832;
  --warning-bg:      #f0e0b8;
  --warning-border:  #c0a062;
  --danger:          #b04050;
  --danger-bright:   #d05068;
  --danger-bg:       #f0d4d8;
  --danger-border:   #c89090;
  --inventory:       #a07832;
  --inventory-bg:    #f0e0b8;
  --inventory-border:#c0a062;
  --favorite:        #b04d6a;
  --catno:           #5a4ab8;
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
  --font:            "Iowan Old Style", "Charter", "Palatino Linotype", Georgia, serif;
}

/* ── Light: Paper Forest (soft white + forest green + slab serif) ── */
:root[data-theme="paper-forest"] {
  color-scheme: light;
  --bg:              #f7faf6;
  --bg-elevated:     #ecf0eb;
  --bg-hover:        #e0e6df;
  --surface:         #fafdfa;
  --surface-raised:  #ffffff;
  --surface-sunken:  #e6ece4;
  --border:          #d0d8ce;
  --border-strong:   #a8b0a4;
  --border-soft:     #e0e6de;
  --fg:              #0a1a0e;
  --text:            #1a2418;
  --muted:           #5a685e;
  --muted-dim:       #7a887e;
  --text-disabled:   #b0b8ae;
  --accent:          #2d5a3d;
  --accent-hover:    #3a7050;
  --accent-dim:      #1a3a25;
  --accent2:         #3a7050;
  --accent-hi:       #8a6a18;
  --accent-soft:     #d8e8d8;
  --success:         #2d5a3d;
  --success-bg:      #d8e8d8;
  --success-border:  #a8c8a0;
  --warning:         #8a6a18;
  --warning-bg:      #f0e0b8;
  --warning-border:  #c0a062;
  --danger:          #8a2828;
  --danger-bright:   #a83838;
  --danger-bg:       #f0d4d4;
  --danger-border:   #c89090;
  --inventory:       #8a6a18;
  --inventory-bg:    #f0e0b8;
  --inventory-border:#c0a062;
  --favorite:        #8a6a18;
  --catno:           #5a4ab8;
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
  --font:            "Rockwell", "Roboto Slab", "Slabo 27px", "Calisto MT", Georgia, serif;
}

/* ── Light: Stone Violet (warm grey + violet + humanist sans) ─────── */
:root[data-theme="stone-violet"] {
  color-scheme: light;
  --bg:              #ececea;
  --bg-elevated:     #e0e0de;
  --bg-hover:        #d4d4d2;
  --surface:         #f2f2f0;
  --surface-raised:  #f8f8f6;
  --surface-sunken:  #d8d8d6;
  --border:          #c4c4c0;
  --border-strong:   #989894;
  --border-soft:     #d8d8d4;
  --fg:              #0a0a0a;
  --text:            #1a1a1a;
  --muted:           #5a5a58;
  --muted-dim:       #80807e;
  --text-disabled:   #aeaeab;
  --accent:          #5a3aa0;
  --accent-hover:    #7050b8;
  --accent-dim:      #3a2070;
  --accent2:         #7050b8;
  --accent-hi:       #b87020;
  --accent-soft:     #e0d8ec;
  --success:         #2a6a30;
  --success-bg:      #d8e8d8;
  --success-border:  #a8c8a0;
  --warning:         #8a5a18;
  --warning-bg:      #f0e0c0;
  --warning-border:  #c0a070;
  --danger:          #a02020;
  --danger-bright:   #c83030;
  --danger-bg:       #f0d4d4;
  --danger-border:   #c89090;
  --inventory:       #b87020;
  --inventory-bg:    #f0e0c0;
  --inventory-border:#c0a070;
  --favorite:        #5a3aa0;
  --catno:           #0d7a7a;
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
  --font:            "Verdana", "Geneva", "Tahoma", sans-serif;
}

/* ── Light: Stone Sun (light grey + sun gold + geometric sans) ────── */
:root[data-theme="stone-sun"] {
  color-scheme: light;
  --bg:              #efefee;
  --bg-elevated:     #e4e4e2;
  --bg-hover:        #d8d8d6;
  --surface:         #f5f5f4;
  --surface-raised:  #fbfbfa;
  --surface-sunken:  #dcdcda;
  --border:          #c8c8c4;
  --border-strong:   #9c9c98;
  --border-soft:     #dcdcd8;
  --fg:              #0a0a0a;
  --text:            #1a1a1a;
  --muted:           #5e5e5c;
  --muted-dim:       #828280;
  --text-disabled:   #b0b0ad;
  --accent:          #b89020;
  --accent-hover:    #d4a838;
  --accent-dim:      #80600c;
  --accent2:         #d4a838;
  --accent-hi:       #2a6080;
  --accent-soft:     #ece0b8;
  --success:         #2a6a30;
  --success-bg:      #d8e8d8;
  --success-border:  #a8c8a0;
  --warning:         #b89020;
  --warning-bg:      #ece0b8;
  --warning-border:  #c0a060;
  --danger:          #a02020;
  --danger-bright:   #c83030;
  --danger-bg:       #f0d4d4;
  --danger-border:   #c89090;
  --inventory:       #b89020;
  --inventory-bg:    #ece0b8;
  --inventory-border:#c0a060;
  --favorite:        #b89020;
  --catno:           #1a6a78;
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
  --font:            "Avenir Next", "Avenir", "Futura", "Trebuchet MS", sans-serif;
}

/* ── Dark: Noir White (pure black + white-only + monospace) ──────── */
:root[data-theme="noir-white"] {
  color-scheme: dark;
  --bg:              #000000;
  --bg-elevated:     #0e0e0e;
  --bg-hover:        #1a1a1a;
  --surface:         #0a0a0a;
  --surface-raised:  #1a1a1a;
  --surface-sunken:  #000000;
  --border:          #2e2e2e;
  --border-strong:   #5a5a5a;
  --border-soft:     #1a1a1a;
  --fg:              #ffffff;
  --text:            #f0f0f0;
  --muted:           #888888;
  --muted-dim:       #666666;
  --text-disabled:   #444444;
  --accent:          #ffffff;
  --accent-hover:    #ffffff;
  --accent-dim:      #aaaaaa;
  --accent2:         #d0d0d0;
  /* Highlight matches the catno baby-blue cyan so the lone chromatic
     in this otherwise-greyscale theme is unified — logo-lo, active-tab
     underlines, link hovers, and catalog numbers all share the same
     cyan spot color. */
  --accent-hi:       #5fe8e0;
  --accent-soft:     #2a2a2a;
  --success:         #b0b0b0;
  --success-bg:      #1a1a1a;
  --success-border:  #3a3a3a;
  --warning:         #c8c8c8;
  --warning-bg:      #2a2a2a;
  --warning-border:  #4a4a4a;
  --danger:          #ffffff;
  --danger-bright:   #ffffff;
  --danger-bg:       #2a2a2a;
  --danger-border:   #5a5a5a;
  --inventory:       #b0b0b0;
  --inventory-bg:    #1f1f1f;
  --inventory-border:#3a3a3a;
  --favorite:        #ffffff;
  --catno:           #5fe8e0;
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
  /* Optima is the marquee humanist sans for stark minimalist looks —
     refined, very readable, distinctly NOT typewriter. Falls back
     across platforms: Optima (macOS) → Avenir Next / Avenir / Futura
     (macOS/iOS) → Trebuchet MS / Geneva (Windows/Linux) → system. */
  --font:            "Optima", "Optima Nova", "Avenir Next", "Avenir", "Futura", "Trebuchet MS", "Geneva", "Helvetica Neue", system-ui, sans-serif;
}

/* ── Dark: Graphite Amber (charcoal + amber + system sans) ───────── */
:root[data-theme="graphite-amber"] {
  color-scheme: dark;
  --bg:              #1a1a1a;
  --bg-elevated:     #242424;
  --bg-hover:        #2e2e2e;
  --surface:         #1f1f1f;
  --surface-raised:  #292929;
  --surface-sunken:  #131313;
  --border:          #353535;
  --border-strong:   #555555;
  --border-soft:     #252525;
  --fg:              #f0f0f0;
  --text:            #e0e0e0;
  --muted:           #909090;
  --muted-dim:       #707070;
  --text-disabled:   #4a4a4a;
  --accent:          #ffb84a;
  --accent-hover:    #ffce72;
  --accent-dim:      #a07418;
  --accent2:         #ffce72;
  --accent-hi:       #88c5e0;
  --accent-soft:     #2e2410;
  --success:         #6ec070;
  --success-bg:      #1c2a1a;
  --success-border:  #3a5a3a;
  --warning:         #ffb84a;
  --warning-bg:      #2e2410;
  --warning-border:  #5a4520;
  --danger:          #e06060;
  --danger-bright:   #ff8080;
  --danger-bg:       #2e1414;
  --danger-border:   #5a2828;
  --inventory:       #ffb84a;
  --inventory-bg:    #2e2410;
  --inventory-border:#5a4520;
  --favorite:        #ffb84a;
  --catno:           #e878d4;
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
  --font:            system-ui, -apple-system, "Segoe UI", sans-serif;
}

/* ── Dark: Graphite Cyan (charcoal + electric cyan + monospace) ──── */
:root[data-theme="graphite-cyan"] {
  color-scheme: dark;
  --bg:              #1a1a1a;
  --bg-elevated:     #242424;
  --bg-hover:        #2e2e2e;
  --surface:         #1f1f1f;
  --surface-raised:  #292929;
  --surface-sunken:  #131313;
  --border:          #353535;
  --border-strong:   #555555;
  --border-soft:     #252525;
  --fg:              #f0f0f0;
  --text:            #e0e0e0;
  --muted:           #909090;
  --muted-dim:       #707070;
  --text-disabled:   #4a4a4a;
  --accent:          #00d4d0;
  --accent-hover:    #4ae8e4;
  --accent-dim:      #008885;
  --accent2:         #4ae8e4;
  --accent-hi:       #ff8a4a;
  --accent-soft:     #0a2a2a;
  --success:         #6ec070;
  --success-bg:      #1c2a1a;
  --success-border:  #3a5a3a;
  --warning:         #d4b84a;
  --warning-bg:      #2e2410;
  --warning-border:  #5a4520;
  --danger:          #e06060;
  --danger-bright:   #ff8080;
  --danger-bg:       #2e1414;
  --danger-border:   #5a2828;
  --inventory:       #ff8a4a;
  --inventory-bg:    #2e1a10;
  --inventory-border:#5a3520;
  --favorite:        #00d4d0;
  --catno:           #e878d4;
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
  --font:            "SF Mono", "JetBrains Mono", "Fira Code", "Cascadia Code", Menlo, Consolas, "Courier New", monospace;
}

/* ── Dark: Graphite Coral (charcoal + coral + classic serif) ─────── */
:root[data-theme="graphite-coral"] {
  color-scheme: dark;
  --bg:              #1a1a1a;
  --bg-elevated:     #242424;
  --bg-hover:        #2e2e2e;
  --surface:         #1f1f1f;
  --surface-raised:  #292929;
  --surface-sunken:  #131313;
  --border:          #353535;
  --border-strong:   #555555;
  --border-soft:     #252525;
  --fg:              #f0f0f0;
  --text:            #e0e0e0;
  --muted:           #909090;
  --muted-dim:       #707070;
  --text-disabled:   #4a4a4a;
  --accent:          #ff7878;
  --accent-hover:    #ff9a9a;
  --accent-dim:      #a83838;
  --accent2:         #ff9a9a;
  --accent-hi:       #d4b84a;
  --accent-soft:     #2e1414;
  --success:         #6ec070;
  --success-bg:      #1c2a1a;
  --success-border:  #3a5a3a;
  --warning:         #d4b84a;
  --warning-bg:      #2e2410;
  --warning-border:  #5a4520;
  --danger:          #ff7878;
  --danger-bright:   #ff9a9a;
  --danger-bg:       #2e1414;
  --danger-border:   #5a2828;
  --inventory:       #d4b84a;
  --inventory-bg:    #2e2410;
  --inventory-border:#5a4520;
  --favorite:        #ff7878;
  --catno:           #5fd4d0;
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
  --font:            Georgia, "Iowan Old Style", "Times New Roman", serif;
}

/* ── Dark: Slate Violet (cool slate + electric violet + geometric) ─ */
:root[data-theme="slate-violet"] {
  color-scheme: dark;
  --bg:              #1c1d22;
  --bg-elevated:     #26282e;
  --bg-hover:        #30323a;
  --surface:         #22232a;
  --surface-raised:  #2c2e36;
  --surface-sunken:  #14151a;
  --border:          #383a44;
  --border-strong:   #5a5d6a;
  --border-soft:     #28292f;
  --fg:              #f0f0f5;
  --text:            #d8d8e0;
  --muted:           #8a8a98;
  --muted-dim:       #6a6a78;
  --text-disabled:   #3a3a45;
  --accent:          #b070ff;
  --accent-hover:    #c490ff;
  --accent-dim:      #6a40a0;
  --accent2:         #c490ff;
  --accent-hi:       #50d0a0;
  --accent-soft:     #2a1c4a;
  --success:         #50d0a0;
  --success-bg:      #1c2a26;
  --success-border:  #3a5a4a;
  --warning:         #d4b84a;
  --warning-bg:      #2e2410;
  --warning-border:  #5a4520;
  --danger:          #e06080;
  --danger-bright:   #ff80a0;
  --danger-bg:       #2e1418;
  --danger-border:   #5a2838;
  --inventory:       #d4b84a;
  --inventory-bg:    #2e2410;
  --inventory-border:#5a4520;
  --favorite:        #b070ff;
  --catno:           #ff7878;
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
  --font:            "Avenir Next", "Avenir", "Futura", "Trebuchet MS", sans-serif;
}

/* ── Dark: Slate Emerald (cool slate + emerald + slab serif) ─────── */
:root[data-theme="slate-emerald"] {
  color-scheme: dark;
  --bg:              #1c1d22;
  --bg-elevated:     #26282e;
  --bg-hover:        #30323a;
  --surface:         #22232a;
  --surface-raised:  #2c2e36;
  --surface-sunken:  #14151a;
  --border:          #383a44;
  --border-strong:   #5a5d6a;
  --border-soft:     #28292f;
  --fg:              #f0f0f5;
  --text:            #d8d8e0;
  --muted:           #8a8a98;
  --muted-dim:       #6a6a78;
  --text-disabled:   #3a3a45;
  --accent:          #50d68a;
  --accent-hover:    #78e8a8;
  --accent-dim:      #2a8a50;
  --accent2:         #78e8a8;
  --accent-hi:       #ff8a50;
  --accent-soft:     #1c3a2a;
  --success:         #50d68a;
  --success-bg:      #1c3a2a;
  --success-border:  #3a6a4a;
  --warning:         #d4b84a;
  --warning-bg:      #2e2410;
  --warning-border:  #5a4520;
  --danger:          #e06060;
  --danger-bright:   #ff8080;
  --danger-bg:       #2e1414;
  --danger-border:   #5a2828;
  --inventory:       #ff8a50;
  --inventory-bg:    #2e1a10;
  --inventory-border:#5a3520;
  --favorite:        #50d68a;
  --catno:           #e878d4;
  --link:            var(--accent);
  --panel:           var(--surface);
  --radius:          6px;
  --input-h:         28px;
  --font:            "Rockwell", "Roboto Slab", "Slabo 27px", "Calisto MT", Georgia, serif;
}

body {
  background: var(--bg);
  color: var(--text);
  /* --font lets each theme swap the typeface — defaults to the system
     stack when a theme doesn't override it. The new "neutral-bg + colored
     accent + distinctive font" themes set --font in their :root block. */
  font-family: var(--font, system-ui, -apple-system, sans-serif);
  min-height: 100vh;
  overflow-x: hidden;
}

/* ── Scrollbars ── */
* {
  scrollbar-width: thin;
  scrollbar-color: #3a3020 transparent;
}
*::-webkit-scrollbar { width: 6px; height: 6px; }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb { background: #2a3a44; border-radius: 3px; }
*::-webkit-scrollbar-thumb:hover { background: #3a5a6a; }

#site-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.6rem 1.5rem;
  /* ~60px breathing room between the header and the first content
     block below (search form, page eyebrow, modal content, etc.) so
     the navbar doesn't crowd the body. */
  margin: 0 auto 60px;
  max-width: 1100px;
}

.header-logo-wrap { display: flex; flex-direction: column; align-items: flex-start; flex-shrink: 0; line-height: 1; }
.header-logo-wrap .header-logo { margin: 0; }
.header-version {
  font-size: 0.58rem;
  color: #3d3d3d;
  letter-spacing: 0.04em;
  margin-top: 0.15rem;
  padding-left: 0.15rem;
  font-family: 'SF Mono', 'Menlo', 'Consolas', monospace;
  user-select: none;
  pointer-events: none;
}
.header-logo { display: flex; align-items: center; flex-shrink: 0; text-decoration: none; }

#site-header img {
  height: 48px;
  width: auto;
  display: block;
}

/* Text logo. Desktop bumped ~75% (1.55rem → 2.7rem) for stronger
   brand presence; mobile breakpoints below scale back down. */
.text-logo {
  font-family: 'Inter', 'Segoe UI', system-ui, sans-serif;
  font-size: 2rem;
  letter-spacing: 0.03em;
  line-height: 1;
  user-select: none;
}
.logo-hi {
  color: var(--accent);
  font-weight: 700;
}
/* "rch" and "gs" — the lowercase tail of "SEArch DISCOgs" — use the
   theme's highlight accent (--accent-hi). Full opacity so the color
   reads cleanly; weight stays 400 so it's still visually distinct
   from the bolder "SEA" / "DISCO" hi-color text. */
.logo-lo {
  color: var(--accent-hi, var(--accent2, var(--accent)));
  font-weight: 400;
}
.logo-gap { width: 0.2em; display: inline-block; }
.text-logo:hover .logo-hi { color: var(--accent-hi, var(--favorite)); }
.text-logo:hover .logo-lo { color: var(--accent); }

#site-tagline {
  font-size: 0.78rem;
  color: #6a5d4a;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* ── Main nav ────────────────────────────────────────────────────────────── */
#main-nav {
  display: flex;
  align-items: center;
  position: relative;
}
#nav-tabs-wrap {
  position: relative;
  display: inline-flex;
}
#main-nav-tabs {
  display: flex;
  flex-direction: column;
  /* Borderless wrap — the icon-nav tabs are visually distinct enough on
     their own; the surrounding 1px box created a "pill" look that
     fought the floating-tooltip label and active-tab underline. */
  overflow: visible;
}
/* ─ Nav rows ───────────────────────────────────────────────────────────── */
.nav-row {
  display: flex;
}
.nav-row-top .nav-tab-top { flex: 1 1 0; }
/* ─ Top row tabs (discover + auth) ─────────────────────────────────────── */
.nav-tab-top {
  background: none;
  border: none;
  border-radius: 0;
  /* No inter-tab separator — the inset box-shadow that drew a 1px
     vertical line between tabs is removed for a cleaner navbar. */
  box-shadow: none;
  color: var(--muted);
  height: auto;
  padding: 0.3rem 1rem;
  cursor: pointer;
  font-size: 0.68rem;
  font-weight: normal;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  align-self: stretch;
}
.nav-tab-top:hover           { color: #888; background: none; }
.nav-tab-top.active          { color: var(--accent); font-weight: 600; }
/* Record tabs — disabled state + per-tab default/active colors. The
   nav now starts colored per category and de-saturates to grey on
   hover — that way the icons read at a glance without needing to
   point at them, and hover gives clear feedback. */
.nav-tab-top.nav-rec-disabled { color: #555; cursor: pointer; }
.nav-tab-top.nav-rec-disabled:hover { color: var(--accent); }
/* Hide Inventory / Lists tabs (and matching footer links) entirely
   when the user has zero of them. Set by _updateEmptyRecordTabs()
   once /api/user/discogs-ids resolves. */
.nav-tab-top.nav-rec-empty,
footer a.nav-rec-empty { display: none !important; }
.nav-tab-top[data-rtab="collection"],
.nav-tab-top[data-rtab="collection"].active  { color: #6ddf70; }
.nav-tab-top[data-rtab="collection"]:hover   { color: #888; }
.nav-tab-top[data-rtab="wantlist"],
.nav-tab-top[data-rtab="wantlist"].active    { color: #f0c95c; }
.nav-tab-top[data-rtab="wantlist"]:hover     { color: #888; }
.nav-tab-top[data-rtab="lists"],
.nav-tab-top[data-rtab="lists"].active       { color: #a0ccf0; }
.nav-tab-top[data-rtab="lists"]:hover        { color: #888; }
.nav-tab-top[data-rtab="inventory"],
.nav-tab-top[data-rtab="inventory"].active   { color: #cda0f5; }
.nav-tab-top[data-rtab="inventory"]:hover    { color: #888; }
.nav-tab-top[data-rtab="favorites"],
.nav-tab-top[data-rtab="favorites"].active   { color: #ff7eb6; }
.nav-tab-top[data-rtab="favorites"]:hover    { color: #888; }

/* ── Icon-nav variant (admin page test bed) ─────────────────────────────
   When renderSharedHeader is called with iconNav:true the tab markup is
   [icon][label]. The icon stays visible at all times; the label appears
   as an absolute-positioned tooltip below the icon on hover/focus so
   the navbar dimensions stay stable (no inline width animation that
   would push neighboring tabs around). The active tab is marked with
   an accent bottom-border + slightly more saturated icon. */
.nav-tab-top.icon-nav {
  position: relative;
  padding: 0.4rem 0.85rem;
  gap: 0;
}
.nav-tab-top.icon-nav .nav-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  /* Trimmed from 56/40/28 — the original sizing was tuned for a
     vinyl-detail-rich icon set, but at full size the bar dominated
     the header. Smaller still keeps the line-art readable. */
  width: 40px;
  height: 40px;
  opacity: 0.85;
  transition: opacity 0.15s, transform 0.15s;
}
@media (max-width: 1024px) {
  .nav-tab-top.icon-nav .nav-icon { width: 32px; height: 32px; }
}
@media (max-width: 720px) {
  .nav-tab-top.icon-nav .nav-icon { width: 22px; height: 22px; }
}
.nav-tab-top.icon-nav .nav-icon svg {
  /* SVG markup carries no fixed width/height — fill the container
     so the CSS sizing above controls the icon size cleanly. */
  width: 100%;
  height: 100%;
  display: block;
}
.nav-tab-top.icon-nav:hover .nav-icon,
.nav-tab-top.icon-nav:focus-visible .nav-icon,
.nav-tab-top.icon-nav.active .nav-icon {
  opacity: 1;
  transform: scale(1.06);
}
/* Discover tab: a bit smaller + greyer than the rest so the
   question-mark glyph reads as "secondary / lookup tool" rather
   than dominating the bar. Sized at ~80% of the new baseline
   (40/32/22) and tinted grey. Lights up to the accent color on
   hover / active just like any other tab. */
.nav-tab-top.icon-nav[data-view="discover"] .nav-icon {
  width: 32px;
  height: 32px;
  color: #6a6a6a;
}
@media (max-width: 1024px) {
  .nav-tab-top.icon-nav[data-view="discover"] .nav-icon {
    width: 26px; height: 26px;
  }
}
@media (max-width: 720px) {
  .nav-tab-top.icon-nav[data-view="discover"] .nav-icon {
    width: 18px; height: 18px;
  }
}
.nav-tab-top.icon-nav[data-view="discover"]:hover .nav-icon,
.nav-tab-top.icon-nav[data-view="discover"]:focus-visible .nav-icon,
.nav-tab-top.icon-nav[data-view="discover"].active .nav-icon {
  color: var(--accent);
}
.nav-tab-top.icon-nav.active::after {
  content: "";
  position: absolute;
  left: 0.55rem;
  right: 0.55rem;
  bottom: 0;
  height: 2px;
  background: var(--accent-hi, var(--accent));
  border-radius: 2px;
}
/* Label as floating tooltip below the icon. Hidden until hover/focus.
   pointer-events: none keeps it from intercepting clicks on the icon
   itself or stealing hover from neighbours. */
.nav-tab-top.icon-nav .nav-label {
  position: absolute;
  top: calc(100% + 4px);
  left: 50%;
  transform: translateX(-50%);
  background: var(--surface);
  color: var(--text);
  font-size: 0.68rem;
  padding: 0.2rem 0.5rem;
  border: 1px solid var(--border);
  border-radius: 4px;
  white-space: nowrap;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  z-index: 600;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.35);
  transition: opacity 0.12s ease;
}
.nav-tab-top.icon-nav:hover .nav-label,
.nav-tab-top.icon-nav:focus-visible .nav-label {
  opacity: 1;
  visibility: visible;
}
/* On the mobile drawer the icon-nav row stacks vertically, so revert
   to inline labels (no floating tooltip needed at full-width rows). */
@media (max-width: 720px) {
  .nav-tab-top.icon-nav .nav-label {
    position: static;
    transform: none;
    opacity: 1;
    visibility: visible;
    background: none;
    border: none;
    box-shadow: none;
    padding: 0;
    margin-left: 0.5rem;
    color: inherit;
  }
}

/* ─ Auth popup ──────────────────────────────────────────────────────────── */
/* ─ Hamburger (desktop: hidden) ────────────────────────────────────────── */
#nav-hamburger {
  display: none;
  flex-direction: column;
  justify-content: space-between;
  width: 36px;
  height: 28px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 7px;
  cursor: pointer;
}
#nav-hamburger span {
  display: block;
  width: 100%;
  height: 3px;
  background: var(--accent);
  border-radius: 2px;
}
/* ─ Mobile nav ─────────────────────────────────────────────────────────── */
@media (max-width: 640px) {
  #main-nav { padding: 0; }
  /* Hamburger sits top-right on mobile (was top-left). Right-side
     placement matches platform convention on iOS/Android and keeps
     the logo readable on the left without the button bumping into
     the SeaDISCOgs wordmark. */
  #nav-hamburger {
    display: flex !important;
    position: fixed;
    top: 1rem;
    right: 1rem;
    z-index: 500;
    background: var(--surface);
    border-color: var(--accent);
  }
  /* Drawer panel anchors to the same edge as the hamburger. */
  #nav-tabs-wrap { position: fixed; top: 3.5rem; right: 1rem; z-index: 500; min-width: 200px; }
  #main-nav-tabs {
    display: none !important;
    flex-direction: column;
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--surface);
  }
  #main-nav-tabs.mobile-open { display: flex !important; }
  .nav-row { flex-direction: column; }
  .nav-tab-top {
    box-shadow: none;
    border-radius: 0 !important;
    border-bottom: 1px solid var(--border);
    background: var(--surface);
    padding: 0.65rem 1.2rem;
    font-size: 0.82rem;
    letter-spacing: 0.03em;
    text-align: left;
    width: 100%;
  }
  .nav-tab-top[data-rtab] { padding-left: 1.5rem; font-size: 0.78rem; }
}

/* ── Recent Searches pills (inline under results) ───────────────────────── */
#favorites-sort { height: 1.6rem; font-size: 0.7rem; padding: 0 0.3rem; }
#favorites-sample-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 1rem;
}
.pill-strip-wrap {
  overflow: hidden;
  max-height: 5.5rem;
  mask-image: linear-gradient(to right, transparent, black 40px, black calc(100% - 40px), transparent);
  -webkit-mask-image: linear-gradient(to right, transparent, black 40px, black calc(100% - 40px), transparent);
}
/* ── Unified pill base ────────────────────────────────────────────────── */
.pill {
  /* inline-flex + align-items:center + line-height:1 strips the
     descender / line-height padding that inline-block inherits from
     the document's default 1.5 line-height, so the pill height
     matches its text + padding exactly instead of having an extra
     ~6px of empty space below the glyph. */
  display: inline-flex;
  align-items: center;
  line-height: 1;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 0.3rem 0.65rem;
  font-size: 0.72rem;
  color: var(--muted-dim);
  cursor: pointer;
  white-space: nowrap;
  transition: border-color 0.15s, color 0.15s, background 0.15s;
  user-select: none;
  -webkit-appearance: none;
}
.pill:hover { border-color: var(--accent-dim); color: #bbb; }
.pill.active { border-color: var(--accent); color: var(--accent); background: #1e1408; }

/* ── Synonym expansion info bar ────────────────────────────────────────── */
.cw-synonym-info {
  font-size: 0.72rem;
  color: #665a45;
  text-align: center;
  margin-top: 0.2rem;
  line-height: 1.5;
}
.cw-synonym-info .syn-icon { color: var(--accent-dim); margin-right: 0.2rem; }
.cw-synonym-info .syn-term { color: var(--muted-dim); font-style: italic; }

/* My Records sub-tabs */
/* records-sub-tabs removed — now in header nav row 2 */

/* Lists table */
.lists-table-wrap {
  padding: 0 1rem;
  overflow-x: auto;
}
.lists-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.82rem;
  font-variant-numeric: tabular-nums;
}
.lists-table thead th {
  text-align: left;
  color: var(--muted-dim);
  font-size: 0.7rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 0.35rem 0.5rem;
  border-bottom: 1px solid var(--border);
  position: sticky;
  top: 0;
  background: var(--bg);
  user-select: none;
}
.lists-th-sortable { cursor: pointer; }
 { color: var(--accent-hi); }
.lists-th-items { text-align: right; }
.lists-table tbody tr { border-bottom: 1px solid var(--border); cursor: pointer; }
.lists-table tbody tr:hover { background: rgba(255,255,255,0.03); }
.lists-table td { padding: 0.35rem 0.5rem; vertical-align: top; }
.lists-td-name { color: var(--muted); font-weight: 600; white-space: nowrap; }
.lists-td-items { text-align: right; color: var(--muted); white-space: nowrap; }
.lists-td-vis { color: var(--muted-dim); font-size: 0.75rem; white-space: nowrap; }
.lists-td-desc { color: var(--muted-dim); font-size: 0.75rem; max-width: 350px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lists-ext-link { color: #555; margin-left: 0.3rem; font-size: 0.7rem; text-decoration: none; }
 { color: var(--accent-hi); }

/* Collection folder pill cloud */
.cw-folder-cloud {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.35rem;
  margin-top: 0.75rem;
  margin-bottom: 0.65rem;
}
/* .cw-folder-pill extends .pill — no overrides needed */
.cw-folder-manage-btn {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  border-radius: 12px;
  padding: 0.15rem 0.45rem;
  font-size: 0.85rem;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.cw-folder-manage-btn:hover {
  background: var(--surface);
  border-color: var(--accent);
  color: var(--text);
}

/* ── Folder Manager modal ────────────────────────────────────────────── */
.folder-manager-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.7);
  z-index: 9000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
}
.folder-manager-panel {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  max-width: 520px;
  width: 100%;
  max-height: 82vh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  box-shadow: 0 12px 48px rgba(0, 0, 0, 0.65);
}
.fm-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border);
}
.fm-header h3 {
  margin: 0;
  font-size: 0.95rem;
  letter-spacing: 0.02em;
  color: var(--text);
}
.fm-close {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 1.1rem;
  cursor: pointer;
  padding: 0.15rem 0.35rem;
  line-height: 1;
}
.fm-close:hover { color: var(--text); }
.quick-folder-picker-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  z-index: 10000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}
.quick-folder-picker-panel {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.6);
  max-width: 360px;
  width: 100%;
  max-height: 70vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.qfp-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border);
}
.qfp-header h4 {
  margin: 0;
  font-size: 0.9rem;
  color: var(--text);
  font-weight: 600;
}
.qfp-close {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 1.1rem;
  cursor: pointer;
  line-height: 1;
  padding: 0 0.25rem;
}
.qfp-close:hover { color: var(--text); }
.qfp-list {
  list-style: none;
  margin: 0;
  padding: 0.4rem 0;
  overflow-y: auto;
  flex: 1;
}
.qfp-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.55rem 1rem;
  font-size: 0.85rem;
  color: var(--text);
  cursor: pointer;
  transition: background 0.12s;
}
.qfp-row:hover { background: rgba(255, 255, 255, 0.06); }
.qfp-row.is-current { color: var(--muted); }
.qfp-current-label {
  font-size: 0.68rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.fm-default-row {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  flex-wrap: wrap;
  padding: 0.65rem 1rem;
  border-bottom: 1px solid var(--border);
  font-size: 0.78rem;
  color: var(--muted);
}
.fm-default-row label { color: var(--muted); }
.fm-default-row select {
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 0.3rem 0.45rem;
  border-radius: 4px;
  font-size: 0.78rem;
  font-family: inherit;
  cursor: pointer;
}
.fm-default-row select:focus {
  outline: none;
  border-color: var(--accent);
}
.fm-default-status { font-size: 0.72rem; min-width: 4rem; }
.fm-create-row {
  display: flex;
  gap: 0.4rem;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border);
}
.fm-create-row input[type="text"] {
  flex: 1;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 0.35rem 0.55rem;
  border-radius: 4px;
  font-size: 0.8rem;
  font-family: inherit;
}
.fm-create-row input[type="text"]:focus {
  outline: none;
  border-color: var(--accent);
}
.fm-table-wrap {
  overflow-y: auto;
  flex: 1;
}
.fm-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8rem;
}
.fm-table thead th {
  position: sticky;
  top: 0;
  background: var(--bg);
  color: var(--muted);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-weight: 600;
  text-align: left;
  padding: 0.45rem 0.8rem;
  border-bottom: 1px solid var(--border);
}
.fm-table tbody td {
  padding: 0.45rem 0.8rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
  color: var(--text);
  vertical-align: middle;
}
.fm-name { min-width: 0; }
.fm-name-input {
  background: var(--surface);
  border: 1px solid var(--accent);
  color: var(--text);
  padding: 0.25rem 0.45rem;
  border-radius: 3px;
  font-size: 0.8rem;
  font-family: inherit;
  width: 100%;
  max-width: 280px;
}
.fm-count {
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  width: 60px;
}
.fm-actions {
  white-space: nowrap;
  width: 1%;
  text-align: right;
}
.fm-btn {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  padding: 0.2rem 0.45rem;
  border-radius: 3px;
  font-size: 0.72rem;
  cursor: pointer;
  margin-left: 0.2rem;
  transition: all 0.12s;
  line-height: 1;
  font-family: inherit;
}
.fm-btn:hover {
  color: var(--text);
  border-color: var(--accent);
}
.fm-btn-del:hover { border-color: #e06c75; color: #e06c75; }
.fm-btn-save:hover { border-color: #98c379; color: #98c379; }
.fm-btn-create {
  background: var(--accent);
  color: #0a0a0a;
  border-color: var(--accent);
  font-weight: 600;
}
.fm-btn-create:hover {
  filter: brightness(1.1);
  color: #0a0a0a;
}
.fm-locked { color: var(--muted); opacity: 0.4; }
.fm-empty {
  text-align: center;
  color: var(--muted);
  padding: 1.2rem !important;
  font-style: italic;
}
.fm-footer-hint {
  padding: 0.5rem 1rem 0.7rem;
  font-size: 0.68rem;
  color: var(--muted);
  opacity: 0.7;
  text-align: center;
  border-top: 1px solid var(--border);
}

/* No-match drop popup — floated cover, text right */
.drop-nomatch {
  display: flex;
  gap: 1.2rem;
  padding: 1.25rem 1rem;
}
.drop-nomatch-cover {
  width: 180px;
  height: 180px;
  object-fit: cover;
  border-radius: 6px;
  flex-shrink: 0;
}
.drop-nomatch-details {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  min-width: 0;
}
.drop-nomatch-artist {
  font-size: 0.88rem;
  color: var(--accent);
}
.drop-nomatch-artist a { color: var(--accent); text-decoration: none; }
.drop-nomatch-artist a:hover { text-decoration: underline; text-underline-offset: 2px; }
.drop-nomatch-title {
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--text);
}
.drop-nomatch-title a { color: inherit; text-decoration: none; }
.drop-nomatch-title a:hover { text-decoration: underline; text-underline-offset: 2px; }
.drop-nomatch-line {
  font-size: 0.78rem;
  color: #9a8d78;
}
.drop-nomatch-tags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin-top: 0.25rem;
}
.drop-nomatch-tag {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 0.1rem 0.45rem;
  font-size: 0.65rem;
  color: var(--muted);
  text-decoration: none;
  white-space: nowrap;
}
a.drop-nomatch-tag:hover { border-color: var(--accent); color: var(--accent); }
.drop-nomatch-msg {
  font-size: 0.82rem;
  color: var(--muted-dim);
  font-style: italic;
  margin-top: 0.4rem;
}
.drop-nomatch-google {
  font-size: 0.75rem;
  color: var(--accent);
  text-decoration: none;
  margin-top: 0.15rem;
}
.drop-nomatch-google:hover { text-decoration: underline; }
@media (max-width: 480px) {
  .drop-nomatch { flex-direction: column; align-items: center; text-align: center; }
  .drop-nomatch-cover { width: 160px; height: 160px; }
  .drop-nomatch-tags { justify-content: center; }
}

/* Mobile pill readability */
@media (max-width: 600px) {
  .pill {
    font-size: 0.78rem;
    padding: 0.3rem 0.75rem;
  }
  .pill-strip-wrap {
    max-height: 6.2rem;
  }
  .cw-folder-cloud {
    gap: 0.45rem;
  }
}

main {
  width: 90%;
  max-width: 1400px;
  margin: 0 auto;
  padding: 0.4rem 0 1.5rem;
}
#info-view, #privacy-view, #terms-view {
  width: 90%;
  max-width: 900px;
  margin: 0 auto;
  padding: 0.4rem 0 1.5rem;
}
@media (max-width: 1024px) { main, #info-view, #privacy-view, #terms-view { width: 94%; } }
@media (max-width: 640px)  { main, #info-view, #privacy-view, #terms-view { width: 97%; } }
@media (max-width: 400px)  { main, #info-view, #privacy-view, #terms-view { width: 99%; } }


/* ── Content narrow utility ── */
.content-narrow { max-width: 900px; margin-left: auto; margin-right: auto; }

/* ── Search form ── */
.search-row {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 0.5rem;
  align-items: center;
}

.swap-search-btn {
  background: none;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: #555;
  cursor: pointer;
  font-size: 1rem;
  padding: 0 0.45rem;
  height: var(--input-h);
  line-height: var(--input-h);
  flex-shrink: 0;
  transition: color 0.15s, border-color 0.15s;
}
.swap-search-btn:hover:not(:disabled) {
  color: var(--accent);
  border-color: var(--accent);
}
.swap-search-btn:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}

input[type="text"],
input[type="search"] {
  flex: 1;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--muted);
  font-family: inherit;
  font-size: 0.78rem;
  height: var(--input-h);
  padding: 0 0.6rem;
  line-height: var(--input-h);
  box-sizing: border-box;
  outline: none;
  transition: border-color 0.15s;
}

input[type="text"]:focus,
input[type="search"]:focus {
  border-color: var(--accent);
}
/* Highlight fields that have content. Uses --catno (the theme's
   off-spectrum accent) for the border so populated fields pop on
   every theme, not just amber-dark where the old hardcoded #8b5a1b
   happened to fit. Falls back to --accent for any theme without
   --catno. */
input[type="text"]:not(:placeholder-shown),
select.has-value {
  background: var(--accent-soft);
  border-color: var(--catno, var(--accent));
  color: var(--fg);
  box-shadow: 0 0 5px color-mix(in srgb, var(--catno, var(--accent)) 30%, transparent);
}

select {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  color: var(--muted);
  font-family: inherit;
  font-size: 0.78rem;
  /* Theme fonts with tall vertical metrics (some serifs / display
     fonts) overflow the bottom of the box at the previous fixed
     28px height — descenders + browser default line-height push
     past the inner area. min-height + auto height + explicit
     line-height keeps text vertically centered without clipping
     on any theme. */
  min-height: var(--input-h);
  line-height: 1.4;
  padding: 0.2rem 0.5rem;
  box-sizing: border-box;
  outline: none;
  cursor: pointer;
  color-scheme: dark;
}

button {
  background: var(--accent);
  border: none;
  border-radius: var(--radius);
  color: #000;
  cursor: pointer;
  font-family: inherit;
  font-size: 0.78rem;
  font-weight: 500;
  height: var(--input-h);
  padding: 0 1rem;
  box-sizing: border-box;
  transition: background 0.15s;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  line-height: 1;
}

button:hover:not(.nav-tab-top) { background: var(--accent2); }
button:disabled { background: var(--accent-dim); cursor: not-allowed; }

/* Match the records page Search button — content-fit width with a
   sensible minimum, no fixed 120px override. */
#search-btn { flex-shrink: 0; }

/* Advanced panel — smooth open/close via max-height transition */
#advanced-panel {
  overflow: hidden;
  max-height: 0;
  transition: max-height 0.25s ease, opacity 0.2s ease;
  opacity: 0;
}
#advanced-panel[data-open="true"] {
  max-height: 600px;
  opacity: 1;
}

.filters {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-bottom: 1.5rem;
  row-gap: 1.5rem;
}

.filters input[type="text"],
.filters select {
  flex: 1;
  min-width: 120px;
  color-scheme: dark;
}

.filters label {
  font-size: 0.75rem;
  color: var(--muted);
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  flex: 1;
  min-width: 100px;
}

/* ── Status / error ── */
#blurb {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  padding: 0.9rem 1.1rem;
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--text);
  margin-bottom: 1.25rem;
  display: none;
}

/* ── Video popup ── */
/* ── Persistent mini-player (bottom-docked) ── */
.mini-player {
  display: none;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 300;
  background: #111;
  /* Subtle accent on the top edge anchors the bar against the page
     content so it reads as a docked surface rather than a floating
     overlay. The shadow puts more depth between bar and content. */
  border-top: 1px solid rgba(126, 184, 218, 0.12);
  box-shadow: 0 -8px 28px rgba(0,0,0,0.6), 0 -1px 0 rgba(255,255,255,0.04) inset;
  font-family: inherit;
}
.mini-player.open { display: block; }
/* Reserve space at the bottom of the page whenever either bottom-docked
   audio bar is visible so the last row of album cards doesn't disappear
   behind it. The expanded YouTube mini-player needs more headroom. */
body.player-open { padding-bottom: 96px; }
body.player-open.expanded-mini { padding-bottom: 168px; }
/* Hide-bar mode: user clicked × to push the player out of view so the
   bottom of open popups (master/version lists on mobile especially)
   becomes reachable. Playback continues — only the chrome moves.
   Drop the player-open padding too so the body can scroll all the
   way down. */
body.mini-player-bar-hidden #mini-player {
  transform: translateY(110%);
  pointer-events: none;
}
body.mini-player-bar-hidden.player-open { padding-bottom: 0; }
body.mini-player-bar-hidden.player-open.expanded-mini { padding-bottom: 0; }
/* Floating restore tab. Hidden by default; revealed when the bar is
   hidden. Sits above any other footer / drawer chrome. */
#mini-player-show-tab {
  display: none;
  position: fixed;
  right: 12px;
  bottom: 12px;
  width: 44px;
  height: 44px;
  border-radius: 22px;
  background: var(--accent);
  color: #000;
  border: none;
  font-size: 1.2rem;
  cursor: pointer;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
  z-index: 1500;
  line-height: 1;
}
#mini-player-show-tab:hover { filter: brightness(1.1); }
body.mini-player-bar-hidden #mini-player-show-tab { display: flex; align-items: center; justify-content: center; }
/* When any popup is open, the page underneath must NOT scroll —
   only the popup's own content. overscroll-behavior:none blocks the
   rubber-band that lets a wheel/touch over the dark overlay edges
   propagate to the body in some browsers. */
body.modal-open  { overflow: hidden; overscroll-behavior: none; }

/* Anon mode: hide save / favorite affordances across LOC, Wiki,
   Archive, and YouTube companion views — anons can search & view
   but can't save (server-side requireUser on the save endpoints
   would 401 anyway; this just keeps the UI honest). The Saved sub-
   tabs in those views are also hidden. */
body.sd-anon .loc-save-badge,
body.sd-anon .archive-save-btn,
body.sd-anon .wiki-save-btn,
body.sd-anon .yt-save-btn,
body.sd-anon .loc-tab-saved,
body.sd-anon .archive-tab-saved,
body.sd-anon .wiki-tab-saved,
body.sd-anon .youtube-saved-tab,
body.sd-anon .card-badge.badge-favorite,
body.sd-anon .card-badge.badge-collection,
body.sd-anon .card-badge.badge-wantlist,
body.sd-anon .card-badge.badge-list,
body.sd-anon .card-badge.badge-inventory {
  display: none !important;
}

.mini-player-bar {
  display: flex;
  align-items: center;
  padding: 0.5rem 0.6rem 0.65rem;
  gap: 0.4rem;
  min-height: 48px;
}
/* Click/drag-to-seek progress strip below the bar. Slim by default, grows
   on hover so the click target is reasonable on desktop. The knob is
   only rendered while dragging so there's no extra visual noise during
   normal playback (the fill alone shows position). */
.mini-progress {
  position: relative;
  height: 4px;
  background: rgba(255, 255, 255, 0.08);
  cursor: pointer;
  margin: 0 0.6rem 0.3rem;
  border-radius: 2px;
  transition: height 0.12s ease;
  user-select: none;
  /* Hide entirely until the player has a known duration */
  display: none;
}
.mini-player.has-duration .mini-progress { display: block; }
.mini-progress:hover,
.mini-progress.is-dragging { height: 8px; }
.mini-progress-fill {
  height: 100%;
  width: 0%;
  background: var(--accent);
  border-radius: 2px;
  pointer-events: none;
  transition: width 0.12s linear;
}
.mini-progress.is-dragging .mini-progress-fill { transition: none; }
.mini-progress-knob {
  position: absolute;
  top: 50%;
  width: 12px;
  height: 12px;
  background: var(--accent);
  border-radius: 50%;
  transform: translate(-50%, -50%);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.12s ease;
}
.mini-progress:hover .mini-progress-knob,
.mini-progress.is-dragging .mini-progress-knob { opacity: 1; }
.mini-progress-times {
  position: absolute;
  top: -16px;
  left: 0;
  right: 0;
  display: flex;
  justify-content: space-between;
  font-size: 0.62rem;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.12s ease;
}
.mini-progress:hover .mini-progress-times,
.mini-progress.is-dragging .mini-progress-times { opacity: 1; }
.mini-player-info {
  flex: 1;
  min-width: 0;
  cursor: pointer;
  display: flex;
  align-items: center;
  gap: 0;
  overflow: hidden;
}
.mini-player-title {
  font-size: 0.78rem;
  color: #ccc;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex-shrink: 1;
  min-width: 0;
}
.mini-player-title .vt-track { font-weight: 600; color: #fff; }
.mini-player-title .vt-sep   { color: #555; margin: 0 0.25em; }

.mini-player-status {
  font-size: 0.68rem;
  margin-left: 0.5em;
  letter-spacing: 0.02em;
  flex-shrink: 0;
  white-space: nowrap;
}
.mini-player-status.status-loading  { color: #b0a060; }
.mini-player-status.status-playing  { color: var(--success); }
.mini-player-status.status-paused   { color: var(--muted); }
.mini-player-status.status-ended    { color: #666; }
.mini-player-status.status-error    { color: #e88; }

@keyframes pulse-status {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.4; }
}
.mini-player-status.status-loading,
.mini-player-status.status-error {
  animation: pulse-status 1.5s ease-in-out infinite;
}

.mini-player-controls {
  display: flex;
  align-items: center;
  gap: 0.15rem;
  flex-shrink: 0;
}
.mini-player-controls button {
  background: none;
  border: none;
  color: #aaa;
  font-size: 0.85rem;
  padding: 0.25rem 0.45rem;
  cursor: pointer;
  border-radius: 4px;
  line-height: 1;
}
.mini-player-controls button:hover:not(:disabled) { color: #fff; background: rgba(255,255,255,0.1); }
.mini-player-controls button:disabled { opacity: 0.3; cursor: default; }
#mini-close { font-size: 1.1rem; }
#mini-expand { transition: transform 0.2s; }
.mini-player.expanded #mini-expand { transform: rotate(180deg); }

.mini-player-expanded {
  display: none;
  padding: 0 0.6rem 0.5rem;
}
.mini-player.expanded .mini-player-expanded { display: block; }

.mini-player #video-box {
  position: relative;
  width: 100%;
  max-width: 640px;
  margin: 0 auto;
  padding-bottom: min(56.25%, 360px);
  height: 0;
  background: #000;
  border-radius: 6px;
  overflow: hidden;
}
.mini-player #video-box iframe,
.mini-player #video-player {
  position: absolute;
  top: 0; left: 0;
  width: 100%;
  height: 100%;
  border: none;
}

.mini-player #video-nav {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: 0.4rem;
  gap: 0.5rem;
  max-width: 640px;
  margin-left: auto;
  margin-right: auto;
}
.mini-player #video-nav button {
  background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.15);
  color: #ccc;
  font-size: 0.85rem;
  padding: 0.25rem 0.8rem;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.15s;
  flex: 1;
  max-width: 140px;
}
.mini-player #video-nav button:hover:not(:disabled) { background: rgba(255,255,255,0.15); color: #fff; }
.mini-player #video-nav button:disabled { opacity: 0.3; cursor: default; }

@media (max-width: 640px) {
  .mini-player #video-box { padding-bottom: 56.25%; }
  .mini-player-expanded { padding: 0 0.4rem 0.4rem; }
}

/* ── Modal ── */
#modal-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.75);
  z-index: 100;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}

/* ── Version overlay (layered over master popup & series browser) ── */
#version-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.55);
  z-index: 220;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}
#version-overlay.open { display: flex; }
#version-box {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  max-width: 560px;
  width: 100%;
  max-height: 82vh;
  overflow-y: auto;
  position: relative;
  box-shadow: 0 8px 40px rgba(0,0,0,0.7);
}
/* #modal-close still used by admin.html */
#modal-close {
  position: sticky; top: 0.5rem; float: right;
  margin: 0.5rem 0.6rem 0 0; background: none; border: none;
  color: var(--muted); font-size: 1.5rem; line-height: 1;
  cursor: pointer; padding: 0.1rem 0.4rem; border-radius: 4px; z-index: 1;
}
#modal-close:hover { color: var(--text); background: var(--border); }
#version-info { overflow: hidden; }

/* ── Series browser overlay ───────────────────────────────────────────── */
#series-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.55);
  z-index: 210;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}
#series-overlay.open { display: flex; }
#series-box {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  max-width: 640px;
  width: 100%;
  max-height: 85vh;
  overflow-y: auto;
  position: relative;
  box-shadow: 0 8px 40px rgba(0,0,0,0.7);
  padding: 1rem;
}
#series-close {
  position: sticky;
  top: 0;
  float: right;
  margin: 0 0 0 0;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.1rem 0.4rem;
  border-radius: 4px;
  z-index: 1;
}
#series-close:hover { color: var(--text); background: var(--border); }
.sr-grid {
  display: grid;
  grid-template-columns: auto 1fr auto auto auto;
  gap: 0.25rem 0.6rem;
  font-size: 0.75rem;
  align-items: center;
}
.sr-grid img {
  width: 40px;
  height: 40px;
  object-fit: cover;
  border-radius: 3px;
}
.sr-grid .sr-title { color: var(--fg); cursor: pointer; text-decoration: none; word-break: break-word; overflow-wrap: break-word; min-width: 0; }
 { color: var(--accent-hi); text-decoration: dotted underline; }
.sr-pill-row { display: flex; flex-wrap: wrap; gap: 0.3rem; margin-bottom: 0.6rem; }
.sr-pill {
  background: #2a2a2a;
  border: none;
  color: var(--fg);
  padding: 0.2rem 0.55rem;
  border-radius: 999px;
  font-size: 0.68rem;
  cursor: pointer;
  white-space: nowrap;
}
.sr-pill:hover { background: #3a3a3a; }

#modal-overlay.open { display: flex; }

#modal-box {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  max-width: 620px;
  width: 100%;
  max-height: 88vh;
  overflow-y: auto;
  position: relative;
  /* Soft outer shadow gives the popup a clear "lifted" reading against
     the dimmed overlay. The inset hairline fakes a top edge highlight
     so the lift looks intentional rather than a glow. */
  box-shadow: 0 8px 28px rgba(0,0,0,0.55), 0 1px 0 rgba(255,255,255,0.04) inset;
}

/* Empty close zone at top of popup — tap to dismiss (especially on mobile) */
.popup-close-zone {
  height: 1.5rem; cursor: pointer;
  position: sticky; top: 0; z-index: 3; background: var(--surface);
}
.popup-close-zone::after {
  content: ""; position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: 2rem; height: 4px; border-radius: 2px; background: #333;
}
.popup-close-zone:hover::after { background: var(--muted); }
/* Inline share button next to type badge */
.popup-share-inline {
  background: none; border: none; cursor: pointer;
  font-size: 0.72rem; color: var(--muted); padding: 0.15rem 0.4rem;
  border-radius: 4px; letter-spacing: 0.03em;
}
 { color: var(--accent-hi); background: var(--surface); }

/* Share button inside bio / video popups */
.popup-share {
  background: none; border: none; cursor: pointer;
  font-size: 0.72rem; color: var(--muted); padding: 0.2rem 0.5rem;
  border-radius: 4px; float: right; margin: 0.6rem 0.2rem 0 0;
  letter-spacing: 0.03em;
}
 { color: var(--accent-hi); background: var(--surface); }

/* ── Wikipedia dropdown (sits next to the eBay logo in modal header) ── */
.wiki-link-wrap {
  position: relative;
  display: inline-block;
  margin-left: 0.35rem;
  vertical-align: baseline;
}
/* The sitewide `button:hover:not(.nav-tab-top)` rule has specificity
   (0,2,1) which beats `.wiki-link-btn:hover` (0,2,0), so the orange
   button background was bleeding through on hover even though we
   wanted just the W glyph to change color. Prefix with `button` to
   match specificity, force background transparent with !important to
   defeat any leftover sitewide overrides, and disable transitions so
   there's no flash mid-animation. */
button.wiki-link-btn,
button.wiki-link-btn:hover,
button.wiki-link-btn:focus,
button.wiki-link-btn:active {
  background: transparent !important;
  border: none;
  border-radius: 0;
  padding: 0;
  height: auto;
  min-height: 0;
  box-shadow: none;
  outline: none;
  transition: none;
}
.wiki-link-btn {
  cursor: pointer;
  font: inherit;
  line-height: 1;
  color: #eaeaea;
  vertical-align: baseline;
}
.wiki-link-btn .wiki-w {
  display: inline-block;
  font-family: "Linux Libertine", "Georgia", "Times New Roman", serif;
  font-size: 0.82rem;
  font-weight: 400;
  line-height: 1;
  color: #eaeaea;
  text-shadow: 0 0 1px rgba(0, 0, 0, 0.4);
  transition: color 0.15s;
}
 { color: var(--accent-hi); }
.wiki-link-menu {
  position: absolute;
  top: calc(100% + 0.35rem);
  left: 0;
  min-width: 220px;
  max-width: 320px;
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: 5px;
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.5);
  padding: 0.25rem;
  z-index: 260;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}
.wiki-link-menu[hidden] { display: none; }
.wiki-menu-item {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.35rem 0.55rem;
  border-radius: 3px;
  text-decoration: none;
  color: var(--text);
  font-size: 0.78rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
 { background: var(--bg-elevated); color: var(--accent-hi); }
.wiki-menu-key {
  color: var(--muted);
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  flex-shrink: 0;
  min-width: 3rem;
}
.wiki-menu-val {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

#modal-loading {
  padding: 2rem;
  text-align: center;
  color: var(--muted);
  font-size: 0.9rem;
}

#album-info, #version-info { overflow: hidden; clear: both; }

#album-info .album-header, #version-info .album-header {
  display: flex;
  gap: 1rem;
  padding: 0.75rem;
  border-bottom: 1px solid var(--border);
}

#album-info .album-cover, #version-info .album-cover {
  width: 130px;
  height: 130px;
  object-fit: cover;
  border-radius: 4px;
  flex-shrink: 0;
  background: var(--surface);
  cursor: pointer;
  transition: opacity 0.15s;
}
#album-info .album-cover:hover, #version-info .album-cover:hover { opacity: 0.8; }

.album-cover-wrap { flex-shrink: 0; }
.album-thumb-strip {
  display: flex;
  gap: 4px;
  margin-top: 4px;
  flex-wrap: wrap;
  max-width: 130px;
}
.album-thumb {
  width: 28px; height: 28px;
  object-fit: cover;
  border-radius: 3px;
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 0.15s;
}
.album-thumb:hover { opacity: 1; }

/* ── Lightbox ─────────────────────────────────────────────────────── */
#lightbox-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.92);
  z-index: 9000;
  align-items: center;
  justify-content: center;
  flex-direction: column;
}
#lightbox-overlay.open { display: flex; }
#lightbox-img {
  max-width: min(90vw, 700px);
  max-height: 80vh;
  object-fit: contain;
  border-radius: 4px;
  box-shadow: 0 4px 40px rgba(0,0,0,0.8);
  display: block;
}
#lightbox-close {
  position: absolute;
  top: 0.75rem; right: 0.75rem;
  background: rgba(0,0,0,0.5);
  border: 1px solid rgba(255,255,255,0.2);
  color: #fff; font-size: 1.5rem;
  cursor: pointer; line-height: 1;
  padding: 0.3rem 0.55rem;
  border-radius: 50%;
  z-index: 2;
  text-shadow: 0 1px 4px rgba(0,0,0,0.8);
}
#lightbox-close:hover { background: rgba(0,0,0,0.75); border-color: rgba(255,255,255,0.5); }
#lightbox-prev, #lightbox-next {
  position: absolute;
  top: 50%; transform: translateY(-50%);
  background: rgba(0,0,0,0.55);
  border: 1px solid rgba(255,255,255,0.25);
  color: #fff;
  font-size: 2.2rem;
  width: 3.5rem; height: 3.5rem;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
  cursor: pointer; border-radius: 50%;
  transition: background 0.15s, border-color 0.15s;
  text-shadow: 0 1px 4px rgba(0,0,0,0.8);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  z-index: 2;
  line-height: 1;
}
#lightbox-prev:hover, #lightbox-next:hover { background: rgba(0,0,0,0.75); border-color: rgba(255,255,255,0.5); }
#lightbox-prev { left: 0.75rem; }
#lightbox-next { right: 0.75rem; }
#lightbox-prev:disabled, #lightbox-next:disabled { opacity: 0.15; cursor: default; }
#lightbox-counter {
  margin-top: 0.75rem;
  font-size: 0.8rem;
  color: rgba(255,255,255,0.5);
  letter-spacing: 0.05em;
}

#album-info .album-cover-placeholder, #version-info .album-cover-placeholder {
  width: 130px;
  height: 130px;
  background: var(--surface);
  border-radius: 4px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--border);
  font-size: 2rem;
}

#album-info .album-type-badge, #version-info .album-type-badge {
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 0.1rem 0.4rem;
  display: inline-block;
  margin-bottom: 0.1rem;
  position: relative;
  transition: color 0.15s;
}
#album-info .album-type-badge[data-copied="true"],
#version-info .album-type-badge[data-copied="true"] {
  color: var(--accent);
  border-color: var(--accent);
}
#album-info .album-type-badge[data-copied="true"]::after,
#version-info .album-type-badge[data-copied="true"]::after {
  content: " ✓ copied";
  font-size: 0.6rem;
  color: var(--accent);
}

#album-info .album-meta, #version-info .album-meta { min-width: 0; overflow-wrap: break-word; }
#album-info .album-meta h2, #version-info .album-meta h2 {
  font-size: 1.05rem;
  font-weight: 700;
  margin-bottom: 0.2rem;
  line-height: 1.3;
}

.album-title-search {
  color: var(--accent);
  text-decoration: none;
  font-size: 1.1em;
}
.album-title-search:hover,
.modal-internal-link:hover {
  color: var(--accent-hi);
  text-decoration: underline dotted;
  text-underline-offset: 3px;
  text-decoration-color: var(--muted);
}
.modal-internal-link {
  text-decoration: none;
  color: var(--fg);
}
.catno-link,
.catno-link:visited {
  /* Catalog numbers use a per-theme "off-spectrum" color so they pop
     out from the primary accent (which is usually link/CTA color).
     Falls back to success for any theme that doesn't define --catno. */
  color: var(--catno, var(--success)) !important;
  font-variant-numeric: tabular-nums;
}
.mv-grid a:hover {
  text-decoration: underline dotted !important;
  text-decoration-color: var(--muted);
  text-underline-offset: 3px;
}
.matrix-runout[data-copied="true"]::after {
  content: " ✓ copied";
  color: var(--muted);
  font-size: 0.7em;
}
.catno-collection-search {
  color: var(--accent);
  text-decoration: none;
  font-size: 1.1em;
}
.catno-collection-search:hover {
  text-decoration: underline dotted;
  text-underline-offset: 3px;
  text-decoration-color: var(--muted);
}
.track-search-icon {
  color: var(--muted);
  text-decoration: none;
  font-size: 1.1em;
}
.track-search-icon:hover {
  color: var(--fg);
  text-decoration: underline dotted;
  text-underline-offset: 3px;
  text-decoration-color: var(--muted);
}

#album-info .album-meta .album-artist, #version-info .album-meta .album-artist {
  color: var(--fg);
  font-size: 0.75rem;
  margin-bottom: 0.5rem;
}
.modal-artist-link { color: var(--fg); text-decoration: none; font-size: 0.75rem; }
.modal-artist-link:hover { color: var(--accent-hi); text-decoration: underline dotted; text-underline-offset: 3px; text-decoration-color: var(--muted); }
.modal-title-link { color: var(--fg); text-decoration: none; }
.modal-title-link:hover { color: var(--accent-hi); text-decoration: underline dotted; text-underline-offset: 3px; text-decoration-color: var(--muted); }

#album-info .album-detail-grid, #version-info .album-detail-grid {
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  gap: 0.15rem 0.5rem;
  font-size: 0.78rem;
  min-width: 0;
}
#album-info .album-detail-grid > span:nth-child(even),
#version-info .album-detail-grid > span:nth-child(even) {
  overflow-wrap: break-word;
  word-break: break-word;
  min-width: 0;
}

#album-info .detail-label, #version-info .detail-label {
  color: var(--muted);
}

#album-info .album-tracklist, #version-info .album-tracklist {
  padding: 0.75rem;
}

#album-info .tracklist-heading, #version-info .tracklist-heading {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin-bottom: 0.5rem;
}
.tracklist-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.tracklist-toggle {
  cursor: pointer;
  user-select: none;
  flex-shrink: 0;
}
.tracklist-toggle:hover { color: var(--fg); }
.tracklist-arrow {
  display: inline-block;
  font-size: 0.6rem;
  vertical-align: middle;
  margin-right: 0.15em;
  transition: color 0.15s;
}
/* "(N ▶)" — playable count + start-from-first-track button shown
   inline next to the Tracklist heading text. */
.tracklist-playable {
  font-size: 0.65rem;
  color: var(--muted);
  text-transform: none;
  letter-spacing: 0;
  margin-left: 0.25rem;
  font-weight: 400;
}
.tracklist-play-all {
  display: inline-block;
  color: var(--accent);
  text-decoration: none;
  font-size: 0.7rem;
  margin-left: 0.15rem;
  cursor: pointer;
  transition: color 0.15s, transform 0.15s;
}
.tracklist-play-all:hover {
  color: var(--accent-hover);
  transform: scale(1.2);
}
/* "+ Queue album" link in the tracklist heading. Subtle muted color
   so it doesn't compete with the play button next to it; brightens
   to --accent-hi on hover like other link affordances. */
.tracklist-queue-album {
  display: inline-block;
  color: var(--muted);
  text-decoration: none;
  font-size: 0.7rem;
  margin-left: 0.45rem;
  cursor: pointer;
  letter-spacing: 0.02em;
  transition: color 0.15s;
}
.tracklist-queue-album:hover { color: var(--accent-hi, var(--accent)); }
.tracklist-filter {
  flex: 1;
  max-width: 160px;
  background: rgba(255,255,255,0.06);
  border: 1px solid #333;
  border-radius: 4px;
  color: var(--fg);
  font-size: 0.68rem;
  padding: 0.15rem 0.4rem;
  outline: none;
  font-family: inherit;
}
.tracklist-filter:focus { border-color: var(--accent); }
.tracklist-filter::placeholder { color: #555; }

/* Site-wide filter input + select — used wherever a list/grid has a
   "filter" affordance (home strip, picks page, etc). Matches the
   .tracklist-filter footprint so the visual rhythm is consistent.
   Slightly larger touch target than .tracklist-filter since these
   live outside dense tracklist rows. */
.sd-filter-input,
.sd-filter-select {
  background: rgba(255,255,255,0.06);
  border: 1px solid #333;
  border-radius: 4px;
  color: var(--fg);
  font-size: 0.78rem;
  padding: 0.3rem 0.5rem;
  outline: none;
  font-family: inherit;
  line-height: 1.2;
  transition: border-color 0.15s;
  color-scheme: dark;
}
.sd-filter-input { width: 9rem; }
.sd-filter-input:focus,
.sd-filter-select:focus { border-color: var(--accent); }
.sd-filter-input::placeholder { color: #555; }
/* Native <select> renders its dropdown panel with OS / browser
   defaults — without these, the open option list is white-on-white
   in some Chromium builds (the parent's `color-scheme: dark` doesn't
   always cascade to the popup). Style each <option> explicitly so
   the dropdown matches the theme on every platform. */
.sd-filter-select option {
  background: var(--surface);
  color: var(--fg);
}
.sd-filter-select option:checked,
.sd-filter-select option:hover {
  background: var(--surface-raised);
  color: var(--text);
}

/* Inline label paired with .sd-filter-input or .sd-filter-select.
   Keeps the "Sort" / "Filter" word at the right size + color. */
.sd-filter-label {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.72rem;
  color: var(--muted);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.sd-filter-label .sd-filter-select { text-transform: none; letter-spacing: 0; }

/* ── Anonymous-visitor splash (waitlist pitch + OAuth feature list) ─
   Replaces the home strip for signed-out users. Sits in the same
   slot but reads as a marketing panel: title, lead, primary CTA,
   then a feature list explaining what users get post-sign-up. */
.anon-splash {
  /* Slim banner — anon visitors get the full app surface (search,
     feed, playback). The splash now just nudges signup, doesn't take
     over the page. */
  margin: 0.6rem 0 0.4rem;
  padding: 0.55rem 0.85rem;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 6px;
  font-size: 0.82rem;
}
.anon-splash-title {
  font-size: 1.3rem;
  margin: 0 0 0.4rem;
  color: var(--text);
}
.anon-splash-lead {
  margin: 0;
  font-size: 0.84rem;
  color: var(--muted);
  line-height: 1.5;
}
.anon-splash-lead strong { color: var(--text); }
.anon-splash-lead a { color: var(--accent); text-decoration: none; }
.anon-splash-lead a:hover { text-decoration: underline; }
.anon-splash-cta {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  margin-bottom: 1.5rem;
  flex-wrap: wrap;
}
.anon-splash-btn {
  background: var(--accent);
  color: var(--surface);
  border: none;
  border-radius: 4px;
  padding: 0.6rem 1.2rem;
  font-size: 0.92rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s, transform 0.1s;
}
.anon-splash-btn:hover {
  background: var(--accent-hi, var(--accent));
  transform: translateY(-1px);
}
.anon-splash-cta-note {
  font-size: 0.78rem;
  color: var(--muted);
}
.anon-splash-cta-note a {
  color: var(--accent);
  text-decoration: none;
}
.anon-splash-cta-note a:hover { text-decoration: underline; }
.anon-splash-section {
  font-size: 0.78rem;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0 0 0.6rem;
}
.anon-splash-features {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 0.5rem 1.2rem;
}
.anon-splash-features li {
  font-size: 0.82rem;
  color: var(--muted);
  line-height: 1.5;
  padding-left: 1rem;
  position: relative;
}
.anon-splash-features li::before {
  content: "·";
  position: absolute;
  left: 0;
  color: var(--accent);
  font-weight: 700;
}
.anon-splash-features li strong {
  color: var(--text);
  font-weight: 600;
}

/* Home strip Recent / Suggestions / Submitted header — title-wrap on the left,
   controls (filter + sort + clear) on the right. Single row whenever
   the viewport allows; on narrow screens controls drop below the
   title cleanly instead of breaking individually. */
.rr-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.6rem 0.75rem;
  margin: 0 0 0.5rem 0;
  padding: 0 0.15rem;
  flex-wrap: wrap;
}
.rr-title-wrap {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  flex-shrink: 0;
}
.rr-tab { cursor: pointer; color: var(--muted); transition: color 0.15s; }
.rr-tab:hover { color: var(--text); }
.rr-tab.rr-tab-active { color: var(--text); }
.rr-tab.rr-tab-disabled {
  color: #444 !important;
  cursor: not-allowed;
  opacity: 0.55;
}
.rr-tab.rr-tab-disabled:hover { color: #444 !important; }
.rr-tab-sep { color: #444; }
/* External-source sub-nav strip (LOC / Wikipedia / Archive / YouTube).
   Shares .rr-header + .rr-tab styling so it visually matches the home
   Recent / Suggestions / Submitted / Feed strip. The bottom border
   reads as "this row is a sub-nav heading the page below it." */
.extras-tabs {
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.4rem;
  margin-bottom: 0.6rem;
  /* The strip uses .rr-header's flex+space-between layout, but
     .rr-header sets margin:0 0 0.5rem 0 which zeroes out
     .content-narrow's auto left/right margins — so without this
     override the whole strip pinned to the left edge of <body>
     while everything else on the page sits inside the centered
     900px gutter. !important to beat .rr-header's later cascade. */
  margin-left: auto !important;
  margin-right: auto !important;
}
.rr-controls {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-shrink: 0;
  flex-wrap: nowrap;
}
.rr-clear-btn {
  background: none;
  border: none;
  padding: 0 0.4rem;
  font-size: 0.78rem;
  color: var(--muted);
  cursor: pointer;
  line-height: 1;
  flex-shrink: 0;
  transition: color 0.15s;
}
.rr-clear-btn:hover { color: var(--text); }

.credits-header {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-bottom: 0.4rem;
}
.credits-body {
  font-size: 0.78rem;
  line-height: 1.7;
  color: var(--fg);
}
.album-credits {
  padding: 0.75rem;
}
.credit-sep {
  color: var(--muted);
  font-size: 1.05em;
  font-weight: 700;
  margin: 0 0.15em;
}

/* ── Master versions grid ── */
.mv-grid-scroll {
  overflow-x: auto;
  padding-bottom: 0.75rem;
}
.mv-grid {
  overflow: hidden;
}
.mv-grid > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  min-width: 0;
}

/* ── Master version filter pills ── */
.mv-pill-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem;
  margin-bottom: 0.4rem;
}
.mv-pill {
  cursor: pointer;
  border: none;
  border-radius: 14px;
  padding: 0.1rem 0.45rem;
  font-size: 0.62rem;
  font-weight: 600;
  font-family: inherit;
  transition: background 0.15s;
  background: #2a2a2a;
  color: var(--fg);
}
.mv-pill:hover { background: #3a3a3a; }
.mv-pill[data-filter=""] { background: var(--accent); color: #000; }

#album-info .track, #version-info .track {
  display: flex;
  gap: 0.6rem;
  font-size: 0.82rem;
  padding: 0.25rem 0;
  border-bottom: 1px solid var(--border);
  align-items: baseline;
}
#album-info .track-title a, #version-info .track-title a {
  display: inline;
}

#album-info .track:last-child, #version-info .track:last-child { border-bottom: none; }

#album-info .track-pos, #version-info .track-pos {
  color: var(--muted);
  min-width: 2rem;
  text-align: right;
  flex-shrink: 0;
}

#album-info .track-title, #version-info .track-title { flex: 1; }

.track-credits {
  font-size: 0.78em;
  color: var(--muted);
  line-height: 1.3;
  margin-top: 0.15rem;
}

#album-info .track-dur, #version-info .track-dur {
  color: var(--muted);
  flex-shrink: 0;
}

#album-info .track-link, #version-info .track-link {
  color: inherit;
  text-decoration: none;
}

.track-link.now-playing {
  color: var(--accent) !important;
}
#album-info .track-link:hover, #version-info .track-link:hover {
  color: var(--accent-hi);
  text-decoration: underline dotted;
  text-underline-offset: 3px;
  text-decoration-color: var(--muted);
}

#album-info .yt-search, #version-info .yt-search {
  display: inline-flex;
  align-items: center;
  margin-left: 0.4em;
  flex-shrink: 0;
  filter: grayscale(1) brightness(0.6);
  transition: filter 0.15s;
}
#album-info .yt-search:hover, #version-info .yt-search:hover { filter: none; }

#album-info .album-extra, #version-info .album-extra {
  border-top: 1px solid var(--border);
  padding: 0.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

#album-info .album-meta-row, #version-info .album-meta-row {
  display: flex;
  gap: 0.75rem;
  font-size: 0.8rem;
}

#album-info .meta-label, #version-info .meta-label {
  color: var(--muted);
  min-width: 5rem;
  flex-shrink: 0;
}

.credit-name { color: #d4815a; }
#album-info .credit-role, #version-info .credit-role {
  color: var(--muted);
}

#album-info .album-notes, #version-info .album-notes {
  margin-top: 0.25rem;
  font-size: 0.8rem;
  line-height: 1.55;
  color: var(--muted);
}

/* ── Modal action buttons ── */
.modal-actions {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.6rem;
  flex-wrap: wrap;
}
/* Multi-instance panel — shown when user owns multiple copies of a release */
.modal-instances-panel {
  margin-top: 0.55rem;
  padding: 0.5rem 0.7rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.72rem;
  color: var(--muted);
}

/* ── Notes & custom fields editor panel ──────────────────────────────── */
.modal-notes-panel {
  margin-top: 0.45rem;
  padding: 0.5rem 0.7rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 0.72rem;
  color: var(--muted);
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}
/* Clickable header above the notes/fields body. Full-width transparent
   button so the whole row is a hit target. Chevron flips based on the
   .is-collapsed state on the parent panel (persisted per user via
   localStorage sd-notes-collapsed). Hover just brightens a subtle
   bottom border — no color shift, no background flash. */
.modal-notes-header {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.15rem 0 0.3rem;
  background: none;
  border: none;
  border-bottom: 1px solid transparent;
  color: var(--text);
  font: inherit;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  cursor: pointer;
  text-align: left;
  width: 100%;
  transition: border-color 0.15s;
}
.modal-notes-header:hover { border-bottom-color: var(--border-strong); }
.modal-notes-chev {
  color: var(--muted);
  font-size: 0.75rem;
  width: 0.9rem;
  display: inline-flex;
  justify-content: center;
}
.modal-notes-header-label { flex: 1; }
.modal-notes-body {
  display: flex;
  flex-direction: column;
  gap: 0.45rem;
}
.modal-notes-panel.is-collapsed .modal-notes-body { display: none; }
.modal-notes-panel.is-collapsed { gap: 0; padding: 0.35rem 0.7rem; }
.modal-notes-block {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.modal-notes-block + .modal-notes-block {
  border-top: 1px solid var(--border);
  padding-top: 0.45rem;
}
.modal-notes-title {
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text);
}
.modal-notes-hint {
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  color: var(--muted);
  font-size: 0.66rem;
}
.modal-notes-row {
  display: flex;
  gap: 0.5rem;
  align-items: flex-start;
  font-size: 0.7rem;
}
.modal-notes-label {
  flex: 0 0 7.5rem;
  max-width: 7.5rem;
  padding-top: 0.28rem;
  color: var(--muted);
  font-size: 0.68rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.modal-notes-input {
  flex: 1;
  min-width: 0;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 4px;
  color: var(--text);
  padding: 0.28rem 0.45rem;
  font: inherit;
  font-size: 0.72rem;
  resize: vertical;
}
.modal-notes-input:focus {
  outline: none;
  border-color: var(--inventory-border);
  background: var(--surface-raised);
}
.modal-notes-input:disabled { opacity: 0.5; }
.modal-notes-empty,
.modal-notes-loading {
  font-size: 0.68rem;
  color: var(--muted);
  font-style: italic;
}
@media (max-width: 560px) {
  .modal-notes-row { flex-direction: column; gap: 0.2rem; }
  .modal-notes-label { flex: initial; max-width: none; padding-top: 0; }
}
.modal-instances-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  font-size: 0.7rem;
  margin-bottom: 0.35rem;
  color: var(--muted);
  letter-spacing: 0.02em;
}
.modal-instances-header strong { color: var(--text); }
.modal-instances-title { flex: 1; min-width: 0; }

/* ── Sale listings section inside the instances panel ─────────────── */
.modal-sale-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
  font-size: 0.7rem;
  margin-top: 0.5rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--border);
  color: var(--muted);
  letter-spacing: 0.02em;
}
.modal-sale-header strong { color: var(--inventory); }
.modal-sale-title { flex: 1; min-width: 0; }
.modal-sale-toggle {
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  font: inherit;
  font-size: 0.68rem;
  font-weight: 600;
  padding: 0.22rem 0.55rem;
  border-radius: 4px;
  cursor: pointer;
}
.modal-sale-toggle:hover { background: var(--border); border-color: var(--inventory-border); color: var(--inventory); }
.modal-sale-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: none;
  flex-direction: column;
  gap: 0.35rem;
}
.modal-sale-list.is-open {
  display: flex;
  margin-top: 0.4rem;
}
.modal-sale-row {
  padding: 0.45rem 0.55rem;
  background: rgba(232, 168, 74, 0.04);
  border: 1px solid rgba(107, 74, 24, 0.5);
  border-radius: 5px;
  font-size: 0.72rem;
  color: var(--muted);
}
.modal-sale-row-top {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  flex-wrap: wrap;
}
.modal-sale-price {
  font-weight: 700;
  color: var(--inventory);
  font-size: 0.8rem;
}
.modal-sale-status {
  font-size: 0.65rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 0.1rem 0.4rem;
  border-radius: 3px;
}
.modal-sale-status.sale-status-live    { background: var(--success-bg); color: var(--success); }
.modal-sale-status.sale-status-draft   { background: #2a2418; color: #c0a468; }
.modal-sale-status.sale-status-expired { background: #3a1a1a; color: #cf6b6b; }
.modal-sale-status.sale-status-other   { background: #222;    color: #888;    }
.modal-sale-date { color: #7a6d58; font-size: 0.68rem; }
.modal-sale-edit {
  background: var(--inventory-bg);
  border: 1px solid var(--inventory-border);
  color: var(--inventory);
  font: inherit;
  font-size: 0.68rem;
  font-weight: 600;
  padding: 0.22rem 0.6rem;
  border-radius: 4px;
  cursor: pointer;
}
.modal-sale-edit:hover { background: #4a3612; border-color: #8a5e22; color: #f5c060; }
.modal-sale-row-cond {
  display: flex;
  gap: 0.9rem;
  flex-wrap: wrap;
  margin-top: 0.3rem;
  font-size: 0.7rem;
}
.modal-sale-row-cond strong { color: var(--text); font-weight: 600; }
.modal-sale-row-notes {
  margin-top: 0.3rem;
  font-size: 0.7rem;
  font-style: italic;
  color: var(--muted-dim);
  word-break: break-word;
}
.modal-add-copy-btn {
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  font: inherit;
  font-size: 0.7rem;
  font-weight: 600;
  padding: 0.28rem 0.6rem;
  border-radius: 4px;
  cursor: pointer;
  white-space: nowrap;
  transition: border-color 0.15s, background 0.15s, color 0.15s;
}
.modal-add-copy-btn:hover {
  border-color: var(--accent);
  color: var(--text);
  background: rgba(255, 255, 255, 0.05);
}
@media (max-width: 640px) {
  .modal-add-copy-btn { font-size: 0.78rem; padding: 0.38rem 0.7rem; }
}
.modal-instances-list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
}
.modal-instance-row {
  display: flex;
  gap: 0.6rem;
  align-items: baseline;
  flex-wrap: wrap;
  padding: 0.15rem 0;
  border-top: 1px dashed var(--border);
}
.modal-instance-row:first-child { border-top: none; }
.modal-instance-row { cursor: pointer; transition: background 0.12s; padding: 0.2rem 0.35rem; border-radius: 3px; }
.modal-instance-row:hover { background: rgba(255,255,255,0.04); }
.modal-instance-row.is-active { background: rgba(255,255,255,0.08); box-shadow: inset 3px 0 0 var(--accent); }
.modal-instance-folder { font-weight: 600; color: var(--text); }
.modal-folder-chip {
  font: inherit;
  font-weight: 600;
  color: var(--text);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 0.1rem 0.4rem;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
  white-space: nowrap;
  max-width: 12rem;
  overflow: hidden;
  text-overflow: ellipsis;
  vertical-align: baseline;
}
.modal-folder-chip:hover {
  border-color: var(--accent);
  background: rgba(255, 255, 255, 0.08);
}
.modal-folder-chip-inline {
  font-size: 0.68rem;
  padding: 0.05rem 0.35rem;
  margin-left: 0.15rem;
}
@media (max-width: 640px) {
  .modal-folder-chip { padding: 0.18rem 0.5rem; }
  .modal-folder-chip-inline { padding: 0.1rem 0.4rem; font-size: 0.75rem; }
}
.modal-instance-rating { color: #f0a830; font-size: 0.68rem; }
.modal-instance-added { color: var(--muted); font-size: 0.66rem; }
.modal-instance-notes { color: var(--muted); font-style: italic; font-size: 0.66rem; }
.modal-instances-hint { color: var(--muted); font-weight: normal; font-size: 0.66rem; margin-left: 0.3rem; }

/* ── (N) multi-copy badge on card thumbnails ── */
.card-instance-badge {
  position: absolute;
  left: 0.35rem;
  bottom: 0.35rem;
  background: rgba(0, 0, 0, 0.72);
  color: #fff;
  font-size: 0.78rem;
  font-weight: 600;
  padding: 0.2rem 0.5rem;
  min-width: 1.75rem;
  min-height: 1.5rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: 10px;
  border: 1px solid rgba(255, 255, 255, 0.25);
  cursor: pointer;
  z-index: 3;
  line-height: 1.2;
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  -webkit-tap-highlight-color: transparent;
  transition: background 0.12s, transform 0.12s;
}
@media (max-width: 640px) {
  .card-instance-badge {
    font-size: 0.85rem;
    padding: 0.28rem 0.6rem;
    min-width: 2rem;
    min-height: 1.75rem;
    left: 0.3rem;
    bottom: 0.3rem;
  }
}
.card-instance-badge:hover {
  background: rgba(0, 0, 0, 0.9);
  transform: scale(1.08);
}

/* ── Popover listing each stored instance of a release ── */
.instance-popover {
  position: absolute;
  z-index: 9999;
  min-width: 220px;
  max-width: 320px;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.5);
  padding: 0.5rem 0.6rem;
  font-size: 0.72rem;
  color: var(--text);
}
.instance-popover-header {
  font-size: 0.68rem;
  color: var(--muted);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  margin-bottom: 0.35rem;
}
.instance-popover-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.instance-popover-row {
  display: flex;
  gap: 0.55rem;
  align-items: baseline;
  padding: 0.3rem 0.4rem;
  border-radius: 4px;
  cursor: pointer;
  transition: background 0.12s;
}
.instance-popover-row:hover { background: rgba(255, 255, 255, 0.07); }
.instance-popover-folder { font-weight: 600; color: var(--text); }
.instance-popover-rating { color: #f0a830; font-size: 0.66rem; }
.instance-popover-added { color: var(--muted); font-size: 0.64rem; margin-left: auto; }
.modal-act-btn {
  font-size: 0.72rem;
  padding: 0.25rem 0.6rem;
  border-radius: 4px;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--muted);
  cursor: pointer;
  transition: all 0.15s;
  font-family: inherit;
}
.modal-act-btn:hover { border-color: #555; color: var(--text); }
.modal-act-btn.active { border-color: var(--border); background: var(--surface); }
.modal-act-btn.in-collection { background: var(--success-bg); border-color: var(--success-border); color: var(--success); }
.modal-act-btn.in-collection:hover { background: #1f4a1f; border-color: #3a6a3a; }
/* "Listed for sale" button — amber/gold to distinguish from the green
   "Collected" state, since owning a copy and actively selling one are
   meaningfully different user-actions. */
.modal-act-btn.is-listed { background: var(--inventory-bg); border-color: var(--inventory-border); color: var(--inventory); }
.modal-act-btn.is-listed:hover { background: #4a3612; border-color: #8a5e22; color: #f5c060; }
.modal-act-btn.in-wantlist { background: var(--warning-bg); border-color: var(--warning-border); color: #d4a843; }
.modal-act-btn.in-wantlist:hover { background: #3a3518; border-color: #5a4f2a; }
.want-icon { filter: grayscale(1) opacity(0.5); }
.want-icon.active { filter: none; }
.modal-rating {
  display: inline-flex;
  gap: 0.1rem;
  margin-left: 0.3rem;
}
.modal-star {
  font-size: 0.85rem;
  cursor: pointer;
  color: var(--border);
  transition: color 0.1s;
  user-select: none;
}
.modal-star.active { color: var(--warning); }
.modal-star.preview { color: #c8922a; }
.modal-star:hover { color: var(--warning); }

/* Price sparkline */
.price-sparkline-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin-top: 0.15rem;
}
.price-sparkline-label {
  font-size: 0.72rem;
  font-weight: 600;
}
.price-sparkline-dates {
  font-size: 0.65rem;
  color: var(--muted);
}
.price-badge {
  font-size: 0.65rem;
  color: var(--muted);
  margin-top: 0.1rem;
}
.price-badge .price-change {
  font-weight: 600;
  margin-left: 0.2rem;
}
.price-badge .price-up { color: #4caf50; }
.price-badge .price-down { color: var(--danger); }


#status {
  color: var(--muted);
  font-size: 0.9rem;
  margin-top: 1rem;
  margin-bottom: 1rem;
  display: none;
}

#status.error { color: #e05555; }

/* ── Unified card grid ── */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 1rem;
}

/* Wide card mode (toggled via the ▦ Wide button — body.card-mode-wide).
   Roughly doubles each card's min-width so two compact-mode cards
   become one wide one. Title + artist clamps drop so all text shows.
   Layout becomes a horizontal flex row inside each card so the cover
   sits next to the metadata instead of above it. */
body.card-mode-wide .card-grid {
  grid-template-columns: repeat(auto-fill, minmax(360px, 1fr));
}
body.card-mode-wide .card {
  /* Override the aspect-ratio from the compact card style — wide
     cards should size to their content (the body / tracklist), not
     stay square.

     display: block + position: relative is the key change here. We
     used to be flex-row, which meant the card's height = max of
     children, so a tall image-stack inside the cover panel pushed
     the card taller than the tracklist. By taking the cover panel
     OUT of normal flow (position: absolute below) the body alone
     drives the card height — the cover panel and image stack just
     fill whatever vertical space the body claims, and the card's
     overflow:hidden clips anything past the body bottom.

     height: 100% + align-self: stretch keeps every card in a grid
     row at the tallest body's height (no background showing
     between unequal-content cards). */
  aspect-ratio: auto;
  height: 100%;
  align-self: stretch;
  display: block;
  position: relative;
}
/* Same row-equalization at the grid level — explicit so it doesn't
   rely on the grid's default stretch behaviour being inherited. */
body.card-mode-wide .card-grid {
  align-items: stretch;
}
body.card-mode-wide .card-thumb-wrap {
  /* Pinned to the card's left edge and stretched top→bottom. With
     absolute positioning the wrap doesn't contribute to the card's
     intrinsic height — its height matches whatever the body claims.
     overflow:hidden then clips the image stack at the bottom of the
     body, exactly what the user wants ("cut the extra photos
     wherever that line might be"). */
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  width: 40%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
body.card-mode-wide .card-body {
  /* Leave room for the absolutely-positioned cover panel on the
     left. margin-left (vs padding-left) so the body's own padding
     stays as authored. */
  margin-left: 40%;
  padding: 0.6rem 0.7rem;
  min-width: 0;
}
/* Wide cards stack content from the top — no auto-margin pushing
   label / format / genre / year to the bottom of the card body. */
body.card-mode-wide .card-bottom {
  margin-top: 0.3rem;
}
body.card-mode-wide .card-artist,
body.card-mode-wide .card-title {
  /* Drop the line clamps so the full text shows. */
  -webkit-line-clamp: unset;
  display: block;
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
}
body.card-mode-wide .card-title {
  font-size: 0.85rem;
  margin-bottom: 0.3rem;
}
body.card-mode-wide .card-artist {
  font-size: 0.8rem;
  margin-bottom: 0.2rem;
}
/* Toggle button "on" state — applies to every .card-mode-toggle-btn
   instance (search-page button, records-page button, etc.). All share
   the same shape language: bordered pill that lights up in the accent
   color when wide mode is active. */
.card-mode-toggle-btn.is-on { color: var(--accent); border-color: var(--accent); }
/* Sparse cards — the underlying release_cache row was missing or
   pruned, so the feed endpoint returned a fallback record with just
   id+type. Visual: dimmed border + a ↻ Re-fetch button so the user
   can force a fresh Discogs pull (which repopulates the cache). */
.card.card-sparse {
  opacity: 0.85;
  border-style: dashed;
}
.card-refresh-btn {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.15);
  color: var(--muted);
  font-size: 0.7rem;
  padding: 0.3rem 0.6rem;
  border-radius: 4px;
  margin-top: 0.6rem;
  cursor: pointer;
  letter-spacing: 0.02em;
  transition: color 0.12s, border-color 0.12s, background 0.12s;
  align-self: flex-start;
}
.card-refresh-btn:hover {
  color: var(--accent);
  border-color: var(--accent);
  background: rgba(255, 255, 255, 0.1);
}
.card-refresh-btn:disabled {
  opacity: 0.5;
  cursor: progress;
}
/* Wide-mode image strip — sits at the bottom of the cover panel. The
   wrap becomes flex-column in wide mode so the cover takes the upper
   chunk and the strip is a fixed-height row underneath. Hidden in
   compact mode. */
.card-images-strip {
  display: none;
  flex-wrap: nowrap;
  overflow-x: auto;
  gap: 4px;
  padding: 4px;
  background: rgba(0, 0, 0, 0.5);
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.2) transparent;
}
/* Selectors here use .card prefix to beat the generic ".card img"
   width:100% rule (specificity 0,1,1) — without it the thumbs render
   at full card width. */
.card .card-images-thumb {
  width: 36px !important;
  height: 36px !important;
  object-fit: cover;
  border-radius: 3px;
  flex-shrink: 0;
  cursor: pointer;
  border: 1px solid rgba(255, 255, 255, 0.1);
  opacity: 0.7;
  transition: border-color 0.12s, transform 0.12s, opacity 0.12s;
  display: inline-block;
}
.card .card-images-thumb:hover {
  border-color: var(--accent);
  opacity: 1;
}
.card .card-images-thumb.is-active {
  border-color: var(--accent);
  opacity: 1;
  transform: scale(1.05);
}
/* Full-size image stack rendered below the thumb-picker in wide
   mode. Each image matches the main cover's width (100% of the
   thumb-wrap) and stays in 1:1 aspect. The card's overflow:hidden
   clips the bottom when the body (tracklist) sets the card height,
   so users see as many full images as the row allows without the
   thumb-wrap pushing the card taller. Hidden in compact mode. */
.card-images-stack {
  display: none;
  flex-direction: column;
  gap: 0;
}
body.card-mode-wide .card-images-stack {
  display: flex;
}
.card-images-stack-img {
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  cursor: pointer;
  display: block;
}
.card-images-stack-img:hover {
  opacity: 0.92;
}
body.card-mode-wide .card-thumb-wrap {
  display: flex;
  flex-direction: column;
  aspect-ratio: auto;
  /* Stretch the cover panel to fill the full card height even though
     the card uses align-items:flex-start (which keeps the main image
     from growing and cropping). overflow:hidden then clips the
     full-size image stack at the card bottom — the user sees as many
     extra images as the body's height allows, no more. */
  align-self: stretch;
  overflow: hidden;
}
/* Main image stays at its intrinsic computed size — square based on
   the wrap's 50% width — and explicitly does NOT flex-grow when the
   card gets taller. Without this, a long tracklist on the right side
   stretched the wrap, pulled the image up to fill, and object-fit
   cropped the cover into a center-zoomed thumbnail. */
body.card-mode-wide .card-thumb-wrap > img:first-of-type,
body.card-mode-wide .card-thumb-wrap > .thumb-placeholder {
  flex: 0 0 auto;
  width: 100%;
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  display: block;
}
body.card-mode-wide .card-images-strip {
  display: flex;
  flex: 0 0 auto;
}
/* Inline tracklist on wide cards. Hidden in compact mode. Caps at
   ~6 rows visible with scroll for longer ones, so a 4-LP box set
   doesn't stretch the card to the moon. */
.card-tracklist {
  display: none;
  margin-top: 0.5rem;
  padding-top: 0.5rem;
  border-top: 1px dashed rgba(255, 255, 255, 0.08);
  font-size: 0.72rem;
}
.card-tracklist-head {
  font-size: 0.65rem;
  color: var(--muted);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  margin-bottom: 0.25rem;
}
.card-tracklist-rows {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 12rem;
  overflow-y: auto;
  scrollbar-width: thin;
  scrollbar-color: rgba(255, 255, 255, 0.2) transparent;
}
.card-tracklist-rows li {
  display: grid;
  /* Columns: actions | pos | title | dur. Actions moved to the left
     of the position column so the play/queue buttons are the first
     visual element on each row. Tightened: gap 0.4 → 0.2rem and
     pos column 2 → 1.5rem so the title column claims back the room. */
  grid-template-columns: auto 1.5rem 1fr auto;
  gap: 0.2rem;
  align-items: center;
  padding: 0.12rem 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.04);
}
.card-tracklist-rows li:last-child { border-bottom: none; }
.card-track-pos { color: var(--muted); font-variant-numeric: tabular-nums; }
.card-track-title {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.card-track-dur { color: #777; font-variant-numeric: tabular-nums; }
/* Per-track ▶ / ＋ buttons. Tiny so the row stays compact. Disabled
   variant (no YT match) is dimmed and non-clickable. */
.card-track-actions {
  display: inline-flex;
  gap: 0.25rem;
  align-items: center;
  font-size: 0.78rem;
}
.card-track-play,
.card-track-queue {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.4rem;
  height: 1.4rem;
  border-radius: 3px;
  color: var(--muted);
  cursor: pointer;
  text-decoration: none;
  transition: color 0.12s, background 0.12s;
}
.card-track-play:hover {
  color: var(--accent);
  background: rgba(255, 255, 255, 0.05);
}
/* ＋ buttons: plain text, no hover box, a bit larger than the row's
   default font so they read as a tap target without a visible button
   chrome. Override the play-button width/height so the glyph isn't
   clipped at the larger size. */
.card-track-queue {
  width: auto;
  height: auto;
  background: none !important;
  border-radius: 0;
  font-size: 1.15rem;
  line-height: 1;
  padding: 0 0.15rem;
}
.card-track-queue:hover {
  color: var(--accent);
  background: none !important;
}
/* Play buttons that resolved to a real YT URL render in bright white
   so the user can see at-a-glance which rows are actually playable.
   Disabled / no-match rows stay dim (.card-track-disabled rule below). */
.card-track-play-active {
  color: #ffffff !important;
  font-weight: 600;
}
.card-track-play-active:hover {
  color: var(--accent) !important;
  background: rgba(255, 255, 255, 0.08);
}
.card-track-disabled {
  color: #444 !important;
  cursor: default !important;
}
.card-track-disabled:hover { background: none !important; color: #444 !important; }
/* Tracklist head row: label on the left, "Play all / Queue all"
   buttons on the right. Visible only when there's at least one
   playable track on the card (helper handles that). */
.card-tracklist-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.4rem;
}
.card-tracklist-head-label { flex: 0 1 auto; }
.card-tracklist-head-actions {
  display: inline-flex;
  gap: 0.3rem;
  align-items: center;
}
/* "▶ All" head button — same shape as the per-track .card-track-play
   buttons (square, subtle background hover) but slightly larger so
   the album-wide control reads as the dominant affordance. Glyph
   only, no "All" label. */
.card-tracklist-playall {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.7rem;
  height: 1.7rem;
  border-radius: 3px;
  cursor: pointer;
  color: #ffffff;
  font-weight: 600;
  font-size: 0.95rem;
  line-height: 1;
  background: none;
  transition: color 0.12s, background 0.12s;
}
.card-tracklist-playall:hover {
  color: var(--accent);
  background: rgba(255, 255, 255, 0.08);
}
/* "＋" head button: plain text, no box. Sized to align next to the
   ▶ head button without dominating it. */
.card-tracklist-queueall {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--muted);
  background: none !important;
  border-radius: 0;
  padding: 0 0.25rem;
  font-size: 1.25rem;
  line-height: 1;
  transition: color 0.12s, background 0.12s;
}
.card-tracklist-queueall:hover {
  color: var(--accent);
  background: none !important;
}
/* Track-title click target — same dotted underline / hover treatment
   as the entity-lookup popup uses elsewhere. We override the generic
   .entity-lookup-link rule for ergonomics inside the tight tracklist
   row: tighter underline offset + inherited color so the row stays
   readable. The popup itself is unchanged. */
.card-track-title-link {
  color: inherit !important;
  text-decoration: none !important;
  cursor: pointer;
}
.card-track-title-link:hover {
  color: var(--accent) !important;
  text-decoration: underline dotted !important;
  text-underline-offset: 2px;
}
/* Full-album row stands out a bit so the user sees it as the special
   "play the whole thing" affordance, not just another track. */
.card-track-fullalbum {
  background: rgba(192, 132, 252, 0.06);
  border-radius: 3px;
  padding: 0.18rem 0.3rem !important;
}
.card-track-fullalbum .card-track-title { color: #c084fc; font-weight: 600; }
.card-track-fullalbum .card-track-pos    { color: #c084fc; }
/* Artist + title on cards use entityLookupLinkHtml (same popup the
   modal uses — SeaDisco / Wiki / LOC / YouTube / Copy). In compact
   mode the popup links are inert: pointer-events:none so the outer
   card click reaches the card and opens the album modal as before.
   In wide mode (where the outer click is restricted to the cover
   image) the links become active so the user can choose where to
   search. Selectors here intentionally beat the generic
   .entity-lookup-link rule (which adds a dotted underline) — the
   parent .card-artist / .card-title styling already conveys the
   color/weight, so we only want the underline on hover in wide mode. */
.card .card-artist-link,
.card .card-title-link {
  color: inherit;
  text-decoration: none;
}
body:not(.card-mode-wide) .card .card-artist-link,
body:not(.card-mode-wide) .card .card-title-link {
  pointer-events: none;
}
body.card-mode-wide .card .card-artist-link:hover,
body.card-mode-wide .card .card-title-link:hover {
  text-decoration: underline;
  cursor: pointer;
  color: var(--accent-hi, var(--accent));
}
/* In wide mode, hovering over the body shouldn't suggest "click to
   open modal" — only the main cover should. Switch the cursor on
   the body areas that aren't clickable to default. */
body.card-mode-wide .card .card-body { cursor: default; }
body.card-mode-wide .card .card-thumb-wrap > img:first-of-type { cursor: pointer; }
body.card-mode-wide .card-tracklist {
  display: block;
}
/* On narrow screens, wide cards drop to single column instead of
   trying to squeeze the cover + metadata into ~150px each. */
@media (max-width: 640px) {
  body.card-mode-wide .card-grid {
    grid-template-columns: 1fr;
    gap: 0.7rem;
  }
}

/* ── Recent history strip (front-page Recent cards) ── */
/* Uses the standard .card-grid layout and the full card body, so cards
   look identical to search results. Each card is wrapped in .recent-wrap
   so we can overlay a small X button to drop a single item from history. */
.recent-wrap {
  position: relative;
}
.recent-dismiss {
  position: absolute;
  top: 0.3rem;
  left: 0.3rem;
  width: 1.3rem;
  height: 1.3rem;
  border-radius: 50%;
  border: none;
  background: rgba(0,0,0,0.6);
  color: #ddd;
  cursor: pointer;
  font-size: 0.75rem;
  line-height: 1;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.15s, background 0.15s;
  z-index: 3;
}
.recent-wrap:hover .recent-dismiss { opacity: 1; }
.recent-dismiss:hover { background: rgba(160, 30, 30, 0.85); color: #fff; }

/* ── Results grid ── */
#results {
  min-height: 4rem;
}

.card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  transition: border-color 0.15s, transform 0.15s, box-shadow 0.15s;
  cursor: pointer;
  text-decoration: none;
  color: inherit;
  display: flex;
  flex-direction: column;
  /* Subtle resting elevation — barely visible against body bg, but
     gives the grid a hint of dimension when scanning many cards. */
  box-shadow: 0 1px 2px rgba(0,0,0,0.25), 0 1px 0 rgba(255,255,255,0.025) inset;
}

.card:hover {
  border-color: var(--accent);
  transform: translateY(-2px);
  /* Stronger shadow on hover reinforces clickability — paired with the
     existing translateY lift it reads as a press-ready affordance. */
  box-shadow: 0 6px 20px rgba(0,0,0,0.45), 0 1px 0 rgba(255,255,255,0.04) inset;
}

/* Currently playing LOC card — animated accent border with a small
   "NOW PLAYING" label pinned to the top-left of the thumb. */
.card.is-playing {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent), 0 4px 18px rgba(0, 0, 0, 0.35);
  animation: loc-playing-pulse 2.2s ease-in-out infinite;
}
.card.is-playing .card-thumb-wrap::before {
  content: "▶ NOW PLAYING";
  position: absolute;
  top: 0.35rem;
  left: 0.35rem;
  padding: 0.18rem 0.45rem;
  font-size: 0.6rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--surface-sunken);
  background: var(--accent);
  border-radius: 3px;
  z-index: 4;
  pointer-events: none;
}
@keyframes loc-playing-pulse {
  0%, 100% { box-shadow: 0 0 0 2px var(--accent), 0 4px 18px rgba(0, 0, 0, 0.35); }
  50%      { box-shadow: 0 0 0 2px var(--accent), 0 0 24px 2px var(--accent); }
}

.card img {
  /* Image is exactly the card's width and renders at its natural
     aspect ratio — no forced square, no crop, no letterbox. Card
     heights become variable to match the cover. Discogs's
     cover_image thumbs ARE actually square most of the time, so
     in practice cards stay close to uniform-tall in a row; tall or
     wide artwork (compilation covers, magazine sleeves) shows in
     full instead of being chopped. */
  width: 100%;
  height: auto;
  display: block;
  background: var(--surface);
}

.card .thumb-placeholder {
  width: 100%;
  aspect-ratio: 1;
  background: linear-gradient(135deg, var(--surface-raised), var(--bg));
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  font-size: 2.8rem;
  text-shadow: 0 0 8px rgba(0, 0, 0, 0.4);
  position: relative;
}
.card .thumb-placeholder::after {
  content: "no image";
  position: absolute;
  bottom: 0.4rem;
  right: 0.5rem;
  font-size: 0.55rem;
  color: var(--muted-dim);
  letter-spacing: 0.05em;
  text-transform: uppercase;
  text-shadow: none;
}
/* Keep the LOC-card-type variant consistent even on light themes */
.card-type-loc .thumb-placeholder {
  background: linear-gradient(135deg, var(--bg-elevated), var(--surface-sunken));
}

.card-body {
  position: relative;
  padding: 0.75rem 0.85rem 0.9rem;
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}

.card-artist {
  font-size: 0.75rem;
  color: var(--accent);
  font-weight: 500;
  display: -webkit-box;
  /* A bit less than double the title clamp (which is now 2 lines) so
     long artists like "Niney The Observer Aka Winston Holness" still
     show in full while shorter ones don't claim extra height. */
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.card-title {
  font-size: 0.78rem;
  font-weight: 600;
  line-height: 1.35;
  color: var(--fg);
  display: -webkit-box;
  /* 2 lines (was 3) — drops ~one line worth of overflow on the long-
     suffix titles like "… (Aladdin & Peacock Sides)". */
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.card-visited { opacity: 0.5; }
.link-visited { opacity: 0.45; }

/* Version-list interactive dots — colors match the navbar tabs:
   collection (green), wantlist (yellow), favorites (pink), lists
   (light blue), inventory (purple). Each dot now renders the same
   line-art SVG the nav uses; inactive dots are dimmed but still
   show the icon so users can see what each slot represents. */
.mv-dots { display: inline-flex; gap: 3px; align-items: center; vertical-align: middle; }
.mv-dot {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; border-radius: 3px;
  cursor: pointer; opacity: 0.32;
  transition: opacity 0.15s, background 0.15s, color 0.15s;
  color: #888;
}
.mv-dot svg { width: 14px; height: 14px; display: block; }
.mv-dot svg path,
.mv-dot svg circle { vector-effect: non-scaling-stroke; }
.mv-dot.active { opacity: 1; }
.mv-dot:hover  { opacity: 0.85; }
.mv-dot.active:hover { opacity: 1; }
/* Active colors come from inline style in JS so each dot tints to its
   corresponding navbar color via currentColor. */

/* Search history dropdown — compact so it doesn't visually swallow
   the next row of advanced-search fields. Aimed at ~4 visible rows
   max; user can scroll to see the rest. */
.sh-dropdown {
  position: absolute; top: 100%;
  z-index: 230; max-height: 6.5rem; overflow-y: auto;
  background: #1a1a1a; border: 1px solid #333; border-radius: 0 0 6px 6px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.5);
  text-align: left;
}
.sh-row {
  display: flex; align-items: center; padding: 0.2rem 0.55rem;
  cursor: pointer; font-size: 0.74rem; color: var(--fg);
  text-align: left;
  line-height: 1.3;
}
.sh-row:hover { background: #252525; }
.sh-text { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; text-align: left; }
.sh-del {
  flex-shrink: 0; color: #555; font-size: 0.95rem; padding: 0 0.2rem;
  margin-left: 0.4rem; cursor: pointer; line-height: 1;
}
.sh-del:hover { color: #e44; }

.card-sub {
  font-size: 0.75rem;
  color: var(--muted);
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.card-catno-line {
  font-size: 0.68rem;
  color: var(--catno, var(--success));
  margin-top: 0.15rem;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.02em;
}

/* ── Saved searches ── */
.saved-search-wrap {
  position: relative;
  display: inline-block;
}
.saved-search-toggle {
  background: none;
  border: 1px solid #333;
  border-radius: 4px;
  color: #888;
  cursor: pointer;
  padding: 0.2rem 0.35rem;
  line-height: 1;
  display: flex;
  align-items: center;
  transition: color 0.15s, border-color 0.15s;
}
.saved-search-toggle:hover { color: #ccc; border-color: #555; }
.saved-search-dropdown {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 230;
  min-width: 200px;
  max-width: 300px;
  background: #1a1a1a;
  border: 1px solid #333;
  border-radius: 6px;
  box-shadow: 0 4px 16px rgba(0,0,0,0.5);
  overflow: hidden;
}
/* Flipped above the toggle when the default downward placement would
   cover a text input below it. JS adds .drop-up on open if it detects
   a colliding input or a viewport overflow. */
.saved-search-dropdown.drop-up {
  top: auto;
  bottom: calc(100% + 4px);
  /* Heavier shadow above so it's clearly elevated over the toggle */
  box-shadow: 0 -4px 16px rgba(0,0,0,0.5);
}
.ss-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 0.4rem 0.5rem;
  border-bottom: 1px solid #2a2a2a;
}
.ss-save-btn {
  background: none;
  border: 1px solid #444;
  border-radius: 4px;
  color: var(--success);
  font-size: 0.68rem;
  padding: 0.1rem 0.4rem;
  cursor: pointer;
  font-weight: 600;
}
.ss-save-btn:hover { background: rgba(126,200,126,0.1); border-color: var(--success); }
.ss-list {
  max-height: 240px;
  overflow-y: auto;
}
.ss-section-label {
  padding: 0.35rem 0.5rem 0.15rem;
  font-size: 0.65rem;
  font-weight: 600;
  color: #666;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-top: 1px solid #333;
}
.ss-section-label:first-child { border-top: none; }
.ss-empty {
  padding: 0.6rem 0.5rem;
  font-size: 0.72rem;
  color: #555;
  text-align: center;
}
.ss-item {
  display: flex;
  align-items: center;
  border-bottom: 1px solid #222;
}
.ss-item:last-child { border-bottom: none; }
.ss-item-btn {
  flex: 1;
  background: none;
  border: none;
  color: #ccc;
  font-size: 0.72rem;
  padding: 0.4rem 0.5rem;
  cursor: pointer;
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-family: inherit;
}
.ss-item-btn:hover { background: rgba(255,255,255,0.05); color: #fff; }
.ss-item-del {
  background: none;
  border: none;
  color: #555;
  font-size: 0.85rem;
  padding: 0.2rem 0.4rem;
  cursor: pointer;
  flex-shrink: 0;
}
.ss-item-del:hover { color: var(--danger); }

.card-format {
  font-size: 0.72rem;
  color: var(--fg);
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.card-rating {
  font-size: 0.65rem;
  color: #c8a83e;
  letter-spacing: 0.05em;
  margin-top: 0.15rem;
}
.card-notes-btn {
  position: absolute;
  bottom: 0.4rem;
  right: 0.4rem;
  font-size: 0.7rem;
  cursor: pointer;
  opacity: 0.5;
  transition: opacity 0.15s;
}
.card-notes-btn:hover { opacity: 1; }
.card-bottom {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: 0.25rem;
}
.card-meta {
  padding-top: 0.25rem;
  font-size: 0.7rem;
  color: #7a6d58;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* ── Card type colours ── */
:root {
  --type-master:  #c49a3c;
  --type-release: #a0725a;
  --type-artist:  #5a9a8a;
  --type-label:   #7a9a5a;
}
.card-type-artist  { border-bottom: 3px solid var(--type-artist); }
.card-type-label   { border-bottom: 3px solid var(--type-label); }
.card-type-master  { border-bottom: 3px solid var(--type-master); }
.card-type-release { border-bottom: 3px solid var(--type-release); }
.card-type-artist:hover  { border-color: var(--type-artist); }
.card-type-label:hover   { border-color: var(--type-label); }
.card-type-master:hover  { border-color: var(--type-master); }
.card-type-release:hover { border-color: var(--type-release); }

/* Radio label hover + checked colours per type */
.type-radios label { transition: color 0.15s; cursor: pointer; }
.type-radios label:hover:has(input[value=""])        { color: var(--accent); }
.type-radios label:hover:has(input[value="master"])  { color: var(--type-master); }
/* Masters+ shares the master type color so the related variants read
   as the same family — was missing before, leaving Masters+ with no
   hover affordance while Masters lit up. */
.type-radios label:hover:has(input[value="master+"]) { color: var(--type-master); }
.type-radios label:hover:has(input[value="release"]) { color: var(--type-release); }
.type-radios label:hover:has(input[value="artist"])  { color: var(--type-artist); }
.type-radios label:hover:has(input[value="label"])   { color: var(--type-label); }
.type-radios label:hover:has(input[value="ai"])      { color: var(--accent-hi, var(--accent)); }

.type-radios label:has(input[value=""]:checked)       { color: var(--accent); }
.type-radios label:has(input[value="master"]:checked)  { color: var(--type-master); text-shadow: 0 0 6px var(--type-master); }
.type-radios label:has(input[value="release"]:checked) { color: var(--type-release); text-shadow: 0 0 6px var(--type-release); }
.type-radios label:has(input[value="artist"]:checked)  { color: var(--type-artist); text-shadow: 0 0 6px var(--type-artist); }
.type-radios label:has(input[value="label"]:checked)   { color: var(--type-label); text-shadow: 0 0 6px var(--type-label); }
.type-radios label:has(input[value="master+"]:checked) { color: var(--type-master); text-shadow: 0 0 6px var(--type-master); }
/* AI engaged uses the theme's highlight (--accent-hi) so it reads as
   a deliberate "special mode" rather than another instance of the
   primary accent — visually distinct from regular search states. */
.type-radios label:has(input[value="ai"]:checked)      { color: var(--accent-hi, var(--accent)); text-shadow: 0 0 6px var(--accent-hi, var(--accent)); }

.type-radios input[value=""]        { accent-color: var(--accent); }
.type-radios input[value="master"]  { accent-color: var(--type-master); }
.type-radios input[value="master+"] { accent-color: var(--type-master); }
.type-radios input[value="release"] { accent-color: var(--type-release); }
.type-radios input[value="artist"]  { accent-color: var(--type-artist); }
.type-radios input[value="label"]   { accent-color: var(--type-label); }
.type-radios input[value="ai"]      { accent-color: var(--accent-hi, var(--accent)); }

/* ── Pagination ── */
#pagination {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 0.35rem;
  margin-top: 2.5rem;
  margin-bottom: 2.5rem;
  flex-wrap: wrap;
}

#pagination .pag-arrow {
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  font-weight: 500;
  padding: 0.45rem 1rem;
  cursor: pointer;
  border-radius: 4px;
  font-size: 0.85rem;
}

#pagination .pag-arrow:hover:not(:disabled) {
  border-color: var(--accent);
  color: var(--accent);
}

#pagination .pag-arrow:disabled {
  opacity: 0.3;
  cursor: default;
}

#pagination .pag-num {
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--muted);
  font-weight: 500;
  padding: 0.4rem 0.7rem;
  min-width: 2.2rem;
  text-align: center;
  cursor: pointer;
  border-radius: 4px;
  font-size: 0.85rem;
}

#pagination .pag-num:hover {
  border-color: var(--accent);
  color: var(--accent);
}

#pagination .pag-num.pag-active {
  background: var(--accent);
  border-color: var(--accent);
  /* Use the page background as the active-button text color so it
     always inverts the accent — was hardcoded #fff which collapsed
     to white-on-white in Noir White and any other theme where
     --accent is light/white. */
  color: var(--bg);
  cursor: default;
}

#pagination .pag-ellipsis {
  color: var(--muted);
  font-size: 0.85rem;
  padding: 0 0.2rem;
}

/* ── Bio full popup ── */
#bio-full-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.75);
  z-index: 160;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}

#bio-full-overlay.open { display: flex; }

#bio-full-box {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  max-width: 620px;
  width: 100%;
  max-height: 82vh;
  overflow-y: auto;
  position: relative;
  padding: 1.25rem 1.4rem 1.4rem;
}

#bio-full-close {
  position: absolute;
  top: 0.5rem;
  right: 0.6rem;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 1.4rem;
  cursor: pointer;
  padding: 0.1rem 0.4rem;
  line-height: 1;
  border-radius: 4px;
}

#bio-full-close:hover { color: var(--text); background: var(--border); }

#bio-full-name {
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--accent);
  margin-bottom: 0.75rem;
  padding-right: 2rem;
}

#bio-full-text {
  font-size: 0.88rem;
  line-height: 1.65;
  color: var(--text);
}

.bio-artist-link {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px dotted var(--accent-dim);
  cursor: pointer;
}

.bio-artist-link:hover {
  color: var(--accent2);
  border-bottom-color: var(--accent2);
}

/* ── Artist-relations rows + overflow popup (utils.js) ─────────────────
   Replaces the inline style="color:#777..." / "color:#555..." blobs
   that fought every theme. Now fully theme-driven. */
.rel-block {
  margin-top: 0.6rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--border);
}
.rel-row {
  font-size: 0.78rem;
  margin-top: 0.55rem;
  line-height: 1.6;
}
.rel-row-urls { line-height: 1.8; }
.rel-row-label {
  color: var(--muted);
  margin-right: 0.4em;
}
.rel-sep {
  color: var(--muted-dim, var(--muted));
  margin: 0 0.2em;
}
.rel-more-btn {
  font-size: 0.72rem;
  color: var(--muted);
  white-space: nowrap;
  text-decoration: none;
}
.rel-more-btn:hover { color: var(--accent-hi, var(--accent)); }
.rel-url-link {
  color: var(--accent);
  text-decoration: none;
}
.rel-url-link:hover { color: var(--accent-hi, var(--accent)); }

#rel-overflow-popup {
  position: absolute;
  z-index: 600;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.6rem 0.85rem;
  max-width: 260px;
  font-size: 0.78rem;
  line-height: 1.7;
  box-shadow: 0 4px 20px rgba(0,0,0,0.6);
  display: none;
}

/* ── Alternatives "more" popup ── */
#alts-popup {
  display: none;
  position: fixed;
  top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 1rem 1.2rem;
  z-index: 300;
  min-width: 220px;
  max-width: 320px;
  max-height: 60vh;
  overflow-y: auto;
  box-shadow: 0 8px 32px rgba(0,0,0,0.6);
}
#alts-popup.open { display: block; }
#alts-popup-backdrop {
  display: none;
  position: fixed; inset: 0;
  z-index: 299;
}
#alts-popup-backdrop.open { display: block; }
#alts-popup h4 {
  margin: 0 0 0.7rem;
  font-size: 0.8rem;
  color: #9a8d78;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
#alts-popup a {
  display: block;
  padding: 0.3rem 0;
  color: var(--accent);
  text-decoration: none;
  font-size: 0.88rem;
  border-bottom: 1px solid var(--border);
}
#alts-popup a:last-child { border-bottom: none; }
#alts-popup a:hover { color: var(--accent2); }

/* ── Collection / Wantlist tabs ── */
.result-tabs {
  display: flex;
  justify-content: center;
  gap: 0;
  margin: 0.75rem 0;
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.25rem;
}
.result-tab {
  background: none;
  border: none;
  color: var(--muted);
  padding: 0.45rem 1.4rem;
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.82rem;
  letter-spacing: 0.02em;
  transition: all 0.15s;
  flex: 1;
  text-align: center;
}
.result-tab.active {
  background: var(--surface);
  color: var(--accent);
  font-weight: 600;
  box-shadow: 0 1px 4px rgba(0,0,0,0.4);
}
.result-tab:hover:not(.active) {
  color: var(--text);
  background: var(--surface);
}
.card-thumb-wrap {
  position: relative;
}
/* ── Card badge strip (right edge, fixed-position slots) ─────────── */
.card-thumb-badges {
  position: absolute;
  top: 0;
  right: 4px;
  bottom: 0;
  width: 14px;
  z-index: 2;
  pointer-events: none;
}
/* Colored dots instead of letter badges — cleaner at a glance and don't
   compete with text on the card. Each dot sits in a fixed slot on the
   right edge so relative position conveys meaning (top=C, then W, L, I).
   All badges share the same 16px footprint so masters showing a count
   sit perfectly aligned with plain release dots. */
/* Card badges are now line-art icons matching the navbar's per-tab
   set (collection / wantlist / lists / inventory / favorites).
   Active state = full per-category color; inactive = a faded
   placeholder so the order stays consistent across cards. */
.card-badge {
  position: absolute;
  right: 0;
  width: 18px;
  height: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: rgba(0, 0, 0, 0.42);
  border-radius: 4px;
  pointer-events: auto;
  box-sizing: border-box;
  color: rgba(255, 255, 255, 0.18);
  transition: color 0.15s, opacity 0.15s, background 0.15s;
}
.card-badge svg {
  width: 14px;
  height: 14px;
  display: block;
  stroke-width: 1.5;
}
/* Fixed slot positions — 22px stride for the slightly larger icons.
   Order matches the navbar: collection / wantlist / favorites /
   inventory / lists. */
.badge-collection { top: 4px;   cursor: pointer; }
.badge-wantlist   { top: 26px;  cursor: pointer; }
.badge-favorite   { top: 48px;  cursor: pointer; }
.badge-inventory  { top: 70px; }
.badge-list       { top: 92px; }
/* Active per-tab colors — match the navbar palette. */
.badge-collection.is-active { color: #6ddf70; }
.badge-wantlist.is-active   { color: #f0c95c; }
.badge-list.is-active       { color: #a0ccf0; }
.badge-inventory.is-active  { color: #cda0f5; }
.badge-favorite.is-favorite { color: #ff7eb6; } /* matching pink */
.badge-favorite:hover       { color: #ff7eb6; }
.card-badge:hover           { background: rgba(0, 0, 0, 0.65); }
/* C / W / F always rendered; L / I always rendered when the user
   has any items in that category. Inactive placeholders fade in on
   hover so they don't fight with cover art. */
.badge-collection:not(.is-active),
.badge-wantlist:not(.is-active),
.badge-favorite:not(.is-favorite) { opacity: 0; }
.badge-list:not(.is-active),
.badge-inventory:not(.is-active)  { opacity: 0; }
@media (hover: hover) {
  .card:hover .card-badge { opacity: 1; }
  .card:hover .badge-collection:not(.is-active),
  .card:hover .badge-wantlist:not(.is-active),
  .card:hover .badge-favorite:not(.is-favorite),
  .card:hover .badge-list:not(.is-active),
  .card:hover .badge-inventory:not(.is-active) { opacity: 0.6; }
}
/* Active badges are visible at all times so users can scan a grid
   for "what's already in my collection". */
.badge-collection.is-active,
.badge-wantlist.is-active,
.badge-list.is-active,
.badge-inventory.is-active,
.badge-favorite.is-favorite { opacity: 1; }
/* Superscript count badges for master cards (e.g. "C₃" = 3 versions). */
.card-badge-count {
  position: absolute;
  top: -3px;
  right: -4px;
  font-size: 0.55rem;
  font-weight: 800;
  background: var(--bg, #111);
  color: currentColor;
  border-radius: 7px;
  padding: 0 3px;
  line-height: 1.2;
}

/* Favorite button in modal */
.modal-act-btn.is-favorite {
  background: #2a1a0e;
  border-color: #5a3a1a;
  color: var(--accent);
}
.modal-act-btn.is-favorite:hover {
  background: #3a2210;
  border-color: #6a4a2a;
}

/* ── Filters grid (main search + collection) ── */
.filters-grid {
  display: grid;
  gap: 0.5rem;
  row-gap: 1rem;
  margin-bottom: 0.5rem;
}
.filters-grid label {
  font-size: 0.75rem;
  color: var(--muted);
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.filters-grid input[type="text"],
.filters-grid select {
  flex: 1;
  min-width: 0;
  color-scheme: dark;
}

/* Main search: row 1 has 3 wide fields (Artist, Release, Label),
   row 2 has 5 short fields (Format, Year, Country, Genre, Style).
   We use a 15-col grid (LCM of 3 and 5) so each row divides evenly:
   row-1 children span 5, row-2 children span 3. */
.main-filters { grid-template-columns: repeat(15, 1fr); }
.main-filters > label:nth-child(-n+3) { grid-column: span 5; }
.main-filters > label:nth-child(n+4)  { grid-column: span 3; }
/* Collection: 3 columns on desktop */
.cw-filters { grid-template-columns: repeat(3, 1fr); }

/* ── Mobile: 2-col grid layouts for filter forms ── */
@media (max-width: 640px) {
  /* Main search: 2 cols on mobile — natural flow gives
     Artist/Release, Label/Format, Year/Country, Genre/Style.
     Reset desktop's nth-child span rules so each label takes one slot. */
  .main-filters { grid-template-columns: repeat(2, 1fr); }
  .main-filters > label:nth-child(-n+3),
  .main-filters > label:nth-child(n+4) { grid-column: auto; }

  /* Collection: 6-col grid for flexible row sizing */
  .cw-filters {
    grid-template-columns: repeat(6, 1fr);
  }
  /* Default: 2 per row (span 3 of 6) */
  .cw-filters label { grid-column: span 3; }
  /* Year/Notes/Rating row: 3 per row (span 2 of 6) */
  .cw-filters .cw-year-field,
  .cw-filters .cw-notes-field,
  .cw-filters .cw-rating-field { grid-column: span 2; }
  /* Reorder for mobile: Artist Release / Label Format / Year Notes Rating / Genre Style */
  .cw-filters label:nth-child(1) { order: 1; } /* Artist */
  .cw-filters label:nth-child(2) { order: 2; } /* Release */
  .cw-filters label:nth-child(3) { order: 3; } /* Label */
  .cw-filters .cw-notes-field    { order: 6; } /* Notes — moved after Year */
  .cw-filters label:nth-child(5) { order: 4; } /* Format */
  .cw-filters .cw-year-field     { order: 5; } /* Year */
  .cw-filters label:nth-child(7) { order: 8; } /* Genre */
  .cw-filters label:nth-child(8) { order: 9; } /* Style */
  .cw-filters .cw-rating-field   { order: 7; } /* Rating — after Notes */
}

@media (max-width: 640px) {
  #info-view   { padding-left: 0.4rem !important; padding-right: 0.4rem !important; }
  footer       { padding-left: 0.4rem; padding-right: 0.4rem; }
}

/* ── Screen-reader-only utility (hidden visually, readable by crawlers/AT) ── */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  white-space: nowrap;
  border: 0;
}

/* ── Account page ── */
.account-box {
  max-width: 1100px;
  margin: 2rem auto;
  background: var(--surface);
  border-radius: var(--radius);
  padding: 2rem;
}
.account-tab-content h3 {
  font-size: 0.95rem;
  color: var(--text);
  margin: 1.4rem 0 0.5rem;
}
.account-tab-content ul {
  color: var(--muted);
  font-size: 0.88rem;
  line-height: 1.8;
  padding-left: 1.2rem;
}
.account-tab-content li { margin-bottom: 0.3rem; }
.account-box h2 { margin-top: 0; font-size: 1.2rem; color: var(--text); }
.account-box p  { color: var(--muted); font-size: 0.9rem; line-height: 1.5; }
.account-box a  { color: #aaa; }
.token-form { display: flex; flex-direction: column; gap: 0.6rem; margin-top: 1.2rem; }
.token-form input[type="text"] { font-family: monospace; font-size: 0.85rem; }
.token-status { font-size: 0.82rem; color: var(--muted); margin-top: 0.3rem; }
.token-status.ok { color: var(--success); }
.danger-btn { background: #5a1a1a; border-color: #7a2a2a; color: #e88; }
.danger-btn:hover { background: #7a2a2a; }
#clerk-sign-in { margin-top: 1rem; }
#auth-section { display: none; }
#signed-out-section { display: none; }

/* Hide Clerk's built-in "Have an account? Sign in" footer links inside the
   invite-only splash waitlist widget. Clerk's appearance.elements API only
   sets inline styles that can lose specificity battles with its own CSS —
   a real stylesheet rule with !important is reliable. The splash has its
   own "Already approved? Sign in" link underneath that opens our in-page
   modal via openSignInModal(), so the Clerk footer is redundant and leaks
   users into Clerk's hosted pages. */
#splash-waitlist-mount .cl-footer,
#splash-waitlist-mount .cl-footerAction,
#splash-waitlist-mount .cl-footerActionText,
#splash-waitlist-mount .cl-footerActionLink {
  display: none !important;
}

/* Clerk modal (openSignInModal / openSignUpModal) — give it a
   visible card edge. The appearance API's `elements.card` style
   string is overridden by Clerk's own CSS in some builds, so we
   reinforce with !important rules targeting the actual rendered
   classes. .cl-modalContent is the OUTER positioning wrapper;
   .cl-card is the actual rendered panel the user sees. Earlier we
   styled BOTH, which produced a double-border effect (one ring on
   the wrapper, another on the card just inside it). Now only
   .cl-card gets the visible chrome; the wrapper stays transparent
   so it doesn't draw a second ring. */
.cl-modalContent.cl-modalContent {
  background: transparent !important;
  border: none !important;
  box-shadow: none !important;
}
.cl-modalContent .cl-card {
  border: 1px solid rgba(255, 255, 255, 0.22) !important;
  border-radius: 10px !important;
  box-shadow: 0 12px 48px rgba(0, 0, 0, 0.75) !important;
  background: var(--bg, #15120e) !important;
  /* Clip any internal element (input rows, footer) that tries to
     extend past the card's rounded corners — was the source of the
     "white field bleeds outside the dark card" artifact. */
  overflow: hidden !important;
}
/* Slightly brighter overlay backdrop so the dimmed page reads as
   a clear "behind the modal" surface and the modal pops forward. */
.cl-modalBackdrop { background: rgba(0, 0, 0, 0.65) !important; }
.user-email { color: #aaa; font-size: 0.85rem; margin-bottom: 1.2rem; }
.section-divider { border: none; border-top: 1px solid #333; margin: 1.5rem 0; }

/* ── Admin tab bar ── */
.admin-tab-bar {
  display: flex; gap: 0; margin: 1rem 0 0; border-bottom: 1px solid var(--border);
  /* Horizontal scroll on narrow screens so the full set of admin tabs
     stays reachable without wrapping into messy multiple rows. The
     scrollbar itself is hidden for cleaner look; users scroll via
     swipe / shift-wheel / drag — chevron edge-fade hints at overflow. */
  overflow-x: auto;
  flex-wrap: nowrap;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  /* Right-side gradient fade as a visual cue that more tabs exist;
     uses theme bg so it blends with whatever's behind. */
  -webkit-mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 24px), transparent 100%);
  mask-image: linear-gradient(to right, #000 0, #000 calc(100% - 24px), transparent 100%);
}
.admin-tab-bar::-webkit-scrollbar { display: none; }
.admin-tab {
  padding: 0.45rem 1rem; font-size: 0.78rem; font-weight: 600;
  background: none; border: 1px solid transparent; border-bottom: none;
  color: var(--muted); cursor: pointer; border-radius: 6px 6px 0 0;
  transition: color 0.15s, background 0.15s;
  white-space: nowrap;
  flex-shrink: 0;
}
.admin-tab:hover { color: var(--fg); background: rgba(255,255,255,0.03); }
.admin-tab.active {
  color: var(--accent); background: var(--surface-raised);
  border-color: var(--border); margin-bottom: -1px; padding-bottom: calc(0.45rem + 1px);
}
.admin-tab-panel { padding: 1rem 0; }
/* Mobile: drop the edge-fade mask (it can clip the tap target on the
   rightmost tab) and reduce padding so more tabs fit per screen. */
@media (max-width: 720px) {
  .admin-tab-bar {
    -webkit-mask-image: none;
    mask-image: none;
    margin: 0.5rem -0.5rem 0;
    padding: 0 0.5rem;
  }
  .admin-tab {
    padding: 0.5rem 0.7rem;
    font-size: 0.74rem;
    /* Bigger tap target on touch — minimum 36px height per WCAG */
    min-height: 36px;
  }
}
.admin-refresh-btn {
  background: none; border: 1px solid #333; border-radius: 4px;
  color: #888; font-size: 1rem; cursor: pointer; padding: 0.1rem 0.4rem;
  line-height: 1; transition: color 0.15s, border-color 0.15s, background 0.2s;
}
.admin-refresh-btn:hover { color: var(--accent); border-color: var(--accent); }
.admin-refresh-btn:disabled { cursor: wait; opacity: 0.7; }
/* Spin the icon (wrapped in a span) rather than the button so the
   rounded-rect border doesn't tilt with the animation. */
@keyframes admin-refresh-spin { to { transform: rotate(360deg); } }
.admin-refresh-btn .admin-refresh-icon {
  display: inline-block;
  line-height: 1;
  transition: transform 0.2s;
}
.admin-refresh-btn.is-refreshing { color: var(--accent); border-color: var(--accent); }
.admin-refresh-btn.is-refreshing .admin-refresh-icon {
  animation: admin-refresh-spin 0.8s linear infinite;
}
.admin-refresh-btn.just-refreshed {
  color: #6ddf70;
  border-color: #6ddf70;
  background: rgba(109, 223, 112, 0.1);
}
.admin-refresh-status {
  font-size: 0.72rem;
  color: var(--muted);
  font-style: italic;
}
.admin-refresh-status.is-success { color: #6ddf70; font-style: normal; }
.admin-refresh-status.is-error   { color: var(--danger); font-style: normal; }

/* ── Load More ── */
.load-more-wrap {
  text-align: center;
  padding: 1.2rem 0;
}
.load-more-btn {
  display: inline-block;
  background: none;
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--accent);
  padding: 0.45rem 1.5rem;
  cursor: pointer;
  font-size: 0.82rem;
  text-decoration: none;
  transition: border-color 0.2s, opacity 0.2s;
}
.load-more-btn:hover {
  border-color: var(--accent);
}
.load-more-btn.loading {
  opacity: 0.5;
  pointer-events: none;
}

/* ── Consistent footer ── */
footer {
  text-align: center;
  padding: 2rem 1rem 1.5rem;
  font-size: 0.72rem;
  color: var(--muted);
  line-height: 1.4;
}

/* ══════════════════════════════════════════════
   LOADING SKELETONS
   ══════════════════════════════════════════════ */
@keyframes shimmer {
  0%   { background-position: -400px 0; }
  100% { background-position: 400px 0; }
}
.skeleton {
  background: linear-gradient(90deg, var(--bg-elevated) 25%, var(--border) 50%, var(--bg-elevated) 75%);
  background-size: 800px 100%;
  animation: shimmer 1.5s infinite ease-in-out;
  border-radius: var(--radius);
}
.skeleton-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.skeleton-thumb {
  width: 100%;
  aspect-ratio: 1;
  background: linear-gradient(90deg, var(--bg-elevated) 25%, var(--border) 50%, var(--bg-elevated) 75%);
  background-size: 800px 100%;
  animation: shimmer 1.5s infinite ease-in-out;
}
.skeleton-line {
  height: 12px;
  margin: 6px 8px;
  border-radius: 4px;
  background: linear-gradient(90deg, var(--bg-elevated) 25%, var(--border) 50%, var(--bg-elevated) 75%);
  background-size: 800px 100%;
  animation: shimmer 1.5s infinite ease-in-out;
}
.skeleton-line.short { width: 60%; }
.skeleton-line.shorter { width: 40%; }

/* ══════════════════════════════════════════════
   VIEW TRANSITIONS
   ══════════════════════════════════════════════ */
@keyframes viewFadeIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: translateY(0); }
}
.view-enter {
  animation: viewFadeIn 0.2s ease-out both;
}

/* ══════════════════════════════════════════════
   CARD LOAD ANIMATIONS
   ══════════════════════════════════════════════ */
@keyframes cardFadeIn {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: translateY(0); }
}
.card-animate {
  animation: cardFadeIn 0.3s ease both;
  animation-delay: calc(var(--i, 0) * 30ms);
}

/* ══════════════════════════════════════════════
   TOAST NOTIFICATIONS
   ══════════════════════════════════════════════ */
#toast-container {
  position: fixed;
  top: 1rem;
  right: 1rem;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  pointer-events: none;
}
.toast {
  pointer-events: auto;
  padding: 0.65rem 1rem;
  border-radius: 6px;
  font-size: 0.82rem;
  color: #fff;
  max-width: 340px;
  box-shadow: 0 4px 20px rgba(0,0,0,0.5);
  animation: toastIn 0.3s ease both;
}
.toast-removing {
  animation: toastOut 0.3s ease both;
}
@keyframes toastIn  { from { opacity:0; transform:translateX(40px); } to { opacity:1; transform:translateX(0); } }
@keyframes toastOut { from { opacity:1; transform:translateX(0); } to { opacity:0; transform:translateX(40px); } }
.toast-error   { background: #c0392b; }
.toast-warning { background: #e67e22; }
.toast-success { background: #27ae60; }
.toast-info    { background: #2980b9; }
.toast-with-action { display: flex; align-items: center; gap: 0.5rem; }
.toast-action-btn {
  background: rgba(255, 255, 255, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.35);
  color: #fff;
  font: inherit;
  font-size: 0.78rem;
  font-weight: 600;
  padding: 0.25rem 0.6rem;
  border-radius: 4px;
  cursor: pointer;
  white-space: nowrap;
}
.toast-action-btn:hover { background: rgba(255, 255, 255, 0.3); }
@media (max-width: 640px) {
  #toast-container { top: auto; bottom: 1rem; left: 1rem; right: 1rem; align-items: stretch; }
  .toast { max-width: none; font-size: 0.88rem; padding: 0.75rem 1rem; }
  .toast-action-btn { font-size: 0.85rem; padding: 0.4rem 0.8rem; }
}

/* ══════════════════════════════════════════════
   SCROLL TO TOP
   ══════════════════════════════════════════════ */
#scroll-top-btn {
  position: fixed;
  bottom: 5.75rem;
  right: 1.5rem;
  z-index: 500;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--surface);
  color: var(--accent);
  font-size: 1.2rem;
  cursor: pointer;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s, border-color 0.15s, transform 0.2s;
  display: flex;
  align-items: center;
  justify-content: center;
}
#scroll-top-btn.visible {
  opacity: 1;
  pointer-events: auto;
}
#scroll-top-btn:hover {
  border-color: var(--accent);
}
/* When the queue drawer is open it occupies the bottom-right corner
   on top of the scroll-top button. Slide the button to the left of
   the drawer (drawer width 360px + 1rem gap) so they don't overlap.
   On screens narrower than the drawer, hide the button instead — the
   drawer takes up effectively the whole bottom strip. */
body:has(.queue-drawer.open) #scroll-top-btn {
  transform: translateX(calc(-360px - 0.5rem));
}
@media (max-width: 480px) {
  body:has(.queue-drawer.open) #scroll-top-btn {
    opacity: 0;
    pointer-events: none;
    transform: none;
  }
}

/* ══════════════════════════════════════════════
   EMPTY STATES
   ══════════════════════════════════════════════ */
.empty-state {
  text-align: center;
  padding: 3rem 1.5rem;
  color: var(--muted);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 40vh;
  grid-column: 1 / -1;
}
.empty-state-icon {
  font-size: 2.5rem;
  margin-bottom: 0.75rem;
  opacity: 0.5;
}
.empty-state-title {
  font-size: 1rem;
  color: var(--text);
  margin-bottom: 0.4rem;
}
.empty-state-subtitle {
  font-size: 0.82rem;
  color: var(--muted);
}

/* ══════════════════════════════════════════════
   FOOTER (redesigned)
   ══════════════════════════════════════════════ */
.footer-grid {
  display: flex;
  justify-content: center;
  gap: 3rem;
  margin-bottom: 1.5rem;
}
/* Four columns mirrored around the page midpoint: outer two
   right/left-aligned to pull the labels inward, inner two
   right/left-aligned closer to center. Reads as two pairs that
   visually frame the middle. (Was three cols before the home-strip
   shortcut column was added between Records and LOC.) */
.footer-grid > .footer-col:nth-child(1) { text-align: right; }
.footer-grid > .footer-col:nth-child(2) { text-align: right; }
.footer-grid > .footer-col:nth-child(3) { text-align: left; }
.footer-grid > .footer-col:nth-child(4) { text-align: left; }
.footer-col h4 {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  margin-bottom: 0.5rem;
  font-weight: 600;
}
.footer-col a {
  display: block;
  color: var(--accent);
  text-decoration: none;
  font-size: 0.78rem;
  padding: 0.15rem 0;
  transition: color 0.15s;
}
.footer-col a:hover {
  color: var(--accent);
}
@media (max-width: 640px) {
  .footer-grid { gap: 1.5rem; flex-wrap: wrap; }
}

/* Search info row — single line on desktop, stacked on mobile */
.search-info-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  margin-bottom: 0.4rem;
  min-height: 1em;
  font-size: 0.82rem;
  color: var(--muted);
  line-height: 2.2;
}
.search-info-cell {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
  flex: 1 1 0;
}
.search-info-cell:first-child {
  flex-shrink: 0;
}
.search-info-cell:nth-child(2) {
  text-align: center;
}
.search-info-ai {
  font-style: italic;
  text-align: right;
}
@media (max-width: 640px) {
  .search-info-row {
    flex-direction: column;
    gap: 0;
    line-height: 1.8;
  }
  .search-info-cell {
    white-space: normal;
    text-align: left;
  }
}

/* ── Inventory toolbar + per-card edit actions ────────────────────────── */
.inventory-toolbar {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  margin: 0.5rem 0 0.75rem 0;
  flex-wrap: wrap;
}
.inv-new-btn,
.inv-refresh-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.35rem;
  padding: 0.4rem 0.85rem;
  border: 1px solid var(--border);
  background: var(--bg-elevated);
  color: var(--text);
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.9rem;
  line-height: 1;
  text-align: center;
}
.inv-new-btn {
  background: var(--accent);
  border-color: var(--accent);
  /* Use page bg as the button text so it inverts the accent — was
     hardcoded #fff which collapsed to white-on-white under Noir
     White and any other theme with a light accent. */
  color: var(--bg);
  font-weight: 600;
}
.inv-new-btn:hover { filter: brightness(1.1); }
.inv-refresh-btn:hover { background: var(--bg-hover); }

.inv-card-wrap {
  position: relative;
}
.inv-card-actions {
  position: absolute;
  top: 6px;
  left: 6px;
  display: flex;
  gap: 4px;
  z-index: 5;
  opacity: 0;
  transition: opacity 0.15s;
}
.inv-card-wrap:hover .inv-card-actions,
.inv-card-wrap:focus-within .inv-card-actions {
  opacity: 1;
}
.inv-card-edit {
  background: rgba(0, 0, 0, 0.72);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 4px;
  width: 30px;
  height: 30px;
  cursor: pointer;
  font-size: 0.95rem;
  display: flex;
  align-items: center;
  justify-content: center;
}
.inv-card-edit:hover { background: rgba(0, 0, 0, 0.9); }
@media (max-width: 640px) {
  .inv-card-actions { opacity: 0.85; }
}

/* ── Inventory editor modal ───────────────────────────────────────────── */
#inventory-editor-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.65);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10000;
  padding: 1rem;
}
#inventory-editor-panel {
  background: var(--bg-elevated);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 10px;
  width: min(680px, 100%);
  max-height: 92vh;
  overflow-y: auto;
  padding: 1.25rem 1.5rem;
  position: relative;
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);
}
.inv-editor-close {
  position: absolute;
  top: 8px;
  right: 10px;
  background: transparent;
  border: none;
  color: var(--text);
  font-size: 1.6rem;
  cursor: pointer;
  line-height: 1;
}
.inv-editor-title {
  margin: 0 0 0.75rem 0;
  font-size: 1.2rem;
}
.inv-editor-release {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.55rem 0.75rem;
  margin-bottom: 0.85rem;
  font-size: 0.9rem;
}
.inv-editor-release-name { font-weight: 600; }
.inv-editor-release-id { opacity: 0.7; font-size: 0.82rem; margin-top: 2px; }
.inv-release-results {
  margin-top: 0.5rem;
  max-height: 280px;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
}
.inv-release-loading {
  padding: 0.6rem 0.8rem;
  font-size: 0.85rem;
  color: var(--muted);
}
.inv-release-result {
  display: flex;
  gap: 0.6rem;
  align-items: center;
  padding: 0.4rem 0.55rem;
  cursor: pointer;
  border-bottom: 1px solid var(--border);
}
.inv-release-result:last-child { border-bottom: none; }
.inv-release-result:hover { background: var(--bg-elevated); }
.inv-release-result img,
.inv-release-thumb-ph {
  width: 44px;
  height: 44px;
  object-fit: cover;
  border-radius: 4px;
  background: #222;
  flex-shrink: 0;
}
.inv-release-info { flex: 1; min-width: 0; }
.inv-release-title {
  font-size: 0.88rem;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.inv-release-meta {
  font-size: 0.76rem;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.inv-editor-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.7rem 0.9rem;
}
.inv-editor-label {
  display: flex;
  flex-direction: column;
  font-size: 0.82rem;
  opacity: 0.85;
  gap: 4px;
}
.inv-editor-label input[type="text"],
.inv-editor-label input[type="number"],
.inv-editor-label select,
.inv-editor-label textarea {
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 0.4rem 0.55rem;
  font-size: 0.9rem;
  font-family: inherit;
}
/* Force dark styling on the expanded option list. Chrome/Edge honor
   color-scheme on :root, but Firefox still needs explicit option colors. */
.inv-editor-label select option,
.inv-editor-label select optgroup {
  background: var(--surface);
  color: var(--text);
}
.inv-editor-label textarea { resize: vertical; }
.inv-editor-wide { grid-column: 1 / -1; }
.inv-editor-checkbox {
  flex-direction: row;
  align-items: center;
  gap: 8px;
}
.inv-price-row {
  display: flex;
  gap: 6px;
}
.inv-price-row input[type="number"] { flex: 1; }
.inv-price-row select { width: 80px; }
.inv-editor-suggest {
  padding: 0 10px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
  border-radius: 5px;
  cursor: pointer;
}
.inv-editor-link {
  background: transparent;
  border: none;
  color: var(--link);
  cursor: pointer;
  padding: 4px 0 0 0;
  font-size: 0.85rem;
  text-decoration: underline;
}
.inv-price-suggestions {
  margin-top: 0.8rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.55rem 0.75rem;
  font-size: 0.85rem;
}
.inv-ps-row {
  display: flex;
  justify-content: space-between;
  padding: 2px 0;
}
.inv-editor-error {
  margin-top: 0.8rem;
  background: rgba(200, 40, 40, 0.15);
  border: 1px solid rgba(200, 40, 40, 0.6);
  color: #ffb3b3;
  border-radius: 6px;
  padding: 0.5rem 0.75rem;
  font-size: 0.88rem;
}
.inv-editor-actions {
  display: flex;
  gap: 0.5rem;
  margin-top: 1rem;
  align-items: center;
}
.inv-editor-cancel,
.inv-editor-save,
.inv-editor-delete {
  padding: 0.5rem 1rem;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: var(--bg);
  color: var(--text);
  cursor: pointer;
  font-size: 0.9rem;
}
.inv-editor-save {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  font-weight: 600;
}
.inv-editor-save:hover { filter: brightness(1.1); }
.inv-editor-delete {
  background: #8a1f1f;
  border-color: #8a1f1f;
  color: #fff;
}
.inv-editor-delete:hover { background: #a42525; }

@media (max-width: 640px) {
  .inv-editor-grid { grid-template-columns: 1fr; }
  #inventory-editor-panel {
    max-height: 100vh;
    border-radius: 0;
    width: 100%;
  }
  #inventory-editor-overlay { padding: 0; }
}

#inv-confirm-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.75);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10010;
  padding: 1rem;
}
#inv-confirm-panel {
  background: var(--bg-elevated);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 1.25rem 1.5rem;
  width: min(420px, 100%);
  box-shadow: 0 10px 40px rgba(0, 0, 0, 0.6);
}

/* ── Seller Orders section on Account page ───────────────────────────── */
#orders-section { margin-top: 1rem; }
.ord-pill {
  padding: 0.3rem 0.7rem;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 999px;
  cursor: pointer;
  font-size: 0.8rem;
}
.ord-pill-active {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
}
.ord-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
  padding: 0.55rem 0.75rem;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-elevated);
  margin-bottom: 0.4rem;
  cursor: pointer;
  flex-wrap: wrap;
}
.ord-row:hover { border-color: var(--accent); }
.ord-row-main {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  flex-wrap: wrap;
}
.ord-row-id { font-family: monospace; font-size: 0.85rem; }
.ord-row-buyer { color: var(--muted); font-size: 0.85rem; }
.ord-row-meta {
  display: flex;
  gap: 0.9rem;
  font-size: 0.82rem;
  color: var(--muted);
}
.ord-chip {
  font-size: 0.72rem;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: 999px;
  white-space: nowrap;
}
.ord-chip-new { background: #2d4a6e; color: #cfe4ff; }
.ord-chip-pending { background: #6e5a2d; color: #ffe7b3; }
.ord-chip-progress { background: #2d6e42; color: #c3ffd8; }
.ord-chip-shipped { background: #2e7d32; color: #fff; }
.ord-chip-cancelled { background: #6e2d2d; color: #ffd0d0; }
.ord-chip-refund { background: #6e4a2d; color: #ffddbb; }
.ord-pager {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  justify-content: center;
  margin-top: 0.6rem;
  font-size: 0.85rem;
}
.ord-pager button {
  padding: 0.3rem 0.7rem;
  background: var(--bg-elevated);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 5px;
  cursor: pointer;
}
.ord-pager button[disabled] { opacity: 0.4; cursor: default; }

/* Order detail modal */
#order-detail-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10001;
  padding: 1rem;
}
#order-detail-panel {
  background: var(--bg-elevated);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 10px;
  width: min(720px, 100%);
  max-height: 92vh;
  overflow-y: auto;
  padding: 1.25rem 1.5rem;
  position: relative;
}
.ord-detail-close {
  position: absolute;
  top: 8px;
  right: 12px;
  background: transparent;
  border: none;
  color: var(--text);
  font-size: 1.6rem;
  cursor: pointer;
}
.ord-detail-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0.6rem 1rem;
  margin-bottom: 1rem;
}
.ord-detail-wide { grid-column: 1 / -1; }
.ord-detail-label {
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  color: var(--muted);
  margin-bottom: 2px;
}
.ord-detail-section { margin-top: 1rem; }
.ord-detail-section h3 {
  font-size: 0.95rem;
  margin: 0 0 0.5rem 0;
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.25rem;
}
.ord-detail-items {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.ord-detail-item {
  display: flex;
  gap: 0.6rem;
  align-items: center;
  padding: 0.4rem;
  background: var(--bg);
  border-radius: 5px;
}
.ord-detail-item img,
.ord-thumb-ph {
  width: 56px;
  height: 56px;
  object-fit: cover;
  border-radius: 4px;
  background: #222;
}
.ord-detail-item-body { flex: 1; min-width: 0; }
.ord-msgs {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  max-height: 260px;
  overflow-y: auto;
}
.ord-msg {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 0.5rem 0.65rem;
}
.ord-msg-head {
  font-size: 0.78rem;
  color: var(--muted);
  display: flex;
  justify-content: space-between;
  margin-bottom: 0.25rem;
}
.ord-msg-subj { font-weight: 600; font-size: 0.85rem; }
.ord-msg-body { font-size: 0.88rem; white-space: pre-wrap; }
#ord-status-select {
  background: var(--bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 0.35rem 0.5rem;
}
.ord-btn-primary {
  padding: 0.4rem 0.9rem;
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  font-weight: 600;
  font-size: 0.85rem;
}
.ord-btn-primary:hover { filter: brightness(1.1); }

@media (max-width: 640px) {
  .ord-detail-grid { grid-template-columns: 1fr; }
  #order-detail-panel { max-height: 100vh; border-radius: 0; }
  #order-detail-overlay { padding: 0; }
  .ord-row { flex-direction: column; align-items: flex-start; }
}

/* --- Orders: unread indicators + quick reply --- */
.orders-unread-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 10px;
  background: var(--accent);
  color: #fff;
  font-size: 0.72rem;
  font-weight: 700;
  margin-left: 0.4rem;
  vertical-align: middle;
}
.ord-row-unread {
  background: rgba(255, 107, 53, 0.06);
  border-left: 3px solid var(--accent);
}
.ord-unread-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--accent);
  margin-right: 0.35rem;
  vertical-align: middle;
  box-shadow: 0 0 0 2px rgba(255, 107, 53, 0.25);
}
.ord-row-clickarea {
  cursor: pointer;
  flex: 1;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 0.75rem;
  flex-wrap: wrap;
  min-width: 0;
}
.ord-row-quick {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.3rem;
  margin-left: 0.5rem;
}
.ord-quick-toggle {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--text);
  width: 30px;
  height: 30px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 0.9rem;
  flex-shrink: 0;
}
.ord-quick-toggle:hover { background: #2a2a30; }
.ord-quick-panel {
  width: 260px;
  background: #15151a;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 0.5rem;
}
.ord-quick-panel textarea {
  width: 100%;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 4px;
  padding: 0.35rem;
  font-family: inherit;
  font-size: 0.82rem;
  resize: vertical;
  box-sizing: border-box;
}
.ord-quick-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.4rem;
  margin-top: 0.35rem;
}
.ord-quick-actions button {
  font-size: 0.78rem;
  padding: 0.25rem 0.6rem;
  border-radius: 4px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--text);
  cursor: pointer;
}
.ord-quick-actions button.ord-btn-primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #000;
  font-weight: 600;
}

@media (max-width: 640px) {
  .ord-quick-panel { width: 100%; }
  .ord-row-quick { margin-left: 0; width: 100%; align-items: stretch; }
}

/* --- Profile panel (account page) --- */
.profile-panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 1rem 1.1rem;
  margin-top: 1.25rem;
  margin-bottom: 1rem;
}
.profile-head {
  display: flex;
  align-items: center;
  gap: 0.9rem;
}
.profile-avatar {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  object-fit: cover;
  background: #2a2a30;
  flex-shrink: 0;
}
.profile-avatar-ph {
  width: 64px;
  height: 64px;
  border-radius: 50%;
  background: #2a2a30;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.6rem;
  color: #888;
  flex-shrink: 0;
}
.profile-head-text {
  flex: 1;
  min-width: 0;
}
.profile-name {
  font-size: 1.15rem;
  font-weight: 700;
  line-height: 1.2;
  margin-bottom: 0.15rem;
}
.profile-sub {
  font-size: 0.82rem;
  color: var(--muted);
  line-height: 1.35;
}
.profile-sub strong { color: var(--fg); }
.profile-head-actions {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  align-items: flex-end;
  flex-shrink: 0;
}
.profile-refresh {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--fg);
  border-radius: 8px;
  width: 34px;
  height: 34px;
  cursor: pointer;
  font-size: 1rem;
}
.profile-refresh:hover { background: #2a2a30; }
.profile-refresh:disabled { opacity: 0.5; cursor: default; }
.profile-disconnect {
  background: transparent;
  border: 1px solid #3a3a42;
  color: #9a9aa3;
  border-radius: 6px;
  padding: 0.2rem 0.55rem;
  font-size: 0.7rem;
  cursor: pointer;
  white-space: nowrap;
}
.profile-disconnect:hover { border-color: var(--danger); color: var(--danger); }
.profile-badge {
  display: inline-block;
  font-size: 0.62rem;
  font-weight: 700;
  padding: 0.1rem 0.4rem;
  border-radius: 3px;
  text-transform: uppercase;
  vertical-align: middle;
  margin-left: 0.35rem;
  letter-spacing: 0.03em;
}
.profile-badge-oauth { background: var(--success-bg); color: #4caf50; }
.profile-badge-pat   { background: #2a2a1a; color: var(--warning); }
.profile-stats {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 0.5rem;
  margin-top: 0.9rem;
}
.profile-stat {
  background: #15151a;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0.5rem 0.4rem;
  text-align: center;
}
a.profile-stat-link {
  text-decoration: none;
  color: inherit;
  display: block;
  cursor: pointer;
  transition: background 0.12s, border-color 0.12s, transform 0.12s;
}
a.profile-stat-link:hover {
  background: #1d1d24;
  border-color: var(--accent);
  transform: translateY(-1px);
}
 { color: var(--accent-hi); }
.profile-stat-num {
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--fg);
}
.profile-stat-label {
  font-size: 0.7rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
  margin-top: 0.15rem;
}
.profile-seller {
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px dashed var(--border);
  font-size: 0.85rem;
  color: var(--muted);
}
.profile-seller strong { color: var(--fg); }
.profile-stars { color: #f5c518; letter-spacing: 1px; }

@media (max-width: 640px) {
  .profile-stats { grid-template-columns: repeat(3, 1fr); }
  .profile-avatar, .profile-avatar-ph { width: 52px; height: 52px; }
  .profile-name { font-size: 1rem; }
}

/* ── Library of Congress view ─────────────────────────────────────────── */
#loc-view { padding: 1rem 0 4rem; }
.loc-header { margin-bottom: 1rem; }
.loc-title {
  font-size: 1.4rem;
  color: var(--accent);
  margin: 0 0 0.35rem;
  letter-spacing: 0.01em;
}
.loc-sub {
  font-size: 0.82rem;
  color: var(--muted);
  margin: 0 0 0.85rem;
  line-height: 1.5;
}
.loc-tabs {
  display: flex;
  gap: 0.4rem;
  border-bottom: 1px solid var(--border);
  padding-bottom: 0.5rem;
}
.loc-tab {
  background: none;
  border: 1px solid transparent;
  color: var(--muted);
  font: inherit;
  font-size: 0.8rem;
  font-weight: 600;
  padding: 0.4rem 0.9rem;
  border-radius: 5px;
  cursor: pointer;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}
.loc-tab:hover { color: var(--text); }
.loc-tab.active {
  color: var(--accent);
  border-color: var(--border);
  background: var(--surface);
}

.loc-form {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  padding: 0.9rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  margin-bottom: 0.9rem;
}
.loc-form-row {
  display: flex;
  gap: 0.5rem;
}
.loc-form-row input {
  flex: 1;
  min-width: 0;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 5px;
  padding: 0.55rem 0.75rem;
  font: inherit;
  font-size: 0.85rem;
}
.loc-form-row input:focus { outline: none; border-color: var(--accent); }
.loc-submit {
  background: var(--accent);
  border: 1px solid var(--accent);
  color: var(--surface-sunken);
  font: inherit;
  font-weight: 700;
  font-size: 0.82rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 0 1.3rem;
  border-radius: 5px;
  cursor: pointer;
}
.loc-submit:hover:not(:disabled) { background: var(--accent2); }
.loc-submit:disabled { opacity: 0.5; cursor: wait; }
.loc-form-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 0.5rem 0.7rem;
}
.loc-form-grid label {
  display: flex;
  flex-direction: column;
  gap: 0.2rem;
  font-size: 0.7rem;
  color: var(--muted);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  min-width: 0;
}
.loc-form-grid label > span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.loc-form-grid input,
.loc-form-grid select {
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 4px;
  padding: 0.4rem 0.55rem;
  font: inherit;
  font-size: 0.82rem;
  text-transform: none;
  letter-spacing: 0;
  /* Override sitewide `select { height: var(--input-h) }` so padding
     controls the box — otherwise the 28px fixed height clips text. */
  height: auto;
  line-height: normal;
}
.loc-form-grid input:focus,
.loc-form-grid select:focus { outline: none; border-color: var(--accent); }
/* Icon-only "Playable only" toggle in the search row. The checkbox
   itself is hidden; the label renders as a small button and changes
   color when :has(input:checked). */
.loc-playable-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.3rem;
  height: 2.3rem;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--bg);
  color: var(--muted);
  cursor: pointer;
  flex-shrink: 0;
  transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.loc-playable-btn input { display: none; }
.loc-playable-btn:hover {
  border-color: var(--accent);
  color: var(--accent);
}
.loc-playable-btn:has(input:checked) {
  border-color: var(--accent);
  color: var(--accent);
  background: var(--accent-soft);
}
.loc-playable-icon {
  font-size: 1.1rem;
  line-height: 1;
  pointer-events: none;
}

/* Sort + Per Page combined into one grid cell to save a row on desktop.
   On mobile the 2-col grid still holds because the cell behaves like any
   other — the row flex inside keeps both selects on one line. */
.loc-form-split-row {
  display: flex;
  gap: 0.4rem;
}
.loc-form-split-row select { flex: 1; min-width: 0; }
.loc-form-split-row .loc-perpage-select { flex: 0 0 4rem; }

.loc-status {
  font-size: 0.78rem;
  color: var(--muted);
  margin-bottom: 0.6rem;
  min-height: 1.1rem;
}

/* LOC cards now reuse the main .card grid layout. These rules only add
   the LOC-specific thumb play overlay and badge colors. */
.loc-results { min-height: 4rem; }

.loc-thumb-play {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%) scale(0.9);
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.65);
  color: #fff;
  font-size: 1.3rem;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transition: opacity 0.15s, transform 0.15s, background 0.15s;
  cursor: pointer;
  z-index: 3;
  line-height: 1;
  padding-left: 0.15rem;
}
.card:hover .loc-thumb-play { opacity: 1; transform: translate(-50%, -50%) scale(1); }
.loc-thumb-play:hover { background: var(--accent); color: var(--surface-sunken); }

/* Star badge inside the card-thumb-badges bar (same pattern as C/W/F) */
.loc-save-badge,
.loc-remove-badge {
  cursor: pointer;
  font-size: 0.85rem;
}
.loc-save-badge.is-saved { color: var(--accent-hi); border-color: var(--accent-hi); }
.loc-remove-badge:hover { color: var(--danger-bright); border-color: var(--danger-bright); }

.loc-pagination {
  display: flex;
  gap: 0.6rem;
  align-items: center;
  justify-content: center;
  padding: 1rem 0 0.3rem;
}
.loc-page-btn {
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  font: inherit;
  font-size: 0.8rem;
  padding: 0.42rem 0.95rem;
  border-radius: 5px;
  cursor: pointer;
}
.loc-page-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.loc-page-btn:disabled { opacity: 0.35; cursor: not-allowed; }
.loc-page-info { font-size: 0.78rem; color: var(--muted); }

.loc-skeleton {
  height: 110px;
  background: linear-gradient(90deg, var(--surface) 25%, var(--bg-hover) 50%, var(--surface) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.4s linear infinite;
  border-radius: var(--radius);
}
.loc-empty {
  padding: 2rem 1rem;
  text-align: center;
  color: var(--muted);
  font-size: 0.85rem;
  font-style: italic;
}
.loc-saved-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 0.55rem;
}
.loc-saved-title {
  font-size: 0.9rem;
  color: var(--text);
  font-weight: 600;
}
.loc-saved-count { color: var(--muted); font-weight: 400; }
.loc-refresh-btn {
  background: none;
  border: 1px solid var(--border);
  color: var(--muted);
  font-size: 1rem;
  cursor: pointer;
  padding: 0.15rem 0.55rem;
  border-radius: 4px;
}
.loc-refresh-btn:hover { color: var(--accent); border-color: var(--accent); }

.loc-saved-toolbar {
  display: flex;
  gap: 0.5rem;
  margin-bottom: 0.7rem;
}
.loc-saved-filter-input {
  flex: 1;
  min-width: 0;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 5px;
  padding: 0.45rem 0.7rem;
  font: inherit;
  font-size: 0.82rem;
}
.loc-saved-filter-input:focus { outline: none; border-color: var(--accent); }
.loc-saved-sort {
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 5px;
  padding: 0.45rem 0.55rem;
  font: inherit;
  font-size: 0.78rem;
  cursor: pointer;
  height: auto;
  line-height: normal;
}
.loc-saved-sort:focus { outline: none; border-color: var(--accent); }

/* Trash icon shown in place of the ★ on Saved-tab cards. Uses the same
   base size as .loc-save-btn so the card layout stays identical. */
.loc-remove-btn {
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--muted);
  font: inherit;
  font-size: 0.95rem;
  width: 2.1rem;
  height: 2.1rem;
  border-radius: 50%;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  transition: color 0.12s, border-color 0.12s;
}
.loc-remove-btn:hover:not(:disabled) {
  color: var(--danger-bright);
  border-color: var(--danger-bright);
}
.loc-remove-btn:disabled { opacity: 0.35; cursor: wait; }

/* ── LOC audio bar — mirrors .mini-player exactly ─────────────────────
   The bar shape, padding, gap, button sizing/colors, and hover states
   are copied from .mini-player / .mini-player-bar / .mini-player-controls
   so the LOC and YouTube persistent players are visually identical
   except for the icon (♪ vs none) and the expand-panel content. The
   native <audio> element only appears in the expanded panel. */
/* ── Unified mini-player engine show/hide rules ─────────────────────────
   The bar's expanded panel and source-specific buttons swap based on
   .mini-player.engine-yt / .engine-loc set by _setPlayerEngine. The
   former dedicated #loc-audio-bar element is gone — its <audio> is
   now hosted inside the mini-player. */
.mini-engine-yt, .mini-engine-loc { display: none; }
.mini-player.engine-yt.expanded .mini-engine-yt { display: block; }
.mini-player.engine-loc.expanded .mini-engine-loc { display: block; }

/* Source-specific buttons in the controls cluster */
.mini-loc-only { display: none !important; }
.mini-player.engine-loc .mini-loc-only { display: inline-flex !important; }
.mini-yt-only { display: inline-flex; }
.mini-player.engine-loc .mini-yt-only { display: none !important; }

/* The little source-icon next to the title (♪ for LOC, ▶ for YT) */
.mini-player-source-icon {
  display: inline-block;
  margin-right: 0.35rem;
  color: var(--accent);
  font-size: 0.85rem;
  flex-shrink: 0;
}
.mini-player-source-icon:empty { display: none; }

/* LOC's audio scrubber inside the expanded panel */
#loc-audio {
  width: 100%;
  height: 36px;
  /* Tint the OS-native control to read on the dark bar. WebKit/Chromium
     respect this; Firefox renders its own dark control by default. */
  filter: invert(0.85) hue-rotate(180deg);
}
/* The save badge keeps its is-saved highlight regardless of source */
#mini-loc-save.is-saved { color: var(--favorite); }

/* ── Cross-source play queue drawer ─────────────────────────────────────
   Slides up from the right side of the bar; persistent until dismissed.
   z-index sits above the bar (300) but below modal overlays. */
.queue-drawer {
  position: fixed;
  right: 1rem;
  bottom: 60px;
  z-index: 320;
  width: 360px;
  max-width: calc(100vw - 2rem);
  max-height: 60vh;
  background: #111;
  border: 1px solid #2a2a2a;
  border-radius: 8px;
  box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.7);
  display: none;
  flex-direction: column;
  overflow: hidden;
}
.queue-drawer.open { display: flex; }
body.player-open .queue-drawer.open { bottom: 102px; }

.queue-drawer-head {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.55rem 0.7rem;
  border-bottom: 1px solid #2a2a2a;
  background: #18181a;
}
.queue-drawer-title {
  font-size: 0.78rem;
  font-weight: 700;
  color: #ccc;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.queue-drawer-count {
  font-size: 0.7rem;
  color: #888;
  flex: 1;
}
.queue-drawer-clear,
.queue-drawer-close,
.queue-drawer-repeat,
.queue-drawer-consume,
.queue-drawer-save,
.queue-drawer-load {
  background: none;
  border: none;
  color: #888;
  cursor: pointer;
  padding: 0.2rem 0.45rem;
  border-radius: 4px;
  font-size: 0.72rem;
}
.queue-drawer-close   { font-size: 1.1rem; }
.queue-drawer-repeat  { font-size: 1.05rem; line-height: 1; position: relative; }
.queue-drawer-consume { font-size: 1rem; line-height: 1; opacity: 0.7; }
.queue-drawer-consume.is-on { color: var(--accent); opacity: 1; }
.queue-drawer-save,
.queue-drawer-load { font-size: 0.95rem; line-height: 1; opacity: 0.75; }
.queue-drawer-clear:hover,
.queue-drawer-close:hover,
.queue-drawer-repeat:hover,
.queue-drawer-consume:hover,
.queue-drawer-save:hover,
.queue-drawer-load:hover { color: #fff; background: rgba(255,255,255,0.08); opacity: 1; }
.queue-drawer-consume.is-on:hover { color: var(--accent); }

/* ── Playlist picker modal ───────────────────────────────────────── */
.playlist-picker {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 9000;
}
.playlist-picker.open { display: flex; }
.playlist-picker-card {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  width: min(560px, 90vw);
  max-height: 80vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.playlist-picker-head {
  display: flex;
  align-items: center;
  padding: 0.5rem 0.7rem;
  border-bottom: 1px solid var(--border);
  gap: 0.5rem;
}
.playlist-picker-title {
  flex: 1;
  font-weight: 600;
  font-size: 0.85rem;
  color: #ddd;
}
.playlist-picker-close {
  background: none;
  border: none;
  color: #888;
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  padding: 0 0.3rem;
}
.playlist-picker-close:hover { color: #fff; }
.playlist-picker-body {
  overflow-y: auto;
  padding: 0.5rem 0.7rem 0.7rem;
  font-size: 0.8rem;
  color: var(--muted);
}
.playlist-picker-empty {
  padding: 1rem 0.5rem;
  text-align: center;
  color: #777;
}
.playlist-picker-list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.playlist-picker-row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.4rem 0.3rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.05);
}
.playlist-picker-row:last-child { border-bottom: none; }
.playlist-picker-name {
  flex: 1;
  color: #ddd;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.playlist-picker-count {
  color: #777;
  font-size: 0.7rem;
  flex-shrink: 0;
}
.playlist-picker-actions {
  display: inline-flex;
  gap: 0.25rem;
  flex-shrink: 0;
}
.playlist-picker-actions button {
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--border);
  color: var(--muted);
  cursor: pointer;
  padding: 0.2rem 0.45rem;
  border-radius: 3px;
  font-size: 0.72rem;
  line-height: 1;
}
.playlist-picker-actions button:hover {
  color: #fff;
  border-color: var(--accent);
}
.playlist-picker-load {
  color: #fff !important;
}
/* Repeat button: three distinct visuals so each state reads at a
   glance. Off uses a muted gray + linear arrow; all uses the accent
   color (blue in the default theme); one uses a warm yellow + a tiny
   "1" badge tucked above the loop arrow.
   We use monochrome glyphs (→ / ↻) here — emoji 🔁/🔂 ignore CSS
   `color` on most platforms, which made the old off/all states both
   read as blue. */
.queue-drawer-repeat.repeat-off { color: #888; opacity: 0.7; }
.queue-drawer-repeat.repeat-all { color: var(--accent); }
.queue-drawer-repeat.repeat-one { color: #f0c95c; }
.queue-drawer-repeat .queue-repeat-1 {
  position: absolute;
  top: -2px;
  right: 2px;
  font-size: 0.55rem;
  font-weight: 700;
  line-height: 1;
}

.queue-drawer-list {
  overflow-y: auto;
  max-height: calc(60vh - 48px);
}
.queue-empty {
  padding: 1.5rem 1rem;
  font-size: 0.78rem;
  color: #888;
  text-align: center;
  line-height: 1.5;
}

.queue-row {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.45rem 0.55rem;
  border-bottom: 1px solid #1d1d20;
}
.queue-row:last-child { border-bottom: none; }
.queue-row.sortable-chosen { background: rgba(255,255,255,0.04); }
.queue-row-handle {
  color: #555;
  cursor: grab;
  user-select: none;
  font-size: 0.85rem;
  letter-spacing: -2px;
  padding: 0 0.15rem;
}
.queue-row-handle:hover { color: #aaa; }
.queue-row-source {
  color: var(--accent);
  font-size: 0.85rem;
  flex-shrink: 0;
  width: 16px;
  text-align: center;
}
.queue-row-play {
  flex: 1 1 0;
  /* width: 0 + flex-basis 0 forces the button to derive its width
     entirely from flex-grow. Without this, the <button>'s default
     content-fit width can refuse to shrink below the natural width
     of long LOC titles, defeating the inner ellipsis. */
  width: 0;
  min-width: 0;
  background: none;
  border: none;
  color: #ccc;
  text-align: left;
  cursor: pointer;
  padding: 0.15rem 0.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
  overflow: hidden;
}
.queue-row-play:hover .queue-row-title { color: var(--accent-hi, var(--accent)); }
.queue-row-title {
  font-size: 0.78rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-weight: 600;
  max-width: 100%;
  min-width: 0;
}
.queue-row-artist {
  font-size: 0.7rem;
  color: #888;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 100%;
  min-width: 0;
}
.queue-row-remove {
  background: none;
  border: none;
  color: #555;
  cursor: pointer;
  padding: 0.15rem 0.4rem;
  border-radius: 4px;
  font-size: 0.95rem;
  flex-shrink: 0;
}
.queue-row-remove:hover { color: var(--danger-bright, #ff6b6b); background: rgba(255,255,255,0.06); }

/* ── Album thumbnail on each queue row ────────────────────────────────
   LOC/archive items snapshot data.image at queue-add time; YT items
   fall back to YouTube's mqdefault thumbnail. The wrapper carries the
   small source-color badge in the corner so users can see LOC-vs-YT
   without reading text. */
.queue-row-thumb-wrap {
  position: relative;
  display: inline-flex;
  flex-shrink: 0;
}
.queue-row-thumb {
  width: 36px;
  height: 36px;
  object-fit: cover;
  border-radius: 4px;
  background: rgba(255,255,255,0.05);
  display: block;
}
.queue-row-thumb.thumb-broken { display: none; }
.queue-row-thumb-empty {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  color: var(--accent);
  background: rgba(255,255,255,0.05);
}
.queue-row-source-badge {
  position: absolute;
  bottom: -2px;
  right: -2px;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 2px solid #111;
  pointer-events: none;
}
.queue-row-source-loc { background: #6ddf70; }
.queue-row-source-yt  { background: #c43d3d; }

/* ── Now-playing row indication ───────────────────────────────────────
   The currently-playing item stays in the queue (we no longer consume
   on play; only on track-end). It gets a left accent stripe, a tinted
   row background, an animated equalizer overlay on the thumb, and a
   tiny "Now playing" label above the title. */
.queue-row.is-playing {
  background: rgba(255,255,255,0.04);
  border-left: 3px solid var(--accent);
  padding-left: calc(0.55rem - 3px);
}
.queue-row.is-playing .queue-row-title { color: var(--accent); }
.queue-row-now-playing {
  font-size: 0.6rem;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-weight: 700;
  display: block;
  margin-bottom: 0.05rem;
}
/* Three little vertical bars overlaid on the thumb that "dance" while
   the track is playing — visually distinguishes the playing row from
   any other selected/hover state. Pure CSS, no JS keepalive. */
.queue-row-eq {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  gap: 2px;
  background: rgba(0,0,0,0.45);
  border-radius: 4px;
  padding: 5px;
  pointer-events: none;
}
.queue-row-eq i {
  width: 3px;
  background: var(--accent);
  display: block;
  border-radius: 1px;
  animation: queue-eq-bounce 0.9s ease-in-out infinite;
}
.queue-row-eq i:nth-child(1) { animation-delay: -0.3s; }
.queue-row-eq i:nth-child(2) { animation-delay: -0.6s; }
.queue-row-eq i:nth-child(3) { animation-delay: -0.1s; }
@keyframes queue-eq-bounce {
  0%, 100% { height: 25%; }
  50%      { height: 90%; }
}

/* ── Idle-queue mini-player surface ───────────────────────────────────
   Shown when the queue has items but no engine is loaded yet. Hides
   only the engine-source-specific controls (LOC save / info, YT
   share / album link) — the cross-source nav (prev / next / queue /
   expand / repeat) stays visible so the user sees the full toolbar
   from the start instead of having buttons appear once a track
   starts. The progress strip stays hidden because there's no
   duration to scrub yet. */
.mini-player.idle-queue #mini-loc-save,
.mini-player.idle-queue #mini-loc-info,
.mini-player.idle-queue #mini-share,
.mini-player.idle-queue #mini-album { display: none; }
/* Disc + share buttons:
   - Hidden when nothing's playing (idle-queue / no engine).
   - VISIBLE while an engine is active. Dimmed if we don't know the
     release ID for this track (clicking is a no-op + toast); full
     opacity once .has-release is on the mini-player.
   This keeps the disc icon as a consistent presence in the bar
   while still telegraphing whether it'll do anything when clicked. */
.mini-player .mini-needs-release { display: none !important; }
.mini-player.engine-yt .mini-needs-release,
.mini-player.engine-loc .mini-needs-release {
  display: inline-block !important;
  opacity: 0.35;
  cursor: default;
  transition: opacity 0.15s;
}
.mini-player.has-release .mini-needs-release {
  opacity: 1;
  cursor: pointer;
}
.mini-player.idle-queue .mini-needs-release { display: none !important; }

/* Queue drawer drag-to-reorder visuals. The default Sortable.js
   styles are minimal; these give the user clearer "this row is
   moving / this is the drop slot" feedback. */
.queue-row {
  cursor: grab;
  transition: background-color 0.15s, transform 0.15s;
}
.queue-row:active { cursor: grabbing; }
/* The placeholder slot at the drop target. */
.queue-row-ghost {
  opacity: 0.35;
  background: rgba(255, 255, 255, 0.04) !important;
}
/* The row currently being dragged — slight emphasis. */
.queue-row-chosen {
  background: rgba(255, 255, 255, 0.06) !important;
}
.queue-row-dragging {
  background: var(--bg-elevated, #15120e) !important;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.6);
  border-radius: 6px;
}
/* Buttons inside the row keep pointer cursor regardless. */
.queue-row .queue-row-play,
.queue-row .queue-row-remove,
.queue-row .queue-row-handle { cursor: pointer; }

/* Jimmy Witherfork easter-egg popup — surfaces from the footer line
   click. Tiny floating panel with a single external link. */
#sd-jimmy-popup {
  position: fixed;
  z-index: 9998;
  background: var(--bg-elevated, #15120e);
  border: 1px solid var(--border, #2e2e2e);
  border-radius: 6px;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.5);
  padding: 0.6rem 0.9rem;
  font-size: 0.82rem;
  text-align: center;
  min-width: 180px;
}
#sd-jimmy-popup #sd-jimmy-link {
  color: var(--accent, #ffffff);
  text-decoration: none;
  font-weight: 600;
}
#sd-jimmy-popup #sd-jimmy-link:hover { text-decoration: underline; }

/* Offline / connection banner — fixed-top strip surfaced by
   web/offline.js when the user has opted in to offline mode and the
   device is currently offline. Only visible when both conditions
   hold (controlled via body.is-offline + the banner element being
   in the DOM at all). */
.offline-banner {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 9999;
  display: none;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  padding: 0.4rem 0.8rem;
  background: rgba(80, 50, 20, 0.95);
  color: #ffd89b;
  font-size: 0.8rem;
  letter-spacing: 0.02em;
  border-bottom: 1px solid rgba(232, 160, 32, 0.5);
  pointer-events: none;
}
body.is-offline .offline-banner { display: flex; }
.offline-banner-dot {
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  background: #ffb84d;
  box-shadow: 0 0 6px rgba(255, 184, 77, 0.7);
  animation: offline-pulse 2s ease-in-out infinite;
}
@keyframes offline-pulse {
  0%, 100% { opacity: 0.6; }
  50%      { opacity: 1; }
}
/* Disable in-app actions that require connectivity while offline.
   Visual cue only — handlers themselves should also reject the
   call if it'd 401/timeout. */
body.is-offline .offline-disabled,
body.is-offline button.offline-disabled {
  opacity: 0.4 !important;
  pointer-events: none !important;
}

/* Cross-device prompt — shown when a user signs in on a fresh device
   and their server-side offlineEnabled pref is true. Floats bottom-
   right, non-modal; user can dismiss without acting. */
.sd-offline-cross-prompt {
  position: fixed;
  bottom: 1rem;
  right: 1rem;
  z-index: 9998;
  max-width: 360px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.6rem;
  padding: 0.75rem 1rem;
  background: var(--bg-elevated, #1f1a14);
  color: var(--text, #e8dcc8);
  border: 1px solid var(--border, rgba(255, 255, 255, 0.18));
  border-radius: 8px;
  box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
  font-size: 0.84rem;
  line-height: 1.4;
}
.sd-offline-cross-msg { flex: 1 1 100%; }
.sd-offline-cross-prompt button {
  font-size: 0.8rem;
  padding: 0.3rem 0.85rem;
  border-radius: 5px;
  cursor: pointer;
  border: 1px solid var(--border);
  background: none;
  color: inherit;
  font-weight: 600;
}
.sd-offline-cross-prompt .sd-offline-cross-yes {
  background: var(--accent, #e8a020);
  color: #000;
  border-color: transparent;
}
.sd-offline-cross-prompt .sd-offline-cross-yes:hover { filter: brightness(1.08); }
.sd-offline-cross-prompt .sd-offline-cross-no:hover { background: rgba(255, 255, 255, 0.06); }
@media (max-width: 480px) {
  .sd-offline-cross-prompt {
    left: 1rem; right: 1rem; max-width: none;
    bottom: 4.5rem; /* clear of the mini-player */
  }
}
.mini-player.idle-queue .mini-progress { display: none; }
.mini-idle-count {
  color: var(--muted);
  font-size: 0.7rem;
  margin-left: 0.4em;
}

/* Tiny ➕ "add to queue" icon, used inline next to track titles, on
   LOC card thumbnails, and in info popups. Matches the existing
   .track-loc-icon footprint so it doesn't crowd track rows. */
.queue-add-icon {
  display: inline-block;
  font-size: 0.78em;
  margin-left: 0.2rem;
  padding: 0 0.25rem;
  text-decoration: none;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 3px;
  cursor: pointer;
  line-height: 1.2;
  transition: color 0.12s, border-color 0.12s, background 0.12s;
  vertical-align: baseline;
}
.queue-add-icon:hover {
  color: var(--accent-hi, var(--accent));
  border-color: var(--accent-hi, var(--accent));
  background: rgba(255,255,255,0.04);
}
.queue-add-icon.queued { color: var(--success); border-color: var(--success); }

/* ── Track YouTube override affordances ─────────────────────────────
   .track-yt-suggest  — shown on tracks Discogs missed (signed-in users).
                         Click opens the YT search popup with track context.
   .track-yt-override-badge — small 🎵 marker on rows whose play link
                         came from a crowd-sourced override.
   .track-yt-admin-delete  — admin-only ✕ on overridden rows; removes
                         the override after confirm.
   .archive-btn-suggest — "✓ Suggest" button on each YT search result
                         when the popup was opened in suggest mode. */
.track-yt-suggest {
  display: inline-block;
  font-size: 0.78em;
  margin-left: 0.2rem;
  padding: 0 0.25rem;
  text-decoration: none;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 3px;
  cursor: pointer;
  line-height: 1.2;
  opacity: 0.55;
  transition: color 0.12s, border-color 0.12s, opacity 0.12s, background 0.12s;
}
.track-yt-suggest:hover {
  color: #c084fc;
  border-color: #c084fc;
  opacity: 1;
  background: rgba(192, 132, 252, 0.08);
}
.track-yt-override-badge {
  display: inline-block;
  font-size: 0.72em;
  margin-left: 0.25rem;
  opacity: 0.7;
  cursor: default;
}
.track-yt-admin-delete {
  display: inline-block;
  font-size: 0.7em;
  margin-left: 0.15rem;
  padding: 0 0.2rem;
  text-decoration: none;
  color: var(--muted);
  border: 1px solid var(--border);
  border-radius: 3px;
  cursor: pointer;
  line-height: 1.2;
  opacity: 0.6;
}
.track-yt-admin-delete:hover {
  color: #ff7b7b;
  border-color: #ff7b7b;
  opacity: 1;
  background: rgba(255,123,123,0.08);
}
.archive-btn-suggest {
  background: rgba(192, 132, 252, 0.12);
  border-color: rgba(192, 132, 252, 0.45);
  color: #c084fc;
}
.archive-btn-suggest:hover:not(:disabled) {
  background: rgba(192, 132, 252, 0.22);
  border-color: #c084fc;
}
.archive-btn-suggest:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Album-mode YT popup: highlight portions of result titles +
   descriptions that match the names of still-missing tracks, so
   the user can scan a long result list and immediately spot which
   row maps to which track. Same purple as the contribution
   affordances elsewhere on the site. */
.album-track-match {
  background: rgba(192, 132, 252, 0.25);
  color: #f5e6ff;
  padding: 0 0.15em;
  border-radius: 2px;
  font-weight: 600;
}

/* ── Tracklist heading "🎵 N missing" affordance ────────────────────
   Lives in the Tracklist header next to the (N) playable count.
   Only shows when ≥2 tracks are missing AND the user is signed in. */
.tracklist-find-missing {
  color: #c084fc;
  text-decoration: none;
  font-size: 0.78em;
  margin-left: 0.35rem;
  padding: 0.05rem 0.35rem;
  border: 1px solid rgba(192,132,252,0.45);
  border-radius: 3px;
  background: rgba(192,132,252,0.08);
  transition: background 0.12s, border-color 0.12s;
}
.tracklist-find-missing:hover {
  background: rgba(192,132,252,0.18);
  border-color: #c084fc;
}

/* ── Album-mode YT popup: per-result assignment row ──────────────── */
.album-assign-row {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.4rem;
  flex-wrap: wrap;
}
.album-assign-select {
  max-width: 18rem;
  flex: 1 1 auto;
}
.album-assign-stage.is-staged {
  background: rgba(109, 223, 112, 0.15);
  border-color: rgba(109, 223, 112, 0.55);
  color: #6ddf70;
}

/* ── Album-mode YT popup: sticky footer (status + submit) ────────── */
.album-suggest-footer {
  margin-top: 0.6rem;
  padding-top: 0.6rem;
  border-top: 1px solid var(--border);
  position: sticky;
  bottom: 0;
  background: var(--surface);
  z-index: 2;
}
.album-suggest-status-list {
  max-height: 8rem;
  overflow-y: auto;
  margin-bottom: 0.5rem;
  padding: 0.3rem 0.4rem;
  background: rgba(255,255,255,0.03);
  border-radius: 4px;
}
.album-suggest-track {
  font-size: 0.78rem;
  color: var(--muted);
  padding: 0.1rem 0;
  display: flex;
  align-items: center;
  gap: 0.4rem;
}
.album-suggest-track.is-staged { color: var(--text); }
.album-suggest-mark {
  display: inline-block;
  width: 1rem;
  text-align: center;
  font-weight: 600;
}
.album-suggest-track.is-staged .album-suggest-mark { color: #6ddf70; }
.album-suggest-tnum {
  font-family: monospace;
  font-size: 0.72rem;
  color: var(--muted);
  min-width: 2rem;
}
.album-suggest-staged-vid {
  margin-left: 0.4rem;
  font-size: 0.72rem;
  color: #c084fc;
  font-style: italic;
}
.album-suggest-submit-row {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  flex-wrap: wrap;
}
.album-suggest-submit-btn:not(:disabled) {
  background: rgba(192, 132, 252, 0.15);
  border-color: rgba(192, 132, 252, 0.55);
  color: #c084fc;
}
.album-suggest-submit-btn:not(:disabled):hover {
  background: rgba(192, 132, 252, 0.25);
  border-color: #c084fc;
}

/* "No CDs" toggle button — a small circular icon button with a CD
   glyph and a red diagonal strike that brightens when active. Lives
   on the same row as the "Hard to find" checkbox in the advanced
   search panel. Filter is applied client-side in renderResults. */
.f-exclude-cd-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  width: 1.7rem;
  height: 1.7rem;
  padding: 0;
  border-radius: 50%;
  background: rgba(255,255,255,0.04);
  border: 1px solid var(--border);
  color: var(--muted);
  cursor: pointer;
  font-size: 0.95rem;
  line-height: 1;
  transition: background 0.15s, border-color 0.15s, transform 0.1s;
}
.f-exclude-cd-btn:hover { transform: scale(1.06); }
.f-exclude-cd-btn .f-exclude-cd-glyph {
  /* Slight desaturation so the strike reads as the dominant shape. */
  filter: grayscale(0.4);
  font-size: 0.95rem;
  line-height: 1;
  display: inline-block;
}
.f-exclude-cd-btn::after {
  content: "";
  position: absolute;
  left: 12%;
  right: 12%;
  top: 50%;
  height: 2px;
  background: #ff5050;
  border-radius: 1px;
  transform: rotate(-30deg);
  transform-origin: center;
  opacity: 0.45;
  box-shadow: 0 0 1px rgba(0,0,0,0.7);
  transition: opacity 0.15s;
  pointer-events: none;
}
.f-exclude-cd-btn.active {
  background: rgba(255, 80, 80, 0.12);
  border-color: rgba(255, 80, 80, 0.55);
}
.f-exclude-cd-btn.active::after { opacity: 1; }

/* "Hard to Find" search-mode badge — decorates result cards whose
   master/release has no embedded YouTube videos, signaling a place
   where a user can contribute via the per-track 🎵 affordance. Sits
   in the lower-left of the card thumbnail, opposite the multi-instance
   (N) badge so they don't collide. */
.card-needs-yt-badge {
  position: absolute;
  left: 0.35rem;
  bottom: 0.35rem;
  z-index: 5;
  background: rgba(192, 132, 252, 0.18);
  border: 1px solid rgba(192, 132, 252, 0.55);
  color: #c084fc;
  border-radius: 50%;
  width: 1.5rem;
  height: 1.5rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.78rem;
  line-height: 1;
  pointer-events: none;
  backdrop-filter: blur(2px);
}

/* ── LOC info popup overlay ───────────────────────────────────────── */
.loc-info-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.7);
  z-index: 240;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 1rem;
}
.loc-info-overlay.open { display: flex; }
.loc-info-box {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  max-width: 640px;
  width: 100%;
  max-height: 86vh;
  overflow-y: auto;
  position: relative;
  box-shadow: 0 10px 50px rgba(0, 0, 0, 0.75);
  padding: 1.1rem 1.2rem 1.3rem;
}
.loc-info-close {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  padding: 0.15rem 0.55rem;
  border-radius: 4px;
  z-index: 2;
}
.loc-info-close:hover { color: var(--text); background: var(--border); }
.loc-info-head {
  display: flex;
  gap: 1rem;
  margin-bottom: 1rem;
  padding-right: 2rem;
}
.loc-info-thumb {
  width: 140px;
  height: 140px;
  object-fit: cover;
  border-radius: 4px;
  background: var(--bg);
  flex-shrink: 0;
}
.loc-info-thumb-ph {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2.5rem;
  color: var(--muted);
  background: linear-gradient(135deg, var(--surface-raised), var(--surface-sunken));
}
.loc-info-head-text {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
}
.loc-info-title {
  font-size: 1.2rem;
  color: var(--fg);
  font-weight: 700;
  line-height: 1.2;
}
.loc-info-artist {
  font-size: 0.92rem;
  color: var(--text);
  opacity: 0.85;
}
.loc-info-actions {
  display: flex;
  gap: 0.4rem;
  margin-top: 0.6rem;
  flex-wrap: wrap;
}
.loc-info-btn {
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text);
  font: inherit;
  font-size: 0.8rem;
  padding: 0.45rem 0.9rem;
  border-radius: 5px;
  cursor: pointer;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
}
.loc-info-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.loc-info-btn.is-disabled { opacity: 0.4; cursor: not-allowed; }
.loc-info-btn-play {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--surface-sunken);
  font-weight: 700;
}
.loc-info-btn-play:hover:not(:disabled) { background: var(--accent2); color: var(--surface-sunken); }
.loc-info-btn-save.is-saved {
  color: var(--accent-hi);
  border-color: var(--accent-hi);
}
.loc-info-btn-loc {
  color: var(--muted);
}
.loc-info-btn-queue {
  color: var(--accent-hi, var(--accent));
}
.loc-info-btn-queue:hover:not(:disabled) {
  background: var(--accent-hi, var(--accent));
  color: var(--bg);
  border-color: var(--accent-hi, var(--accent));
}

/* ── Archive.org list page ──────────────────────────────────────────── */
.archive-list {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  margin-top: 1rem;
}
.archive-row {
  display: flex;
  gap: 0.85rem;
  align-items: flex-start;
  padding: 0.75rem 0.9rem;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
}
.archive-row:hover { border-color: var(--accent); }
.archive-row-main { flex: 1; min-width: 0; }
.archive-row-title {
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--text);
  /* Long archive show titles can exceed the row width — wrap on word
     boundaries with up to 2 lines, then ellipsis. Falls back to plain
     wrap on browsers without -webkit-line-clamp. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  word-break: break-word;
  line-height: 1.3;
}
.archive-meta-bar {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  margin-bottom: 0.6rem;
  font-size: 0.78rem;
  color: var(--muted);
  flex-wrap: wrap;
}
.archive-filter {
  flex: 1 1 220px;
  min-width: 0;
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 5px;
  padding: 0.4rem 0.6rem;
  font: inherit;
  font-size: 0.82rem;
}
.archive-filter:focus { outline: none; border-color: var(--accent); }
.archive-sort {
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 5px;
  padding: 0.35rem 0.5rem;
  font: inherit;
  font-size: 0.78rem;
  cursor: pointer;
}
.archive-meta-count {
  font-variant-numeric: tabular-nums;
  flex-shrink: 0;
}
.archive-refresh {
  background: none;
  border: 1px solid var(--border);
  color: var(--muted);
  padding: 0.25rem 0.6rem;
  border-radius: 5px;
  font-size: 0.75rem;
  cursor: pointer;
  flex-shrink: 0;
}
.archive-refresh:hover {
  color: var(--accent-hi, var(--accent));
  border-color: var(--accent-hi, var(--accent));
}
.archive-load-more-wrap {
  display: flex;
  justify-content: center;
  margin-top: 0.7rem;
}
.archive-load-more {
  background: none;
  border: 1px solid var(--border);
  color: var(--muted);
  padding: 0.5rem 1.4rem;
  border-radius: var(--radius);
  cursor: pointer;
  font-size: 0.85rem;
}
.archive-load-more:hover {
  border-color: var(--accent);
  color: var(--accent);
}
/* Browse / Saved tab switcher — mirrors the LOC tab look. */
.archive-tabs {
  display: flex;
  gap: 0.4rem;
  margin-bottom: 0.7rem;
  border-bottom: 1px solid var(--border);
}
.archive-tab {
  background: none;
  border: none;
  color: var(--muted);
  cursor: pointer;
  padding: 0.5rem 0.95rem;
  border-bottom: 2px solid transparent;
  font-size: 0.85rem;
  font-weight: 500;
  font-family: inherit;
  margin-bottom: -1px;
}
.archive-tab:hover { color: var(--text); }
.archive-tab.active {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
/* ★ save toggle on each archive row. Outline by default; filled in
   the accent color once saved so the user can scan the list for
   their bookmarks at a glance. */
.archive-save-btn {
  font-size: 1rem;
  line-height: 1;
  padding: 0.3rem 0.55rem;
}
.archive-save-btn.is-saved { color: var(--accent); }
.archive-save-btn:not(.is-saved) { color: var(--muted); }
.archive-save-btn:hover { color: var(--accent-hi, var(--accent)); }

/* Now-playing indication on archive rows. _locUpdatePlayingCard adds
   .is-playing to the row whose data-id matches the LOC bar's current
   item id (archive items play via the LOC engine). Visually mirrors
   the .queue-row.is-playing treatment: accent left stripe, tinted
   background, accent title color, and a tiny "▶" pulse to the left
   of the title. */
.archive-row.is-playing {
  background: rgba(255,255,255,0.04);
  border-left: 3px solid var(--accent);
  padding-left: calc(var(--archive-row-pad, 0.7rem) - 3px);
}
.archive-row.is-playing .archive-row-title {
  color: var(--accent);
}
.archive-row.is-playing .archive-row-title::before {
  content: "▶";
  display: inline-block;
  margin-right: 0.4em;
  color: var(--accent);
  animation: archive-row-pulse 1.4s ease-in-out infinite;
}
@keyframes archive-row-pulse {
  0%, 100% { opacity: 0.55; }
  50%      { opacity: 1; }
}

/* ── Archive item info popup ──────────────────────────────────────────
   Shares the .loc-info-overlay + .loc-info-box wrapper styling with the
   LOC popup; everything below targets the curated archive content
   (cover image, file listing, detail grid). */
.archive-info-head {
  display: flex;
  gap: 1rem;
  align-items: flex-start;
  margin-bottom: 0.9rem;
}
.archive-info-cover {
  width: 140px;
  height: 140px;
  object-fit: cover;
  border-radius: 6px;
  background: rgba(255,255,255,0.05);
  flex-shrink: 0;
}
.archive-info-cover-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2.4rem;
  color: var(--accent);
}
.archive-info-head-text { flex: 1; min-width: 0; }
.archive-info-title {
  font-size: 1.15rem;
  margin: 0 0 0.4rem;
  line-height: 1.25;
  color: var(--text);
}
.archive-info-creator {
  font-size: 0.9rem;
  color: var(--accent);
  margin-bottom: 0.3rem;
}
.archive-info-meta-line {
  font-size: 0.78rem;
  color: var(--muted);
  margin-bottom: 0.4rem;
}
.archive-info-meta-sep { color: #444; margin: 0 0.2em; }
.archive-info-rating {
  font-size: 0.8rem;
  color: var(--accent-hi, var(--accent));
  margin-bottom: 0.5rem;
}
.archive-info-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin-top: 0.5rem;
}
.archive-info-desc {
  font-size: 0.85rem;
  line-height: 1.55;
  color: var(--text);
  margin: 0.5rem 0 1rem;
  white-space: pre-wrap;
  max-height: 240px;
  overflow-y: auto;
  padding: 0.75rem;
  background: rgba(255,255,255,0.025);
  border-radius: 5px;
  border-left: 2px solid var(--accent);
}
.archive-info-section-head {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin: 0.8rem 0 0.4rem;
  font-weight: 600;
}
.archive-info-files { margin: 0.5rem 0 1rem; }
.archive-info-file-row {
  display: grid;
  grid-template-columns: auto auto 1fr auto auto;
  align-items: center;
  gap: 0.45rem;
  padding: 0.3rem 0.4rem;
  border-bottom: 1px solid rgba(255,255,255,0.04);
  font-size: 0.78rem;
}
.archive-info-file-row:last-child { border-bottom: none; }
.archive-info-file-row:hover { background: rgba(255,255,255,0.025); }
.archive-info-file-play,
.archive-info-file-queue {
  background: none;
  border: 1px solid var(--border, #2a2a2a);
  color: var(--accent);
  cursor: pointer;
  width: 26px;
  height: 26px;
  border-radius: 4px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.85rem;
  padding: 0;
}
.archive-info-file-play:hover,
.archive-info-file-queue:hover {
  border-color: var(--accent);
  background: rgba(255,255,255,0.04);
}
.archive-info-file-title {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--text);
}
.archive-info-file-dur {
  font-variant-numeric: tabular-nums;
  color: var(--muted);
  font-size: 0.72rem;
}
.archive-info-file-fmt {
  color: #555;
  font-size: 0.65rem;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
}

/* Detail grid — compact two-column layout for subjects/license/etc.
   Mirrors the .album-detail-grid pattern from the modal. */
.archive-info-detail-grid {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: 1rem;
  row-gap: 0.4rem;
  margin-top: 0.8rem;
  font-size: 0.78rem;
}
.archive-info-detail-label {
  color: var(--muted);
  font-weight: 600;
  text-transform: uppercase;
  font-size: 0.68rem;
  letter-spacing: 0.05em;
}
.archive-info-detail-val { color: var(--text); }
.archive-info-tag {
  display: inline-block;
  padding: 0.15rem 0.5rem;
  margin: 0 0.2rem 0.2rem 0;
  background: rgba(255,255,255,0.05);
  border-radius: 3px;
  font-size: 0.7rem;
  color: var(--muted);
  text-decoration: none;
}
.archive-info-tag:hover { color: var(--accent); background: rgba(255,255,255,0.1); }

@media (max-width: 600px) {
  .archive-info-head { flex-direction: column; align-items: stretch; }
  .archive-info-cover { width: 100%; height: 200px; }
}
.archive-row-date {
  font-size: 0.75rem;
  color: var(--accent-hi, var(--accent));
  margin-top: 0.15rem;
  font-variant-numeric: tabular-nums;
}
.archive-row-desc {
  font-size: 0.78rem;
  color: var(--muted);
  margin-top: 0.35rem;
  line-height: 1.45;
}
.archive-row-actions {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  flex-shrink: 0;
  align-items: flex-end;
}
.archive-btn {
  background: var(--bg);
  border: 1px solid var(--border);
  color: var(--text);
  padding: 0.35rem 0.7rem;
  border-radius: 5px;
  font-size: 0.78rem;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  font: inherit;
  font-size: 0.78rem;
  min-width: 6em;
  text-align: center;
}
.archive-btn:hover:not(.is-disabled) {
  border-color: var(--accent-hi, var(--accent));
  color: var(--accent-hi, var(--accent));
}
.archive-btn-play {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--bg);
  font-weight: 600;
}
.archive-btn-play:hover:not(.is-disabled) {
  background: var(--accent-hi, var(--accent2));
  color: var(--bg);
}
.archive-btn-play.is-disabled {
  background: none;
  color: var(--muted-dim);
  cursor: not-allowed;
}
.archive-btn-queue { color: var(--accent-hi, var(--accent)); }
.archive-btn-link  { color: var(--muted); font-size: 0.72rem; min-width: 0; }
@media (max-width: 720px) {
  .archive-row { flex-direction: column; }
  .archive-row-actions { flex-direction: row; align-items: stretch; width: 100%; }
  .archive-btn { flex: 1; min-width: 0; }
}
.loc-info-summary {
  font-size: 0.85rem;
  color: var(--text);
  font-style: italic;
  line-height: 1.5;
  padding: 0.7rem 0.85rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 5px;
  margin-bottom: 1rem;
}
.loc-info-section { margin-bottom: 1rem; }
.loc-info-section-title {
  font-size: 0.72rem;
  color: var(--accent);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 0.35rem;
}
.loc-info-list {
  list-style: disc;
  margin: 0;
  padding-left: 1.15rem;
  font-size: 0.82rem;
  color: var(--text);
  line-height: 1.5;
}
.loc-info-list li { margin-bottom: 0.15rem; }
.loc-info-list-inline {
  list-style: none;
  padding-left: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem 0.55rem;
}
.loc-info-list-inline li {
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 3px;
  padding: 0.15rem 0.5rem;
  font-size: 0.76rem;
  color: var(--muted);
  margin-bottom: 0;
}
.loc-info-article {
  font-size: 0.82rem;
  color: var(--text);
  line-height: 1.55;
  max-height: 18rem;
  overflow-y: auto;
  padding: 0.7rem 0.85rem;
  background: var(--bg);
  border: 1px solid var(--border);
  border-radius: 5px;
  white-space: pre-wrap;
}

/* ── LOC tracklist inside info popup ─────────────────────────────── */
.loc-tracklist {
  list-style: none;
  margin: 0;
  padding: 0;
  max-height: 22rem;
  overflow-y: auto;
  border: 1px solid var(--border);
  border-radius: 5px;
  background: var(--bg);
}
.loc-track-row {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.45rem 0.7rem;
  border-bottom: 1px solid var(--border-soft);
  font-size: 0.82rem;
  color: var(--text);
}
.loc-track-row:last-child { border-bottom: none; }
.loc-track-row:hover { background: var(--bg-elevated); }
.loc-track-play {
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--accent);
  font-size: 0.8rem;
  width: 1.9rem;
  height: 1.9rem;
  border-radius: 50%;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  flex-shrink: 0;
  line-height: 1;
}
.loc-track-play:hover { background: var(--accent); color: var(--surface-sunken); }
.loc-track-num {
  color: var(--muted);
  font-size: 0.72rem;
  min-width: 1.8rem;
  text-align: right;
}
.loc-track-title {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.loc-track-dur {
  color: var(--muted);
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
}

/* Clickable title link in the LOC info popup header. Same visual
   weight as the plain <div> it replaces — just gains hover underline. */
.loc-title-link {
  color: inherit;
  text-decoration: none;
}
.loc-title-link:hover {
  color: var(--accent);
  text-decoration: underline dotted;
  text-underline-offset: 3px;
  text-decoration-color: var(--muted);
}
.loc-info-title {
  display: flex;
  align-items: baseline;
  gap: 0.25rem;
  flex-wrap: wrap;
}

/* ── Speakers / participants — mirrors .album-credits layout ─────── */
.loc-speaker-credits {
  padding: 0.25rem 0;
  font-size: 0.82rem;
  line-height: 1.7;
}
/* The artist line under the title uses the same credit-name format
   as .loc-speaker-credits so multiple contributors are each clickable. */
.loc-info-artist {
  padding: 0.1rem 0 0.25rem;
  line-height: 1.6;
}
/* Use the same base credit-name color from the main search modal */
.loc-credit-name { font-size: 0.88rem; }
/* Discogs / Collection magnifying-glass icons get theme-adjacent colors
   so you can tell them apart at a glance. Hover lights them up. */
.loc-credit-discogs  { color: var(--accent-hi);  margin-left: 0.15rem; }
  { color: var(--accent-hi); }
.loc-credit-collection { color: var(--success); margin-left: 0.1rem; }
 { color: var(--accent-hi); }

/* LOC reuses the shared .saved-search-wrap / .saved-search-dropdown
   styles from the main search UI — no overrides needed. */
.loc-info-meta {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  font-size: 0.82rem;
}
.loc-info-row {
  display: grid;
  grid-template-columns: 7rem 1fr;
  gap: 0.6rem;
  padding: 0.3rem 0;
  border-bottom: 1px solid var(--border);
}
.loc-info-row:last-child { border-bottom: none; }
.loc-info-key {
  color: var(--muted);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  padding-top: 0.1rem;
}
.loc-info-val {
  color: var(--text);
  word-break: break-word;
}
.loc-info-credit {
  margin-top: 1rem;
  padding: 0.6rem 0.85rem;
  background: var(--bg);
  border: 1px dashed var(--border);
  border-radius: 5px;
}
.loc-info-credit-label {
  font-size: 0.65rem;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: 0.2rem;
}
.loc-info-credit-text {
  font-size: 0.8rem;
  color: var(--text);
  font-style: italic;
}
.loc-attribution-link {
  color: var(--accent);
  text-decoration: none;
}
.loc-attribution-link:hover { text-decoration: underline; }

@media (max-width: 640px) {
  .loc-form-grid { grid-template-columns: 1fr 1fr; gap: 0.5rem; }
  .loc-form-grid label { font-size: 0.62rem; }
  .loc-info-box { padding: 0.8rem; }
  .loc-info-head { flex-direction: column; gap: 0.7rem; padding-right: 1.5rem; }
  .loc-info-thumb { width: 100%; max-width: 200px; height: auto; aspect-ratio: 1; }
  .loc-info-title { font-size: 1.05rem; }
  .loc-info-row { grid-template-columns: 1fr; gap: 0.15rem; }
}

/* ── Wikipedia popup (stacks above other modals) ─────────────────────── */
#wiki-overlay {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.78);
  z-index: 200;       /* above #modal-overlay (100), version (140), bio-full (160) */
  align-items: center;
  justify-content: center;
  padding: 1rem;
}
#wiki-overlay.open { display: flex; }

#wiki-box {
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  max-width: 760px;
  width: 100%;
  max-height: 86vh;
  overflow-y: auto;
  position: relative;
  padding: 1.25rem 1.4rem 1.4rem;
}


.wiki-header { padding-right: 2rem; margin-bottom: 0.6rem; }
.wiki-header h2 { color: var(--accent); font-size: 1.1rem; }
.wiki-read-full,
.wiki-footer a {
  display: inline-block;
  color: var(--accent);
  text-decoration: none;
  font-size: 0.8rem;
  border-bottom: 1px dotted var(--accent-dim);
}
.wiki-read-full:hover,
.wiki-footer a:hover { color: var(--accent2); border-bottom-color: var(--accent2); }

/* Wiki popup: small subnote under the search header in the popup,
   and the "← Back to results" button on article view. */
.wiki-popup-subnote {
  font-size: 0.78rem;
  color: var(--muted);
  margin-bottom: 0.4rem;
}
.wiki-back-btn {
  display: inline-block;
  background: none;
  border: 1px solid var(--accent-dim);
  color: var(--accent);
  font-size: 0.78rem;
  padding: 0.25rem 0.6rem;
  border-radius: var(--radius);
  cursor: pointer;
  margin-bottom: 0.3rem;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.wiki-back-btn:hover {
  background: var(--accent);
  color: #1a1208;
  border-color: var(--accent);
}

.wiki-extract {
  font-size: 0.9rem;
  line-height: 1.6;
  color: var(--text);
}
.wiki-extract p { margin: 0 0 0.8rem 0; }
.wiki-extract a {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px dotted var(--accent-dim);
  cursor: pointer;
}
.wiki-extract a:hover { color: var(--accent2); border-bottom-color: var(--accent2); }
.wiki-footer { margin-top: 1rem; padding-top: 0.8rem; border-top: 1px solid var(--border); font-size: 0.82rem; }

/* ── Reusable small page indicator — shows which SPA page is active.
   Used by content pages (wiki, info, privacy, terms, loc) so the user
   sees a consistent compact label instead of a giant H1. ─────────── */
.page-eyebrow {
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  color: var(--muted);
  margin: 0 0 0.9rem 0;
  padding-bottom: 0.45rem;
  border-bottom: 1px solid var(--border);
}

/* Wikipedia SPA page — matches the LOC SPA's spacing/heading layout
   so the two browse pages feel like siblings (same .loc-header, same
   .loc-tabs). The .wiki-panel-* divs swap visibility based on tab. */
#wiki-view { padding: 1rem 0 4rem; }
.wiki-panel { margin-top: 1rem; }

/* Wikipedia SPA page results list — each row is a clickable title plus
   a snippet with Wikipedia's <span class="searchmatch"> highlighting. */
.wiki-results-list { margin-top: 1rem; }
.wiki-result {
  padding: 0.7rem 0.2rem;
  border-bottom: 1px solid var(--border);
}
.wiki-result:last-child { border-bottom: none; }
.wiki-result-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.5rem;
  margin-bottom: 0.2rem;
}
.wiki-result-head .wiki-result-title { margin-bottom: 0; }
.wiki-result-title {
  display: inline-block;
  color: var(--accent);
  font-size: 1rem;
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px dotted var(--accent-dim);
  margin-bottom: 0.2rem;
  cursor: pointer;
}
/* ★ Save toggle next to result rows + article header. Inactive is dim
   muted; saved is full accent + slight bg tint. Match the LOC star
   button visually so the two pages share a save vocabulary. */
.wiki-save-btn {
  background: none;
  border: 1px solid transparent;
  color: var(--muted-dim, #888);
  font-size: 1rem;
  line-height: 1;
  padding: 0.15rem 0.45rem;
  border-radius: 4px;
  cursor: pointer;
  flex-shrink: 0;
  transition: color 0.12s, background 0.12s, border-color 0.12s, transform 0.12s;
}
.wiki-save-btn:hover {
  color: var(--favorite);
  background: rgba(232,212,77,0.08);
  border-color: var(--border);
  transform: scale(1.05);
}
.wiki-save-btn.is-saved {
  color: var(--favorite);
  background: rgba(232,212,77,0.12);
  border-color: rgba(232,212,77,0.4);
}
.wiki-save-btn.is-saved:hover {
  color: var(--accent);
  background: rgba(255,107,53,0.08);
  border-color: rgba(255,107,53,0.4);
}
/* Title + ★ row inside the article popup header */
.wiki-article-title-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 0.6rem;
}
.wiki-article-title-row h2 { flex: 1; }
.wiki-article-title-row .wiki-save-btn {
  font-size: 1.2rem;
  padding: 0.25rem 0.55rem;
}
.wiki-result-title:hover {
  color: var(--accent2, var(--accent));
  border-bottom-color: var(--accent2, var(--accent));
}
.wiki-result-snippet {
  font-size: 0.85rem;
  color: var(--muted);
  line-height: 1.45;
}
.wiki-result-snippet .searchmatch {
  color: var(--text);
  font-weight: 600;
  background: rgba(232,160,32,0.12);
  padding: 0 2px;
  border-radius: 2px;
}
.wiki-results-loading,
.wiki-results-empty,
.wiki-results-error {
  padding: 1rem 0.2rem;
  font-size: 0.88rem;
  color: var(--muted);
}
.wiki-results-error { color: #d27a6c; }

/* Footer under the result list — counter + load-more button. */
.wiki-results-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.8rem;
  margin-top: 0.8rem;
  padding-top: 0.7rem;
  border-top: 1px solid var(--border);
  font-size: 0.82rem;
}
.wiki-results-counter { color: var(--muted); }
.wiki-results-end { color: var(--muted); font-style: italic; }
.wiki-load-more {
  background: none;
  border: 1px solid var(--accent-dim);
  color: var(--accent);
  padding: 0.35rem 0.9rem;
  border-radius: var(--radius);
  cursor: pointer;
  font-size: 0.82rem;
  transition: background 0.12s, color 0.12s, border-color 0.12s;
}
.wiki-load-more:hover:not(:disabled) {
  background: var(--accent);
  color: #1a1208;
  border-color: var(--accent);
}
.wiki-load-more:disabled { opacity: 0.5; cursor: default; }

/* Wikipedia SPA page — clean, themed search form. */
/* .wiki-search-form retired — the wiki + youtube views now use the
   shared .search-row class so their forms match the main-page
   Search bar exactly. Input + button styles come from the global
   input[type="text"|"search"] + .search-row rules. */
.wiki-search-form {
  display: flex;
  gap: 0.5rem;
  margin: 0.4rem 0 1rem 0;
  align-items: center;
}

/* Inline W icon used after every magnifying glass in popups.
   Sized relative to context so it matches the neighbouring ⌕ visually,
   uses the site beige (--text) so it sits in the line of body copy. */
.wiki-icon {
  display: inline-block;
  /* Visible breathing room between the preceding ⌕ magnifier and the W
     so the two cross-reference icons don't crowd each other. Applied
     site-wide — modal popups, track rows, credit lines, blues DB, etc. */
  margin-left: 0.35rem;
  font-family: 'Times New Roman', serif;
  font-style: italic;
  font-weight: 700;
  font-size: 0.78em;
  color: var(--text);
  text-decoration: none;
  border-bottom: none;
  line-height: 1;
  cursor: pointer;
  vertical-align: baseline;
}
 { color: var(--accent-hi); }

/* Admin-only "+ add to Blues DB" icon — sits right after the W,
   only renders for admin and only when the artist is not already
   in the DB. Small accent-coloured "+" mirroring the W's footprint. */
.blues-add-icon {
  display: inline-block;
  margin-left: 0.18rem;
  font-weight: 700;
  font-size: 0.92em;
  color: var(--accent-dim);
  text-decoration: none;
  line-height: 1;
  cursor: pointer;
  vertical-align: baseline;
  padding: 0 0.18rem;
  border: 1px solid var(--accent-dim);
  border-radius: 3px;
  transition: color 0.12s, border-color 0.12s, background 0.12s;
}
.blues-add-icon:hover {
  color: #1a1208;
  background: var(--accent);
  border-color: var(--accent);
}

/* Card variant — sits inside .card-artist (font-size 0.75rem, line-
   clamp 1). The boxed-button look from .blues-add-icon would balloon
   the line height; use a flat unboxed "+" that drops in inline. */
.card-artist .card-blues-add {
  margin: 0 0.25rem 0 0;
  padding: 0;
  border: none;
  background: transparent;
  font-size: 1.05em;
  font-weight: 700;
  color: var(--accent);
  line-height: 1;
  display: inline;
}
.card-artist .card-blues-add:hover {
  color: var(--accent2, var(--accent));
  background: transparent;
}

/* ── Blues DB admin grid: row thumb + hover popup + lightbox ─── */
.blues-row-thumb {
  width: 32px;
  height: 32px;
  object-fit: cover;
  border-radius: 4px;
  cursor: zoom-in;
  border: 1px solid var(--border);
  display: inline-block;
  vertical-align: middle;
}
.blues-row-thumb-empty {
  background: var(--surface-sunken, var(--surface));
  cursor: default;
}
.blues-row-name {
  color: var(--accent);
  text-decoration: none;
  cursor: pointer;
}
.blues-row-name:hover { text-decoration: underline; }
.blues-row-icon {
  margin-left: 0.35em;
  color: var(--accent);
  text-decoration: none;
  font-size: 1.05em;
}
.blues-row-icon.blues-row-wiki {
  color: var(--text);
  font-family: 'Times New Roman', serif;
  font-style: italic;
  font-weight: 700;
  font-size: 0.78em;
  margin-left: 0.05em;
}
.blues-row-icon:hover { color: var(--accent2, var(--accent)); }
.blues-hover-cell { cursor: help; }

#blues-hover-popup {
  display: none;
  position: absolute;
  z-index: 9000;
  max-width: 480px;
  min-width: 200px;
  background: var(--surface-raised, var(--surface));
  border: 1px solid var(--accent-dim);
  border-radius: 6px;
  padding: 0.55rem 0.7rem;
  font-size: 0.78rem;
  color: var(--text);
  box-shadow: 0 6px 24px rgba(0,0,0,0.55);
  /* Pointer events ENABLED — the cursor needs to be able to enter the
     popup to scroll long bios / release lists. Show/hide is now driven
     by tracking whether the mouse is over either the trigger or the
     popup itself (see admin.html _bluesHoverShow / _bluesHoverHide). */
  pointer-events: auto;
  line-height: 1.4;
}
.blues-hover-section { margin-bottom: 0.4rem; }
.blues-hover-section:last-child { margin-bottom: 0; }
.blues-hover-label { color: var(--accent); font-weight: 600; margin-right: 0.25em; }
.blues-hover-empty { color: var(--muted); font-style: italic; }
.blues-hover-notes {
  white-space: pre-wrap;
  border-top: 1px solid var(--border);
  padding-top: 0.4rem;
  max-height: 320px;
  overflow-y: auto;
  /* Re-enable pointer events INSIDE the popup so the user could scroll
     long bios, while the popup itself ignores mouse so it doesn't
     intercept the trigger's mouseleave. Ignored when popup is dismissed
     on mouseleave anyway, but keeps long-bio scrolling intact during
     the small grace period before hide. */
}
.blues-hover-list { list-style: none; margin: 0; padding: 0; max-height: 320px; overflow-y: auto; }
.blues-hover-list li { padding: 0.1rem 0; }
.blues-hover-year { color: var(--accent); font-weight: 600; margin-right: 0.4em; min-width: 2.5em; display: inline-block; }

/* Clickable references inside the popup — alias / collaborator names
   open a SeaDisco artist search in a new tab; release titles open the
   master/release modal in a new tab. Subtle by default, accent on hover. */
.blues-hover-link {
  color: var(--text);
  text-decoration: none;
  border-bottom: 1px dotted var(--accent-dim);
  cursor: pointer;
}
.blues-hover-link:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}
.blues-hover-list a.blues-hover-link { display: inline-block; width: 100%; }
.blues-hover-list a.blues-hover-link:hover { background: var(--bg-hover, transparent); }

.blues-image-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0,0,0,0.85);
  z-index: 9999;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: zoom-out;
  padding: 1.5rem;
}
.blues-image-overlay img {
  max-width: 90vw;
  max-height: 90vh;
  object-fit: contain;
  border-radius: 4px;
  box-shadow: 0 12px 48px rgba(0,0,0,0.7);
}

/* Bold proper-nouns inside wiki articles become clickable Discogs searches.
   Keeps the visual weight so the article still reads as Wikipedia. */
.wiki-bold-search {
  font-weight: 700;
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px dotted var(--accent-dim);
  cursor: pointer;
  transition: color 0.12s, border-color 0.12s;
}
.wiki-bold-search:hover {
  color: var(--accent2, var(--accent));
  border-bottom-color: var(--accent2, var(--accent));
}

/* Disambiguation-list entries — leading "Name (qualifier)" becomes a
   click that loads that exact Wikipedia article in the popup. */
.wiki-disambig-link {
  color: var(--accent);
  text-decoration: none;
  border-bottom: 1px dotted var(--accent-dim);
  cursor: pointer;
  transition: color 0.12s, border-color 0.12s;
}
.wiki-disambig-link:hover {
  color: var(--accent2, var(--accent));
  border-bottom-color: var(--accent2, var(--accent));
}

/* ── AI results panel (persistent, scrollable, top-X close) ──────────── */
.ai-results-panel {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
  margin: 0.75rem 0 1rem 0;
  padding: 0.85rem 1rem 0.5rem 1rem;
  max-width: 100%;
}
.ai-panel-close,
.ai-panel-min {
  position: absolute;
  top: 0.35rem;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 1.2rem;
  cursor: pointer;
  padding: 0.1rem 0.4rem;
  line-height: 1;
  border-radius: 4px;
}
.ai-panel-close { right: 0.5rem; }
.ai-panel-min   { right: 2rem; font-size: 1.1rem; }
.ai-panel-close:hover,
.ai-panel-min:hover { color: var(--text); background: var(--border); }

.ai-panel-head { padding-right: 3rem; }

/* Minimized state — collapse body to a thin clickable header bar.
   Content + ai= URL stay intact so click-to-expand restores instantly. */
.ai-results-panel.is-minimized { padding-bottom: 0.35rem; }
.ai-results-panel.is-minimized .ai-panel-head { cursor: pointer; }
.ai-results-panel.is-minimized .ai-panel-blurb,
.ai-results-panel.is-minimized .ai-panel-scroll { display: none; }
.ai-results-panel.is-minimized .ai-panel-eyebrow { margin-bottom: 0; }
.ai-panel-eyebrow {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: #888;
  margin-bottom: 0.35rem;
}
.ai-panel-blurb {
  font-size: 0.85rem;
  color: var(--muted);
  font-style: italic;
  margin-bottom: 0.6rem;
}

.ai-panel-scroll {
  max-height: 360px;
  overflow-y: auto;
  padding-right: 0.4rem;
}

.ai-row {
  padding: 0.55rem 0;
  border-bottom: 1px solid var(--border);
}
.ai-row:last-child { border-bottom: none; }
.ai-row-title { font-size: 0.95rem; font-weight: 600; color: var(--text); }
.ai-row-desc { font-size: 0.83rem; color: var(--muted); margin-top: 0.2rem; }
.ai-row-label { font-size: 0.78rem; color: var(--muted); margin-top: 0.25rem; }
.ai-row-label-tag { color: #888; margin-right: 0.3rem; font-size: 0.7rem; text-transform: uppercase; letter-spacing: 0.08em; }
.ai-entity-link { color: var(--accent); text-decoration: none; border-bottom: 1px dotted var(--accent-dim); cursor: pointer; }
.ai-entity-link:hover { color: var(--accent2); border-bottom-color: var(--accent2); }
.ai-entity-icon { margin-left: 0.15rem; }
.ai-sep { color: #555; margin: 0 0.25rem; }

/* ── Tracklist play column (always reserves space so rows align) ─────── */
#album-info .track,
#version-info .track {
  display: grid;
  grid-template-columns: 28px 2.4rem 1fr auto;
  align-items: baseline;
  gap: 0.5rem;
  padding: 0.25rem 0;
}
.track-play-cell {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  min-width: 28px;
  height: 1.2rem;
}
/* Play arrow — bare ▶ in accent colour, no orange circle background.
   Selectors scoped to album/version popups to outrank the existing
   `#album-info .track-link { color: inherit }` rule above. */
.track-play-btn,
#album-info .track-play-btn,
#version-info .track-play-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  background: transparent;
  color: var(--accent);
  text-decoration: none;
  font-size: 0.95rem;
  line-height: 1;
  transition: color 0.12s, transform 0.08s;
}
.track-play-btn:hover,
#album-info .track-play-btn:hover,
#version-info .track-play-btn:hover { color: var(--accent2, var(--accent)); transform: scale(1.1); }
/* Now-playing track in the popup tracklist uses the same theme-specific
   "off-spectrum" --catno color as catalog numbers, so the active row
   reads as a deliberate accent rather than another shade of the link
   color. Falls back to --accent2 for any theme that hasn't defined it. */
.track-play-btn.now-playing,
#album-info .track-play-btn.now-playing,
#version-info .track-play-btn.now-playing { color: var(--catno, var(--accent2)) !important; }

/* External YouTube-search fallback — sits at the end of the title row,
   after the wiki W. Only shown when no in-app playable URL exists.
   Default state is dim so the muted red doesn't shout against text;
   hover brightens it. The SVG itself uses a desaturated #8a2a22, not
   the eye-piercing pure-red #FF0000. */
.track-yt-search-end {
  display: inline-flex;
  vertical-align: middle;
  margin-left: 0.25rem;
  text-decoration: none;
  opacity: 0.65;
  transition: opacity 0.12s;
}
.track-yt-search-end:hover { opacity: 1; }
/* Per-track Library of Congress lookup icon. Sits between the W (wiki)
   and the YouTube-search rectangle so the row reads "title ⌕ W 🏛 ▭". */
.track-loc-icon {
  display: inline-block;
  font-size: 0.85em;
  margin-left: 0.2rem;
  text-decoration: none;
  opacity: 0.6;
  transition: opacity 0.12s, transform 0.12s;
  cursor: pointer;
  filter: grayscale(0.3);
}
.track-loc-icon:hover { opacity: 1; transform: translateY(-1px); filter: none; }
.track-loc-icon.is-loading { opacity: 1; animation: track-loc-pulse 1s ease-in-out infinite; }
@keyframes track-loc-pulse {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.4; }
}
/* Floating popup with multiple LOC matches per track */
.track-loc-popup {
  background: #15151a;
  border: 1px solid #2e2e2e;
  border-radius: 6px;
  box-shadow: 0 6px 24px rgba(0,0,0,0.55);
  z-index: 1100;
  font-size: 0.82rem;
  color: var(--text);
  max-height: 360px;
  overflow-y: auto;
}
.track-loc-popup-header {
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  padding: 0.45rem 0.7rem;
  border-bottom: 1px solid #2a2a2a;
  background: #0e0e12;
  position: sticky;
  top: 0;
}
.track-loc-popup-list { display: flex; flex-direction: column; }
.track-loc-popup-row {
  display: block;
  padding: 0.5rem 0.7rem;
  text-decoration: none;
  color: var(--text);
  border-bottom: 1px solid #1d1d22;
  cursor: pointer;
}
.track-loc-popup-row:last-child { border-bottom: none; }
.track-loc-popup-row:hover { background: #1d1d24; }
.track-loc-popup-title {
  font-size: 0.84rem;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.track-loc-popup-meta {
  font-size: 0.72rem;
  color: var(--muted);
  margin-top: 0.15rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Tiny toast that appears under the icon on 0-result / error responses */
.track-loc-toast {
  background: #1a1a1f;
  border: 1px solid #2e2e2e;
  border-radius: 6px;
  padding: 0.4rem 0.7rem;
  color: var(--muted);
  font-size: 0.78rem;
  z-index: 1100;
  box-shadow: 0 4px 16px rgba(0,0,0,0.5);
  pointer-events: none;
  transition: opacity 0.4s ease;
}
.track-loc-toast.fade-out { opacity: 0; }
.track-title-link {
  color: var(--text);
  text-decoration: none;
  border-bottom: 1px dotted var(--border);
  cursor: pointer;
}
 { color: var(--accent-hi); border-bottom-color: var(--accent); }
/* Force orange magnifying glass on tracks */
.track .track-search-icon,
.track-search-icon {
  color: var(--accent) !important;
  text-decoration: none;
  margin-left: 0.25rem;
  font-size: 1em;
}
.track .track-search-icon:hover,
.track-search-icon:hover { color: var(--accent2) !important; }

/* ── Site-wide default link-hover color ───────────────────────────────
   Generic <a> hovers pick up the theme's highlight (--accent-hi). Any
   element with its own explicit :hover rule keeps it — selector
   specificity ensures things like .album-title-search:hover or
   .wiki-icon:hover override this default. */
a:hover,
a:focus-visible {
  color: var(--accent-hi, var(--accent));
}

/* Persistent corner chip shown only when an admin has flipped the
   "view as user" toggle in /admin → Theme. Click to restore. */
#admin-as-user-chip {
  position: fixed;
  bottom: 1rem;
  right: 1rem;
  z-index: 5000;
  background: var(--surface);
  color: var(--accent-hi, var(--accent));
  border: 1px solid var(--accent-hi, var(--accent));
  padding: 0.4rem 0.7rem;
  border-radius: 999px;
  font-size: 0.72rem;
  font-weight: 600;
  cursor: pointer;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.4);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  transition: background 0.12s, color 0.12s, transform 0.12s;
}
#admin-as-user-chip:hover {
  background: var(--accent-hi, var(--accent));
  color: var(--bg);
  transform: translateY(-1px);
}

/* ── YouTube popup overlay (small modal launched from album / version
   popups so users don't lose context). Layered above the modal-overlay
   z-index so it sits on top of any open Discogs popup. */
#youtube-popup-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 1100;
  background: rgba(0, 0, 0, 0.65);
  align-items: center;
  justify-content: center;
  padding: 1.5rem;
}
#youtube-popup-overlay.open { display: flex; }
#youtube-popup-box {
  position: relative;
  width: min(720px, calc(100vw - 2rem));
  max-height: calc(100vh - 3rem);
  background: var(--bg-elev, var(--bg, #15120e));
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 8px;
  box-shadow: 0 12px 48px rgba(0, 0, 0, 0.7);
  padding: 1rem;
  overflow-y: auto;
}
.youtube-popup-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-right: 2rem; /* leave room for the × close button */
}
.youtube-popup-head-actions {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  flex-wrap: wrap;
}
#youtube-popup-loosen {
  font-size: 0.72rem;
  color: var(--muted);
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 4px;
  padding: 0.2rem 0.5rem;
  cursor: pointer;
  letter-spacing: 0.02em;
}
#youtube-popup-loosen:hover { color: var(--text); background: rgba(255, 255, 255, 0.1); }
#youtube-popup-overlay .loc-info-close {
  position: absolute;
  top: 0.4rem;
  right: 0.5rem;
  background: none;
  border: none;
  color: var(--muted);
  font-size: 1.4rem;
  cursor: pointer;
  line-height: 1;
}
#youtube-popup-overlay .loc-info-close:hover { color: var(--text); }
#youtube-popup-fullpage:hover { color: var(--accent) !important; }

/* Album-mode context strip — cover thumb + artist / title / year /
   label. Sits between the popup header and the search status so the
   user always sees which album they're submitting for, even on mobile
   where the underlying album modal is fully obscured. */
.youtube-popup-album-ctx {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.5rem 0.65rem;
  margin: 0.35rem 0 0.4rem;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 6px;
}
.youtube-popup-album-ctx img {
  width: 56px;
  height: 56px;
  object-fit: cover;
  border-radius: 4px;
  flex-shrink: 0;
  background: rgba(255, 255, 255, 0.05);
}
.youtube-popup-album-meta {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0.1rem;
}
.youtube-popup-album-artist {
  font-size: 0.78rem;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.youtube-popup-album-title {
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.youtube-popup-album-sub {
  font-size: 0.72rem;
  color: #888;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Album-mode admin "Add by URL" form. Lets admin paste a known YT URL
   instead of paying the 100-unit search.list cost — useful any time
   they already know the video, and essential when daily quota's gone. */
.youtube-popup-paste {
  margin: 0.4rem 0 0.55rem;
  padding: 0.5rem 0.65rem;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 6px;
}
.youtube-popup-paste-head {
  font-size: 0.74rem;
  color: var(--muted);
  margin-bottom: 0.35rem;
  letter-spacing: 0.02em;
}
.youtube-popup-paste-head .muted { color: #666; font-size: 0.68rem; }
.youtube-popup-paste-row {
  display: flex;
  gap: 0.4rem;
  align-items: center;
  flex-wrap: wrap;
}
#youtube-popup-paste-url {
  flex: 1 1 240px;
  min-width: 200px;
  background: rgba(0, 0, 0, 0.35);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 4px;
  padding: 0.32rem 0.45rem;
  color: var(--text);
  font-size: 0.78rem;
  font-family: inherit;
}
#youtube-popup-paste-track { font-size: 0.78rem; }
.youtube-popup-paste-status {
  font-size: 0.72rem;
  color: var(--muted);
  margin-top: 0.3rem;
  min-height: 1em;
}

/* ── YouTube view list ────────────────────────────────────────────────
   Each result is a flex row: thumbnail · title/channel/desc · actions.
   Reuses .archive-row / .archive-btn rules where possible so the
   look matches the LOC / Archive Saved tabs. */
.youtube-results-list { display: flex; flex-direction: column; gap: 0.5rem; }
.yt-row {
  display: flex;
  gap: 0.7rem;
  align-items: flex-start;
  padding: 0.55rem 0.7rem;
}
.yt-row-thumb-wrap {
  position: relative;
  flex-shrink: 0;
  display: inline-block;
  line-height: 0;
}
.yt-row-thumb {
  width: 160px;
  height: 90px;
  object-fit: cover;
  border-radius: 5px;
  flex-shrink: 0;
  background: rgba(255,255,255,0.05);
}
.yt-row-duration {
  position: absolute;
  right: 4px;
  bottom: 4px;
  background: rgba(0, 0, 0, 0.78);
  color: #fff;
  font-size: 0.72rem;
  font-weight: 600;
  padding: 1px 5px;
  border-radius: 3px;
  line-height: 1.2;
  pointer-events: none;
  letter-spacing: 0.02em;
}
.yt-row .archive-row-actions { flex-direction: column; align-items: flex-end; gap: 0.35rem; }
.yt-save-btn { font-size: 1rem; line-height: 1; padding: 0.3rem 0.55rem; }
.yt-save-btn.is-saved { color: var(--accent); }
.yt-save-btn:not(.is-saved) { color: var(--muted); }
.yt-save-btn:hover { color: var(--accent-hi, var(--accent)); }
@media (max-width: 600px) {
  .yt-row { flex-direction: column; }
  .yt-row-thumb-wrap { width: 100%; }
  .yt-row-thumb { width: 100%; height: auto; aspect-ratio: 16 / 9; }
  .yt-row .archive-row-actions { flex-direction: row; align-items: center; justify-content: flex-start; flex-wrap: wrap; }
}

/* ── Unified entity-lookup popup ───────────────────────────────────────
   Floating menu that opens when a track-title or artist-name link is
   clicked. Positioned by JS at the click point, clamped to viewport.
   Replaces the inline cluster of W / 🏛 / 📺 icons that used to hang
   next to every entity link. */
.entity-lookup-link {
  color: inherit;
  text-decoration: underline dotted;
  text-decoration-color: rgba(255, 255, 255, 0.25);
  text-underline-offset: 2px;
  cursor: pointer;
}
.entity-lookup-link:hover { color: var(--accent); text-decoration-color: var(--accent); }
.lookup-popup {
  position: fixed;
  z-index: 9999;
  background: var(--bg-elev, #1a1a1a);
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 6px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.55);
  padding: 0.4rem 0;
  font-size: 0.78rem;
  width: 240px;
}
.lookup-popup-head {
  padding: 0.2rem 0.7rem 0.35rem;
  margin-bottom: 0.25rem;
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  color: #aaa;
  font-size: 0.7rem;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.lookup-popup-list { display: flex; flex-direction: column; }
.lookup-popup-btn {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 0.6rem;
  width: 100%;
  background: none;
  border: none;
  color: #ddd;
  cursor: pointer;
  padding: 0.4rem 0.7rem;
  font-size: 0.78rem;
  text-align: left;
  text-decoration: none;
  font-family: inherit;
  white-space: nowrap;
}
.lookup-popup-btn:hover { background: rgba(255, 255, 255, 0.08); color: #fff; }
/* Icon column has a fixed width so the text labels line up vertically
   regardless of glyph variation (emoji widths differ per OS).
   `overflow:hidden` clips wide emoji to the column so they can't push
   the text right. */
.lookup-popup-icon {
  display: inline-flex;
  flex: 0 0 1.3rem;
  width: 1.3rem;
  justify-content: center;
  align-items: center;
  font-size: 0.85rem;
  color: var(--accent);
  overflow: hidden;
}
/* SVG icon variant — used by the SeaDisco search / Collection rows so
   they reuse the navbar's vinyl line-art set. Forced white (the nav
   tints them per-tab, here we want a plain monochrome icon) and
   sized to fill the icon column. */
.lookup-popup-icon .lookup-popup-icon-svg {
  display: inline-flex;
  width: 1.05rem;
  height: 1.05rem;
  color: #fff;
}
.lookup-popup-icon .lookup-popup-icon-svg svg {
  width: 100%;
  height: 100%;
  stroke: #fff;
}
/* Visual separator between in-app actions and external links. */
.lookup-popup-sep {
  height: 1px;
  background: rgba(255, 255, 255, 0.08);
  margin: 0.35rem 0.7rem;
}
/* ↗ glyph after the label on external-link rows so users can tell
   at a glance which options leave the site. Pushed to the right
   edge with margin-left:auto. */
.lookup-popup-external .lookup-popup-ext-indicator {
  margin-left: auto;
  color: rgba(255, 255, 255, 0.35);
  font-size: 0.75rem;
}
.lookup-popup-external:hover .lookup-popup-ext-indicator {
  color: rgba(255, 255, 255, 0.7);
}
