/* Universe — a media library that should feel like one.
   Dark by default; a media dashboard lives in the dark. Poster-forward, with
   real hierarchy: one confident accent, layered surfaces, and enough air that
   the eye lands somewhere on purpose rather than drowning in a grey table. */

/* PETROL — a deep, desaturated teal on cool ink.
   The neutrals carry the app and stay near-neutral so the posters own the
   colour; the accent appears only for interaction and identity, never as a fill
   inside the grid. The four states are held perceptually apart from it and from
   each other: have is a quiet green (it is most of the library, so it must not
   shout), wanted a violet, downloading the accent itself, failed a coral. */

:root {
  --bg:        #0a0c0d;
  --bg-2:      #0c1011;
  --surface:   #14181a;
  --surface-2: #1a2023;
  --elevated:  #232b2e;
  --line:      #293236;
  --line-soft: rgba(255,255,255,.055);

  --text:  #eaf0f1;
  --muted: #93a0a2;
  --dim:   #5e6b6e;

  --accent:      #3fa7b0;
  --accent-soft: color-mix(in srgb, var(--accent) 16%, transparent);
  --accent-line: color-mix(in srgb, var(--accent) 42%, transparent);
  --on-accent:   #06242a;

  --good: #5fbf8c;
  --warn: #e6b45c;
  --bad:  #f2726a;
  --want: #b49bff;

  --radius:   12px;
  --radius-s: 8px;
  --shadow:   0 1px 2px rgba(0,0,0,.45), 0 8px 24px -12px rgba(0,0,0,.6);
  --shadow-lift: 0 2px 6px rgba(0,0,0,.45), 0 20px 40px -16px rgba(0,0,0,.72);
}

@media (prefers-color-scheme: light) {
  :root {
    --bg: #eef3f3; --bg-2: #e6eded; --surface: #ffffff; --surface-2: #f2f6f6;
    --elevated: #ffffff; --line: #dbe4e5; --line-soft: rgba(15,35,40,.07);
    --text: #0f1719; --muted: #556366; --dim: #869599;
    --accent: #1f7d87; --accent-soft: color-mix(in srgb, var(--accent) 12%, transparent);
    --accent-line: color-mix(in srgb, var(--accent) 38%, transparent);
    --on-accent: #ffffff;
    --good: #1c8f5c; --warn: #986713; --bad: #cf3b31; --want: #6b46c9;
    --shadow: 0 1px 2px rgba(15,35,40,.08), 0 10px 30px -14px rgba(15,35,40,.2);
    --shadow-lift: 0 2px 8px rgba(15,35,40,.12), 0 24px 44px -18px rgba(15,35,40,.28);
  }
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background:
    radial-gradient(1200px 600px at 78% -10%, color-mix(in srgb, var(--accent) 10%, transparent), transparent 60%),
    var(--bg);
  color: var(--text);
  font: 14.5px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI", Inter, system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  min-height: 100vh;
}

::selection { background: var(--accent-soft); }

a { color: inherit; }

/* ---------------------------------------------------------------- nav

   Collapsible side rail. Resting width is a slim strip of icons
   (RAIL_W) so every page stays one click away without a hamburger to
   hunt for; the small button at the top expands the rail into a full
   drawer (DRAW_W) laid over the page so labels are readable when the
   operator wants them. ESC, the backdrop, or clicking a nav link snaps
   it back to icons.

   Both states are one element — .side is always position:fixed and its
   width animates — so main content never reflows when the drawer
   opens.

   --rail-w keeps main's left padding in sync with the rail width;
   change it here and layout follows. */

:root { --rail-w: 60px; --drawer-w: 232px; }

.nav-backdrop {
  position: fixed; inset: 0;
  background: rgba(0, 0, 0, .5);
  opacity: 0; pointer-events: none;
  transition: opacity .18s ease;
  z-index: 45;
}
body.nav-open .nav-backdrop { opacity: 1; pointer-events: auto; }

.side {
  position: fixed;
  top: 0; left: 0; bottom: 0;
  width: var(--rail-w);
  padding: 10px 8px;
  border-right: 1px solid var(--line-soft);
  background: linear-gradient(180deg, var(--bg-2), var(--bg));
  overflow: hidden;
  transition: width .2s ease, padding .2s ease, box-shadow .2s ease;
  z-index: 50;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
body.nav-open .side {
  width: var(--drawer-w);
  padding: 10px 12px;
  box-shadow: 6px 0 30px rgba(0, 0, 0, .4);
  overflow-y: auto;
}

/* Head row: brand button (identity + toggle in one) plus a close X
   that appears only when the drawer is open. In the collapsed rail
   the brand button is a bare 44×44 tile centered on the mark; in the
   open drawer it stretches to fit "Universe" and the X slides in on
   the right. */
.side-head {
  display: flex;
  align-items: center;
  gap: 6px;
  padding-bottom: 8px;
  flex: none;
}
.brand-btn {
  display: flex;
  align-items: center;
  gap: 10px;
  height: 44px;
  min-width: 44px;
  padding: 0 8px;
  background: transparent;
  color: var(--text);
  border: 1px solid transparent;
  border-radius: 10px;
  cursor: pointer;
  font: inherit;
  font-weight: 650;
  font-size: 15px;
  letter-spacing: -.01em;
  white-space: nowrap;
  flex: 1 1 auto;
  overflow: hidden;
}
.brand-btn:hover { background: var(--surface); }
.brand-btn .mark {
  width: 28px; height: 28px; flex: none;
  display: grid; place-items: center;
  border-radius: 8px;
  color: var(--on-accent);
  background: linear-gradient(140deg, color-mix(in srgb, var(--accent) 78%, #8fe0dc), color-mix(in srgb, var(--accent) 70%, #05343c));
  box-shadow: 0 4px 12px -4px var(--accent);
}
.brand-btn .mark svg { width: 15px; height: 15px; }

.side-close {
  width: 36px; height: 36px;
  display: none;
  place-items: center;
  background: transparent;
  color: var(--muted);
  border: 1px solid transparent;
  border-radius: 9px;
  cursor: pointer;
  flex: none;
}
.side-close:hover { color: var(--text); background: var(--surface); }
.side-close svg { width: 16px; height: 16px; }
body.nav-open .side-close { display: grid; }

/* Nav items live in the rail as centered 44×44 icon buttons and
   stretch into full-width label rows when the drawer opens. Both
   layouts use the same flex container; only the label's opacity and
   the row padding animate, so switching states never re-flows the
   icons. */
.side a.nav {
  display: flex;
  align-items: center;
  gap: 12px;
  height: 44px;
  padding: 0 12px;
  border-radius: 10px;
  color: var(--muted);
  text-decoration: none;
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  transition: background .12s ease, color .12s ease;
  flex: none;
}
.side a.nav svg { width: 20px; height: 20px; flex: none; opacity: .85; }
.side a.nav:hover { background: var(--surface); color: var(--text); }
.side a.nav.on {
  background: var(--accent-soft);
  color: var(--text);
  box-shadow: inset 0 0 0 1px var(--accent-line);
}
.side a.nav.on svg { color: var(--accent); opacity: 1; }

/* Labels + brand text + foot line hide behind the rail's clip when
   collapsed and fade in with the drawer. Opacity is decoupled from
   width so the labels don't smear during the width animation. */
.side .label, .side-foot {
  opacity: 0;
  transition: opacity .1s ease;
}
body.nav-open .side .label,
body.nav-open .side-foot { opacity: 1; transition-delay: .08s; }

.side-foot {
  margin-top: auto;
  color: var(--dim);
  font-size: 11.5px;
  padding: 12px 8px 4px;
  line-height: 1.4;
}

/* ---------------------------------------------------------------- layout */

main {
  min-width: 0;
  /* Leaves the rail (var(--rail-w)) plus a comfortable gutter. */
  padding: 30px 38px 80px calc(var(--rail-w) + 22px);
  max-width: calc(1640px + var(--rail-w));
}

.head { margin-bottom: 26px; }
.head h1 {
  font-size: 26px; font-weight: 680; letter-spacing: -.02em;
  margin: 0 0 5px;
}
.head .sub { margin: 0; color: var(--muted); max-width: 74ch; }
.back {
  display: inline-block; color: var(--muted);
  text-decoration: none; font-size: 13px; margin-bottom: 10px;
}
.back:hover { color: var(--accent); }

.panel {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  margin-bottom: 20px;
  overflow: hidden;
  box-shadow: var(--shadow);
}

.panel-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 15px 18px;
  border-bottom: 1px solid var(--line-soft);
}
.panel-head h2 { font-size: 14px; font-weight: 620; margin: 0; letter-spacing: -.01em; }
.hint { color: var(--dim); font-size: 12px; margin-left: auto; }

.empty { color: var(--muted); padding: 20px 18px; margin: 0; }
.note  { color: var(--muted); padding: 0 18px 15px; margin: 10px 0 0; max-width: 80ch; }

/* Page-level tab strip — used on Sources to switch between Indexers and
   Servers instead of stacking them. Sits above the panel it selects, is
   flush with the panel's top edge, and looks like a set of file-folder
   tabs so it reads as "which one am I viewing" rather than as buttons. */
.tabbar {
  display: flex;
  gap: 4px;
  margin: 0 0 -1px 4px;
  position: relative;
  z-index: 1;
}
.tab-link {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 16px 10px;
  font-size: 13px; font-weight: 550; color: var(--muted);
  text-decoration: none;
  background: var(--bg-2);
  border: 1px solid var(--line-soft);
  border-bottom: none;
  border-radius: 10px 10px 0 0;
  cursor: pointer;
}
.tab-link:hover { color: var(--text); }
.tab-link.on {
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 -1px 0 var(--accent) inset;
}
.tab-link .count {
  font-variant-numeric: tabular-nums;
  color: var(--dim); font-weight: 500;
  padding: 1px 6px; border-radius: 8px; background: var(--line-soft);
  font-size: 12px;
}
.tab-link.on .count { color: var(--accent); background: var(--accent-soft); }
.tab-link.recovery-tab .count.has-items {
  color: var(--warn);
  background: color-mix(in srgb, var(--warn) 13%, transparent);
}
.tab-link.recovery-tab.on .count.has-items {
  color: var(--warn);
  background: color-mix(in srgb, var(--warn) 18%, transparent);
}
.tab-panel[hidden] { display: none; }

/* Recovery is an action queue, not another history table. Each physical
   payload gets one composed row with its identity, disk cost, and the three
   mutually clear outcomes: process, refetch, or discard. */
.recovery-head { align-items: center; }
.recovery-head > div:first-child { display: grid; gap: 3px; }
.recovery-head .hint { margin-left: 0; }
.recovery-total {
  margin-left: auto;
  display: inline-flex; align-items: baseline; gap: 5px;
  color: var(--muted); font-size: 12px;
  padding: 6px 10px; border: 1px solid var(--line-soft); border-radius: 8px;
  background: var(--bg-2);
}
.recovery-total b { color: var(--text); font-size: 13px; }
.recovery-section-head {
  display: flex; align-items: center;
  padding: 13px 18px 9px;
  border-bottom: 1px solid var(--line-soft);
  background: color-mix(in srgb, var(--surface) 92%, var(--warn));
}
.recovery-section-head.orphan-head { border-top: 1px solid var(--line); }
.recovery-section-head > div { display: grid; gap: 2px; }
.recovery-section-head strong { font-size: 12.5px; font-weight: 650; }
.recovery-section-head span { color: var(--muted); font-size: 11.5px; }
.recovery-list { display: grid; }
.recovery-row {
  display: grid;
  grid-template-columns: minmax(280px, 1fr) 105px minmax(325px, auto);
  gap: 18px; align-items: center;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line-soft);
}
.recovery-row:last-child { border-bottom: 0; }
.recovery-row:hover { background: color-mix(in srgb, var(--elevated) 48%, transparent); }
.recovery-main { min-width: 0; display: grid; gap: 5px; }
.recovery-title-line { display: flex; align-items: center; flex-wrap: wrap; gap: 7px; }
.recovery-title { color: var(--text); font-size: 13.5px; font-weight: 620; text-decoration: none; }
a.recovery-title:hover { color: var(--accent); }
.recovery-release {
  color: var(--muted); font-size: 11.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.recovery-detail { color: var(--bad); font-size: 11.5px; line-height: 1.35; }
.recovery-size { display: grid; justify-items: end; gap: 2px; font-variant-numeric: tabular-nums; }
.recovery-size b { font-size: 13px; color: var(--text); }
.recovery-size span { font-size: 11px; color: var(--dim); }
.recovery-actions { display: flex; justify-content: flex-end; align-items: center; flex-wrap: wrap; gap: 6px; }
.pill.recovery-ready { color: var(--good); }
.pill.recovery-partial { color: var(--warn); }
.recovery-empty { min-height: 120px; justify-content: center; }

@media (max-width: 940px) {
  .recovery-row { grid-template-columns: minmax(220px, 1fr) 90px; }
  .recovery-actions { grid-column: 1 / -1; justify-content: flex-start; }
}

.flash, .msg-panel { }

/* ---------------------------------------------------------------- stats */

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(184px, 1fr));
  gap: 12px;
  margin-bottom: 24px;
}

.stat {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: 16px 17px;
  overflow: hidden;
  box-shadow: var(--shadow);
}
.stat::before {
  content: ""; position: absolute; left: 0; top: 14px; bottom: 14px; width: 3px;
  border-radius: 3px; background: var(--accent); opacity: .55;
}
.stat.total::before { background: var(--good); }
.stat.total { background: linear-gradient(180deg, var(--surface-2), var(--surface)); }
.stat-k { color: var(--muted); font-size: 12px; font-weight: 500; text-transform: capitalize; letter-spacing: .01em; }
.stat-v { font-size: 30px; font-weight: 700; letter-spacing: -.03em; margin: 3px 0 1px; font-variant-numeric: tabular-nums; }
.stat-m { color: var(--dim); font-size: 12px; }
.stat-w { color: var(--want); font-size: 12px; margin-top: 4px; font-weight: 500; }

/* ---------------------------------------------------------------- tables */

table.rows { width: 100%; border-collapse: collapse; }

.rows th {
  text-align: left;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--dim);
  padding: 11px 18px;
  border-bottom: 1px solid var(--line-soft);
}

.rows td {
  padding: 11px 18px;
  border-bottom: 1px solid var(--line-soft);
  vertical-align: middle;
}
.rows tr:last-child td { border-bottom: none; }
.rows tbody tr { transition: background .1s ease; }
.rows tbody tr:hover { background: var(--surface-2); }
.rows tr.off, .rows tr.quiet { opacity: .5; }

.rows a { color: var(--text); text-decoration: none; font-weight: 500; }
.rows a:hover { color: var(--accent); }

.num   { text-align: right; font-variant-numeric: tabular-nums; }
.mono  { font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace; font-size: 12px; }
.muted { color: var(--muted); }
.small { font-size: 12px; }
.sub2  { color: var(--dim); font-size: 12px; margin-top: 1px; }

.w-item  { width: 210px; font-weight: 500; }
.w-state { width: 104px; }
.w-size  { width: 92px; }
.w-when  { width: 150px; font-size: 12px; color: var(--muted); }
.w-bar   { width: 150px; }
.w-title { min-width: 240px; font-weight: 500; }
.w-ref   { width: 74px; color: var(--muted); }
.w-pname { }
.w-why   { width: 44px; text-align: right; }
.w-stage { width: 100px; }
.w-rel   { color: var(--muted); max-width: 0; overflow: hidden;
           text-overflow: ellipsis; white-space: nowrap; }

tr.detail td { color: var(--muted); font-size: 12px; padding-top: 0;
               border-bottom: 1px solid var(--line-soft); }
tr.detail    { background: transparent; }
tr.bad td, .bad-text { color: var(--bad); }
tr.empty-row td { color: var(--muted); padding: 20px 18px; }
tr.wanting .w-ref { color: var(--want); }
.neg { color: var(--bad); }

/* ---------------------------------------------------------------- library: poster grid */

.lib-bar {
  display: flex; align-items: center; gap: 14px; flex-wrap: wrap;
  margin-bottom: 20px;
}
.lib-bar .filters { flex: 1; margin: 0; min-width: 260px; }

.view-toggle { display: inline-flex; gap: 2px; padding: 3px; border-radius: 10px;
  background: var(--surface); border: 1px solid var(--line-soft); }
.view-toggle a {
  display: grid; place-items: center; width: 34px; height: 30px;
  border-radius: 7px; color: var(--muted); text-decoration: none;
}
.view-toggle a svg { width: 16px; height: 16px; }
.view-toggle a:hover { color: var(--text); }
.view-toggle a.on { background: var(--accent-soft); color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent-line); }

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(158px, 1fr));
  gap: 20px 18px;
}

.card { text-decoration: none; color: inherit; display: block; }
.card .poster {
  position: relative;
  aspect-ratio: 2 / 3;
  border-radius: var(--radius-s);
  overflow: hidden;
  background: linear-gradient(160deg, var(--surface-2), var(--surface));
  box-shadow: var(--shadow);
  transition: transform .16s ease, box-shadow .16s ease;
}
.card.k-music .poster { aspect-ratio: 1 / 1; }
.card .poster img { width: 100%; height: 100%; object-fit: cover; display: block; }
.card:hover .poster { transform: translateY(-4px); box-shadow: var(--shadow-lift); }
.card:hover .poster::after {
  content: ""; position: absolute; inset: 0; border-radius: var(--radius-s);
  box-shadow: inset 0 0 0 2px var(--accent-line);
}

.card .cover-none {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  padding: 12px; text-align: center;
  font-size: 13px; font-weight: 600; line-height: 1.25; color: var(--muted);
}

/* Status corner: a wanted count, or a quiet tick when complete. */
.card .badge {
  position: absolute; top: 8px; right: 8px;
  min-width: 20px; height: 20px; padding: 0 6px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 11.5px; font-weight: 700; border-radius: 999px;
  color: #fff; background: var(--want);
  box-shadow: 0 2px 8px -2px rgba(0,0,0,.6);
}
.card .badge.done { background: color-mix(in srgb, var(--good) 90%, black); }
.card .badge.flight { background: var(--accent); }
.card .cap { padding: 9px 2px 0; }
.card .cap-title {
  font-size: 13px; font-weight: 560; line-height: 1.3;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.card:hover .cap-title { color: var(--accent); }
.card .cap-sub { color: var(--dim); font-size: 12px; margin-top: 2px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.lib-foot { margin-top: 26px; color: var(--dim); font-size: 12.5px; }

/* Cover thumbnail inside the list view. */
.w-cover { width: 38px; padding-right: 0; }
.cover {
  display: block; width: 38px; height: 57px; border-radius: 5px;
  overflow: hidden; background: var(--surface-2); box-shadow: var(--shadow);
}
.cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cover-none {
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: 100%;
  font-size: 8px; letter-spacing: .03em; text-transform: uppercase;
  color: var(--dim); text-align: center; line-height: 1.1; padding: 2px;
}

/* ---------------------------------------------------------------- pills */

.pill {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 11.5px; font-weight: 550;
  border: 1px solid var(--line);
  background: var(--surface-2);
  color: var(--muted);
  white-space: nowrap;
}
.pill::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: currentColor; opacity: .8; }
.pill.def::before, .pill.plain::before { display: none; }
.pill.done, .pill.have, .pill.grabbed { color: var(--good); border-color: color-mix(in srgb, var(--good) 32%, transparent); background: color-mix(in srgb, var(--good) 10%, transparent); }
.pill.failed, .pill.rejected          { color: var(--bad);  border-color: color-mix(in srgb, var(--bad) 32%, transparent);  background: color-mix(in srgb, var(--bad) 10%, transparent); }
.pill.wanted                          { color: var(--want); border-color: color-mix(in srgb, var(--want) 32%, transparent); background: color-mix(in srgb, var(--want) 10%, transparent); }
.pill.fetching, .pill.unpacking,
.pill.importing, .pill.verifying      { color: var(--accent); border-color: var(--accent-line); background: var(--accent-soft); }
.pill.def { color: var(--accent); font-size: 10.5px; vertical-align: middle; border-color: var(--accent-line); background: var(--accent-soft); }

.ok   { color: var(--good); }
.warn { color: var(--warn); }
.want { color: var(--want); }

/* ---------------------------------------------------------------- bars */

.bar {
  height: 6px;
  background: var(--surface-2);
  border-radius: 4px;
  overflow: hidden;
  min-width: 60px;
  display: inline-block;
  width: 100%;
  vertical-align: middle;
}
.bar i { display: block; height: 100%;
  background: linear-gradient(90deg, var(--accent), color-mix(in srgb, var(--accent) 55%, #8fe0dc));
  border-radius: 4px; transition: width .3s ease; }

/* ---------------------------------------------------------------- filters / chips */

.filters { margin-bottom: 16px; }
.filters input[type=search] {
  width: 100%;
  max-width: 460px;
  padding: 10px 14px;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--text);
  font-size: 14px;
}
.filters input[type=search]::placeholder { color: var(--dim); }
.filters input:focus { outline: none; border-color: var(--accent-line);
  box-shadow: 0 0 0 3px var(--accent-soft); }

.chips { display: flex; flex-wrap: wrap; gap: 7px; }
.chip {
  padding: 6px 13px;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--surface);
  color: var(--muted);
  text-decoration: none;
  font-size: 13px; font-weight: 500;
  transition: color .1s ease, border-color .1s ease, background .1s ease;
}
.chip:hover { color: var(--text); border-color: var(--line); }
.chip.on { background: var(--accent-soft); color: var(--accent); border-color: var(--accent-line); }

/* ---------------------------------------------------------------- forms */

.addform { border-top: 1px solid var(--line-soft); padding: 16px 18px 8px;
  display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; align-items: end; }
.addform label { display: block; font-size: 12px; color: var(--muted); font-weight: 500; }
.addform input, .addform select {
  width: 100%; margin-top: 5px;
  padding: 8px 11px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--bg-2); color: var(--text); font-size: 13.5px;
}
.addform input:focus, .addform select:focus { outline: none; border-color: var(--accent-line);
  box-shadow: 0 0 0 3px var(--accent-soft); }
.addform .check { display: flex; align-items: center; gap: 8px; margin-bottom: 12px; }
.addform .check input { width: auto; margin: 0; }
.addform label.wide { grid-column: 1 / -1; }
.addform .actions, .addform button[type=submit], .addform button { align-self: end; }

.row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; grid-column: 1 / -1; }

button, .btn {
  padding: 8px 15px; border-radius: 9px; cursor: pointer;
  border: 1px solid var(--line); background: var(--surface-2); color: var(--text);
  font-size: 13.5px; font-weight: 550; font-family: inherit;
  transition: background .12s ease, border-color .12s ease, transform .05s ease;
}
button:hover, .btn:hover { background: var(--elevated); border-color: var(--accent-line); }
button:active, .btn:active { transform: translateY(1px); }
.btn.primary, button.primary { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }
.btn.primary:hover, button.primary:hover { background: color-mix(in srgb, var(--accent) 88%, #fff); }
.mini { padding: 5px 11px; font-size: 12.5px; border-radius: 8px; }
.mini.danger, .btn.danger, button.danger { color: var(--bad); }
/* The "process N on disk" reprocess button — green because it's the
   one action on a failed row that costs nothing to try. */
.mini.good { color: var(--good); }
.mini.good:hover { border-color: var(--good); background: color-mix(in srgb, var(--good) 12%, transparent); }
.mini.danger:hover { border-color: var(--bad); background: color-mix(in srgb, var(--bad) 12%, transparent); }
.mini.armed, .btn.armed {
  background: color-mix(in srgb, var(--bad) 20%, transparent);
  border-color: var(--bad); color: var(--bad);
}
.mini.danger { min-width: 84px; text-align: center; }
/* An anchor styled to sit next to <button class="mini"> without looking
   like a hyperlink — same padding, same border, same hover, so a row of
   actions reads uniformly whether each control is a form or a link. */
a.mini { display: inline-block; text-decoration: none; color: inherit; }
a.mini:hover { color: inherit; }
a.mini.btn-link { border: 1px solid var(--line); background: var(--surface-2); }
a.mini.btn-link:hover { background: var(--elevated); border-color: var(--accent-line); }

form.inline { display: inline-flex; align-items: center; gap: 6px; }
form.inline input.score {
  width: 74px; text-align: right; font-variant-numeric: tabular-nums;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 7px;
  color: var(--text); padding: 4px 7px; font-size: 12.5px;
}
form.inline input.score:focus { outline: none; border-color: var(--accent-line); }
button.link { background: none; border: none; padding: 0; cursor: pointer; color: var(--muted); font-size: 12px; }
button.link:hover { color: var(--accent); }
button.link.danger:hover { color: var(--bad); }

/* ---------------------------------------------------------------- sources */

.source { border-bottom: 1px solid var(--line-soft); }
.source:last-child { border-bottom: none; }
.source.off { opacity: .55; }
.source-head { display: flex; align-items: center; gap: 12px; padding: 14px 18px; flex-wrap: wrap; }
.source-name { font-weight: 600; }
.provider-source-head {
  display: grid;
  grid-template-columns: minmax(210px, 1fr) minmax(245px, auto) auto;
  gap: 18px;
  align-items: center;
}
.provider-identity { display: grid; gap: 3px; min-width: 0; }
.provider-endpoint { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.provider-account { display: grid; justify-items: end; gap: 5px; min-width: 0; }
.provider-order { white-space: nowrap; }
.provider-credential { display: inline-flex; align-items: center; gap: 5px; }
.provider-username {
  max-width: 190px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--text);
}
.provider-password { max-width: min(34vw, 360px); overflow-wrap: anywhere; }
.credential-reveal { margin-left: 2px; }
.provider-row-actions { display: flex; flex-wrap: nowrap; gap: 7px; justify-content: flex-end; }
.grow { flex: 1; }
.source-error { margin: 0; padding: 0 18px 13px; color: var(--bad); font-size: 12.5px; }
/* Second-row account/server info for an indexer: username, retention,
   lifetime grabs, plan cap. Reads as a subtitle to the source-head. */
.source-status {
  display: flex; flex-wrap: wrap; gap: 14px;
  padding: 0 18px 10px; margin-top: -4px;
  font-size: 12px; color: var(--text);
}
.source-status .muted { color: var(--muted); }
.pill.vip {
  color: var(--good); border-color: color-mix(in srgb, var(--good) 40%, transparent);
  background: color-mix(in srgb, var(--good) 14%, transparent);
  font-weight: 700; letter-spacing: .04em; text-transform: uppercase;
}
/* Daily-cap usage bar under an indexer row. Colour tracks percent so
   the operator can see at a glance which indexer is close to burning
   through its allowance today. */
.cap-bar {
  height: 4px; margin: 0 18px 12px;
  background: var(--bg-2); border-radius: 3px; overflow: hidden;
}
.cap-bar-fill {
  height: 100%; background: var(--good);
  transition: width .3s ease;
}
.cap-bar-fill.warn { background: var(--warn); }
.cap-bar-fill.bad  { background: var(--bad); }
/* Inline daily-cap entry beside each indexer row. Narrow so the
   input reads as "just a number here" rather than a form. */
.cap-input {
  width: 68px; text-align: right;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 6px;
  color: var(--text); padding: 3px 6px; font-size: 12px;
  font-variant-numeric: tabular-nums;
}
.cap-input:focus { outline: none; border-color: var(--accent-line); }
/* Collapsible detail block under a Sources flash message — used for
   long diagnostic output (raw response peeks from Test) that would
   otherwise crowd the whole top of the page. Closed by default; the
   summary line reads as a small "Show raw response" link. */
.flash-detail {
  margin: 10px 18px 4px;
  border-top: 1px solid var(--line-soft);
  padding-top: 8px;
}
.flash-detail > summary {
  cursor: pointer; list-style: none;
  color: var(--muted); font-size: 12.5px; font-weight: 500;
  padding: 2px 0;
}
.flash-detail > summary:hover { color: var(--text); }
/* Landed-row group badge: "×N" beside the state pill when multiple
   downloads share an NZB content fingerprint. Neutral by default;
   red-tinted when every attempt in the group failed, because that's
   the case operators most need to see (repeated failures of the
   same content = coordinated takedown or aged-out article set). */
.attempt-badge {
  display: inline-block; margin-left: 6px;
  padding: 1px 7px; border-radius: 6px;
  background: var(--bg-2); color: var(--muted);
  font-size: 11px; font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.attempt-badge.bad {
  background: color-mix(in srgb, var(--bad) 15%, transparent);
  color: var(--bad);
}
/* The expander that shows every attempt inside a collapsed group.
   Sits inside a spanning cell under its Primary row, indented so the
   tree structure reads. */
.arrival-attempts > td { padding-left: 32px; }
.arrival-attempts details > summary {
  cursor: pointer; list-style: none;
  color: var(--muted); font-size: 12px; padding: 4px 0;
}
.arrival-attempts details > summary:hover { color: var(--text); }
.attempts-table { width: 100%; margin-top: 6px; font-size: 12.5px; }
.attempts-table td { padding: 4px 8px; }
.attempts-table tr.bad { color: var(--bad); }

.flash-detail pre {
  margin: 8px 0 0;
  padding: 10px 12px;
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-radius: 8px;
  font-size: 11.5px; line-height: 1.5;
  max-height: 420px; overflow: auto;
  white-space: pre-wrap; word-break: break-all;
  color: var(--text);
}

details.edit > summary, details.add > summary {
  cursor: pointer; list-style: none;
  color: var(--muted); font-size: 12.5px; font-weight: 500;
  padding: 0 18px 13px;
}
details.add > summary { padding: 15px 18px; border-top: 1px solid var(--line-soft); }
details.edit > summary::-webkit-details-marker,
details.add > summary::-webkit-details-marker { display: none; }
details.edit > summary::before, details.add > summary::before { content: "▸ "; color: var(--dim); }
details.edit[open] > summary::before, details.add[open] > summary::before { content: "▾ "; }
details.edit > summary:hover, details.add > summary:hover { color: var(--text); }
details.edit .addform { border-top: none; background: var(--bg-2); }

/* Provider forms read like a compact connection console: endpoint security is
   attached to the host it protects, while credentials occupy a separate band
   so they cannot be mistaken for ordinary tuning fields. */
.provider-editor {
  display: block;
  padding: 20px 18px 18px;
  background:
    linear-gradient(135deg, color-mix(in srgb, var(--accent) 3%, transparent), transparent 42%),
    var(--bg-2);
}
.provider-editor-grid {
  display: grid;
  grid-template-columns: minmax(150px, .75fr) minmax(290px, 1.55fr) minmax(220px, 1.15fr) minmax(110px, .55fr);
  gap: 16px;
  align-items: end;
}
.provider-endpoint-field {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 12px;
  align-items: end;
}
.tls-switch {
  position: relative;
  display: inline-flex !important;
  align-items: center;
  gap: 8px;
  min-height: 37px;
  margin-bottom: 0;
  padding: 0 2px;
  cursor: pointer;
  user-select: none;
}
.tls-switch input {
  position: absolute;
  width: 1px !important;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.tls-track {
  position: relative;
  width: 38px;
  height: 22px;
  flex: 0 0 auto;
  border-radius: 999px;
  border: 1px solid var(--line);
  background: var(--surface-2);
  transition: background .16s ease, border-color .16s ease;
}
.tls-track > span {
  position: absolute;
  width: 16px;
  height: 16px;
  left: 2px;
  top: 2px;
  border-radius: 50%;
  background: var(--muted);
  box-shadow: 0 1px 3px rgb(0 0 0 / .32);
  transition: transform .16s ease, background .16s ease;
}
.tls-switch input:checked + .tls-track {
  border-color: var(--accent-line);
  background: var(--accent-soft);
}
.tls-switch input:checked + .tls-track > span {
  transform: translateX(16px);
  background: var(--accent);
}
.tls-switch input:focus-visible + .tls-track {
  outline: none;
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.tls-copy { display: grid; line-height: 1.05; color: var(--text); }
.tls-copy strong { font-size: 12px; font-weight: 650; }
.tls-copy small { margin-top: 3px; color: var(--dim); font-size: 10px; font-weight: 500; }
.provider-edit-credentials {
  margin-top: 18px;
  padding: 14px 15px;
  border: 1px solid var(--line-soft);
  border-radius: 10px;
  background: color-mix(in srgb, var(--surface) 58%, transparent);
}
.provider-credential-summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 18px;
}
.provider-credential-summary > div { display: grid; gap: 4px; min-width: 0; }
.form-eyebrow {
  color: var(--dim);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: .11em;
  text-transform: uppercase;
}
.provider-signed-in { color: var(--muted); font-size: 12.5px; }
.provider-signed-in strong { color: var(--text); font-weight: 550; }
.credential-change {
  display: inline-flex !important;
  align-items: center;
  gap: 7px;
  flex: 0 0 auto;
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface-2);
  color: var(--text) !important;
  cursor: pointer;
}
.credential-change:hover { border-color: var(--accent-line); background: var(--elevated); }
.credential-change input { width: auto; margin: 0; }
.provider-credential-fields {
  border: 0;
  margin: 14px 0 0;
  padding: 14px 0 0;
  min-width: 0;
  border-top: 1px solid var(--line-soft);
}
.provider-credential-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.provider-editor-footer {
  display: flex;
  align-items: center;
  gap: 11px;
  margin-top: 16px;
}
.provider-editor-footer .hint { font-size: 11.5px; }

@media (max-width: 980px) {
  .provider-source-head { grid-template-columns: minmax(180px, 1fr) auto; }
  .provider-account { justify-items: start; }
  .provider-row-actions { grid-column: 1 / -1; justify-content: flex-start; }
  .provider-editor-grid { grid-template-columns: 1fr 1fr; }
}
@media (max-width: 640px) {
  .provider-source-head, .provider-editor-grid { grid-template-columns: 1fr; }
  .provider-account { justify-items: start; }
  .provider-endpoint-field { grid-template-columns: 1fr; }
  .tls-switch { min-height: 30px; }
  .provider-credential-summary { align-items: flex-start; flex-direction: column; }
  .provider-credential-grid { grid-template-columns: 1fr; }
  .provider-editor-footer { align-items: flex-start; flex-direction: column; }
}

.staged { padding: 14px 18px; }
.staged-head { font-weight: 600; margin-bottom: 4px; }
.staged-report { margin-top: 7px; font-weight: 500; white-space: pre-line; }
.staged-skip { color: var(--muted); font-size: 12.5px; margin-top: 3px; }
.upload { padding: 16px 18px; }
.flag { display: inline-flex; align-items: center; gap: 6px; margin-right: 12px; color: var(--muted); font-size: 12.5px; }

.pill.sonarr, .pill.radarr, .pill.lidarr, .pill.readarr, .pill.prowlarr, .pill.sabnzbd, .pill.plex {
  color: var(--accent); border-color: var(--accent-line); background: var(--accent-soft);
}
.pill.sonarr::before, .pill.radarr::before, .pill.lidarr::before,
.pill.readarr::before, .pill.prowlarr::before, .pill.sabnzbd::before, .pill.plex::before { display: none; }

/* ---------------------------------------------------------------- rules */

.profile { }
.profile .note { padding-top: 12px; }

.limits { display: flex; flex-wrap: wrap; gap: 22px; padding: 15px 18px; border-bottom: 1px solid var(--line-soft); }
.limits > div { display: flex; flex-direction: column; gap: 2px; }
.limits .k { color: var(--dim); font-size: 11px; text-transform: uppercase; letter-spacing: .04em; }
.limits .v { font-weight: 620; font-size: 15px; }
.limits .m { color: var(--dim); font-size: 11.5px; }

.tiers { display: flex; flex-wrap: wrap; gap: 8px; padding: 15px 18px; }
.tier {
  display: inline-flex; align-items: baseline; gap: 6px;
  padding: 5px 11px; border-radius: 8px;
  background: var(--surface-2); border: 1px solid var(--line-soft);
  font-size: 12.5px; color: var(--muted);
}
.tier b { color: var(--text); font-variant-numeric: tabular-nums; }

/* Decision-ladder states on the Rules page. Same chip, coloured by the
   verdict the engine would reach. */
.ladder { padding-top: 6px; padding-bottom: 6px; align-items: center; }
.ladder:first-of-type { padding-top: 15px; }
.lad-k {
  min-width: 96px; font-size: 11px; text-transform: uppercase;
  letter-spacing: .05em; color: var(--dim);
}
.lad-m { font-size: 11.5px; color: var(--dim); }
.tier.target {
  color: var(--accent); border-color: var(--accent-line); background: var(--accent-soft);
}
.tier.target b { color: var(--accent); }
.tier.target .tag {
  margin-left: 4px; font-size: 10px; text-transform: uppercase; letter-spacing: .05em;
}
.tier.finish {
  color: var(--want); border-color: color-mix(in srgb, var(--want) 35%, transparent);
  background: color-mix(in srgb, var(--want) 9%, transparent);
}
.tier.below { opacity: .5; text-decoration: line-through; }
.tier.rank {
  color: var(--text); border-color: var(--line); background: var(--surface-2);
}
.tier.none { opacity: .5; }
.ord {
  display: inline-block; min-width: 20px; text-align: center;
  font-variant-numeric: tabular-nums; color: var(--text);
  border: 1px solid var(--line-soft); border-radius: 6px; padding: 1px 4px;
  margin-right: 4px; font-size: 12px;
}
.lad-gt { color: var(--dim); font-size: 12px; }
.tier.refused {
  color: var(--bad); border-color: color-mix(in srgb, var(--bad) 30%, transparent);
  background: color-mix(in srgb, var(--bad) 8%, transparent);
  text-decoration: line-through;
}

table.impact td { vertical-align: middle; }

/* ---------------------------------------------------------------- why / candidates */

.cand { border-bottom: 1px solid var(--line-soft); padding: 14px 18px; }
.cand:last-child { border-bottom: none; }
.cand-head { display: flex; align-items: baseline; gap: 12px; }
.cand-total { font-size: 20px; font-weight: 700; font-variant-numeric: tabular-nums; letter-spacing: -.02em; }
.cand-name { font-weight: 550; }
.cand-meta, .cand-parts, .cand-why { color: var(--muted); font-size: 12.5px; margin-top: 4px; }
.comp { color: var(--dim); }
.trail { color: var(--muted); }

/* ---------------------------------------------------------------- responsive */

@media (max-width: 900px) {
  /* Narrower drawer + tighter page gutter on small screens. The rail
     itself is already narrow, so main's left padding just tracks
     var(--rail-w) with a smaller gutter. */
  :root { --drawer-w: min(280px, 86vw); }
  main { padding: 22px 18px 60px calc(var(--rail-w) + 12px); }
}

/* Downloading, as distinct from merely wanted — the library should show what is
   in motion. Accent-coloured so it reads as active, not as a problem. */
.dl { color: var(--accent); font-weight: 550; }
.card .badge.flight { background: var(--accent); }

/* Two independent rows of filters: what medium, and what state. Kept apart so
   picking "Wanted" does not clear "Films". */
.facets { display: flex; flex-direction: column; gap: 10px; margin-bottom: 24px; }
.facets .chips { gap: 7px; }
/* The status chips carry the state's own colour when active, so the filter row
   reads at a glance the same way the badges on the posters do. */
.chip.status.owned.on       { color: var(--good); border-color: color-mix(in srgb, var(--good) 40%, transparent); background: color-mix(in srgb, var(--good) 12%, transparent); }
.chip.status.wanted.on      { color: var(--want); border-color: color-mix(in srgb, var(--want) 40%, transparent); background: color-mix(in srgb, var(--want) 12%, transparent); }
.chip.status.downloading.on { color: var(--accent); border-color: var(--accent-line); background: var(--accent-soft); }

/* Sort control — a quiet dropdown beside the view toggle, not a third row of
   chips. The library already has two facet rows; ordering is a single choice
   and reads better as a menu. */
.sort {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 0 4px 0 11px; height: 38px;
  border-radius: 10px; border: 1px solid var(--line-soft); background: var(--surface);
  color: var(--muted);
}
.sort svg { width: 15px; height: 15px; flex: none; }
.sort select {
  border: none; background: none; color: var(--text);
  font: inherit; font-size: 13.5px; padding: 0 6px; height: 100%; cursor: pointer;
  outline: none; appearance: none; -webkit-appearance: none;
  padding-right: 20px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2399a2b2' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 4px center;
}
.sort:focus-within { border-color: var(--accent-line); box-shadow: 0 0 0 3px var(--accent-soft); }

/* Direction toggle beside the sort menu — an arrow that flips ascending and
   descending, so any sort can run either way. */
.dir-toggle {
  display: grid; place-items: center; width: 38px; height: 38px;
  border-radius: 10px; border: 1px solid var(--line-soft); background: var(--surface);
  color: var(--muted); text-decoration: none;
}
.dir-toggle svg { width: 16px; height: 16px; }
.dir-toggle:hover { color: var(--accent); border-color: var(--accent-line); }

/* ---------------------------------------------------------------- title detail */

.detail-hero { display: flex; gap: 28px; margin-bottom: 26px; align-items: flex-start; }
.hero-poster {
  flex: none; width: 200px; aspect-ratio: 2/3; border-radius: var(--radius);
  overflow: hidden; background: linear-gradient(160deg, var(--surface-2), var(--surface));
  box-shadow: var(--shadow-lift);
}
.hero-poster img { width: 100%; height: 100%; object-fit: cover; display: block; }
.hero-poster .cover-none { position: static; height: 100%; font-size: 15px; font-weight: 600; padding: 16px; }
.hero-body { flex: 1; min-width: 0; padding-top: 4px; }
.hero-body h1 { font-size: 30px; font-weight: 700; letter-spacing: -.02em; margin: 0 0 8px; }
.hero-meta { color: var(--muted); margin-bottom: 16px; display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.hero-meta .pill { vertical-align: middle; }

.spec-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 18px; }
.spec {
  display: inline-flex; align-items: center;
  padding: 5px 12px; border-radius: 8px;
  background: var(--surface-2); border: 1px solid var(--line-soft);
  font-size: 13px; font-weight: 550; color: var(--text);
}
.spec.res { color: var(--accent); border-color: var(--accent-line); background: var(--accent-soft); }
.spec.hdr { color: #f0c674; border-color: color-mix(in srgb, #f0c674 34%, transparent);
  background: color-mix(in srgb, #f0c674 12%, transparent); }

.hero-status { display: flex; align-items: center; gap: 14px; margin-bottom: 14px; }
.hero-rule { color: var(--muted); font-size: 13px; }
.hero-rule a { color: var(--accent); text-decoration: none; }

.hero-links { display: flex; gap: 10px; }
.ext {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 6px 12px; border-radius: 8px;
  border: 1px solid var(--line); background: var(--surface); color: var(--muted);
  text-decoration: none; font-size: 13px; font-weight: 500;
}
.ext:hover { color: var(--accent); border-color: var(--accent-line); }

/* The technical panel: a clean two-column grid of labelled values. */
.specs {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 2px 20px; padding: 16px 18px;
}
.specs > div { display: flex; flex-direction: column; gap: 1px; padding: 8px 0;
  border-bottom: 1px solid var(--line-soft); }
.specs .k { color: var(--dim); font-size: 11px; text-transform: uppercase; letter-spacing: .04em; }
.specs .v { font-size: 14.5px; font-weight: 550; }
.file-scene { margin: 0; padding: 4px 18px 2px; color: var(--muted); font-size: 12px;
  word-break: break-all; }
.file-path { margin: 0; padding: 2px 18px 16px; color: var(--dim); font-size: 12px;
  word-break: break-all; }

/* Per-file media line under an episode or track name — the codec or format,
   quiet and secondary to the title. */
.media-line { color: var(--dim); font-size: 12px; margin-top: 2px; }
.media-line.solo { margin-top: 0; font-size: 12.5px; color: var(--muted); }

/* The parts table is 24 rows per season: compact rows, no wrapped
   pills, and per-row actions that appear when the row is engaged
   rather than repeating down the whole column. */
table.parts td { padding: 7px 18px; }
table.parts .w-state { width: 175px; white-space: nowrap; }
table.parts .w-why { width: 96px; white-space: nowrap; }
table.parts .w-why .mini { opacity: 0; transition: opacity .12s ease; }
table.parts tr:hover .w-why .mini,
table.parts tr:focus-within .w-why .mini { opacity: 1; }

/* The aggregate media panel for a multi-part title. */
.summary { padding: 14px 18px; display: flex; flex-direction: column; gap: 12px; }
.sum-row { display: flex; align-items: baseline; gap: 14px; }
.sum-row > .k { color: var(--dim); font-size: 11px; text-transform: uppercase;
  letter-spacing: .04em; width: 66px; flex: none; padding-top: 4px; }
.sum-row .chips { display: flex; flex-wrap: wrap; gap: 8px; }
.sum-row .spec b { color: var(--muted); font-weight: 600; }

/* Per-download provider breakdown, in the download-history table. Who supplied
   this grab, and what a backup filled that the primary could not. */
tr.providers-row td { padding-top: 0; padding-bottom: 10px; border-bottom: 1px solid var(--line-soft); }
.prov-breakdown { display: flex; align-items: center; flex-wrap: wrap; gap: 8px; }
.prov-breakdown > .k { color: var(--dim); font-size: 11px; text-transform: uppercase;
  letter-spacing: .04em; margin-right: 2px; }
.prov-chip { display: inline-flex; align-items: baseline; gap: 7px; padding: 3px 9px;
  border: 1px solid var(--line); border-radius: 999px; background: var(--surface-2);
  font-size: 12px; color: var(--muted); }
.prov-chip b { color: var(--text); font-weight: 600; }
.prov-chip.role-1 { border-color: color-mix(in srgb, var(--want) 34%, transparent); }
.prov-chip.role-2 { border-color: color-mix(in srgb, var(--warn) 34%, transparent); }
.prov-num { color: var(--dim); }
.prov-route { font-size: 10px; font-weight: 700; letter-spacing: .025em; white-space: nowrap; }
.prov-route.weighted { color: var(--good); }
.prov-route.cooldown { color: var(--warn); }
.prov-fill { color: var(--good); font-weight: 600; }
.prov-miss { color: var(--warn); }

/* Provider fetch stats on the Sources page. */
.prov-stats { display: flex; align-items: center; flex-wrap: wrap; gap: 14px;
  padding: 2px 18px 12px; font-size: 12.5px; color: var(--muted); }
.prov-stats b { color: var(--text); font-weight: 600; }
.prov-stats .fill { color: var(--good); font-weight: 600; }
.prov-stats .miss-hi { color: var(--warn); font-weight: 600; }

/* Directory picker (Settings page). One modal, opened by the Browse buttons. */
.picker {
  position: fixed; inset: 0; z-index: 100;
  background: color-mix(in srgb, #000 55%, transparent);
  display: flex; align-items: center; justify-content: center;
  padding: 20px;
}
.picker[hidden] { display: none; }
.picker-inner {
  background: var(--surface); color: var(--text);
  border: 1px solid var(--line); border-radius: 12px;
  width: min(680px, 100%); max-height: 80vh;
  display: flex; flex-direction: column;
  box-shadow: 0 20px 60px rgba(0,0,0,.35);
}
.picker-head {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  padding: 12px 14px; border-bottom: 1px solid var(--line);
  background: var(--bg-2);
  border-radius: 12px 12px 0 0;
}
.picker-crumbs { display: flex; gap: 6px; flex-wrap: wrap; flex-grow: 1; }
.picker-crumb {
  padding: 4px 10px; font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12.5px; color: var(--text);
  background: transparent; border: 1px solid var(--line); border-radius: 6px;
  cursor: pointer;
}
.picker-crumb:hover { background: var(--bg-2); }
.picker-crumb.on { border-color: var(--accent); color: var(--accent); }
.picker-body {
  padding: 8px 6px; overflow-y: auto; flex-grow: 1; min-height: 200px;
}
.picker-entry {
  display: flex; align-items: center; gap: 8px;
  padding: 4px 10px; border-radius: 6px;
}
.picker-entry:hover { background: var(--bg-2); }
.picker-entry.parent { color: var(--muted); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
.picker-entry.parent { display: block; width: 100%; text-align: left; background: transparent;
  border: none; cursor: pointer; padding: 6px 10px; font-size: 13px; }
.picker-entry.parent:hover { color: var(--text); background: var(--bg-2); }
.picker-name {
  flex-grow: 1; text-align: left;
  padding: 6px 4px; background: transparent; border: none; color: var(--text);
  font-size: 14px; cursor: pointer;
}
.picker-name::before { content: "▸ "; color: var(--muted); }
.picker-name:hover { color: var(--accent); }
.picker-foot {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px; border-top: 1px solid var(--line);
  background: var(--bg-2);
  border-radius: 0 0 12px 12px;
}
.picker-foot .grow { flex-grow: 1; }
.picker-heading { display: grid; gap: 2px; flex: 0 0 auto; }
.picker-heading strong { font-size: 13px; }
.picker-heading small { color: var(--muted); font-size: 10.5px; }
.picker-file-name { display: grid; gap: 2px; flex: 1 1 auto; min-width: 0; padding: 6px 4px; }
.picker-file-name strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13px; }
.picker-file-name small { color: var(--muted); font: 500 10.5px/1.2 ui-monospace, SFMono-Regular, Menlo, monospace; }
.picker-file::before { content: "◻"; color: var(--accent); font-size: 10px; }

/* Header with a right-aligned primary action ("Add title" on the Library
   page). The h1/sub stack keeps its default look on the left; the action
   sits opposite, vertically centered. */
.head.has-action {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 20px;
}
.head.has-action > div:first-child { flex: 1 1 auto; }
.head.has-action > .btn { flex: 0 0 auto; margin-top: 4px; }

/* Generic modal shell — backdrop + centered card. Used by the Add-title
   dialog. The directory picker uses a near-identical shape (.picker) that
   predates this; both should eventually collapse into one .modal system. */
.modal {
  position: fixed; inset: 0; z-index: 100;
  background: color-mix(in srgb, #000 55%, transparent);
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
}
.modal[hidden] { display: none; }
.modal-inner {
  background: var(--surface); color: var(--text);
  border: 1px solid var(--line); border-radius: 14px;
  width: min(720px, 100%); max-height: 90vh;
  display: flex; flex-direction: column;
  box-shadow: 0 24px 80px rgba(0,0,0,.5);
  overflow: hidden;
}
.modal-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 18px 22px 14px;
  border-bottom: 1px solid var(--line);
}
.modal-head h2 { margin: 0; font-size: 18px; font-weight: 600; }
.modal-body {
  padding: 20px 22px;
  overflow-y: auto; flex: 1 1 auto;
  display: flex; flex-direction: column; gap: 14px;
}
.modal-foot {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 22px; border-top: 1px solid var(--line);
  background: var(--bg-2);
}
.modal-foot .grow { flex: 1 1 auto; }
/* The HTML `hidden` attribute is display:none in the UA sheet, but a class
   like `.add-row { display: flex }` has equal specificity and wins by
   cascade order. Restore the intent explicitly. */
.modal [hidden] { display: none !important; }

/* Add-title form inside the modal. Row of always-visible fields plus a
   kind-specific row that appears when the medium calls for one. */
.add-form .add-row {
  display: flex; gap: 14px; align-items: flex-end;
}
.add-form .add-row .grow { flex: 1 1 auto; }
.add-form .add-field {
  display: flex; flex-direction: column; gap: 5px;
  flex: 0 0 auto;
}
.add-form .add-field.grow { flex: 1 1 auto; }
.add-form .add-label {
  font-size: 11px; color: var(--muted); font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.05em;
}
.add-form input, .add-form select {
  border: 1px solid var(--line); background: var(--bg-2); color: var(--text);
  border-radius: 8px; padding: 8px 11px; font-size: 14px;
  font-family: inherit;
}
.add-form input:focus, .add-form select:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.add-form select { min-width: 8em; }
.add-hint { margin: 4px 0 0; line-height: 1.5; }

/* Tabs in the modal header for Search / Manual. Kept simple — the whole
   Add flow is either "look it up on TMDb and click a poster" or "type the
   fields", nothing more. */
.modal-head .tabs { display: flex; gap: 4px; margin-left: 20px; }
.modal-head .tab {
  padding: 6px 12px; font-size: 13px; font-weight: 500;
  background: transparent; color: var(--muted);
  border: 1px solid transparent; border-radius: 7px; cursor: pointer;
}
.modal-head .tab:hover { color: var(--text); }
.modal-head .tab.on {
  background: var(--accent-soft); color: var(--accent);
  border-color: var(--accent-line);
}

/* Search pane inside Add modal — search bar + result grid. */
.add-search { padding-top: 16px; }
.search-bar {
  display: flex; gap: 8px; align-items: stretch; margin-bottom: 12px;
}
.search-bar .search-kind {
  border: 1px solid var(--line); background: var(--bg-2); color: var(--text);
  border-radius: 8px; padding: 8px 12px; font-size: 14px;
  min-width: 8em;
}
.search-bar #addSearchInput {
  flex: 1 1 auto;
  border: 1px solid var(--line); background: var(--bg-2); color: var(--text);
  border-radius: 8px; padding: 8px 12px; font-size: 15px;
}
.search-bar #addSearchInput:focus, .search-bar .search-kind:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.search-results { display: flex; flex-direction: column; gap: 8px; }
.search-hint { padding: 20px; text-align: center; }
.result-card {
  display: flex; gap: 14px; align-items: flex-start;
  padding: 10px; text-align: left;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px;
  cursor: pointer; font-family: inherit; color: var(--text);
  transition: border-color 0.1s, background 0.1s;
}
.result-card:hover { border-color: var(--accent-line); background: color-mix(in srgb, var(--accent) 6%, var(--bg-2)); }
.result-card img, .result-card .result-noimg {
  width: 60px; height: 90px; flex-shrink: 0;
  border-radius: 6px; background: var(--bg); object-fit: cover;
}
.result-card .result-noimg {
  background: linear-gradient(140deg, var(--bg-2), var(--bg));
  border: 1px solid var(--line);
}
.result-card .result-meta { flex: 1 1 auto; min-width: 0; }
.result-card .result-title { font-weight: 600; font-size: 15px; }
.result-card .result-rating {
  font-size: 12px; color: var(--muted); margin-top: 2px;
}
.result-card .result-overview {
  margin: 6px 0 0; font-size: 13px; color: var(--muted); line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2;
  -webkit-box-orient: vertical; overflow: hidden;
}

/* Pick pane — the confirmation step after a search result is clicked.
   Composed with .add-form so the season/profile selects inherit the same
   labelled-field treatment as the manual form. */
.add-pick .pick-hero {
  display: flex; gap: 18px; align-items: flex-start;
  padding-bottom: 4px; border-bottom: 1px solid var(--line-soft, var(--line));
  margin-bottom: 8px;
}
.add-pick .pick-hero img {
  width: 110px; height: 165px; border-radius: 8px;
  background: var(--bg); object-fit: cover; flex-shrink: 0;
}
.add-pick .pick-meta { flex: 1 1 auto; min-width: 0; }
.add-pick .pick-meta h3 { margin: 0 0 6px; font-size: 20px; font-weight: 600; }
.add-pick .pick-meta p { margin: 8px 0 0; line-height: 1.5; color: var(--muted); font-size: 14px; }
.add-pick .pick-meta p#pickOverview { color: var(--text); }

/* Checkbox row inside a modal body — the "also delete files from disk"
   opt-in on the Remove dialog. Two-line label with a bolded headline and
   a muted explanation, checkbox aligned to the top so tall labels do not
   look uncentered. */
.modal-body .check-row {
  display: flex; gap: 12px; align-items: flex-start;
  padding: 12px 14px;
  background: var(--bg-2); border: 1px solid var(--line); border-radius: 10px;
  cursor: pointer;
}
.modal-body .check-row:hover { border-color: var(--accent-line); }
.modal-body .check-row input[type="checkbox"] {
  margin-top: 3px; accent-color: var(--accent);
  width: 16px; height: 16px; flex-shrink: 0;
}
.modal-body .check-row > span {
  display: flex; flex-direction: column; gap: 4px;
  line-height: 1.4;
}
/* Danger primary in the modal footer — for destructive submit buttons.
   Same shape as .btn.primary but tinted with the bad token. */
.modal-foot .btn.danger {
  background: var(--bad); border-color: var(--bad); color: #fff;
}
.modal-foot .btn.danger:hover {
  background: color-mix(in srgb, var(--bad) 88%, #fff);
}

/* Search-now button in the title hero — same primary look as the Add
   title button on the Library page, but scaled down slightly for the
   compact hero-status row it lives in. Only shown when there is
   something to search for (missing parts). */
.hero-action {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 13px;
  font-size: 13px;
}
.hero-action svg { flex-shrink: 0; }

/* Flash message under the hero: prominent single-line banner reporting
   the outcome of the last action (search now, etc.). Three treatments —
   neutral, ok (green), bad (red) — all with an icon and optional
   call-to-action link. Sized to actually get noticed rather than sit as
   an easily-missed muted line under the buttons that spawned it. */
.flash {
  display: flex; align-items: center; gap: 10px;
  margin: 14px 0 0;
  padding: 12px 16px; border-radius: 10px;
  background: var(--bg-2); border: 1px solid var(--line);
  color: var(--text); font-size: 14px;
}
.flash svg { flex-shrink: 0; color: var(--muted); }
.flash-text { flex: 1 1 auto; }
.flash-cta {
  flex-shrink: 0;
  padding: 5px 12px; border-radius: 7px;
  background: var(--surface); color: var(--accent);
  border: 1px solid var(--accent-line);
  text-decoration: none; font-weight: 600; font-size: 13px;
}
.flash-cta:hover { background: var(--accent-soft); }
.flash.ok {
  color: var(--text);
  background: color-mix(in srgb, var(--good, #6fbf73) 10%, var(--bg-2));
  border-color: color-mix(in srgb, var(--good, #6fbf73) 34%, var(--line));
}
.flash.ok svg { color: var(--good, #6fbf73); }
.flash.bad {
  color: var(--text);
  background: color-mix(in srgb, var(--bad) 10%, var(--bg-2));
  border-color: color-mix(in srgb, var(--bad) 34%, var(--line));
}
.flash.bad svg { color: var(--bad); }

/* Rich-metadata pieces on the title page — tagline under the hero title,
   quick chips row (runtime / rating / cert / genres), overview panel,
   cast grid with headshots, and a compact crew list.
   Rendered only when title_meta has been populated (TMDb fetch). */

.tagline {
  margin: 8px 0 0; font-style: italic; color: var(--muted);
  font-size: 15px; line-height: 1.4;
}
.meta-quick {
  display: flex; flex-wrap: wrap; gap: 8px;
  margin-top: 12px;
}
.chip-meta {
  padding: 4px 10px; border-radius: 999px;
  background: var(--bg-2); border: 1px solid var(--line);
  color: var(--text); font-size: 12.5px;
}
.chip-meta.muted { color: var(--muted); }

/* Ratings read as a small instrument panel, not another tag cloud. Source
   signals share one quiet glass rail; the operator's score is the only live
   control and therefore gets its own separated bay. */
.rating-shelf {
  display: flex; align-items: stretch; justify-content: space-between; gap: 14px;
  margin: 0 0 15px; padding: 9px;
  border: 1px solid color-mix(in srgb, var(--line) 72%, transparent);
  border-radius: 13px;
  background: color-mix(in srgb, var(--bg-2) 76%, transparent);
  backdrop-filter: blur(16px) saturate(125%);
}
.rating-signals { display: flex; flex-wrap: wrap; gap: 7px; min-width: 0; }
.rating-cell {
  min-width: 92px; padding: 7px 10px; border-radius: 9px;
  display: grid; grid-template-columns: auto auto; align-items: baseline; gap: 1px 8px;
  color: var(--text); text-decoration: none;
  background: color-mix(in srgb, var(--bg) 63%, transparent);
  border: 1px solid color-mix(in srgb, var(--line) 75%, transparent);
}
.rating-cell:hover { border-color: var(--accent-line); background: var(--accent-soft); }
.rating-source {
  grid-column: 1 / -1; color: var(--muted); font-size: 10px; line-height: 1;
  letter-spacing: .06em; font-weight: 700;
}
.rating-cell strong { font-size: 19px; line-height: 1.15; letter-spacing: -.025em; }
.rating-cell strong small { color: var(--muted); font-size: 10px; font-weight: 600; margin-left: 1px; }
.rating-count { color: var(--muted); font-size: 10px; white-space: nowrap; }
.personal-rating {
  display: grid; grid-template-columns: 78px minmax(90px, 160px) 31px auto auto;
  align-items: center; gap: 7px; padding-left: 13px;
  border-left: 1px solid var(--line);
}
.personal-rating label {
  color: var(--muted); font-size: 10px; font-weight: 700;
  text-transform: uppercase; letter-spacing: .07em;
}
.personal-rating input { accent-color: var(--accent); width: 100%; }
.personal-rating output { color: var(--text); font-size: 15px; font-weight: 700; text-align: right; }
.personal-rating .ghost { color: var(--muted); background: transparent; }
@media (max-width: 860px) {
  .rating-shelf { flex-direction: column; }
  .personal-rating { border-left: 0; border-top: 1px solid var(--line); padding: 9px 0 0; }
}

.overview {
  padding: 4px 18px 16px; margin: 0;
  line-height: 1.6; color: var(--text); font-size: 15px;
}
.meta-side {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 6px 24px; padding: 4px 18px 16px;
  font-size: 13.5px;
}
.meta-side > div { display: flex; flex-direction: column; gap: 2px; }
.meta-side .k { color: var(--muted); font-size: 11.5px; text-transform: uppercase;
  letter-spacing: 0.03em; font-weight: 600; }
.meta-side .v { color: var(--text); }

.cast-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 14px; padding: 8px 18px 18px;
}
.cast-card {
  display: flex; flex-direction: column; gap: 6px;
  min-width: 0;
}
.cast-card img, .cast-card .cast-noimg {
  width: 100%; aspect-ratio: 2 / 3; object-fit: cover;
  border-radius: 8px; background: var(--bg);
}
.cast-card .cast-noimg {
  background: linear-gradient(140deg, var(--bg-2), var(--bg));
  border: 1px solid var(--line);
}
.cast-card .cast-name {
  font-size: 13.5px; font-weight: 500; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cast-card .cast-role {
  font-size: 12px; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.crew-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 8px 24px; padding: 6px 18px 18px;
  font-size: 13.5px;
}
.crew-row { display: flex; gap: 10px; }
.crew-role {
  color: var(--muted); text-transform: uppercase; letter-spacing: 0.03em;
  font-size: 11.5px; font-weight: 600; min-width: 100px;
  align-self: center;
}
.crew-name { color: var(--text); }

/* Settings page — one panel per tab, description-left / control-right
   rows. The left column says what a setting is and why it matters; the
   right column is the control itself, so scanning the page vertically
   reads like a table of decisions rather than a wall of prose over each
   field. Groups within a panel (Library, Incomplete) get a heading row
   and a heavier separator. */

.settings-wrap { max-width: 940px; }

.set-group + .set-group { border-top: 1px solid var(--line); }
.set-group-head {
  padding: 18px 22px 14px;
  border-bottom: 1px solid var(--line-soft);
  background: color-mix(in srgb, var(--bg-2) 55%, transparent);
}
.set-group-head h2 {
  margin: 0 0 4px; font-size: 14px; font-weight: 620;
  letter-spacing: -.01em;
}
.set-group-head p {
  margin: 0; font-size: 12.5px; color: var(--muted); line-height: 1.55;
  max-width: 78ch;
}
.set-group-head code, .set-info code {
  padding: 1px 5px; background: var(--bg-2);
  border: 1px solid var(--line); border-radius: 4px;
  font-size: 11.5px; color: var(--text);
}
.set-group-head a, .set-info a { color: var(--accent); }

.set-row {
  display: grid;
  grid-template-columns: 250px minmax(0, 1fr);
  gap: 6px 32px;
  padding: 16px 22px 18px;
  align-items: start;
}
.set-row + .set-row { border-top: 1px solid var(--line-soft); }

.set-info h3 {
  margin: 4px 0 4px; font-size: 13.5px; font-weight: 570;
  letter-spacing: -.005em;
}
.set-info h3 label { cursor: pointer; }
.set-info p {
  margin: 0 0 4px; font-size: 12.5px; color: var(--muted); line-height: 1.5;
}
.set-info p:last-child { margin-bottom: 0; }

.set-ctl { max-width: 560px; min-width: 0; padding-top: 2px; }
.set-ctl input[type="text"],
.set-ctl input[type="number"] {
  width: 100%; min-width: 0;
  padding: 9px 12px;
  border: 1px solid var(--line); background: var(--bg-2); color: var(--text);
  border-radius: 8px;
  font-size: 14px; font-family: inherit;
}
.set-ctl input:focus {
  outline: none; border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}

/* Path field: input + Browse side by side. */
.path-input { display: flex; gap: 8px; align-items: stretch; }
.path-input .btn { flex-shrink: 0; padding: 9px 14px; }

/* Number + unit joined into one visual control, sized for its content
   instead of stretching a five-character number across the column. */
.unit-input { display: inline-flex; align-items: stretch; }
.unit-input input[type="number"] {
  width: 110px; text-align: right;
  border-radius: 8px 0 0 8px; border-right: none;
}
.unit-input .unit {
  display: inline-flex; align-items: center;
  padding: 0 12px;
  background: var(--bg-2); border: 1px solid var(--line);
  border-radius: 0 8px 8px 0;
  color: var(--muted); font-size: 13px;
}

/* Toggle switch — an on/off setting should look like one, not like a
   form checkbox waiting for a submit. (It still submits with the form;
   only the paint differs.) */
.switch-row {
  display: flex; gap: 12px; align-items: flex-start; cursor: pointer;
  max-width: 52ch;
}
.switch-row > span { font-size: 13px; line-height: 1.45; }
.switch-row b { font-weight: 570; }
.switch-sub { display: block; margin-top: 2px; color: var(--muted); font-size: 12.5px; }
input[type="checkbox"].switch {
  appearance: none; -webkit-appearance: none;
  width: 40px; height: 23px; flex: none; margin: 1px 0 0;
  border-radius: 12px; border: 1px solid var(--line);
  background: var(--bg-2);
  cursor: pointer; position: relative;
  transition: background .15s ease, border-color .15s ease;
}
input[type="checkbox"].switch::after {
  content: ""; position: absolute; top: 2px; left: 2px;
  width: 17px; height: 17px; border-radius: 50%;
  background: var(--muted);
  transition: left .15s ease, background .15s ease;
}
input[type="checkbox"].switch:checked {
  background: var(--accent); border-color: var(--accent);
}
input[type="checkbox"].switch:checked::after {
  left: 19px; background: var(--on-accent);
}
input[type="checkbox"].switch:focus-visible {
  outline: none; box-shadow: 0 0 0 3px var(--accent-soft);
}

.settings-hint {
  margin: 6px 0 0; font-size: 12.5px; color: var(--muted);
}
.settings-error {
  margin: 6px 0 0; font-size: 12.5px; color: var(--bad);
}

/* System import is a cutover console, not another settings row. The ledger is
   the one strong visual: it makes source authority readable before a large,
   consequential import starts. */
.import-cutover, .export-cutover { overflow: hidden; }
.import-cutover { background: var(--bg-2); }
.export-cutover .export-workbench { border-bottom: 0; }
.export-workbench {
  padding: 30px 32px 32px;
  border-bottom: 1px solid var(--line-soft);
  background:
    radial-gradient(circle at 92% 2%, color-mix(in srgb, var(--accent) 12%, transparent), transparent 31%),
    color-mix(in srgb, var(--bg-2) 72%, var(--surface));
}
.export-head { display: grid; grid-template-columns: minmax(0, 1fr) minmax(280px, 460px); gap: 28px; align-items: end; }
.export-head h2 { margin: 0; font-size: clamp(22px, 2.8vw, 32px); line-height: 1.12; letter-spacing: -.025em; }
.export-head p { margin: 0; color: var(--muted); font-size: 12.5px; line-height: 1.55; }
.export-manifest {
  margin-top: 23px; overflow: hidden; border: 1px solid var(--line);
  border-radius: 13px; background: color-mix(in srgb, var(--surface) 94%, transparent);
  box-shadow: 0 16px 42px rgb(0 0 0 / 8%);
}
.export-toolbar {
  display: flex; align-items: center; justify-content: space-between; gap: 18px;
  padding: 10px 14px; border-bottom: 1px solid var(--line-soft); background: var(--surface-2);
}
.export-toolbar > span { color: var(--dim); font: 650 10px/1 ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: .1em; text-transform: uppercase; }
.export-toolbar > div { display: flex; gap: 12px; }
.text-action { padding: 2px 0; border: 0; background: transparent; color: var(--muted); font-family: inherit; font-size: 11px; font-weight: 600; line-height: 1.3; cursor: pointer; }
.text-action:hover { color: var(--accent); }
.export-fieldset { min-width: 0; margin: 0; padding: 17px 18px 19px; border: 0; border-bottom: 1px solid var(--line-soft); }
.export-fieldset legend { padding: 0; color: var(--text); font-size: 12px; font-weight: 680; }
.export-pick-grid { display: grid; gap: 8px; margin-top: 9px; }
.export-pick-grid.media { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.export-pick-grid.system { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.export-pick {
  position: relative; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 9px;
  align-items: center; min-height: 58px; padding: 10px 11px 10px 35px;
  border: 1px solid var(--line-soft); border-radius: 9px; background: var(--bg-2);
  cursor: pointer; transition: border-color .14s ease, background .14s ease, box-shadow .14s ease;
}
.export-pick input {
  appearance: none; -webkit-appearance: none; position: absolute; left: 11px; top: 50%;
  width: 14px; height: 14px; margin: -7px 0 0; border: 1px solid var(--line); border-radius: 4px;
  background: var(--surface); cursor: pointer;
}
.export-pick input:checked { border-color: var(--accent); background: var(--accent); }
.export-pick input:checked::after { content: ""; position: absolute; left: 4px; top: 1px; width: 4px; height: 8px; border: solid var(--on-accent); border-width: 0 2px 2px 0; transform: rotate(45deg); }
.export-pick:has(input:checked) {
  border-color: color-mix(in srgb, var(--accent) 42%, var(--line));
  background: color-mix(in srgb, var(--accent) 7%, var(--surface));
  box-shadow: inset 2px 0 0 color-mix(in srgb, var(--accent) 76%, transparent);
}
.export-pick:has(input:focus-visible) { outline: 2px solid var(--accent); outline-offset: 2px; }
.export-pick > span { min-width: 0; }
.export-pick strong, .export-pick small { display: block; }
.export-pick strong { font-size: 12px; font-weight: 650; }
.export-pick small { margin-top: 2px; overflow: hidden; color: var(--dim); font-size: 10.5px; text-overflow: ellipsis; white-space: nowrap; }
.export-pick b { color: var(--muted); font: 550 10.5px/1 ui-monospace, SFMono-Regular, Menlo, monospace; }
.export-pick-mark { display: none; }
.export-security { padding: 15px 18px; border-bottom: 1px solid var(--line-soft); background: color-mix(in srgb, var(--warn) 4%, var(--surface)); }
.export-secret-toggle { display: flex; gap: 10px; align-items: flex-start; cursor: pointer; }
.export-secret-toggle input { width: 16px; height: 16px; margin: 2px 0 0; accent-color: var(--warn); }
.export-secret-toggle strong, .export-secret-toggle small { display: block; }
.export-secret-toggle strong { font-size: 12.5px; }
.export-secret-toggle small { margin-top: 2px; color: var(--muted); font-size: 11px; }
.export-passwords {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 12px;
  margin: 14px 0 0 26px; padding: 13px; border: 1px solid color-mix(in srgb, var(--warn) 34%, var(--line));
  border-radius: 9px; background: color-mix(in srgb, var(--warn) 6%, var(--bg-2));
}
.export-passwords[hidden] { display: none; }
.export-passwords label span { display: block; margin-bottom: 5px; color: var(--muted); font-size: 10.5px; }
.export-passwords input { width: 100%; min-width: 0; padding: 8px 9px; border: 1px solid var(--line); border-radius: 7px; background: var(--surface); color: var(--text); }
.export-passwords input:focus { outline: none; border-color: var(--warn); box-shadow: 0 0 0 3px color-mix(in srgb, var(--warn) 12%, transparent); }
.export-passwords > small { grid-column: 1 / -1; color: var(--dim); font-size: 10.5px; }
.export-error { margin: 0; padding: 11px 18px 0; }
.export-foot { display: flex; align-items: center; justify-content: space-between; gap: 18px; padding: 14px 18px; }
.export-foot strong, .export-foot small { display: block; }
.export-foot strong { font-size: 12px; }
.export-foot small { margin-top: 2px; color: var(--dim); font-size: 10.5px; }
.cutover-divider { display: flex; align-items: center; gap: 13px; padding: 16px 32px; color: var(--dim); background: var(--bg-2); font: 650 10px/1 ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: .1em; text-transform: uppercase; }
.cutover-divider::before, .cutover-divider::after { content: ""; height: 1px; flex: 1; background: var(--line-soft); }
.import-method-head { padding: 28px 32px 17px; background: var(--surface); }
.import-method-head h2 { margin: 0; font-size: clamp(22px, 2.7vw, 30px); line-height: 1.15; letter-spacing: -.025em; }
.import-method-head p { margin: 8px 0 0; color: var(--muted); font-size: 12.5px; }
.import-method-switch {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px;
  padding: 0 32px 24px; border-bottom: 1px solid var(--line-soft); background: var(--surface);
}
.import-method-switch > button {
  display: grid; grid-template-columns: 34px minmax(0, 1fr) 20px; gap: 12px; align-items: center;
  min-height: 74px; padding: 12px 14px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--bg-2); color: var(--text); text-align: left; cursor: pointer;
  transition: border-color .14s ease, background .14s ease, box-shadow .14s ease, transform .14s ease;
}
.import-method-switch > button:hover { border-color: color-mix(in srgb, var(--accent) 42%, var(--line)); transform: translateY(-1px); }
.import-method-switch > button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.import-method-switch > button.is-selected {
  border-color: color-mix(in srgb, var(--accent) 58%, var(--line));
  background: color-mix(in srgb, var(--accent) 7%, var(--surface));
  box-shadow: inset 3px 0 0 var(--accent), 0 9px 24px rgb(0 0 0 / 7%);
}
.import-method-mark {
  display: grid; place-items: center; width: 32px; height: 32px; border: 1px solid var(--line);
  border-radius: 8px; color: var(--accent); background: var(--surface); font: 750 12px/1 ui-monospace, SFMono-Regular, Menlo, monospace;
}
.import-method-mark.stack { color: var(--muted); }
.import-method-switch button.is-selected .import-method-mark { border-color: var(--accent-line); background: var(--accent-soft); }
.import-method-switch strong, .import-method-switch small { display: block; }
.import-method-switch strong { font-size: 13px; }
.import-method-switch small { margin-top: 3px; color: var(--dim); font-size: 10.5px; line-height: 1.35; }
.import-method-switch code { color: inherit; font-size: inherit; }
.import-method-arrow { color: var(--dim); font-size: 17px; transition: color .14s ease, transform .14s ease; }
.import-method-switch button.is-selected .import-method-arrow { color: var(--accent); transform: translateX(2px); }
.import-mode-panel[hidden] { display: none; }
.universe-restore {
  padding: 30px 32px 32px; border-bottom: 1px solid var(--line-soft);
  background:
    radial-gradient(circle at 90% 0, color-mix(in srgb, var(--accent) 14%, transparent), transparent 34%),
    color-mix(in srgb, var(--bg-2) 78%, var(--surface));
}
.universe-restore-head { display: grid; grid-template-columns: minmax(0, 1fr) minmax(280px, 450px); gap: 28px; align-items: end; }
.universe-restore-head h2 { margin: 0; font-size: clamp(22px, 2.8vw, 32px); line-height: 1.12; letter-spacing: -.025em; }
.universe-restore-head p { margin: 0; color: var(--muted); font-size: 12.5px; line-height: 1.55; }
.restore-phase-strip {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); margin-top: 22px;
  overflow: hidden; border: 1px solid var(--line); border-radius: 11px 11px 0 0; background: var(--bg-2);
}
.restore-phase-strip > div { position: relative; display: grid; grid-template-columns: 35px minmax(0, 1fr); padding: 13px 16px; border-right: 1px solid var(--line-soft); opacity: .55; }
.restore-phase-strip > div:last-child { border-right: 0; }
.restore-phase-strip span { grid-row: 1 / 3; align-self: center; color: var(--dim); font: 650 10px/1 ui-monospace, SFMono-Regular, Menlo, monospace; }
.restore-phase-strip strong, .restore-phase-strip small { display: block; }
.restore-phase-strip strong { font-size: 12px; }
.restore-phase-strip small { margin-top: 2px; color: var(--dim); font-size: 10.5px; }
.restore-phase-strip > .is-current { opacity: 1; background: color-mix(in srgb, var(--accent) 7%, var(--surface)); box-shadow: inset 0 2px 0 var(--accent); }
.restore-phase-strip > .is-complete { opacity: .82; }
.restore-phase-strip > .is-complete span { color: var(--good); }
.restore-verify {
  display: grid; grid-template-columns: minmax(280px, 1fr) minmax(260px, .8fr) auto; gap: 14px;
  align-items: start; padding: 18px; border: solid var(--line); border-width: 0 1px 1px; background: color-mix(in srgb, var(--surface) 94%, transparent);
}
.restore-file, .restore-password { display: grid; grid-template-rows: 17px 40px 16px; gap: 5px; min-width: 0; }
.restore-file > span, .restore-password > span { display: block; color: var(--muted); font-size: 10.5px; font-weight: 650; line-height: 17px; }
.restore-password > span small { color: var(--dim); font-weight: 450; }
.restore-file input, .restore-password input { width: 100%; min-width: 0; height: 40px; padding: 8px 10px; border: 1px solid var(--line); border-radius: 7px; background: var(--bg-2); color: var(--text); }
.restore-file input::file-selector-button { margin: -4px 9px -4px -5px; padding: 6px 9px; border: 0; border-right: 1px solid var(--line); background: transparent; color: var(--accent); font: 650 11px/1 inherit; cursor: pointer; }
.restore-file > small, .restore-password > small { display: block; overflow: hidden; color: var(--dim); font-size: 10px; line-height: 16px; text-overflow: ellipsis; white-space: nowrap; }
.restore-verify > .btn { height: 40px; margin-top: 22px; padding-top: 0; padding-bottom: 0; }
.restore-status { padding: 9px 13px; border: solid var(--line); border-width: 0 1px 1px; border-radius: 0 0 11px 11px; color: var(--dim); background: var(--surface-2); font-size: 10.5px; }
.restore-status::before { content: ""; display: inline-block; width: 6px; height: 6px; margin: 0 8px 1px 0; border-radius: 50%; background: var(--dim); }
.restore-status.is-working::before { background: var(--warn); box-shadow: 0 0 0 4px color-mix(in srgb, var(--warn) 12%, transparent); }
.restore-status.is-valid::before { background: var(--good); }
.restore-status.is-error { color: var(--bad); }
.restore-status.is-error::before { background: var(--bad); }
.restore-manifest, .restore-complete { margin-top: 16px; overflow: hidden; border: 1px solid var(--line); border-radius: 11px; background: var(--surface); }
.restore-manifest[hidden], .restore-complete[hidden], .restore-verify[hidden] { display: none; }
.restore-manifest > header { display: flex; justify-content: space-between; gap: 18px; align-items: center; padding: 16px 18px; border-bottom: 1px solid var(--line-soft); }
.restore-manifest h3, .restore-complete h3 { margin: 0; font-size: 18px; }
.restore-export-meta { padding: 9px 18px; border-bottom: 1px solid var(--line-soft); color: var(--dim); background: var(--bg-2); font: 550 10.5px/1.4 ui-monospace, SFMono-Regular, Menlo, monospace; }
.restore-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 12px 18px 6px; }
.restore-toolbar strong { font-size: 11px; text-transform: uppercase; letter-spacing: .08em; }
.restore-toolbar > div { display: flex; gap: 12px; }
.restore-entity-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; padding: 9px 18px 18px; }
.restore-entity { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 10px; align-items: center; min-height: 57px; padding: 10px 12px 10px 38px; border: 1px solid var(--line-soft); border-radius: 9px; background: var(--bg-2); cursor: pointer; }
.restore-entity input { appearance: none; -webkit-appearance: none; position: absolute; left: 13px; top: 50%; width: 15px; height: 15px; margin-top: -8px; border: 1px solid var(--line); border-radius: 4px; background: var(--surface); }
.restore-entity input:checked { border-color: var(--accent); background: var(--accent); }
.restore-entity input:checked::after { content: ""; position: absolute; left: 4px; top: 1px; width: 4px; height: 8px; border: solid var(--on-accent); border-width: 0 2px 2px 0; transform: rotate(45deg); }
.restore-entity:has(input:checked) { border-color: color-mix(in srgb, var(--accent) 40%, var(--line)); background: color-mix(in srgb, var(--accent) 6%, var(--surface)); }
.restore-entity strong, .restore-entity small { display: block; }
.restore-entity strong { font-size: 12px; }
.restore-entity small { margin-top: 2px; color: var(--dim); font-size: 10.5px; }
.restore-entity b { color: var(--muted); font: 550 10.5px/1 ui-monospace, SFMono-Regular, Menlo, monospace; }
.restore-confirm { display: flex; justify-content: space-between; align-items: center; gap: 18px; padding: 14px 18px; border-top: 1px solid var(--line-soft); background: var(--surface-2); }
.restore-confirm strong, .restore-confirm small { display: block; }
.restore-confirm strong { font-size: 12px; }
.restore-confirm small { max-width: 680px; margin-top: 3px; color: var(--dim); font-size: 10.5px; }
.restore-confirm > div:last-child { display: flex; gap: 8px; flex: 0 0 auto; }
.restore-complete { padding: 18px; }
.restore-complete > .eyebrow { color: var(--good); }
.restore-complete [data-restore-results] { margin: 14px 0; border-top: 1px solid var(--line-soft); }
.restore-result { display: grid; grid-template-columns: minmax(140px, .35fr) 1fr; gap: 14px; padding: 9px 0; border-bottom: 1px solid var(--line-soft); font-size: 11px; }
.restore-result span { color: var(--muted); }
.import-flow-divider { display: flex; align-items: center; gap: 14px; padding: 15px 32px; color: var(--dim); background: var(--bg-2); font: 650 9.5px/1 ui-monospace, SFMono-Regular, Menlo, monospace; letter-spacing: .1em; text-transform: uppercase; }
.import-flow-divider::before, .import-flow-divider::after { content: ""; height: 1px; flex: 1; background: var(--line-soft); }
.import-hero {
  padding: 30px 32px 25px;
  background:
    linear-gradient(115deg, color-mix(in srgb, var(--accent) 10%, transparent), transparent 52%),
    var(--surface);
  border-bottom: 1px solid var(--line-soft);
}
.eyebrow {
  display: block; margin-bottom: 7px; color: var(--accent);
  font-size: 10.5px; font-weight: 750; letter-spacing: .16em; text-transform: uppercase;
}
.import-hero h2 { margin: 0; font-size: clamp(23px, 3vw, 34px); line-height: 1.12; letter-spacing: -.025em; }
.import-hero p { max-width: 690px; margin: 10px 0 0; color: var(--muted); font-size: 14px; }
.authority-ledger {
  display: grid; grid-template-columns: repeat(3, 1fr);
  border-bottom: 1px solid var(--line-soft); background: var(--bg-2);
}
.authority-ledger > div {
  position: relative; display: grid; grid-template-columns: 32px 1fr; align-items: center;
  min-height: 76px; padding: 13px 22px; border-right: 1px solid var(--line-soft);
}
.authority-ledger > div:last-child { border-right: 0; }
.ledger-number { grid-row: 1 / 3; color: var(--dim); font: 600 11px/1 ui-monospace, SFMono-Regular, Menlo, monospace; }
.authority-ledger strong { font-size: 13px; font-weight: 650; }
.authority-ledger small { color: var(--muted); font-size: 11.5px; }
.set-flash { margin: 0; padding: 12px 32px; border-bottom: 1px solid var(--line-soft); }
.import-job-progress {
  position: relative; display: grid; grid-template-columns: 42px minmax(0, 1fr) auto;
  gap: 13px; align-items: center; margin: 22px 32px 0; padding: 16px 17px 19px;
  overflow: hidden; border: 1px solid var(--accent-line); border-radius: 11px;
  background: color-mix(in srgb, var(--accent) 7%, var(--surface));
}
.import-job-progress[hidden] { display: none; }
.import-job-progress.failed { border-color: color-mix(in srgb, var(--bad) 46%, var(--line)); }
.import-job-orbit {
  display: grid; place-items: center; width: 38px; height: 38px; border-radius: 50%;
  border: 1px solid var(--accent-line); background: var(--accent-soft);
}
.import-job-orbit span {
  width: 13px; height: 13px; border: 2px solid color-mix(in srgb, var(--accent) 28%, transparent);
  border-top-color: var(--accent); border-radius: 50%; animation: import-orbit .8s linear infinite;
}
.failed .import-job-orbit span { border-color: var(--bad); animation: none; }
.import-job-copy { min-width: 0; }
.import-job-copy .eyebrow { margin-bottom: 3px; }
.import-job-copy strong, .import-job-copy small { display: block; }
.import-job-copy strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 13.5px; }
.import-job-copy small { margin-top: 2px; color: var(--muted); font-size: 11.5px; }
.import-job-progress time { align-self: start; color: var(--dim); font: 500 11px/1 ui-monospace, SFMono-Regular, Menlo, monospace; }
.import-job-rail { position: absolute; right: 0; bottom: 0; left: 0; height: 2px; background: var(--line-soft); }
.import-job-rail span {
  display: block; width: 32%; height: 100%; background: var(--accent);
  animation: import-rail 1.35s ease-in-out infinite;
}
.failed .import-job-rail span { width: 100%; animation: none; background: var(--bad); }
@keyframes import-orbit { to { transform: rotate(360deg); } }
@keyframes import-rail { from { transform: translateX(-105%); } to { transform: translateX(330%); } }
@media (prefers-reduced-motion: reduce) {
  .import-job-orbit span, .import-job-rail span { animation-duration: 3s; }
}
.import-block { padding: 24px 32px 28px; }
.import-block h3 { margin: 0; font-size: 20px; letter-spacing: -.015em; }
.import-note { padding-left: 0; }

.import-source-form { padding: 25px 32px 30px; }
.source-family + .source-family { margin-top: 28px; }
.source-family-head { display: flex; align-items: baseline; gap: 12px; margin: 0 0 10px; }
.source-family-head span { font-weight: 680; font-size: 13px; }
.source-family-head small { color: var(--dim); font-size: 11.5px; }
.source-card-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.source-card-grid.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.import-source-card {
  display: grid; grid-template-columns: 34px 1fr; gap: 11px; align-items: center;
  padding: 14px; border: 1px solid var(--line-soft); border-radius: 10px;
  background: color-mix(in srgb, var(--surface-2) 72%, transparent);
  transition: border-color .15s ease, background .15s ease;
}
.import-source-card:focus-within { border-color: var(--accent-line); background: var(--surface-2); }
.source-card-wide { grid-template-columns: 34px 1fr; }
.source-monogram {
  display: grid; place-items: center; width: 32px; height: 32px; border-radius: 8px;
  color: var(--accent); background: var(--accent-soft); border: 1px solid var(--accent-line);
  font-size: 12px; font-weight: 760;
}
.source-monogram.plex { color: #e5b35d; background: color-mix(in srgb, #e5a841 12%, transparent); border-color: color-mix(in srgb, #e5a841 38%, transparent); }
.import-source-card > span:nth-child(2) { min-width: 0; }
.import-source-card strong, .import-source-card small { display: block; }
.import-source-card strong { font-size: 13px; }
.import-source-card small { color: var(--muted); font-size: 11.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.source-version-controls {
  grid-column: 1 / -1; display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr);
  gap: 9px; padding-top: 2px;
}
.source-version-controls label { min-width: 0; }
.source-version-controls label > span {
  display: block; margin-bottom: 5px; color: var(--dim); font-size: 10px;
  font-weight: 650; letter-spacing: .06em; text-transform: uppercase;
}
.source-version-controls select,
.source-version-controls input[type="file"] { width: 100%; min-width: 0; font-size: 11px; }
.source-version-controls input[type="file"] { padding: 5px 6px; color: var(--muted); }
.source-version-controls input[type="file"]::file-selector-button {
  margin-right: 7px; padding: 4px 7px; border: 1px solid var(--line); border-radius: 5px;
  background: var(--surface-2); color: var(--text); font: inherit; cursor: pointer;
}
.source-upload { position: relative; min-width: 0; }
.source-upload-actions { display: flex; gap: 7px; align-items: center; margin-top: 7px; }
.source-upload-actions .mini { min-height: 27px; padding-inline: 9px; white-space: nowrap; }
.source-upload-actions .mini:disabled { cursor: default; opacity: .52; }
.source-upload-status { display: block; margin-top: 6px; color: var(--dim); font-size: 10.5px; }
.source-upload.saved .source-upload-status { color: var(--good); }
.source-upload.failed .source-upload-status { color: var(--bad); }
.source-upload-rail {
  height: 2px; margin-top: 7px; overflow: hidden; border-radius: 999px; background: var(--line-soft);
}
.source-upload-rail[hidden] { display: none; }
.source-upload-rail span {
  display: block; width: 0; height: 100%; border-radius: inherit; background: var(--accent);
  transition: width .16s linear;
}
.source-upload.saved .source-upload-rail span { background: var(--good); }
.source-version-controls select,
.source-version-controls input[type="file"],
.import-analyze-bar input,
.import-secondary input[type="text"],
.plex-account-map select {
  min-width: 0; padding: 8px 10px; border: 1px solid var(--line); border-radius: 7px;
  background: var(--bg-2); color: var(--text); font-family: inherit;
}
.source-version-controls select:focus,
.source-version-controls input[type="file"]:focus,
.import-analyze-bar input:focus,
.import-secondary input[type="text"]:focus,
.plex-account-map select:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.import-analyze-bar {
  display: grid; grid-template-columns: minmax(230px, .9fr) minmax(260px, 1.1fr) auto; gap: 16px; align-items: end;
  margin-top: 26px; padding: 18px; border: 1px solid var(--accent-line); border-radius: 10px;
  background: color-mix(in srgb, var(--accent) 7%, var(--surface));
}
.import-analyze-bar > div strong,
.import-analyze-bar > div small { display: block; }
.import-analyze-bar > div strong { margin-bottom: 4px; font-size: 13px; }
.import-analyze-bar > div small { color: var(--muted); font-size: 11px; line-height: 1.4; }
.import-analyze-bar label span { display: block; margin-bottom: 6px; color: var(--muted); font-size: 11.5px; }
.import-analyze-bar input { width: 100%; }
.import-analyze-bar .btn { min-height: 39px; padding-inline: 19px; }

.import-secondary { margin: 0 32px 26px; border-top: 1px solid var(--line-soft); border-bottom: 1px solid var(--line-soft); }
.import-secondary > summary { padding: 13px 2px; color: var(--muted); cursor: pointer; font-size: 12.5px; }
.import-secondary-body { padding: 4px 2px 18px; max-width: 700px; }
.import-secondary-body p { color: var(--muted); font-size: 12px; }
.import-rules-transfer { border-top: 0; }

.import-preview-head { display: flex; align-items: center; justify-content: space-between; gap: 18px; margin-bottom: 15px; }
.preview-safe { padding: 5px 9px; border-radius: 999px; color: var(--good); background: color-mix(in srgb, var(--good) 10%, transparent); font-size: 11px; }
.import-source-result {
  display: grid; grid-template-columns: 74px minmax(0, 1fr) auto; gap: 14px 16px;
  padding: 17px 0; border-top: 1px solid var(--line-soft);
}
.import-source-result.has-error { color: var(--bad); }
.import-result-mark { padding-top: 1px; }
.import-result-title { display: flex; gap: 8px; align-items: baseline; }
.import-result-title strong { font-size: 13px; }
.import-result-title span { color: var(--dim); font-size: 11px; }
.import-result-body .staged-report { margin: 3px 0 0; color: var(--muted); font-size: 12.5px; }
.import-result-body .bad-text { margin: 3px 0 0; }
.import-result-state { align-self: start; color: var(--good); font-size: 10px; font-weight: 720; letter-spacing: .08em; text-transform: uppercase; }
.has-error .import-result-state { color: var(--bad); }
.import-path { display: flex; flex-wrap: wrap; gap: 6px 10px; margin: 7px 0 0; color: var(--muted); font-size: 11px; }
.import-path b { color: var(--text); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-weight: 500; }
.import-path.warn { color: var(--warn); }
.import-details { margin-top: 8px; color: var(--muted); font-size: 11.5px; }
.import-details summary { cursor: pointer; }
.import-detail-list { max-height: 170px; overflow: auto; margin-top: 7px; padding: 8px 10px; border-radius: 7px; background: var(--bg-2); }
.import-detail-list > div + div { margin-top: 3px; }
.import-result-table, .plex-account-map { grid-column: 2 / 4; }
.import-result-table { overflow-x: auto; }
.plex-account-map { display: grid; grid-template-columns: 165px minmax(220px, 420px); gap: 5px 12px; align-items: center; padding: 11px 13px; border-radius: 8px; background: var(--surface-2); }
.plex-account-map label { font-size: 12px; font-weight: 620; }
.plex-account-map small { grid-column: 2; color: var(--muted); font-size: 11px; }
.import-owned-choice { display: flex; gap: 11px; align-items: flex-start; margin-top: 13px; padding: 14px; border-radius: 9px; background: var(--surface-2); }
.import-owned-choice input { margin-top: 3px; }
.import-owned-choice strong, .import-owned-choice small { display: block; }
.import-owned-choice strong { font-size: 12.5px; }
.import-owned-choice small { color: var(--muted); font-size: 11.5px; }
.import-actions { display: flex; align-items: center; justify-content: space-between; gap: 18px; margin-top: 15px; padding-top: 17px; border-top: 1px solid var(--line-soft); }
.import-actions strong, .import-actions small { display: block; }
.import-actions small { color: var(--muted); font-size: 11px; }
.import-discard-form { margin-top: 10px; text-align: right; }
.import-finished { max-width: 900px; }

/* Stacked mini-form (path + media + button) inside a control cell. */
.stack-form { display: flex; flex-direction: column; gap: 8px; }
.stack-form-row { display: flex; gap: 8px; align-items: center; }
.stack-form-row input { flex: 1 1 auto; }
.stack-form-row .btn { flex-shrink: 0; }

.settings-actions {
  display: flex; align-items: center; gap: 14px;
  padding: 14px 4px 0;
}
/* display:flex above would otherwise beat the hidden attribute's UA
   display:none — and the Save bar has no business on the Import tab. */
.settings-actions[hidden] { display: none; }
.settings-actions .btn.primary { padding: 10px 18px; font-size: 14px; }

@media (max-width: 760px) {
  .set-row { grid-template-columns: 1fr; gap: 8px; }
  .export-workbench { padding: 24px 18px; }
  .export-head { grid-template-columns: 1fr; gap: 12px; }
  .export-pick-grid.media, .export-pick-grid.system { grid-template-columns: 1fr; }
  .export-passwords { grid-template-columns: 1fr; margin-left: 0; }
  .export-passwords > small { grid-column: 1; }
  .export-foot { align-items: flex-end; }
  .import-method-head { padding: 24px 18px 15px; }
  .import-method-switch { grid-template-columns: 1fr; padding: 0 18px 18px; }
  .universe-restore { padding: 24px 18px; }
  .universe-restore-head, .restore-verify { grid-template-columns: 1fr; }
  .restore-verify > .btn { margin-top: 0; }
  .restore-phase-strip, .restore-entity-grid { grid-template-columns: 1fr; }
  .restore-confirm { align-items: flex-end; flex-direction: column; }
  .restore-confirm > div:last-child { width: 100%; justify-content: flex-end; }
  .import-hero, .import-block, .import-source-form { padding-left: 18px; padding-right: 18px; }
  .import-job-progress { margin-left: 18px; margin-right: 18px; }
  .authority-ledger { grid-template-columns: 1fr; }
  .authority-ledger > div { min-height: 62px; border-right: 0; border-bottom: 1px solid var(--line-soft); }
  .authority-ledger > div:last-child { border-bottom: 0; }
  .source-card-grid, .source-card-grid.two { grid-template-columns: 1fr; }
  .source-card-wide { grid-template-columns: 34px 1fr; }
  .source-version-controls { grid-template-columns: 1fr; }
  .import-analyze-bar { grid-template-columns: 1fr; }
  .import-secondary { margin-left: 18px; margin-right: 18px; }
  .import-source-result { grid-template-columns: 64px minmax(0, 1fr); }
  .import-result-state { grid-column: 1; grid-row: 2; }
  .import-result-table, .plex-account-map { grid-column: 1 / -1; }
  .plex-account-map { grid-template-columns: 1fr; }
  .plex-account-map small { grid-column: 1; }
  .import-actions { align-items: flex-end; }
}

/* Downloading-now panel on the title page — the "am I making progress?"
   answer at the top of a title's page, refreshed every 2s. One row per
   active download with state pill, release name, size progress, and a
   filled progress bar. */
.inflight-panel { border-color: color-mix(in srgb, var(--accent) 34%, var(--line)); }
.inflight-panel .panel-head { background: color-mix(in srgb, var(--accent) 8%, var(--surface)); }
/* Container for the Now page's In flight cards — same list layout the
   title page uses inline. Empty state is a plain sentence, no card
   chrome around it. */
.inflight-list { display: block; }
.inflight-list > .empty { padding: 14px 18px; margin: 0; }
/* Clickable title anchor at the head of an in-flight card. Used on
   the Now page so an operator can jump to the title page for the
   full context; the title page's own in-flight display doesn't need
   this because it's already on the title. */
.inflight-item {
  font-weight: 500; color: var(--text);
  text-decoration: none;
}
.inflight-item:hover { color: var(--accent); text-decoration: underline; }

.inflight-row {
  padding: 14px 18px;
  border-top: 1px solid var(--line-soft);
}
.inflight-row:first-child { border-top: none; }
.inflight-head {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  align-items: center; gap: 12px;
}
.inflight-summary {
  min-width: 0;
  display: flex; align-items: center; gap: 10px;
}
.inflight-identity, .inflight-badges, .inflight-actions, .inflight-meta {
  display: flex; align-items: center;
}
.inflight-identity { gap: 9px; flex: 0 0 auto; }
.inflight-badges { gap: 7px; min-width: 0; }
.inflight-actions {
  gap: 6px; justify-content: flex-end;
  padding-left: 12px; border-left: 1px solid var(--line-soft);
}
.inflight-actions form { display: inline-flex; }
.inflight-actions .mini { min-width: 64px; height: 32px; }
.inflight-actions .icon-toggle { width: 32px; height: 32px; }
.queue-bulkbar {
  position: sticky; top: 8px; z-index: 25;
  display: flex; align-items: center; gap: 12px; min-height: 42px;
  padding: 6px 10px; border-top: 1px solid var(--line-soft);
  border-bottom: 1px solid var(--line-soft);
  background: color-mix(in srgb, var(--surface) 94%, transparent);
  backdrop-filter: blur(16px);
}

/* Keep the pipeline readout panel-wide; its endpoints need a real inset from
   the panel border even though the middle intentionally expands. */
.queue-capacity {
  display: flex;
  box-sizing: border-box;
  align-items: center;
  gap: 7px;
  width: 100%;
  min-height: 36px;
  margin: 0 0 10px;
  padding: 6px 16px 10px;
  color: var(--muted);
  font-size: 12px;
}
.queue-capacity strong {
  color: var(--text);
  font-size: 12.5px;
}
.queue-capacity-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--muted);
  opacity: .55;
}
.queue-capacity-dot.is-active {
  background: var(--good);
  opacity: 1;
  box-shadow: 0 0 10px color-mix(in srgb, var(--good) 55%, transparent);
}
.queue-capacity-note {
  margin-left: auto;
  padding-left: 16px;
  text-align: right;
}
.queue-bulkbar.has-selection {
  border-color: color-mix(in srgb, var(--accent) 30%, var(--line-soft));
  background: color-mix(in srgb, var(--accent) 6%, var(--surface));
}
.queue-select-page, .queue-row-select {
  display: inline-flex; align-items: center; cursor: pointer; user-select: none;
}
.queue-select-page { gap: 7px; color: var(--muted); font-size: 11.5px; }
.queue-select-page input, .queue-row-select input {
  width: 15px; height: 15px; margin: 0; accent-color: var(--accent);
}
.queue-selection-status { display: none; align-items: center; gap: 8px; }
.queue-bulkbar.has-selection .queue-selection-status { display: flex; }
.queue-selection-status strong { color: var(--accent); font-size: 11.5px; font-weight: 650; }
.queue-selection-clear {
  padding: 2px 6px; border: 0; background: transparent; color: var(--muted);
  font-size: 10.5px; text-decoration: underline; text-underline-offset: 2px;
}
.queue-selection-note { color: var(--dim); font-size: 10.5px; }
.bulk-remove-download { display: none; }
.queue-bulkbar.has-selection .bulk-remove-download { display: block; }
.queue-bulkbar .remove-trigger { min-width: 112px; }
.queue-row-select { flex: 0 0 auto; padding: 3px 1px; }
.inflight-row.is-selected {
  background: color-mix(in srgb, var(--accent) 7%, transparent);
  box-shadow: inset 3px 0 0 color-mix(in srgb, var(--accent) 72%, transparent);
}
.remove-download { position: relative; height: 32px; }
.remove-download[open] { z-index: 40; }
.remove-download > summary { list-style: none; }
.remove-download > summary::-webkit-details-marker { display: none; }
.remove-trigger {
  display: grid; place-items: center; box-sizing: border-box;
  cursor: pointer; user-select: none;
}
.inflight-actions .remove-trigger { min-width: 70px; }
.remove-download[open] > .remove-trigger {
  border-color: color-mix(in srgb, var(--bad) 55%, var(--line));
  background: color-mix(in srgb, var(--bad) 10%, var(--surface-2));
}
.remove-decision-card {
  position: absolute; z-index: 30; top: calc(100% + 8px); right: 0;
  width: 286px; padding: 8px; border: 1px solid var(--line);
  border-radius: 12px; background: color-mix(in srgb, var(--surface) 96%, transparent);
  box-shadow: 0 16px 38px rgb(0 0 0 / 38%); backdrop-filter: blur(18px);
}
.remove-decision-card header { padding: 5px 7px 9px; border-bottom: 1px solid var(--line-soft); }
.remove-decision-card header strong { display: block; color: var(--text); font-size: 12px; }
.remove-decision-card header span { display: block; margin-top: 2px; color: var(--dim); font-size: 10.5px; }
.inflight-actions .remove-decision-card form { display: block; }
.remove-choice {
  display: grid; grid-template-columns: 20px 1fr; gap: 9px; align-items: start;
  width: 100%; padding: 10px 8px; border: 0; border-radius: 8px;
  text-align: left; color: var(--text); background: transparent;
}
.remove-choice:hover { background: var(--surface-2); }
.remove-choice svg { margin-top: 2px; color: var(--muted); }
.remove-choice span, .remove-choice b, .remove-choice small { display: block; }
.remove-choice b { font-size: 11.5px; font-weight: 650; }
.remove-choice small { margin-top: 2px; color: var(--dim); font-size: 10.5px; line-height: 1.3; }
.remove-choice.block-choice { color: var(--bad); }
.remove-choice.block-choice:hover { background: color-mix(in srgb, var(--bad) 10%, transparent); }
.remove-choice.block-choice svg { color: var(--bad); }
.inflight-release-row {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline; gap: 18px;
  margin: 8px 0 9px;
}
.inflight-release {
  font-size: 12.5px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  min-width: 0;
}
.inflight-meta { gap: 12px; white-space: nowrap; }
.inflight-size {
  font-variant-numeric: tabular-nums; color: var(--muted); font-size: 13px;
}
.queue-priority.background { color: var(--dim); border-color: var(--line-soft); }
.queue-priority.requested {
  color: var(--accent); border-color: var(--accent-line); background: var(--accent-soft);
}
.queue-priority.playback {
  color: var(--want);
  border-color: color-mix(in srgb, var(--want) 38%, transparent);
  background: color-mix(in srgb, var(--want) 11%, transparent);
}
.queue-order-controls {
  display: inline-flex; align-items: center; gap: 3px;
  padding: 2px; border: 1px solid var(--line-soft); border-radius: 8px;
  background: var(--bg-2);
}
.queue-order-controls form { display: inline-flex; }
.queue-move {
  display: grid; place-items: center; width: 28px; height: 26px;
  padding: 0; border: 0; border-radius: 6px; background: transparent;
  color: var(--muted); font-size: 16px; line-height: 1;
}
.queue-move:hover:not(:disabled) { color: var(--accent); background: var(--surface-2); }
.queue-move:disabled { opacity: .24; cursor: default; }
.bar.wide {
  height: 8px; border-radius: 4px; overflow: hidden;
  background: var(--bg-2); border: 1px solid var(--line); position: relative;
}
.bar.wide i {
  display: block; height: 100%;
  background: linear-gradient(90deg, var(--accent), color-mix(in srgb, var(--accent) 70%, #fff));
  transition: width .3s ease;
}
.bar.wide.indeterminate i {
  width: 40%;
  animation: indet 1.5s ease-in-out infinite;
}
@keyframes indet {
  0% { transform: translateX(-100%); } 100% { transform: translateX(300%); }
}
.inflight-detail { margin-top: 6px; }
.repairing-row .bar.wide {
  border-color: color-mix(in srgb, var(--accent) 48%, var(--line));
}
.repair-sweep {
  position: absolute; inset: 0 auto 0 -22%; width: 22%;
  background: linear-gradient(90deg, transparent,
    color-mix(in srgb, #fff 72%, var(--accent)), transparent);
  opacity: .72; filter: blur(.3px);
  animation: repair-sweep 1.4s linear infinite;
}
.repair-detail {
  display: flex; align-items: center; gap: 7px;
  color: var(--accent); font-weight: 550;
  font-variant-numeric: tabular-nums;
}
.repair-spinner {
  width: 11px; height: 11px; flex: 0 0 auto;
  border: 2px solid color-mix(in srgb, var(--accent) 24%, transparent);
  border-top-color: var(--accent); border-radius: 50%;
  animation: repair-spin .8s linear infinite;
}
@keyframes repair-sweep { to { transform: translateX(560%); } }
@keyframes repair-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .repair-sweep, .repair-spinner { animation-duration: 3s; }
}

/* Downloading pill — the accent colour so a title in progress reads at
   a glance from anywhere the pill appears (hero, library, /now). */
.pill.downloading, .pill.fetching, .pill.repairing, .pill.unpacking, .pill.importing {
  background: var(--accent-soft); color: var(--accent);
  border-color: var(--accent-line);
}

/* Stalled downloads — client-side detection when the progress bar has
   not moved across ~5 polls (10s). Visual is muted + a warn-coloured
   overlay hint so it reads as "waiting for the network" rather than
   "failed". A stall in Usenet is normal-ish (retries, provider throttling)
   and often resolves on its own; the badge just tells you the number in
   the detail line has stopped for good reason to look at it. */
.inflight-row.stalled {
  background: color-mix(in srgb, var(--warn) 6%, transparent);
}
.inflight-row.stalled .inflight-badges::after {
  content: "stalled — waiting for a segment";
  padding: 3px 9px; border-radius: 999px;
  background: color-mix(in srgb, var(--warn) 18%, transparent);
  color: var(--warn); font-size: 11.5px; font-weight: 600;
  border: 1px solid color-mix(in srgb, var(--warn) 40%, transparent);
}
@media (max-width: 760px) {
  .inflight-head { grid-template-columns: 1fr; }
  .inflight-summary { flex-wrap: wrap; }
  .inflight-actions {
    justify-content: flex-start; padding: 0; border-left: 0;
  }
  .inflight-release-row { grid-template-columns: 1fr; gap: 5px; }
  .inflight-meta { justify-content: space-between; }
}
.inflight-row.stalled .bar.wide i {
  animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { opacity: 1; } 50% { opacity: 0.55; }
}

/* Per-file breakdown inside the inflight panel — expandable list of files
   with segments-done and any missing count, each with a two-tone mini
   progress bar (accent-teal for done, warn-yellow for missing). */
.file-breakdown {
  margin-top: 12px;
  border-top: 1px solid var(--line-soft);
  padding-top: 10px;
}
.file-breakdown > summary {
  cursor: pointer; list-style: none; user-select: none;
  color: var(--muted); font-size: 12.5px;
  padding: 4px 0;
}
.file-breakdown > summary::-webkit-details-marker { display: none; }
.file-breakdown > summary::before { content: "▸ "; color: var(--dim); }
.file-breakdown[open] > summary::before { content: "▾ "; }
.file-breakdown > summary:hover { color: var(--text); }

.file-list {
  display: flex; flex-direction: column; gap: 8px;
  padding-top: 10px;
}
.file-row { display: flex; flex-direction: column; gap: 4px; }
.file-row-head {
  display: flex; align-items: center; gap: 10px;
  font-size: 12.5px;
}
.file-row-head .grow { flex: 1 1 auto; }
.file-name {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  min-width: 0; color: var(--muted);
}
.file-row.done .file-name { color: var(--text); }
.file-row.has-missing .file-name { color: var(--warn); }
.file-counts {
  font-variant-numeric: tabular-nums;
  color: var(--muted); font-size: 12px;
}
.file-missing { color: var(--warn); font-weight: 500; }

.bar.mini {
  height: 4px; border-radius: 2px; overflow: hidden;
  background: var(--bg-2); border: 1px solid var(--line);
  position: relative; display: flex;
}
.bar.mini i {
  display: block; height: 100%;
}
.bar.mini i.done   { background: var(--accent); }
.bar.mini i.missing{ background: color-mix(in srgb, var(--warn) 80%, transparent); }

/* Provider chips shown live inside the inflight-row. Same visual as the
   Download history version at the bottom of the page; just a bit of top
   margin so they breathe below the file-list toggle. */
.inflight-providers { margin-top: 10px; }

/* Download-history source row: small line under each grab showing which
   Newznab indexer supplied the NZB and whether the body is now cached in
   the feed archive (a "re-grab costs zero indexer calls" badge). */
.download-source td { padding-top: 4px; padding-bottom: 10px; border-top: none !important; }
.download-source .k {
  color: var(--dim); font-size: 11px; text-transform: uppercase;
  letter-spacing: 0.05em; margin-right: 10px;
}
.src-chip {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 2px 9px; border-radius: 999px;
  background: var(--bg-2); border: 1px solid var(--line-soft);
  color: var(--muted); font-size: 12px; margin-right: 6px;
}
.src-chip b { color: var(--text); font-weight: 600; }
.src-chip.good {
  color: var(--good);
  border-color: color-mix(in srgb, var(--good) 30%, var(--line-soft));
  background: color-mix(in srgb, var(--good) 8%, var(--bg-2));
}

/* Paused rows on the Now-page queue: subtle muted background so a paused
   download is instantly distinguishable from an active one without
   dropping it off the screen. */
.paused-row td { opacity: .55; }
.paused-row .pill.wanted { opacity: 1; }

/* Small action column on the queue table for pause/resume buttons. */
.w-action { text-align: right; padding-right: 18px !important; width: 90px; }

/* Awaiting-review panel on Now — subtle warn tint so it draws the eye
   without shouting: replacement candidates are a routine occurrence when
   the operator uses Replace, not an error state. */
.review-panel { border-color: color-mix(in srgb, var(--warn) 30%, var(--line)); }
.review-panel .panel-head {
  background: color-mix(in srgb, var(--warn) 6%, var(--surface));
}
.review-row .w-action .inline { margin-right: 6px; }
/* Score-gate reason on a Review row: the profile's verdict on the
   candidate, so the operator sees at a glance whether it's borderline
   or clearly worse. */
/* Pick page — one card per candidate. A dense table sacrificed
   scanability once release names crossed 60 characters (which is
   most of them); a card lets each candidate breathe and puts the
   three things the eye actually wants — verdict, score, name — in
   fixed positions so a scan reads like a list, not a spreadsheet. */
.pick-list { display: flex; flex-direction: column; }
.pick {
  display: grid;
  grid-template-columns: 96px 1fr auto;
  gap: 16px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line-soft);
  align-items: start;
}
.pick:last-child { border-bottom: none; }
.pick-bad { background: color-mix(in srgb, var(--bad) 3%, transparent); }
.pick-bad .pick-name { opacity: 0.85; }

.pick-score {
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
  padding-top: 2px;
}
.pick-rank {
  font-size: 13px; font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}
.pick-bad .pick-rank { color: var(--dim); }

/* What-it-is chips under the release name. The tier chip leads with a
   touch of accent; the rest stay quiet. */
.pick-tags { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 6px; }
.pick-tags .tag {
  font-size: 11px; padding: 1px 7px; border-radius: 6px;
  border: 1px solid var(--line-soft); color: var(--muted);
  background: var(--surface-2);
}
.pick-tags .tag.tier {
  color: var(--accent); border-color: var(--accent-line); background: var(--accent-soft);
}
.pick-bad .pick-tags .tag { opacity: .7; }

.pill.skipped {
  color: var(--dim); border-color: var(--line-soft);
  background: color-mix(in srgb, var(--surface-2) 60%, transparent);
}

/* Part-row spec state: finished (spec met, left alone forever) vs
   watching (riding the free RSS watchlist for better). */
.fin-tag, .watch-tag {
  margin-left: 6px; font-size: 10.5px; padding: 1px 7px; border-radius: 999px;
  text-transform: uppercase; letter-spacing: .04em;
}
.fin-tag {
  color: var(--good);
  border: 1px solid color-mix(in srgb, var(--good) 35%, transparent);
  background: color-mix(in srgb, var(--good) 10%, transparent);
}
.watch-tag {
  color: var(--dim); border: 1px solid var(--line-soft);
}

/* A candidate that satisfies the profile's whole finished spec — the
   grab that ends the chase. Green edge on the row, green badge chip. */
.pick.pick-finish { box-shadow: inset 3px 0 0 var(--good); }
.pick-tags .tag.finish {
  color: var(--good);
  border-color: color-mix(in srgb, var(--good) 40%, transparent);
  background: color-mix(in srgb, var(--good) 12%, transparent);
  font-weight: 600;
}

.pick-body { min-width: 0; }
.pick-name {
  font-size: 13.5px; line-height: 1.35;
  overflow-wrap: anywhere;
  color: var(--text); font-weight: 550;
  margin-bottom: 6px;
}
.pick-meta {
  display: flex; flex-wrap: wrap; gap: 10px;
  font-size: 12.5px; color: var(--text);
}
.pick-tier {
  display: inline-block; padding: 1px 8px; border-radius: 6px;
  background: var(--bg-2); border: 1px solid var(--line);
  font-weight: 600;
}
.pick-why {
  margin-top: 6px; font-size: 12.5px;
  color: var(--bad);
}
.pick-why.ok { color: var(--good); }
.pick-parts { margin-top: 6px; }

.pick-action { align-self: center; }

/* On narrow viewports collapse to a single column: score stack on top,
   name/meta in the middle, action at the bottom — same anchors, same
   scan order. */
@media (max-width: 720px) {
  .pick { grid-template-columns: 1fr; }
  .pick-score { flex-direction: row; align-items: center; gap: 10px; }
  .pick-action { align-self: stretch; }
  .pick-action .btn { width: 100%; }
}

.review-row .review-why {
  font-size: 0.85em;
  opacity: 0.85;
  margin-top: 2px;
}

/* -------------------------------------------------------------- notifications
   Live tray at the top-right of every page. One row per active
   notification, with a small icon and a click-to-dismiss ×. Colour
   comes from the level (running/ok/warn/err) so a glance tells you the
   outcome without reading the text. */
#notif-tray {
  position: fixed; top: 14px; right: 14px; z-index: 90;
  display: flex; flex-direction: column; gap: 8px;
  width: min(360px, calc(100vw - 28px));
  pointer-events: none; /* the tray container itself never blocks clicks */
}
.notif {
  pointer-events: auto;
  display: grid;
  grid-template-columns: 28px 1fr 24px;
  align-items: start;
  gap: 10px;
  padding: 10px 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-left-width: 3px;
  border-radius: 10px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.24);
  animation: notif-slide-in .18s ease-out;
  font-size: 13px; line-height: 1.35;
}
@keyframes notif-slide-in {
  from { transform: translateY(-8px); opacity: 0; }
  to   { transform: translateY(0);    opacity: 1; }
}
.notif-link { display: contents; color: inherit; text-decoration: none; }
.notif-link:hover .notif-title { text-decoration: underline; }
.notif-icon {
  display: flex; align-items: center; justify-content: center;
  width: 24px; height: 24px; border-radius: 6px;
  font-weight: 700; font-size: 14px;
  background: var(--bg-2);
}
.notif-body { min-width: 0; }
.notif-title {
  font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis;
}
.notif-msg { color: var(--muted); font-size: 12px; margin-top: 2px; }
.notif-x {
  background: transparent; border: none; color: var(--muted);
  cursor: pointer; padding: 0; font-size: 18px; line-height: 1;
  align-self: start;
}
.notif-x:hover { color: var(--text); }

/* Level tints — border-left colour is what the eye tracks. */
.notif-running { border-left-color: var(--accent); }
.notif-running .notif-icon { background: color-mix(in srgb, var(--accent) 15%, var(--bg-2)); color: var(--accent); }
.notif-ok      { border-left-color: var(--good); }
.notif-ok      .notif-icon { background: color-mix(in srgb, var(--good) 15%, var(--bg-2)); color: var(--good); }
.notif-warn    { border-left-color: var(--warn); }
.notif-warn    .notif-icon { background: color-mix(in srgb, var(--warn) 15%, var(--bg-2)); color: var(--warn); }
.notif-err     { border-left-color: var(--bad); }
.notif-err     .notif-icon { background: color-mix(in srgb, var(--bad) 15%, var(--bg-2)); color: var(--bad); }

/* The spinner replaces the icon glyph while the action is in flight —
   a lightweight CSS ring, no image dependency. */
.notif-spinner {
  width: 14px; height: 14px;
  border: 2px solid color-mix(in srgb, var(--accent) 40%, transparent);
  border-top-color: var(--accent);
  border-radius: 50%;
  animation: notif-spin .8s linear infinite;
}
@keyframes notif-spin { to { transform: rotate(360deg); } }

/* Ephemeral toasts from the base.html fetch interceptor. Plain pill, no
   icon column — the persistent .notif layout is for real notifications
   the operator needs to act on; a "saved" acknowledgement earned by
   pressing a button belongs to a lighter shape so the two never blur. */
.notif-toast {
  pointer-events: auto;
  padding: 10px 14px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-left-width: 3px;
  border-radius: 10px;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.24);
  animation: notif-slide-in .18s ease-out;
  font-size: 13px; line-height: 1.35;
  color: var(--text);
}
.notif-toast-ok  { border-left-color: var(--good); }
.notif-toast-err { border-left-color: var(--bad); }

/* ---------- Spotify markings ----------
   Where a title / artist / album is sourced from a Spotify account, we
   surface it visually so the operator can see at a glance where a row
   came from: a small green corner dot on cards, a chip near the title on
   detail pages, and a per-track affordance later once playback is wired
   (Phase 2). The green is Spotify's canonical brand mark (#1DB954). Kept
   small enough that a library grid doesn't turn into a green sea — this
   is metadata, not the primary axis of the UI. */
:root { --spotify-green: #1DB954; }
.spotify-dot {
  position: absolute; top: 6px; left: 6px;
  width: 14px; height: 14px; border-radius: 50%;
  background: var(--spotify-green);
  box-shadow: 0 0 0 2px var(--bg);
  display: inline-flex; align-items: center; justify-content: center;
  pointer-events: none;   /* the card link owns the whole hit area */
}
.spotify-dot svg { width: 9px; height: 9px; color: #000; }
.card .poster { position: relative; }   /* dot anchors against the poster */
.chip-spotify {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 2px 8px; font-size: 12px; line-height: 1.5;
  border-radius: 999px;
  color: var(--text);
  background: color-mix(in srgb, var(--spotify-green) 14%, transparent);
  border: 1px solid color-mix(in srgb, var(--spotify-green) 45%, transparent);
}
.chip-spotify svg { width: 12px; height: 12px; color: var(--spotify-green); }

/* Per-track spotify indicator (album track lists). Small circular badge
   next to the track number; hover reveals a play icon overlay once
   Phase 2 lands. Non-playable rows leave this slot empty rather than
   showing a greyed control — an absence reads more cleanly than a
   disabled affordance in a dense list. */
.track-spotify {
  display: inline-flex; align-items: center; justify-content: center;
  width: 16px; height: 16px; border-radius: 50%;
  background: color-mix(in srgb, var(--spotify-green) 20%, transparent);
  color: var(--spotify-green);
  flex: 0 0 auto;
}
.track-spotify svg { width: 10px; height: 10px; }

/* Contributor avatar stack — which family accounts have this item saved.
   Renders as tight overlapping circles in the card corner, first letter
   of each display name. Purely informational: knowing "this is in Chase's
   AND Kate's libraries" is useful for shared decisions, but doesn't
   change any behaviour. */
.contrib-avatars {
  position: absolute; bottom: 6px; right: 6px;
  display: flex; flex-direction: row-reverse;   /* stack right-to-left */
  pointer-events: none;
}
.contrib-avatar {
  width: 18px; height: 18px; border-radius: 50%;
  background: var(--bg-2);
  color: var(--text);
  border: 2px solid var(--bg);
  margin-left: -6px;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 10px; font-weight: 700; text-transform: uppercase;
  line-height: 1;
}

/* Per-track spotify play button in the parts table. Small pill on the
   left of the ref cell. Hover state uses the Spotify green so the eye
   picks up "this is the playable one" in a dense tracklist. */
.track-spotify {
  background: color-mix(in srgb, var(--spotify-green) 20%, transparent);
  color: var(--spotify-green);
  border: none;
  width: 20px; height: 20px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
  padding: 0;
  margin-right: 6px;
  vertical-align: middle;
  transition: background 0.12s ease, transform 0.12s ease;
}
.track-spotify:hover {
  background: var(--spotify-green);
  color: #000;
  transform: scale(1.08);
}
.track-spotify:disabled { opacity: 0.5; cursor: default; }
.track-spotify svg { width: 10px; height: 10px; }

/* Album-header "Play album" button — same visual language as the chip
   next to it, but shaped as a call-to-action. Slots in between the
   Spotify chip and the sub-facts run of tags. */
.btn-spotify-album {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px;
  border-radius: 999px;
  border: 1px solid color-mix(in srgb, var(--spotify-green) 55%, transparent);
  background: color-mix(in srgb, var(--spotify-green) 22%, transparent);
  color: var(--text);
  cursor: pointer; font-size: 12px;
}
.btn-spotify-album:hover {
  background: color-mix(in srgb, var(--spotify-green) 32%, transparent);
}
.btn-spotify-album svg { color: var(--spotify-green); }

/* ---------- Now-playing bar (universal player) ----------
   Fixed to the bottom of every page. One strip for every audio
   source — local library, Spotify SDK in-tab, Spotify Connect
   remote — so the operator has ONE place to see + control what's
   playing regardless of source. Video plays full-page on /watch and
   deliberately stays out of this bar.

   Source-aware accent: data-source="spotify" tints the left rail
   Spotify green; "local" tints it have-green. That's the one visual
   cue that the same UI is driving different backends. */
.np[hidden] { display: none; }
.np {
  position: fixed; left: 12px; right: 12px; bottom: 12px;
  z-index: 80;
  display: flex; align-items: center; gap: 12px;
  padding: 8px 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid var(--line);
  border-radius: 12px;
  box-shadow: 0 12px 28px rgba(0, 0, 0, 0.32);
  animation: notif-slide-in 0.2s ease-out;
  min-height: 48px;
}
.np[data-source="spotify"] { border-left-color: var(--spotify-green); }
.np[data-source="local"]   { border-left-color: var(--good); }

/* Source badge — a small colored puck with the source glyph. Sits
   left of the art so the eye reads "spotify: track" or "local: track"
   without a text label. */
.np-source-badge {
  flex: 0 0 auto;
  width: 22px; height: 22px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--bg-2);
  color: var(--muted);
}
.np[data-source="spotify"] .np-source-badge {
  background: color-mix(in srgb, var(--spotify-green) 20%, transparent);
  color: var(--spotify-green);
}
.np[data-source="local"] .np-source-badge {
  background: color-mix(in srgb, var(--good) 20%, transparent);
  color: var(--good);
}

.np-art {
  width: 40px; height: 40px; border-radius: 6px;
  object-fit: cover; flex: 0 0 auto;
  background: var(--bg-2);
}
.np-meta {
  flex: 1 1 auto; min-width: 0;
  display: flex; flex-direction: column; justify-content: center;
}
.np-track { font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.np-sub { font-size: 12px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.np-controls { display: flex; align-items: center; gap: 4px; flex: 0 0 auto; }
.np-btn {
  background: transparent; border: none; color: var(--text);
  cursor: pointer; padding: 6px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 6px;
}
.np-btn:hover { background: var(--bg-2); }
.np-btn-play {
  background: color-mix(in srgb, var(--text) 8%, transparent);
}
.np-attr {
  font-size: 11px; flex: 0 0 auto;
  max-width: 25%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.np-close {
  flex: 0 0 auto;
  background: transparent; border: none; color: var(--muted);
  cursor: pointer; padding: 6px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 6px;
}
.np-close:hover { background: var(--bg-2); color: var(--text); }
@media (max-width: 640px) {
  .np-attr { display: none; }
  .np { left: 8px; right: 8px; bottom: 8px; }
}

/* ---------- Watch page ----------
   Dedicated /watch/{part_id} — full page with the player as the star,
   metadata in a supporting role. The video fills a max-1440px column
   centred on the page; audio-only shows the same layout without the
   16:9 box. Backdrop is the title poster blurred behind the frame so
   films / episodes feel like a media app instead of an embedded tag. */
.watch {
  max-width: 1440px; margin: 0 auto; padding: 12px;
  display: flex; flex-direction: column; gap: 16px;
}
.watch-head {
  display: flex; align-items: center; gap: 12px;
}
.watch-back {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 6px 10px; border-radius: 8px;
  color: var(--muted); text-decoration: none;
}
.watch-back:hover { background: var(--surface); color: var(--text); }
.watch-heading { flex: 1 1 auto; min-width: 0; }
.watch-title {
  margin: 0; font-size: 22px; font-weight: 700;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.watch-part {
  color: var(--muted); font-size: 14px; margin-top: 2px;
}
.watch-stage {
  position: relative;
  background: #000;
  border-radius: 12px;
  overflow: hidden;
  min-height: 220px;
}
.watch-stage video {
  display: block; width: 100%; height: auto;
  max-height: 80vh; background: #000;
}
.watch-stage audio {
  display: block; width: 100%;
  padding: 24px;
  background: var(--surface);
}
.watch-backdrop {
  position: absolute; inset: 0;
  background-size: cover; background-position: center;
  filter: blur(24px) brightness(0.4);
  transform: scale(1.1);   /* hides the blur's soft edges */
  z-index: 0;
}
.watch-stage video, .watch-stage audio { position: relative; z-index: 1; }
.watch-warn {
  padding: 12px 16px;
  background: color-mix(in srgb, var(--warn) 15%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--warn) 40%, transparent);
  border-radius: 10px;
  font-size: 13px; line-height: 1.5;
  margin-top: 12px;
}
.watch-warn strong { display: block; margin-bottom: 4px; color: var(--warn); }
.watch-empty {
  padding: 32px; text-align: center; color: var(--muted);
}
.watch-overview {
  color: var(--muted); font-size: 14px; line-height: 1.55;
  margin: 0;
}
.watch-nav {
  display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
}
.watch-nav-item {
  padding: 12px 16px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  color: var(--text); text-decoration: none;
  display: flex; flex-direction: column; gap: 2px;
}
.watch-nav-item:hover { background: var(--bg-2); }
.watch-nav-item.next { text-align: right; }
.watch-nav-item.next > span:last-child { font-weight: 600; }

/* Audio / subtitle / chapter pickers row. Sits between the player
   frame and the overview text. Wraps on narrow screens so a film
   with English+commentary+French audio doesn't push the layout out. */
.watch-picks {
  display: flex; flex-wrap: wrap; gap: 12px;
  padding: 4px 0;
}
.watch-pick {
  display: flex; align-items: center; gap: 8px;
  padding: 6px 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface);
}
.watch-pick-lbl {
  font-size: 12px; font-weight: 600;
  color: var(--muted);
  text-transform: uppercase; letter-spacing: 0.04em;
}
.watch-pick select {
  background: transparent; color: var(--text);
  border: none; padding: 2px 4px;
  font-size: 13px;
  min-width: 140px; max-width: 340px;
  cursor: pointer;
}
.watch-pick select:focus { outline: 1px solid var(--accent); }
.watch-pick option { background: var(--bg); color: var(--text); }

/* ---------- Library card watched / in-progress markings ---------- */

/* Watched checkmark: green disc in the corner opposite the Spotify dot
   so both can coexist on one card without collision. Green here is
   the have-color, not Spotify green — a title is a completed media
   asset, distinct from "it's in Spotify". */
.watched-check {
  position: absolute; top: 6px; right: 6px;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--good);
  color: #000;
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: 0 0 0 2px var(--bg);
  z-index: 2;
}
.watched-check svg { width: 12px; height: 12px; }

/* Progress bar: thin strip along the bottom of the poster showing
   percent-complete when a title is in-progress. Green fill because
   "you are advancing through it"; grey rail behind so a barely-
   started title (2%) still shows a slot the fill lives in. */
.card-progress {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 3px;
  background: rgba(0, 0, 0, 0.5);
  z-index: 2;
}
.card-progress-fill {
  height: 100%;
  background: var(--good);
  transition: width 0.2s ease;
}

/* Local-play button on parts table rows — same shape as .mini but
   with the have-color tint so it reads distinct from the neutral
   pick/replace buttons and clearly parallel to the green Spotify
   play button (Spotify=track green, local=have green — related but
   not the same source). */
.btn-play-local {
  display: inline-flex; align-items: center; gap: 4px;
  color: var(--text);
  background: color-mix(in srgb, var(--good) 15%, transparent);
  border: 1px solid color-mix(in srgb, var(--good) 35%, transparent);
}
.btn-play-local:hover {
  background: color-mix(in srgb, var(--good) 26%, transparent);
}
.btn-play-local svg { color: var(--good); }

/* Header row above the notification stack, shown only when two or
   more notifications are present. The button reads as a small
   right-aligned link so it lives above the stack without competing
   with the notifications themselves for the eye. */
.notif-header {
  pointer-events: auto;
  display: flex; justify-content: flex-end;
  padding: 0 4px;
}
.notif-clear-all {
  background: transparent; border: none;
  color: var(--muted); font-size: 11.5px; font-weight: 500;
  cursor: pointer; padding: 2px 6px; border-radius: 4px;
  font-family: inherit;
}
.notif-clear-all:hover {
  color: var(--text);
  background: color-mix(in srgb, var(--text) 8%, transparent);
}

/* Page-level toggle at the top of the Pick page that decides the
   auto-retry cascade for the next Grab click. Neutral pill-shaped
   label — feels like a setting, not a button. */
.grab-mode {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border-radius: 999px;
  background: var(--bg-2); border: 1px solid var(--line);
  font-size: 12.5px; color: var(--muted); cursor: pointer;
  user-select: none;
}
.grab-mode input { margin: 0; }
.grab-mode:hover { color: var(--text); border-color: var(--accent-line); }
/* Small chip that shows a Landed row's auto-retry state so the operator
   can see whether that row cascaded or was one-shot without opening it. */
.cascade-chip {
  display: inline-block; margin-left: 6px;
  padding: 1px 6px; border-radius: 6px;
  font-size: 10.5px; font-weight: 500;
  background: var(--bg-2); color: var(--muted);
}
.cascade-chip.off { color: var(--bad); background: color-mix(in srgb, var(--bad) 10%, transparent); }

/* Failed-row action group: keep the two controls (cascade toggle +
   retry) on one horizontal line in a narrow column, so the row's
   right edge reads as a small toolbar instead of a stack of wrapped
   pills. Right-aligned inside the cell so the primary "retry" text
   button sits closest to the column edge. */
.w-action .action-group {
  display: inline-flex; align-items: center; gap: 6px;
  justify-content: flex-end;
}
/* Icon-only toggle for the cascade flag. Square, small, matches the
   .mini height so it sits flush with the text button beside it. The
   `off` state greys the icon and adds a diagonal strikethrough so
   the disabled-cascade meaning reads at a glance. */
.icon-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 26px;
  padding: 0; border-radius: 8px;
  background: transparent; border: 1px solid var(--line);
  color: var(--good); cursor: pointer;
  font-family: inherit;
  position: relative;
}
.icon-toggle:hover { border-color: var(--accent-line); background: var(--surface-2); }
.icon-toggle.off { color: var(--muted); }
.icon-toggle.off::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(to top right, transparent calc(50% - 0.6px),
              var(--bad) calc(50% - 0.6px), var(--bad) calc(50% + 0.6px),
              transparent calc(50% + 0.6px));
  border-radius: 8px; opacity: 0.65; pointer-events: none;
}

/* Extractor availability on Settings → Downloading: green when the
   binary is on PATH, amber when the container image predates it. */
.extractor-status { margin: 4px 0 0; display: flex; gap: 14px; font-size: 13.5px; }
.extractor-status .ok   { color: var(--good); font-weight: 550; }
.extractor-status .warn { color: var(--want); font-weight: 550; }

/* Collapsible panel fold — used by the title page's download history.
   The summary IS the panel head; a chevron signals it opens. */
details.fold > summary.fold-head {
  cursor: pointer; list-style: none; user-select: none;
  border-bottom: none;
}
details.fold[open] > summary.fold-head { border-bottom: 1px solid var(--line-soft); }
details.fold > summary.fold-head::-webkit-details-marker { display: none; }
details.fold > summary.fold-head::after {
  content: "▸"; color: var(--dim); font-size: 12px;
  margin-left: auto; transition: transform .12s ease;
}
details.fold[open] > summary.fold-head::after { transform: rotate(90deg); }
details.fold > summary.fold-head .hint { margin-left: 12px; }
details.fold > summary.fold-head:hover h2 { color: var(--accent); }

/* Download history (title page) — an index, not a casualty report.
   Collapsed: one quiet line per release (pill · name · gist · age).
   Open: meta + actions, the full failure sentence, provider chips,
   and prior attempts. Alarm color is reserved for the state pill;
   the details keep to the muted scale even for failures, because a
   history entry is a record, not an alert. */
.dh-fold + .dh-fold { border-top: 1px solid var(--line-soft); }
.dh-line {
  display: flex; align-items: center; gap: 12px;
  padding: 9px 18px;
  cursor: pointer; list-style: none; user-select: none;
}
.dh-line::-webkit-details-marker { display: none; }
.dh-line:hover { background: color-mix(in srgb, var(--bg-2) 60%, transparent); }
.dh-line .pill { flex: none; }
.dh-name {
  font-size: 12.5px; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dh-gist { color: var(--dim); font-size: 12px; white-space: nowrap; flex: none; }
.dh-line .dh-when {
  margin-left: auto; flex: none;
  color: var(--muted); font-size: 12.5px; white-space: nowrap;
}
.dh-chev { color: var(--dim); font-size: 11px; flex: none; transition: transform .12s ease; }
.dh-fold[open] > .dh-line .dh-chev { transform: rotate(90deg); }

.dh-body { padding: 2px 18px 14px 18px; }
.dh-meta {
  display: flex; flex-wrap: wrap; gap: 4px 14px; align-items: center;
  color: var(--muted); font-size: 12.5px;
  padding: 4px 0 2px;
}
.dh-meta .grow { flex: 1 1 auto; }
.dh-meta a.mini { text-decoration: none; }
.dh-detail {
  margin-top: 8px;
  color: var(--muted); font-size: 12.5px; line-height: 1.55;
  max-width: 110ch;
}
.dh-provs { margin-top: 8px; padding: 0; }
/* Inside the history, miss counts are context, not alarms. */
.dh .prov-miss { color: var(--muted); }

.dh-attempt-list { margin-top: 10px; display: flex; flex-direction: column; gap: 8px; }
.dh-attempt {
  padding: 8px 10px;
  border: 1px solid var(--line-soft); border-radius: 9px;
  background: color-mix(in srgb, var(--bg-2) 50%, transparent);
}
.dh-attempt-line { display: flex; align-items: center; gap: 10px; }
.dh-attempt-line .grow { flex: 1 1 auto; }
.dh-meta-inline { color: var(--muted); font-size: 12px; }
.dh-attempt .dh-when { color: var(--muted); font-size: 12px; }
}

/* Feed viewer — a firehose window. Single-line rows, fixed columns,
   nothing interactive per row; the archive is for scanning and
   searching, not acting. */
.feed-head { gap: 14px; }
.feed-search { display: flex; gap: 8px; align-items: center; }
.feed-search input[type="search"] {
  width: 300px; padding: 7px 11px;
  border: 1px solid var(--line); background: var(--bg-2); color: var(--text);
  border-radius: 8px; font-size: 13.5px; font-family: inherit;
}
.feed-search input[type="search"]:focus { outline: none; border-color: var(--accent); }
.feed-search a.mini { text-decoration: none; }
.feed-chips { display: flex; gap: 6px; flex-wrap: wrap; }

/* The adaptive poller's next-visit marker inside an indexer chip —
   quiet, secondary; the chip stays primarily a filter. */
.chip .chip-note {
  margin-left: 6px; padding-left: 6px;
  border-left: 1px solid var(--line-soft);
  color: var(--dim); font-size: 10.5px;
}
.chip.on .chip-note { color: inherit; opacity: .75; border-left-color: var(--accent-line); }

/* Finished-when editor on the Rules page. Reuses the chip checkbox
   styling from the Add modal's season picker. */
.donespec {
  border: 1px solid var(--line-soft); border-radius: 10px;
  padding: 10px 12px; margin: 4px 0;
}
.donespec legend { padding: 0 6px; font-size: 12.5px; color: var(--muted); }
.done-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding: 4px 0; }
.done-k { min-width: 110px; font-size: 12px; color: var(--dim); }

/* Season checkbox chips in the Add modal's pick pane. */
.season-quick { margin-left: 8px; display: inline-flex; gap: 4px; }
.season-picks {
  display: flex; flex-wrap: wrap; gap: 6px;
  margin-top: 6px; max-height: 160px; overflow-y: auto;
}
.season-pick {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 10px; border: 1px solid var(--line); border-radius: 999px;
  font-size: 12px; color: var(--muted); cursor: pointer; user-select: none;
}
.season-pick:has(input:checked) {
  color: var(--accent); border-color: var(--accent-line); background: var(--accent-soft);
}
.season-pick input { accent-color: var(--accent); margin: 0; }
.season-hint { margin-top: 6px; }

/* Rules thresholds are a policy console, not a generic auto-fit form. Each
   horizontal band maps to one kind of decision: qualification, the finish
   line, and hard exclusions. The slim accent rail makes that stack legible
   without turning every field into another floating card. */
.thresholds-editor > summary {
  display: flex; align-items: baseline; gap: 10px;
}
.thresholds-editor > summary small {
  color: var(--dim); font-size: 10.5px; font-weight: 450;
}
.thresholds-editor[open] > summary {
  color: var(--text);
  background: color-mix(in srgb, var(--accent) 3%, transparent);
}
.thresholds-form {
  position: relative; display: block; padding: 0;
  border-top: 1px solid var(--line-soft);
  background: color-mix(in srgb, var(--bg-2) 64%, transparent);
}
.thresholds-form::before {
  content: ""; position: absolute; z-index: 1; inset: 0 auto 0 0; width: 2px;
  background: linear-gradient(to bottom, var(--accent), color-mix(in srgb, var(--want) 75%, var(--accent)) 58%, var(--bad));
  opacity: .7;
}
.thresholds-form .threshold-band {
  margin: 0; padding: 20px 20px 21px;
  border: 0; border-bottom: 1px solid var(--line-soft); border-radius: 0;
  background: transparent;
}
.threshold-band-head {
  display: grid; grid-template-columns: 112px auto minmax(180px, 1fr);
  align-items: baseline; gap: 10px; margin-bottom: 14px;
}
.threshold-band-head strong {
  color: var(--text); font-size: 13px; font-weight: 640;
}
.threshold-band-head small {
  color: var(--dim); font-size: 10.5px; font-weight: 450;
}
.threshold-band-kicker {
  color: var(--accent); font-size: 10.5px; font-weight: 650;
  letter-spacing: .075em; text-transform: uppercase;
}
.threshold-exclusions .threshold-band-kicker { color: var(--bad); }
.threshold-grid {
  display: grid; grid-template-columns: repeat(5, minmax(120px, 1fr));
  gap: 12px;
}
.thresholds-form label {
  display: block; min-width: 0;
  color: var(--muted); font-size: 11.5px; font-weight: 520;
}
.thresholds-form .label-unit {
  margin-left: 3px; color: var(--dim); font-size: 10.5px; font-weight: 450;
}
.thresholds-form input, .thresholds-form select {
  width: 100%; height: 35px; margin-top: 6px; box-sizing: border-box;
  border-radius: 8px; background: color-mix(in srgb, var(--bg) 78%, transparent);
}
.thresholds-form .done-row {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding: 5px 0;
}
.thresholds-form .done-k {
  min-width: 0; color: var(--dim); font-size: 11px;
  letter-spacing: .025em;
}
.thresholds-form .done-row .done-k { flex: 0 0 112px; }
.thresholds-form label.season-pick {
  display: inline-flex; align-items: center; gap: 7px;
  width: auto; min-height: 31px; padding: 5px 11px;
  border-color: color-mix(in srgb, var(--line) 85%, transparent);
  background: color-mix(in srgb, var(--bg) 44%, transparent);
}
.thresholds-form label.season-pick:hover {
  color: var(--text); border-color: var(--accent-line);
}
.thresholds-form label.season-pick:has(input:checked) {
  color: var(--accent); border-color: var(--accent-line);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}
.thresholds-form label.season-pick input {
  flex: 0 0 auto; width: 14px; height: 14px; margin: 0;
}
.thresholds-form label.season-pick span { white-space: nowrap; }
.threshold-stack { display: grid; gap: 12px; }
.threshold-actions {
  display: flex; justify-content: flex-end; padding: 13px 20px 15px;
}
.threshold-actions button { min-width: 132px; }

@media (max-width: 980px) {
  .threshold-grid { grid-template-columns: repeat(3, minmax(130px, 1fr)); }
}
@media (max-width: 680px) {
  .thresholds-editor > summary { align-items: flex-start; flex-wrap: wrap; }
  .thresholds-editor > summary small { flex-basis: 100%; margin-left: 14px; }
  .threshold-band-head { grid-template-columns: 1fr; gap: 3px; }
  .threshold-grid { grid-template-columns: 1fr; }
  .thresholds-form .done-row .done-k { flex-basis: 100%; }
  .thresholds-form label.season-pick span { white-space: normal; }
  .threshold-actions button { width: 100%; }
}

/* Title page: persistent header above the tabs — a poster thumbnail for
   identity, the name, one line of state + vitals, and the actions. The
   full-size poster and rich metadata live on the Overview tab only. */
.title-head {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  margin: 4px 0 16px;
}
.title-thumb {
  flex: none; width: 54px; aspect-ratio: 2/3; border-radius: 8px;
  overflow: hidden;
  background: linear-gradient(160deg, var(--surface-2), var(--surface));
  border: 1px solid var(--line-soft);
  box-shadow: var(--shadow);
}
.title-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.title-id { min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.title-bar-name { font-size: 25px; margin: 0; min-width: 0; letter-spacing: -.02em; }
.title-sub {
  display: flex; align-items: center; flex-wrap: wrap; gap: 4px 12px;
  color: var(--muted); font-size: 13px;
}
.title-sub .pill { flex: none; }

/* Underline tab variant: plain text tabs over a single rule, for pages
   where the panel below the strip isn't one full-width card the tabs
   could visually attach to. */
.tabbar.line {
  gap: 2px; margin: 0 0 20px;
  border-bottom: 1px solid var(--line);
}
.tabbar.line .tab-link {
  background: none; border: none; border-radius: 0;
  padding: 8px 12px 11px; margin-bottom: -1px;
}
.tabbar.line .tab-link.on {
  background: none;
  box-shadow: 0 -2px 0 var(--accent) inset;
}

/* Overview tab: one About card holds the poster and everything written
   about the title, so the tall poster always has content beside it. */
.about-grid { display: flex; gap: 24px; padding: 20px; }
.about-grid .hero-poster { align-self: flex-start; }
.about-grid .hero-poster { width: 190px; }
.about-body {
  flex: 1; min-width: 0;
  display: flex; flex-direction: column; gap: 14px;
}
.about-body .tagline { margin: 0; }
.about-body .meta-quick { margin: 0; }
.about-overview { margin: 0; line-height: 1.6; font-size: 15px; max-width: 90ch; }
.about-facts { padding: 0; }
.about-foot {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  margin-top: auto; padding-top: 6px;
}
.about-sep { width: 1px; align-self: stretch; background: var(--line-soft); margin: 0 4px; }
.dh-filter .chip .count { margin-left: 4px; opacity: .7; }
.dh-fold[hidden] { display: none; }

/* Blocklist folded into the history list: an amber tag on rows whose
   release is blocked, an amber pill on blocklist-only rows. */
.blk-tag {
  flex: none;
  font-size: 10.5px; font-weight: 650; letter-spacing: .04em;
  text-transform: uppercase;
  color: #e0a458;
  border: 1px solid color-mix(in srgb, #e0a458 35%, transparent);
  background: color-mix(in srgb, #e0a458 10%, transparent);
  padding: 2px 7px; border-radius: 999px;
}
.pill.blocked {
  color: #e0a458;
  background: color-mix(in srgb, #e0a458 12%, transparent);
}
.dh-plain .dh-line { cursor: default; }

/* Per-track audio/subtitle lists in the Media panel. */
.specs .wide { grid-column: 1 / -1; }
.tracklist { display: flex; flex-direction: column; gap: 3px; }
.trk-flag {
  font-style: normal; font-size: 10.5px; font-weight: 650;
  letter-spacing: .04em; text-transform: uppercase;
  color: var(--accent); background: var(--accent-soft);
  padding: 1px 6px; border-radius: 999px; margin-left: 4px;
}

/* Music library: albums shelved under artist headers. */
.artist-shelf { margin-bottom: 26px; }
.artist-head {
  font-size: 15px; font-weight: 650; letter-spacing: -.01em;
  margin: 0 0 10px; padding-bottom: 6px;
  border-bottom: 1px solid var(--line-soft);
  display: flex; align-items: baseline; gap: 8px;
}
.artist-head .count {
  font-size: 12px; font-weight: 500; color: var(--dim);
  padding: 1px 7px; border-radius: 8px; background: var(--line-soft);
}

/* Chapter list fold in the Media panel. */
.chap-fold summary { cursor: pointer; color: var(--text); }
.chap-fold summary:hover { color: var(--accent); }
.chap-list {
  margin: 10px 0 0; padding-left: 2.2em;
  column-count: 3; column-gap: 28px;
  font-size: 13px; color: var(--muted);
}
.chap-list li { break-inside: avoid; padding: 1px 0; }
@media (max-width: 900px) { .chap-list { column-count: 1; } }

/* Episode label on history rows: which episode this release was for,
   with the TMDb synopsis in the tooltip. */
.dh-ep {
  flex: none; color: var(--muted); font-size: 12.5px; white-space: nowrap;
  max-width: 26ch; overflow: hidden; text-overflow: ellipsis;
}
.dh-plain .dh-line .mini { flex: none; }

/* Today's indexer calls — one flat strip, not a stacked table. */
.spend-strip {
  display: flex; align-items: center; gap: 18px; flex-wrap: wrap;
  padding: 12px 18px;
}
.spend-group {
  display: flex; align-items: baseline; gap: 18px; flex-wrap: wrap;
}
.spend-divider {
  align-self: stretch; width: 1px; min-height: 24px;
  background: var(--line-soft);
}
.spend-k {
  font-size: 12px; text-transform: uppercase; letter-spacing: .05em;
  color: var(--dim);
}
.spend-item { display: inline-flex; align-items: baseline; gap: 7px; font-size: 13px; }
.spend-mode { color: var(--muted); }
.spend-item b { font-variant-numeric: tabular-nums; color: var(--text); }
.spend-metered { color: var(--dim); font-size: 11.5px; }
.download-day-stats .spend-item { gap: 5px; }
.download-day-stats .download-bytes b { color: var(--accent); }
.download-day-stats .has-failures b,
.download-day-stats .has-failures .spend-mode { color: var(--bad); }
@media (max-width: 900px) {
  .spend-strip { align-items: stretch; flex-direction: column; gap: 10px; }
  .spend-divider { width: auto; height: 1px; min-height: 1px; }
}

/* Landed advanced stats: the failure diagnosis and provider breakdown
   rows collapse behind the "details" checkbox. */
#landed.hide-adv tr.detail,
#landed.hide-adv tr.providers-row,
#landed.hide-adv .landed-via { display: none; }
.landed-via {
  color: var(--dim); font-size: 11.5px; margin-top: 2px;
  font-family: var(--font, inherit);
}
.landed-tools {
  padding: 12px 18px;
  border-bottom: 1px solid var(--line-soft);
  background: color-mix(in srgb, var(--bg-2) 48%, transparent);
}
.landed-search {
  width: min(760px, 100%);
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto auto;
  align-items: center; gap: 8px;
  padding: 4px 5px 4px 11px;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--bg-2);
  transition: border-color .14s ease, box-shadow .14s ease;
}
.landed-search:focus-within {
  border-color: var(--accent-line);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.landed-search-icon { display: inline-flex; color: var(--dim); }
.landed-search input[type="search"] {
  min-width: 0; width: 100%; padding: 6px 0;
  border: 0; outline: 0; background: transparent; color: var(--text);
  font: inherit; font-size: 13px;
}
.landed-search input[type="search"]::placeholder { color: var(--dim); }
.landed-search .mini { padding: 5px 12px; }
.landed-clear {
  padding: 5px 7px; color: var(--muted); font-size: 12px;
  text-decoration: none; border-radius: 6px;
}
.landed-clear:hover { color: var(--text); background: var(--surface-2); }
.landed-clear.is-hidden { display: none; }
.landed-empty {
  display: flex; flex-direction: column; align-items: center; gap: 5px;
  padding: 42px 18px; color: var(--muted); text-align: center;
}
.landed-empty strong { color: var(--text); font-size: 14px; }
.landed-empty span { font-size: 12.5px; }
.landed-pager {
  min-height: 58px; padding: 11px 18px;
  display: flex; align-items: center; justify-content: space-between; gap: 18px;
  border-top: 1px solid var(--line-soft);
  background: color-mix(in srgb, var(--bg-2) 34%, transparent);
}
.landed-range { color: var(--muted); font-size: 12px; }
.landed-pager nav { display: flex; align-items: center; gap: 9px; }
.pager-step { min-width: 76px; text-align: center; }
.pager-step.disabled {
  display: inline-block; color: var(--dim); opacity: .45;
  border: 1px solid transparent; cursor: default;
}
.pager-position {
  min-width: 88px; color: var(--muted); text-align: center;
  font-size: 12px; font-variant-numeric: tabular-nums;
}
@media (max-width: 720px) {
  .landed-tools { padding: 10px 12px; }
  .landed-search { grid-template-columns: auto minmax(0, 1fr) auto; }
  .landed-search button[type="submit"] { display: none; }
  .landed-pager { align-items: stretch; flex-direction: column; gap: 9px; }
  .landed-pager nav { justify-content: space-between; }
}

/* Opt-in auto-refresh toggle; remembered per browser. */
.feed-auto {
  display: inline-flex; align-items: center; gap: 5px;
  color: var(--muted); font-size: 12px; cursor: pointer; user-select: none;
}
.feed-auto input { accent-color: var(--accent); }

.feed-list { font-variant-numeric: tabular-nums; }
.feed-row {
  display: flex; align-items: center; gap: 14px;
  padding: 5px 18px;
  font-size: 12.5px;
}
.feed-row:nth-child(even) { background: color-mix(in srgb, var(--bg-2) 40%, transparent); }
.feed-row:hover { background: color-mix(in srgb, var(--accent) 7%, transparent); }
.feed-name {
  flex: 1 1 auto; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.feed-cat {
  flex: none; font-size: 10.5px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--dim); border: 1px solid var(--line-soft); border-radius: 5px;
  padding: 0 5px;
}
.feed-size { flex: none; min-width: 70px; text-align: right; color: var(--muted); }
.feed-ix   { flex: none; min-width: 90px; color: var(--dim); font-size: 12px; }
.feed-age  { flex: none; min-width: 90px; text-align: right; color: var(--muted); font-size: 12px; }

.feed-foot {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 18px; border-top: 1px solid var(--line-soft);
}
.feed-foot a.mini { text-decoration: none; }

/* Search/RSS state toggles on indexer rows. The button reads as the
   current state (green = on); clicking flips it. */
.mini.tog { color: var(--muted); min-width: 82px; text-align: center; }
.mini.tog.on { color: var(--good); border-color: color-mix(in srgb, var(--good) 35%, transparent); }

/* ------------------------------------------------------------------ */
/* Artists — the first-class music-browse concept. Grid on /artists,
   detail page at /artist/{id}, discography filter bar on the detail. */

.artist-panel { padding: 0; }
.artist-panel .about-grid { padding: 20px 22px; }
.artist-h { margin: 0 0 10px; font-size: 26px; letter-spacing: -0.01em; }
.artist-h .muted { font-weight: 400; font-size: 20px; }

/* Artists list — poster cards with band portrait + name + count. */
.artist-grid-wrap { margin-top: 20px; }
.artist-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap: 18px;
}
.artist-card {
  display: block; text-decoration: none; color: inherit;
  border-radius: 10px; overflow: hidden;
  transition: transform 0.12s ease;
}
.artist-card:hover { transform: translateY(-2px); }
.artist-portrait {
  position: relative;
  aspect-ratio: 1 / 1;
  background: var(--bg-2);
  border-radius: 10px;
  overflow: hidden;
  display: flex; align-items: center; justify-content: center;
}
.artist-portrait img { width: 100%; height: 100%; object-fit: cover; display: block; }
.artist-portrait-none {
  color: var(--muted); font-size: 13px; text-align: center; padding: 10px;
  font-weight: 600; letter-spacing: 0.02em;
}
.artist-portrait .badge {
  position: absolute; top: 8px; right: 8px;
  background: var(--want); color: white; font-weight: 700;
  padding: 2px 7px; border-radius: 999px; font-size: 11px;
}
.artist-cap { padding: 8px 4px 0; }
.artist-name {
  font-weight: 600; font-size: 14px; color: var(--text);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.artist-sub { font-size: 12px; color: var(--muted); margin-top: 2px; }

/* Add-artist search panel on /artists. The inline pick form's hero
   is smaller than a title's since there's no poster to hang it on. */
.add-artist-panel .add-artist-body { padding: 14px 18px 18px; }
.add-artist-panel .search-bar input { width: 100%; }
.artist-pick-hero { padding: 12px 0; }
.artist-pick-hero h3 { margin: 0 0 4px; font-size: 18px; }
.result-card.artist-result { align-items: center; }
.artist-noimg {
  width: 46px; height: 46px; border-radius: 50%;
  background: var(--bg-3); color: var(--muted);
  display: flex; align-items: center; justify-content: center;
  font-weight: 700; font-size: 18px; flex: none;
}

/* Discography filter bar — chips as toggle links; empty categories
   render dimmer so the row still lists "there's nothing in that
   bucket" without hiding options. */
.disc-filters {
  display: flex; flex-wrap: wrap; gap: 7px;
  padding: 4px 18px 14px;
}
.disc-filter .count { margin-left: 5px; opacity: .7; font-variant-numeric: tabular-nums; }
.disc-filter.empty { opacity: .45; pointer-events: auto; }
.disc-filter.empty:hover { opacity: .7; }
.disc-list { margin-top: 0; }

/* Stacked settings control — for multi-input settings (Spotify's
   Client ID + Client Secret + Redirect URI on one row, or the login
   panel's username + password + rules). Grouped as field-rows so the
   label sits right above its input with tight spacing, then a wider
   gap between rows. */
.set-ctl-stack { display: flex; flex-direction: column; gap: 18px; }
.set-ctl-stack input[type="text"],
.set-ctl-stack input[type="password"] { width: 100%; }
.field-row { display: flex; flex-direction: column; gap: 4px; }
.set-sub-label {
  font-size: 11.5px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted);
}
.settings-actions-inline {
  display: flex; gap: 10px; align-items: center; margin-top: 8px;
}
.settings-actions-inline .btn { text-decoration: none; }

/* Toggle row — a real-sized checkbox with a bold label and a smaller
   help line under it. Reads as a proper setting toggle rather than
   the previous "hint text with a tiny checkbox floating in front". */
.toggle-row {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 8px 10px;
  border: 1px solid var(--line-soft);
  border-radius: 8px;
  background: color-mix(in srgb, var(--bg-2) 30%, transparent);
  cursor: pointer;
  transition: border-color .12s ease, background .12s ease;
}
.toggle-row:hover { border-color: var(--line); background: color-mix(in srgb, var(--bg-2) 55%, transparent); }
.toggle-row input[type="checkbox"] {
  width: 18px; height: 18px; margin: 2px 0 0; flex: none;
  accent-color: var(--accent); cursor: pointer;
}
.toggle-row:has(input:checked) {
  border-color: var(--accent-line);
  background: color-mix(in srgb, var(--accent) 8%, transparent);
}
.toggle-label {
  display: flex; flex-direction: column; gap: 3px;
  font-size: 13px; color: var(--text); line-height: 1.4;
}
.toggle-label b { font-weight: 600; }
.toggle-label code { font-size: 12px; }
.toggle-help {
  font-size: 12px; color: var(--muted); font-weight: 400;
}
.toggle-row.danger-hint { border-color: color-mix(in srgb, var(--want) 30%, transparent); }
.toggle-row.danger-hint:has(input:checked) {
  border-color: color-mix(in srgb, var(--want) 60%, transparent);
  background: color-mix(in srgb, var(--want) 10%, transparent);
}
.toggle-row.danger-hint span { color: var(--want); font-size: 12.5px; }

/* Two-column toggle layout — used at the top of an import list's
   Settings tab to lay Enabled + Auto-add side by side rather than
   stacked. Collapses to one column below 720px so a narrow view
   still reads cleanly. */
.toggle-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 10px;
}
@media (max-width: 720px) {
  .toggle-grid { grid-template-columns: 1fr; }
}

/* Access rules fieldset — group the two toggles with a small header
   and vertical gap between them. Deliberately un-inputs the fieldset
   default browser chrome. */
.access-rules {
  border: none; padding: 0; margin: 6px 0 0;
  display: flex; flex-direction: column; gap: 8px;
}
.access-rules legend {
  font-size: 11.5px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--muted); padding: 0; margin-bottom: 6px;
}

/* Connected accounts list — one row per household Spotify. Row is
   a bordered card mirroring .toggle-row's look for visual consistency
   with the Access rules above it. */
.account-list {
  display: flex; flex-direction: column; gap: 6px;
  margin-top: 12px;
}
.account-row {
  display: flex; flex-direction: column; gap: 4px;
  padding: 10px 14px;
  border: 1px solid var(--line-soft);
  border-radius: 8px;
  background: color-mix(in srgb, var(--bg-2) 30%, transparent);
}
.account-head {
  display: flex; align-items: center; gap: 10px;
  flex-wrap: wrap;
}
.account-ident {
  display: flex; align-items: center; gap: 8px;
  flex: 1 1 auto; min-width: 0;
  flex-wrap: wrap;
}
.account-ident b {
  font-size: 14px; color: var(--text);
  overflow: hidden; text-overflow: ellipsis;
}
.account-ident .muted {
  color: var(--muted); font-size: 12px;
  padding-left: 4px;
  border-left: 1px solid var(--line-soft);
  margin-left: 4px;
}
.account-actions {
  display: flex; align-items: center; gap: 6px;
  flex: 0 0 auto;
}
.account-foot {
  display: flex; align-items: center; gap: 8px;
  flex-wrap: wrap;
}
.account-foot > span { flex: 0 0 auto; }
.account-scope {
  margin-left: auto;
  max-width: 100%;
}
.account-scope summary {
  cursor: pointer;
  color: var(--muted);
  font-size: 12px;
  padding: 2px 6px;
  border-radius: 4px;
  list-style: none;
}
.account-scope summary::-webkit-details-marker { display: none; }
.account-scope summary::before { content: "+"; font-size: 11px; margin-right: 4px; }
.account-scope[open] summary::before { content: "−"; }
.account-scope summary:hover { color: var(--text); }
.account-scope code {
  display: block;
  margin-top: 4px;
  padding: 8px 10px;
  background: var(--bg-2);
  border-radius: 6px;
  font-size: 11px;
  color: var(--muted);
  word-break: break-word;
  line-height: 1.5;
  max-width: 100%;
}

/* Import lists — /lists page. One row per source, similar visual
   language to the toggle-row so the browse page reads consistently
   with Settings. */
.list-rows { display: flex; flex-direction: column; gap: 8px; padding: 12px 16px; }
.list-row {
  border: 1px solid var(--line-soft);
  border-radius: 8px;
  background: color-mix(in srgb, var(--bg-2) 30%, transparent);
  padding: 10px 14px;
}
.list-row-head { display: flex; align-items: center; gap: 10px; }
.list-row-head b { color: var(--text); }
.list-row-status { margin-top: 4px; }
.list-row-result { margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--line-soft); }
.sample-list { display: flex; flex-direction: column; gap: 3px; margin-top: 4px; }
.sample-row {
  display: flex; align-items: center; gap: 6px;
  font-size: 12.5px; padding: 3px 0;
  border-bottom: 1px dotted color-mix(in srgb, var(--line-soft) 40%, transparent);
}
.sample-row:last-child { border-bottom: 0; }
.warn { color: var(--want); }

/* Account authentication. The signed-out surface deliberately shares the
   product palette but not the application rail: there is nowhere legitimate
   to navigate until a session exists. */
.auth-shell { min-height: 100vh; overflow-x: hidden; }
.auth-wrap {
  min-height: 100vh;
  display: grid;
  place-items: center;
  padding: 32px 18px;
  background:
    radial-gradient(720px 520px at 72% 15%, color-mix(in srgb, var(--accent) 18%, transparent), transparent 68%),
    radial-gradient(620px 520px at 18% 92%, rgba(180,155,255,.08), transparent 70%);
}
.auth-card {
  width: min(100%, 440px);
  padding: 30px;
  border: 1px solid var(--line);
  border-radius: 20px;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  box-shadow: var(--shadow-lift);
  backdrop-filter: blur(22px) saturate(120%);
}
.auth-brand { display: flex; align-items: center; gap: 10px; font-size: 17px; font-weight: 750; letter-spacing: -.02em; }
.auth-mark { width: 36px; height: 36px; display: grid; place-items: center; color: var(--accent); }
.auth-mark svg { width: 27px; height: 27px; }
.auth-copy { margin: 30px 0 24px; }
.auth-copy h1 { margin: 4px 0 8px; font-size: clamp(27px, 5vw, 36px); line-height: 1.08; letter-spacing: -.04em; }
.auth-copy > p:last-child { margin-bottom: 0; color: var(--muted); }
.auth-expiry { font-size: 12px; color: var(--accent) !important; }
.auth-field { display: grid; gap: 7px; margin: 15px 0; }
.auth-field > span, .pair-code-form label > span, .inline-auth-form label > span { color: var(--muted); font-size: 12px; font-weight: 700; letter-spacing: .025em; }
.auth-field input, .pair-code-form input, .inline-auth-form select, .secret-result input {
  width: 100%; min-height: 44px; border: 1px solid var(--line); border-radius: 9px;
  background: var(--bg-2); color: var(--text); padding: 9px 12px; font: inherit;
}
.auth-field input:focus, .pair-code-form input:focus, .inline-auth-form select:focus { outline: 2px solid var(--accent-line); border-color: var(--accent); }
.auth-field small { color: var(--dim); }
.auth-user { margin: 12px 0; padding: 10px 12px; border-radius: 9px; background: var(--bg-2); color: var(--text); font-weight: 700; }
.auth-submit { width: 100%; justify-content: center; min-height: 44px; margin-top: 12px; }
.auth-message { border-radius: 8px; padding: 10px 12px; margin: 14px 0 0; background: color-mix(in srgb, var(--bad) 11%, transparent); border: 1px solid color-mix(in srgb, var(--bad) 38%, transparent); }
.auth-message.bad { color: var(--bad); }
.auth-submit:disabled { opacity: .55; cursor: wait; }

.account-page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; }
.auth-panel { margin-bottom: 18px; overflow: hidden; }
.auth-panel .panel-head p { margin: 3px 0 0; color: var(--muted); }
.pair-code-form, .inline-auth-form { padding: 18px 20px 22px; display: flex; align-items: end; gap: 12px; }
.pair-code-form label, .inline-auth-form label { display: grid; gap: 7px; flex: 1; max-width: 330px; }
.pair-code-form input { text-transform: uppercase; letter-spacing: .16em; font-weight: 800; }
.pair-confirm { margin: 0 20px 22px; padding: 18px; border: 1px solid var(--accent-line); background: var(--accent-soft); border-radius: 12px; display: flex; justify-content: space-between; align-items: center; gap: 20px; }
.pair-confirm h3 { margin: 2px 0 8px; font-size: 20px; }
.pair-confirm p { margin: 0; color: var(--muted); }
.pair-confirm code { font-size: 18px; letter-spacing: .12em; color: var(--accent); }
.auth-pair-spinner { width: 24px; height: 24px; flex: 0 0 auto; border: 2px solid var(--accent-line); border-top-color: var(--accent); border-radius: 50%; animation: auth-pair-spin .8s linear infinite; }
@keyframes auth-pair-spin { to { transform: rotate(360deg); } }
.auth-list { padding: 0 20px 18px; display: grid; gap: 8px; }
.auth-list-row { min-height: 62px; display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 11px 13px; border: 1px solid var(--line-soft); border-radius: 9px; background: color-mix(in srgb, var(--surface-2) 54%, transparent); }
.auth-list-row > div:first-child { min-width: 0; display: grid; gap: 2px; }
.auth-list-row > div:first-child span { color: var(--muted); font-size: 12px; }
.auth-list-row.is-muted { opacity: .56; }
.row-actions { display: flex; gap: 7px; align-items: center; }
.row-actions form { margin: 0; }
.secret-result { margin: 0 20px 22px; padding: 13px; border: 1px solid var(--accent-line); border-radius: 9px; background: var(--accent-soft); }
.secret-result > span { display: block; color: var(--muted); font-size: 12px; margin-bottom: 8px; }
.secret-result > div { display: flex; gap: 8px; }
.secret-result input { min-width: 0; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12px; }
@media (max-width: 680px) {
  .auth-card { padding: 24px 20px; }
  .account-page-head, .pair-confirm, .pair-code-form, .inline-auth-form, .auth-list-row { align-items: stretch; flex-direction: column; }
  .pair-code-form label, .inline-auth-form label { max-width: none; }
  .row-actions { width: 100%; flex-wrap: wrap; }
}

/* Play-to-device handoff. A translucent, compact room picker keeps the title
   art and page context visible behind it; online screens get the only strong
   accent so availability is readable before the labels are scanned. */
body.device-play-open { overflow: hidden; }
.device-play-sheet {
  position: fixed; inset: 0; z-index: 120;
  display: grid; place-items: center; padding: 24px;
  background: rgba(2, 8, 10, .55);
  backdrop-filter: blur(12px) saturate(115%);
}
.device-play-sheet[hidden] { display: none; }
.device-play-card {
  width: min(480px, 100%); overflow: hidden;
  border: 1px solid color-mix(in srgb, var(--accent) 28%, var(--line));
  border-radius: 20px;
  background:
    radial-gradient(440px 180px at 18% -12%, color-mix(in srgb, var(--accent) 20%, transparent), transparent 70%),
    color-mix(in srgb, var(--surface) 88%, transparent);
  box-shadow: 0 28px 90px rgba(0,0,0,.62), inset 0 1px rgba(255,255,255,.045);
  backdrop-filter: blur(24px) saturate(125%);
}
.device-play-head { display: flex; align-items: center; gap: 13px; padding: 21px 22px 14px; }
.device-play-mark {
  width: 44px; height: 44px; flex: 0 0 auto; display: grid; place-items: center;
  color: var(--accent); border: 1px solid var(--accent-line); border-radius: 13px;
  background: var(--accent-soft); box-shadow: inset 0 1px rgba(255,255,255,.06);
}
.device-play-mark svg { width: 28px; height: 28px; }
.device-play-kicker { margin: 0 0 1px; color: var(--accent); font-size: 10.5px; font-weight: 750; letter-spacing: .12em; text-transform: uppercase; }
.device-play-head h2 { margin: 0; font-size: 20px; line-height: 1.2; letter-spacing: -.025em; }
.device-play-close { margin-left: auto; width: 34px; height: 34px; padding: 0; border: 0; border-radius: 50%; background: transparent; color: var(--muted); font-size: 23px; font-weight: 300; }
.device-play-copy { margin: 0; padding: 0 22px 15px; color: var(--muted); font-size: 13px; }
.device-play-copy strong { color: var(--text); font-weight: 650; }
.device-play-modes {
  width: fit-content; margin: 0 22px 12px; padding: 3px; display: flex; gap: 3px;
  border: 1px solid var(--line-soft); border-radius: 10px; background: rgba(0,0,0,.18);
}
.device-play-mode {
  min-height: 31px; padding: 5px 12px; border: 0; border-radius: 7px; color: var(--dim);
  background: transparent; box-shadow: none; font-size: 11.5px; font-weight: 700;
}
.device-play-mode.on {
  color: var(--text); background: color-mix(in srgb, var(--accent) 14%, var(--surface-2));
  box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--accent) 25%, transparent);
}
.device-play-sync-note { margin: -2px 22px 13px; color: var(--dim); font-size: 11px; line-height: 1.45; }
.device-play-list { display: grid; gap: 8px; padding: 0 14px 14px; max-height: min(48vh, 390px); overflow-y: auto; }
.device-play-device {
  width: 100%; min-height: 70px; padding: 11px 13px; display: flex; align-items: center; gap: 12px;
  text-align: left; border-radius: 13px; background: color-mix(in srgb, var(--surface-2) 72%, transparent);
  border-color: var(--line-soft); box-shadow: inset 0 1px rgba(255,255,255,.025);
}
.device-play-device.online:hover, .device-play-device.online:focus-visible { outline: none; border-color: var(--accent-line); background: color-mix(in srgb, var(--accent) 10%, var(--surface-2)); }
.device-play-device.offline { cursor: default; opacity: .55; }
.device-play-device.sending { border-color: var(--accent); }
.device-play-device.sent { border-color: var(--good); background: color-mix(in srgb, var(--good) 10%, var(--surface-2)); }
.device-play-device.selected {
  position: relative; border-color: var(--accent); background: color-mix(in srgb, var(--accent) 13%, var(--surface-2));
}
.device-play-device.selected::after {
  content: ""; position: absolute; left: 30px; top: 58px; width: 1px; height: 20px;
  background: linear-gradient(var(--accent), transparent); box-shadow: 0 0 7px var(--accent);
}
.device-play-device.selected:last-child::after { display: none; }
.device-play-screen { width: 36px; height: 36px; display: grid; place-items: center; flex: 0 0 auto; color: var(--dim); }
.device-play-screen svg { width: 29px; height: 29px; }
.device-play-device.online .device-play-screen { color: var(--accent); filter: drop-shadow(0 0 9px color-mix(in srgb, var(--accent) 38%, transparent)); }
.device-play-words { min-width: 0; display: grid; gap: 2px; }
.device-play-words strong { overflow: hidden; text-overflow: ellipsis; font-size: 14px; }
.device-play-words small { color: var(--muted); font-size: 11.5px; }
.device-play-device.online .device-play-words small::before { content: ""; display: inline-block; width: 6px; height: 6px; margin: 0 6px 1px 0; border-radius: 50%; background: var(--good); box-shadow: 0 0 8px color-mix(in srgb, var(--good) 65%, transparent); }
.device-play-state { margin-left: auto; color: var(--dim); font-size: 11px; font-weight: 750; letter-spacing: .04em; text-transform: uppercase; }
.device-play-device.online .device-play-state { color: var(--accent); }
.device-play-device.sent .device-play-state { color: var(--good); }
.device-play-device.selected .device-play-state { color: var(--accent); }
.device-play-loading, .device-play-empty { min-height: 82px; display: flex; align-items: center; justify-content: center; padding: 18px; color: var(--muted); text-align: center; border: 1px dashed var(--line); border-radius: 13px; }
.device-play-loading { gap: 5px; }
.device-play-loading span { width: 5px; height: 5px; border-radius: 50%; background: var(--accent); animation: device-play-pulse .9s ease-in-out infinite alternate; }
.device-play-loading span:nth-child(2) { animation-delay: .15s; }
.device-play-loading span:nth-child(3) { animation-delay: .3s; margin-right: 6px; }
.device-play-empty.error, #device-play-status.error { color: var(--bad); }
.device-play-foot { min-height: 48px; padding: 11px 21px; display: flex; align-items: center; justify-content: space-between; gap: 18px; border-top: 1px solid var(--line-soft); color: var(--dim); font-size: 11.5px; background: rgba(0,0,0,.13); }
.device-play-foot a { flex: 0 0 auto; color: var(--muted); }
.device-play-foot-actions { display: flex; align-items: center; gap: 12px; flex: 0 0 auto; }
.device-play-sync-start { color: #061013; border-color: var(--accent); background: var(--accent); font-weight: 800; }
.device-play-sync-start:disabled { opacity: .42; cursor: default; }
.play-device-trigger { display: inline-flex; align-items: center; gap: 6px; }
.play-device-trigger svg { width: 14px; height: 14px; color: var(--accent); }
@keyframes device-play-pulse { to { opacity: .25; transform: translateY(-2px); } }
@media (prefers-reduced-motion: reduce) {
  .device-play-loading span { animation: none; }
}
@media (max-width: 560px) {
  .device-play-sheet { align-items: end; padding: 12px; }
  .device-play-card { border-radius: 18px; }
  .device-play-foot { align-items: flex-start; flex-direction: column; }
  .device-play-foot-actions { width: 100%; justify-content: space-between; }
}

/* Title navigation feedback. A cover responds on the click itself; the glass
   status card waits 140ms, so ordinary fast pages never flash a modal while a
   large series or a busy database still has an unmistakable working state. */
.title-navigation-pending { cursor: progress; }
a.is-title-loading { outline: 1px solid var(--accent-line); outline-offset: 3px; }
.card.is-title-loading .poster::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(110deg, transparent 22%, color-mix(in srgb, var(--accent) 24%, transparent) 48%, transparent 74%);
  animation: title-cover-scan 1s linear infinite;
}
.title-page-loader[hidden] { display: none; }
.title-page-loader {
  position: fixed; z-index: 1200; inset: 0; display: grid; place-items: center;
  padding: 24px; background: rgba(4, 8, 11, .54);
  backdrop-filter: blur(7px) saturate(112%);
  animation: title-loader-in .16s ease-out both;
}
.title-page-loader-card {
  width: min(390px, calc(100vw - 36px)); min-height: 92px; box-sizing: border-box;
  display: grid; grid-template-columns: 50px minmax(0, 1fr); align-items: center; gap: 16px;
  padding: 18px 20px; border: 1px solid color-mix(in srgb, var(--accent) 32%, var(--line));
  border-radius: 17px;
  background:
    radial-gradient(230px 100px at 9% 0%, color-mix(in srgb, var(--accent) 15%, transparent), transparent 72%),
    color-mix(in srgb, var(--surface) 91%, transparent);
  box-shadow: 0 24px 70px rgba(0,0,0,.5), inset 0 1px rgba(255,255,255,.04);
}
.title-page-loader-orbit, .history-loading-orbit {
  position: relative; display: grid; place-items: center; border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--accent) 34%, transparent);
}
.title-page-loader-orbit { --orbit-radius: 17px; width: 46px; height: 46px; }
.title-page-loader-orbit::before, .history-loading-orbit::before {
  content: ""; position: absolute; inset: 6px; border-radius: 50%;
  border: 1px solid color-mix(in srgb, var(--accent) 20%, transparent);
}
.title-page-loader-orbit i, .history-loading-orbit i {
  position: absolute; width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent); box-shadow: 0 0 12px color-mix(in srgb, var(--accent) 72%, transparent);
  animation: title-orbit 1.05s linear infinite;
}
.title-page-loader-copy { min-width: 0; display: grid; gap: 2px; }
.title-page-loader-copy small {
  color: var(--accent); font-size: 10px; font-weight: 750;
  letter-spacing: .105em; text-transform: uppercase;
}
.title-page-loader-copy strong {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  color: var(--text); font-size: 18px; line-height: 1.28; letter-spacing: -.018em;
}
.title-page-loader-copy > span { color: var(--muted); font-size: 11.5px; }

/* The title is interactive before provider history is. Keep that slower,
   reference-only work visible inside its own destination instead of making
   every Overview/Seasons visit wait for it. */
.history-loading-panel .panel-head { border-bottom: 1px solid var(--line-soft); }
.history-loading {
  display: flex; align-items: center; gap: 13px; min-height: 68px;
  padding: 13px 18px; color: var(--muted);
  background: linear-gradient(90deg, color-mix(in srgb, var(--accent) 3%, transparent), transparent 42%);
}
.history-loading-orbit { --orbit-radius: 10px; flex: 0 0 auto; width: 30px; height: 30px; }
.history-loading-orbit i { width: 5px; height: 5px; animation-duration: .9s; }
.history-loading > span:last-child { display: grid; gap: 2px; }
.history-loading strong { color: var(--text); font-size: 12.5px; font-weight: 620; }
.history-loading small { color: var(--dim); font-size: 10.5px; }

@keyframes title-loader-in { from { opacity: 0; } }
@keyframes title-orbit { from { transform: rotate(0deg) translateX(var(--orbit-radius)) rotate(0deg); } to { transform: rotate(360deg) translateX(var(--orbit-radius)) rotate(-360deg); } }
@keyframes title-cover-scan { from { transform: translateX(-115%); } to { transform: translateX(115%); } }
@media (prefers-reduced-motion: reduce) {
  .title-page-loader, .title-page-loader-orbit i, .history-loading-orbit i, .card.is-title-loading .poster::after { animation: none; }
}
/* --------------------------------------------------------- devices control */
.device-page-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px; }
.device-page-head .lede { max-width: 760px; }

/* The signal board is the page's one expressive move: it reads like a quiet
   distribution bus in an AV rack, with real live counts attached to the line. */
.device-signal-board {
  position: relative;
  display: grid;
  grid-template-columns: minmax(220px, .72fr) minmax(120px, 1fr) auto;
  align-items: center;
  gap: 22px;
  min-height: 104px;
  margin: 4px 0 30px;
  padding: 20px 24px;
  overflow: hidden;
  border: 1px solid var(--accent-line);
  border-radius: 16px;
  background:
    linear-gradient(105deg, color-mix(in srgb, var(--accent) 11%, var(--surface)), color-mix(in srgb, var(--surface) 86%, transparent)),
    var(--surface);
  box-shadow: var(--shadow);
}
.device-signal-board::after {
  content: "";
  position: absolute;
  width: 260px; height: 260px; right: -120px; top: -170px;
  border: 1px solid color-mix(in srgb, var(--accent) 18%, transparent);
  border-radius: 50%;
  pointer-events: none;
}
.device-signal-title { display: flex; align-items: center; gap: 13px; min-width: 0; }
.device-signal-title small {
  display: block; margin-bottom: 3px; color: var(--muted); font-size: 10px;
  font-weight: 700; letter-spacing: .14em; text-transform: uppercase;
}
.device-signal-title strong { display: block; font-size: 15px; font-weight: 650; }
.device-live-mark {
  display: grid; place-items: center; flex: 0 0 auto; width: 34px; height: 34px;
  border: 1px solid color-mix(in srgb, var(--good) 35%, transparent);
  border-radius: 50%; background: color-mix(in srgb, var(--good) 8%, transparent);
}
.device-live-mark i { width: 8px; height: 8px; border-radius: 50%; background: var(--good); box-shadow: 0 0 0 5px color-mix(in srgb, var(--good) 12%, transparent), 0 0 16px var(--good); }
.device-signal-line { position: relative; height: 16px; border-top: 1px solid var(--accent-line); }
.device-signal-line::before,
.device-signal-line::after,
.device-signal-line i { content: ""; position: absolute; top: -4px; width: 7px; height: 7px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 9px color-mix(in srgb, var(--accent) 62%, transparent); }
.device-signal-line::before { left: 0; }
.device-signal-line::after { right: 0; }
.device-signal-line i:nth-child(1) { left: 25%; }
.device-signal-line i:nth-child(2) { left: 50%; }
.device-signal-line i:nth-child(3) { left: 75%; }
.device-signal-counts { display: flex; gap: 10px; margin: 0; }
.device-signal-counts div { min-width: 86px; padding: 9px 12px; border-left: 1px solid var(--line); }
.device-signal-counts dt { color: var(--muted); font-size: 10px; font-weight: 650; letter-spacing: .08em; text-transform: uppercase; white-space: nowrap; }
.device-signal-counts dd { margin: 3px 0 0; color: var(--text); font-size: 22px; font-weight: 660; letter-spacing: -.04em; }

.device-section { margin-top: 28px; }
.device-section[hidden] { display: none; }
.device-section-head { display: flex; align-items: end; justify-content: space-between; gap: 24px; margin-bottom: 13px; }
.device-section-head .eyebrow { margin-bottom: 4px; }
.device-section-head h2 { margin: 0; font-size: 20px; letter-spacing: -.025em; }
.device-section-head > p { margin: 0 0 2px; color: var(--muted); font-size: 12px; text-align: right; }

.shared-play-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(390px, 1fr)); gap: 14px; }
.shared-play-card {
  padding: 19px 20px 17px; border: 1px solid var(--accent-line); border-radius: 14px;
  background: linear-gradient(145deg, color-mix(in srgb, var(--accent) 8%, var(--surface)), var(--surface));
  box-shadow: var(--shadow);
}
.shared-play-head { display: flex; align-items: start; justify-content: space-between; gap: 18px; }
.shared-play-kicker { display: block; margin-bottom: 5px; color: var(--accent); font-size: 10px; font-weight: 750; letter-spacing: .13em; }
.shared-play-head h3 { margin: 0; font-size: 17px; }
.shared-play-head p { margin: 4px 0 0; color: var(--muted); font-size: 12.5px; }
.shared-room-id { padding: 5px 8px; border: 1px solid var(--line); border-radius: 6px; color: var(--dim); background: var(--bg-2); font-size: 10px; }
.shared-member-rail { position: relative; display: flex; gap: 10px; margin-top: 18px; padding-top: 14px; border-top: 1px solid var(--line-soft); }
.shared-member { display: flex; align-items: center; gap: 9px; min-width: 150px; }
.shared-member span:last-child { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.shared-member b { overflow: hidden; font-size: 12px; text-overflow: ellipsis; white-space: nowrap; }
.shared-member small { color: var(--muted); font-size: 10.5px; }

.device-status-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(420px, 1fr)); gap: 14px; }
.device-card {
  position: relative; min-width: 0; overflow: hidden; border: 1px solid var(--line-soft);
  border-radius: 14px; background: color-mix(in srgb, var(--surface) 92%, transparent); box-shadow: var(--shadow);
}
.device-card::before { content: ""; position: absolute; inset: 0 auto 0 0; width: 2px; background: var(--line); }
.device-card.is-playing::before { background: var(--good); box-shadow: 0 0 14px color-mix(in srgb, var(--good) 60%, transparent); }
.device-card.is-buffering::before { background: var(--warn); }
.device-card.is-error::before { background: var(--bad); }
.device-card.is-offline { opacity: .72; background: color-mix(in srgb, var(--surface) 66%, transparent); }
.device-card-head { display: flex; align-items: center; justify-content: space-between; gap: 18px; padding: 17px 18px 15px 20px; border-bottom: 1px solid var(--line-soft); }
.device-identity { display: flex; align-items: center; gap: 11px; min-width: 0; }
.device-identity > span:last-child { min-width: 0; }
.device-identity h3 { overflow: hidden; margin: 0; font-size: 15px; text-overflow: ellipsis; white-space: nowrap; }
.device-identity small { display: block; margin-top: 2px; color: var(--dim); font-size: 10.5px; }
.device-name-display { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.device-name-display h3 { min-width: 0; }
.device-rename-trigger,
.device-rename-cancel { padding: 0; border: 0; color: var(--dim); background: none; font: inherit; font-size: 10px; cursor: pointer; }
.device-rename-trigger:hover,
.device-rename-trigger:focus-visible,
.device-rename-cancel:hover,
.device-rename-cancel:focus-visible { color: var(--accent); }
.device-rename-form { display: flex; align-items: center; gap: 6px; min-width: 0; margin: -5px 0 -4px; }
.device-rename-form[hidden] { display: none; }
.device-rename-form input { width: min(230px, 30vw); min-width: 130px; height: 30px; padding: 5px 8px; font-size: 12px; }
.device-rename-form .btn { min-height: 30px; padding: 5px 9px; }
.device-status-dot { flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%; background: var(--dim); }
.device-status-dot.online { background: var(--accent); box-shadow: 0 0 0 4px var(--accent-soft); }
.device-status-dot.playing { background: var(--good); box-shadow: 0 0 0 4px color-mix(in srgb, var(--good) 12%, transparent), 0 0 12px color-mix(in srgb, var(--good) 48%, transparent); }
.device-state { flex: 0 0 auto; text-align: right; }
.device-state strong { display: block; font-size: 11.5px; }
.device-state small { display: block; margin-top: 2px; color: var(--dim); font-size: 10px; }

.device-playback { padding: 18px 18px 16px 20px; }
.device-now-playing { min-width: 0; }
.device-title { color: var(--text); font-size: 18px; font-weight: 660; letter-spacing: -.02em; text-decoration: none; }
.device-title:hover { color: var(--accent); }
.device-now-playing p { overflow: hidden; margin: 4px 0 0; color: var(--muted); font-size: 12.5px; text-overflow: ellipsis; white-space: nowrap; }
.device-route-row { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 13px; }
.device-route,
.device-room-chip { padding: 4px 8px; border-radius: 6px; font-size: 10px; font-weight: 650; }
.device-route { color: var(--accent); background: var(--accent-soft); border: 1px solid var(--accent-line); }
.device-room-chip { color: var(--want); background: color-mix(in srgb, var(--want) 11%, transparent); border: 1px solid color-mix(in srgb, var(--want) 30%, transparent); }
.device-file { display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; gap: 9px; margin-top: 13px; }
.device-file > span { color: var(--dim); font-size: 9px; font-weight: 750; letter-spacing: .13em; }
.device-file code { overflow: hidden; color: var(--muted); font-size: 10.5px; text-overflow: ellipsis; white-space: nowrap; }
.device-timeline { margin-top: 16px; }
.device-timeline-track { height: 3px; overflow: hidden; border-radius: 4px; background: var(--line); }
.device-timeline-track i { display: block; height: 100%; border-radius: inherit; background: var(--accent); box-shadow: 0 0 8px var(--accent); }
.device-times { display: flex; justify-content: space-between; margin-top: 5px; color: var(--dim); font: 10px ui-monospace, SFMono-Regular, Menlo, monospace; }
.device-playback-action { display: flex; align-items: center; justify-content: space-between; gap: 14px; margin-top: 14px; }
.device-updated { color: var(--dim); font-size: 10.5px; }
.device-playback-action form { margin: 0; }
.device-idle { display: flex; align-items: center; gap: 12px; min-height: 86px; padding: 18px 20px; }
.device-idle-line { width: 34px; height: 1px; background: var(--line); }
.device-idle p { margin: 0; color: var(--muted); font-size: 12px; }

.device-card-loading { display: grid; gap: 11px; padding: 20px; }
.device-card-loading span { display: block; height: 11px; border-radius: 6px; background: linear-gradient(90deg, var(--line-soft), var(--line), var(--line-soft)); background-size: 200% 100%; animation: device-loading 1.2s linear infinite; }
.device-card-loading span:nth-child(1) { width: 34%; }
.device-card-loading span:nth-child(2) { width: 72%; }
.device-card-loading span:nth-child(3) { width: 92%; }
@keyframes device-loading { to { background-position: -200% 0; } }

@media (max-width: 980px) {
  .device-signal-board { grid-template-columns: 1fr auto; }
  .device-signal-line { display: none; }
  .device-status-list { grid-template-columns: 1fr; }
}
@media (max-width: 680px) {
  .device-page-head, .device-section-head { align-items: flex-start; flex-direction: column; }
  .device-section-head > p { text-align: left; }
  .device-signal-board { grid-template-columns: 1fr; }
  .device-signal-counts { width: 100%; }
  .device-signal-counts div { flex: 1; min-width: 0; }
  .device-status-list, .shared-play-list { grid-template-columns: minmax(0, 1fr); }
  .device-card-head { align-items: flex-start; }
}
@media (prefers-reduced-motion: reduce) {
  .device-card-loading span { animation: none; }
}
