/* ═══════════════════════════════════════════════════════════════════
   Unit3D Tracker Dashboard — Stylesheet
   ═══════════════════════════════════════════════════════════════════ */

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{
  --bg:#0d0f14;--surface:#13161e;--surface2:#1a1e2a;--surface3:#1f2433;
  --border:#252b3b;--border2:#2e3548;
  --accent:#6d56eb;--accent-h:#5a44d4;--accent-glow:rgba(109,86,235,.25);
  --green:#22c55e;--red:#ef4444;--amber:#f59e0b;--blue:#3b82f6;
  --teal:#2dd4bf;--purple:#a855f7;--orange:#f97316;--pink:#ec4899;--yellow:#facc15;
  --text:#e2e8f0;--text2:#94a3b8;--text3:#64748b;
  --radius:10px;--radius-sm:6px;--shadow:0 4px 24px rgba(0,0,0,.4);
  --topbar-bg:rgba(13,15,20,.95);--table-hover:rgba(255,255,255,.025);
  /* Themeable whites & overlays */
  --btn-primary-text:#fff;
  --toggle-thumb:#fff;
  --overlay-bg:rgba(0,0,0,.65);
  --overlay-bg-sm:rgba(0,0,0,.5);
  /* Themeable semantic alphas — override in your theme to match your accent/semantic colours */
  --error-bg:rgba(239,68,68,.05);
  --error-border:rgba(239,68,68,.15);
  --error-bg-md:rgba(239,68,68,.1);
  --error-bg-lg:rgba(239,68,68,.12);
  --error-border-md:rgba(239,68,68,.25);
  --error-border-lg:rgba(239,68,68,.35);
  --accent-border:rgba(109,86,235,.3);
  --amber-bg:rgba(245,158,11,.15);
  --amber-border:rgba(245,158,11,.4);
  --accent-bg-sm:rgba(109,86,235,.12);
  --accent-bg-md:rgba(109,86,235,.15);
  --accent-border-sm:rgba(109,86,235,.25);
  --accent-border-md:rgba(109,86,235,.30);
  /* Badge-membership derived from --blue */
  --blue-bg:rgba(59,130,246,.10);
  --blue-border:rgba(59,130,246,.20);
  /* QUI bar SVG icon colours — match the semantic vars above */
  --qui-dl-color:var(--purple);
  --qui-ul-color:var(--green);
  --qui-free-color:var(--text3);
  --qui-ratio-icon-color:var(--text3);
  --qui-size-color:var(--teal);
}
html{background:var(--bg);color:var(--text);font-family:'Geist',sans-serif;font-size:14px;line-height:1.5;min-height:100vh;overflow-y:auto}
body{min-height:100vh;background:var(--bg)}
html{overflow-x:clip}
::-webkit-scrollbar{width:6px;height:6px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--border2);border-radius:3px}

/* ── Layout ── */
/* Comfortable maximum for surfaces that are read rather than scanned — forms,
   label→value lists. They gain nothing from an ultrawide and lose plenty: a
   toggle three feet from its label, a value 1000px from the field it belongs
   to. Grids, tables and charts deliberately DON'T use this; they get the whole
   window. Kept out of the themed :root block since it isn't a theme concern. */
:root{--reading-max:1600px}
.app-wrapper{display:flex;flex-direction:column;min-height:100vh}
.topbar{position:sticky;top:0;z-index:200;display:flex;align-items:center;gap:12px;padding:0 24px;height:58px;background:var(--topbar-bg);backdrop-filter:blur(12px);border-bottom:1px solid var(--border)}
.topbar-logo{display:flex;align-items:center;gap:10px;font-weight:700;font-size:16px;letter-spacing:-.3px;text-decoration:none;color:var(--text)}
.topbar-sep{width:1px;height:20px;background:var(--border);margin:0 4px}
.topbar-badge{font-size:11px;font-weight:600;letter-spacing:.5px;padding:2px 8px;border-radius:20px;background:var(--accent-glow);color:var(--accent);border:1px solid var(--accent-border-md)}
.topbar-right{margin-left:auto;display:flex;align-items:center;gap:8px}
/* No max-width: on an ultrawide a capped .main left ~800px dead on each side
   while the topbar ran edge to edge, so the content read as a floating island.
   The 24px side padding matches the topbar's, keeping the logo and the first
   column on the same line. Anything inside that would look silly stretched to
   3000px caps itself locally (.expanded-cols, .sc-spark) rather than holding
   the whole page back. */
.main{flex:1;padding:24px 24px 48px;width:100%;margin:0 auto}

/* ── View toggle ── */
.view-toggle{display:flex;background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius-sm);overflow:hidden;flex-shrink:0}
.view-btn{display:flex;align-items:center;gap:5px;padding:5px 12px;font-size:12px;font-weight:500;font-family:inherit;cursor:pointer;border:none;background:transparent;color:var(--text3);transition:background .15s,color .15s;white-space:nowrap}
.view-btn:hover{color:var(--text2)}
.view-btn.active{background:var(--surface);color:var(--text)}

/* ── Narrow screens ──
   The topbar is a fixed row of four view buttons plus the logo, the badge, the
   refresh time and four icon actions. Below ~640px that adds up to more than
   the viewport and pushed the whole PAGE into horizontal scroll — every view
   under it dragged sideways by a header that wouldn't fit.
   Nothing here is removed, only de-labelled: the four views stay reachable as
   icons (each button carries a title), and what goes is decoration — the badge,
   the separator, the "updated N ago" line, and finally the wordmark beside a
   logo that already says Yata. */
/* Decoration goes first: the badge, its separator and the refresh time buy
   back ~175px, which is enough to keep the four view LABELS down to 640. */
@media(max-width:820px){
  .topbar{padding:0 14px;gap:10px}
  .topbar-sep,.topbar-badge{display:none}
  .topbar-right{gap:5px}
  .topbar-right #last-refresh{display:none}
}
@media(max-width:640px){
  .topbar{padding:0 12px;gap:8px}
  .view-btn{padding:6px 10px;gap:0}
  .view-btn-label{display:none}
}
@media(max-width:420px){
  /* The logo mark alone still identifies the app; the wordmark is the last
     thing worth its width when four views and four actions have to fit.
     The padding squeeze that follows is what gets a 320px phone — the
     narrowest still in circulation — under the line. */
  .topbar-logo{font-size:0;gap:0}
  .topbar-logo .yata-logo{font-size:16px}
  .topbar{padding:0 6px;gap:4px}
  .view-btn{padding:6px 7px}
  .topbar-right .btn-icon{padding:4px 6px}
}

/* ── Buttons ── */
.btn{display:inline-flex;align-items:center;gap:6px;padding:7px 14px;border-radius:var(--radius-sm);font-size:13px;font-weight:500;font-family:inherit;cursor:pointer;border:1px solid transparent;transition:background .15s,border-color .15s,transform .1s;user-select:none;white-space:nowrap}
.btn:active{transform:scale(.97)}
.btn-primary{background:var(--accent);color:var(--btn-primary-text);border-color:var(--accent)}
.btn-primary:hover{background:var(--accent-h)}
.btn-ghost{background:transparent;color:var(--text2);border-color:var(--border)}
.btn-ghost:hover{background:var(--surface2);color:var(--text);border-color:var(--border2)}
.btn-danger{background:var(--error-bg-md);color:var(--red);border-color:var(--error-border-md)}
.btn-danger:hover{background:var(--error-bg-lg);border-color:var(--red)}
.btn-icon{padding:7px}
.btn-sm{padding:5px 10px;font-size:12px}
.btn[disabled]{opacity:.4;pointer-events:none}

/* ── Status dot ── */
.sdot{width:8px;height:8px;border-radius:50%;flex-shrink:0;display:inline-block}
.sdot.green{background:var(--green);box-shadow:0 0 5px rgba(34,197,94,.6)}
.sdot.red{background:var(--red);box-shadow:0 0 5px rgba(239,68,68,.6)}
.sdot.amber{background:var(--amber);box-shadow:0 0 5px rgba(245,158,11,.6)}
.sdot.pulse{animation:sdpulse 2s infinite}
@keyframes sdpulse{0%,100%{opacity:1}50%{opacity:.3}}
@keyframes spin{to{transform:rotate(360deg)}}
.spinning{animation:spin .8s linear infinite}

/* ══ SHARED: Aggregate stat cards ══ */
.stat-cards-row{display:grid;grid-template-columns:repeat(6,1fr);gap:12px;margin-bottom:16px}
@media(max-width:1300px){.stat-cards-row{grid-template-columns:repeat(3,1fr)}}
@media(max-width:700px){.stat-cards-row{grid-template-columns:1fr 1fr}}
.stat-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:16px 18px 12px;display:flex;flex-direction:column;gap:4px;position:relative;overflow:hidden}
.stat-card::after{content:'';position:absolute;top:0;left:0;right:0;height:2px;background:var(--card-accent,var(--accent));opacity:.7}
.sc-label{font-size:11px;color:var(--text3);font-weight:500;text-transform:uppercase;letter-spacing:.6px}
.sc-value{font-size:22px;font-weight:700;font-family:'Geist Mono',monospace;letter-spacing:-.5px;color:var(--card-accent,var(--text));line-height:1.2;margin-top:2px}
.sc-sub{font-size:11px;color:var(--text3);margin-bottom:4px}
/* Grows with the card instead of staying a fixed 36px ribbon: on an ultrawide
   the six cards are ~550px each, and a week of data drawn 36px tall across
   that is a flat line with no readable shape. Clamped at both ends so it can't
   shrink below the old height or grow tall enough to dominate the numbers. */
.sc-spark{width:100%;height:auto;aspect-ratio:7/1;min-height:36px;max-height:64px;margin-top:6px}
.sc-spark svg{width:100%;height:100%;display:block;overflow:visible}
/* Aggregate card 7-day change chip — mirrors .stat-delta-chip's family/weight
   (Detail page) so the top cards and Detail read as one system. Always
   reserves its one-line slot (block + min-height) even when empty — so a
   card WITHOUT a chip (Tracker Health, which has no history to diff, and any
   card whose change rounds to zero) keeps its sparkline aligned with the
   cards that do show a chip, rather than riding a line higher. */
.agg-delta{display:block;font-size:11px;font-weight:500;line-height:1.35;min-height:1.35em;color:var(--text3);font-family:'Geist Mono',monospace;white-space:nowrap}
.agg-delta--up{color:var(--green)}
.agg-delta--down{color:var(--red)}
.agg-delta--muted{color:var(--text3)}
.sc-health-row{display:flex;align-items:baseline;gap:6px;margin-top:2px}
.sc-health-main{font-size:24px;font-weight:700;font-family:'Geist Mono',monospace;letter-spacing:-.5px;line-height:1}
.sc-health-denom{font-size:14px;font-weight:500;color:var(--text3);font-family:'Geist Mono',monospace}

/* ══ GRID VIEW ══ */
#view-grid{display:block}
#view-table{display:none}
.page-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:20px;flex-wrap:wrap;gap:12px}
.page-title{font-size:20px;font-weight:700;letter-spacing:-.4px}
.page-subtitle{color:var(--text2);font-size:13px;margin-top:2px}
.summary-bar{display:flex;gap:12px;margin-bottom:20px;flex-wrap:wrap}
.summary-pill{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-sm);padding:10px 16px;display:flex;align-items:center;gap:8px}
.sp-label{font-size:12px;color:var(--text3)}
.sp-value{font-size:15px;font-weight:700;font-family:'Geist Mono',monospace;letter-spacing:-.3px}
/* Masonry — CSS multi-columns so cards of differing heights pack tightly with
   no large vertical gaps. DOM order flows column-major; drag-reorder still works. */
.tracker-grid{column-width:400px;column-gap:16px}
.tracker-grid > .tracker-card{break-inside:avoid;-webkit-column-break-inside:avoid;page-break-inside:avoid;width:100%;margin:0 0 16px;display:inline-block;vertical-align:top}

/* ── Even heights ──
   Masonry packs tightly but flows COLUMN-major: at three or four columns that
   reads fine, but across an ultrawide's seven or eight the eye wants rows and
   gets a ragged wall instead. With the option on, the layout becomes a real
   grid — left-to-right reading order, cards in a row sharing a height — which
   only works because the card's variable-height sections collapse at the same
   time (see cardExtras in views/grid.ts). Both halves are needed: a grid alone
   would stretch every card to the tallest in its row. */
.tracker-grid.grid--even{columns:auto;column-width:auto;display:grid;grid-template-columns:repeat(auto-fill,minmax(400px,1fr));gap:16px}
.tracker-grid.grid--even > .tracker-card{display:flex;flex-direction:column;width:auto;margin:0}
.tracker-grid.grid--even > .tracker-card .card-body{flex:1}
/* Footers line up along the bottom of each row rather than floating mid-card. */
.tracker-grid.grid--even > .tracker-card .card-footer{margin-top:auto}

/* Collapsed Targets / More Stats, with a per-card peek. */
.card-extra-toggle{
  width:100%;display:flex;align-items:center;justify-content:center;gap:6px;
  background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius-sm);
  color:var(--text3);font-size:11px;font-weight:600;letter-spacing:.02em;
  padding:6px 10px;cursor:pointer;transition:color .15s,border-color .15s;
}
.card-extra-toggle:hover{color:var(--text);border-color:var(--border2)}
.card-extra-caret{transition:transform .15s;display:inline-block}
.card-extra[data-open="1"] .card-extra-caret{transform:rotate(180deg)}
.card-extra-body{display:none;flex-direction:column;gap:10px;margin-top:10px}
.card-extra[data-open="1"] .card-extra-body{display:flex}

/* ── Grid controls bar ──
   Reuses the History view's control styling (.history-menu-*, .history-range-btn)
   — they are the app's generic control-bar look now, not history-specific. */
.grid-controls{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:14px}
.grid-ctl-label{font-size:11px;font-weight:600;color:var(--text3);letter-spacing:.04em;text-transform:uppercase}
.grid-ctl-select{max-width:170px;padding:5px 8px;font-size:12px}
.grid-ctl-hint{font-size:11px;color:var(--text3);font-style:italic;margin-left:auto}
/* The filter menu lists every tracker, so it needs to scroll on big setups. */
.grid-filter-menu{max-height:min(60vh,420px);overflow-y:auto;min-width:210px}
.drag-handle.is-disabled{cursor:not-allowed;opacity:.35}
.tracker-card:hover .drag-handle.is-disabled{opacity:.35}

/* ── Cards ── */
.tracker-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;transition:border-color .2s,box-shadow .2s,opacity .2s,transform .15s;cursor:default}
.tracker-card:active{cursor:default}
.tracker-card:hover{border-color:var(--border2);box-shadow:var(--shadow)}
.tracker-card.dragging{opacity:.4;transform:scale(.98)}
.tracker-card.drag-over{border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-glow)}
.tracker-card.loading .card-body{opacity:.5;pointer-events:none}
.tracker-card.error-state .card-header{border-bottom-color:var(--error-border)}
.drag-handle{display:flex;align-items:center;padding:0 4px;cursor:grab;color:var(--border2);flex-shrink:0;opacity:0;transition:opacity .15s}
.tracker-card:hover .drag-handle{opacity:1}
.drag-handle:hover{color:var(--text3)}
.card-header{display:flex;align-items:center;gap:8px;padding:12px 14px;border-bottom:1px solid var(--border);background:var(--surface2)}
.card-header-info{flex:1;min-width:0}
.card-tracker-name{font-weight:600;font-size:14px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.card-header-meta{display:flex;align-items:center;gap:6px;margin-top:3px;flex-wrap:wrap}
.card-tracker-url{font-size:11px;color:var(--text3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-family:'Geist Mono',monospace;text-decoration:none;transition:color .15s}
.card-tracker-url:hover{color:var(--accent);text-decoration:underline}
.card-header-actions{display:flex;gap:4px;flex-shrink:0}
.badge-membership{font-size:11px;font-weight:600;padding:2px 8px;border-radius:20px;background:var(--blue-bg);color:var(--blue);border:1px solid var(--blue-border);font-family:'Geist Mono',monospace;letter-spacing:.3px}
/* Account deadline badges — inactivity pruning and API key expiry. Amber
   while the deadline can still be met, red once it has passed. Only rendered
   when a deadline is actually near, so most cards never show one. */
.account-warn{font-size:11px;font-weight:600;padding:2px 8px;border-radius:20px;border:1px solid;font-family:'Geist Mono',monospace;letter-spacing:.3px;white-space:nowrap;cursor:help}
.account-warn--amber{background:var(--amber-bg);color:var(--amber);border-color:var(--amber-border)}
.account-warn--red{background:var(--error-bg);color:var(--red);border-color:var(--error-border)}
.badge-group{font-size:11px;font-weight:600;padding:2px 7px;border-radius:20px;background:var(--accent-bg-md);color:var(--accent);border:1px solid var(--accent-border-sm);letter-spacing:.3px}
.badge-group-styled{font-size:11px;font-weight:600;letter-spacing:.3px;padding:2px 8px;border-radius:20px;border:1px solid;display:inline-flex;align-items:center;gap:5px;border-color:color-mix(in srgb,currentColor 35%,transparent);background:color-mix(in srgb,currentColor 12%,transparent)}
.badge-group-styled i{font-size:11px}
/* Sparkle effect — top-tier groups (e.g. GodPool).
   The sparkles.gif tiles at its natural size across the element (no stretching).
   mix-blend-mode:screen makes the dark GIF background transparent, leaving only the sparks.
   pointer-events:none on ::after so hover/click still targets the element. */
.group-sparkle{position:relative}
.group-sparkle::after{content:'';position:absolute;inset:0;border-radius:inherit;background-image:url('/static/img/sparkles.gif');background-size:auto;background-repeat:repeat;mix-blend-mode:screen;pointer-events:none;opacity:.9}
.username-inner{display:inline-flex;align-items:center;gap:5px;overflow:visible}
.username-inner i{font-size:12px}
.badge-group-icon{display:inline-flex;align-items:center;width:14px;height:14px;flex-shrink:0}
.badge-group-icon svg{width:100%;height:100%}
.targets-group-badge{font-size:11px;font-weight:600;letter-spacing:.3px;color:var(--text3);margin-bottom:6px;display:inline-flex;align-items:center;gap:5px}
.targets-group-badge i{font-size:12px}
.target-group-hint-wrap{display:flex;flex-direction:column;gap:8px;margin:4px 0 10px;padding:10px 12px;background:var(--surface2);border:1px solid var(--border);border-radius:8px}
.target-group-hint-name{font-size:12px;font-weight:700;letter-spacing:.2px;display:inline-flex;align-items:center;gap:5px}
.target-group-hint-name i{font-size:11px}
.target-group-hint-desc{font-size:12px;color:var(--text3);line-height:1.45;max-width:100%;white-space:normal;word-break:break-word}
/* Requirement chips — read-only summary shown when a target group is selected */
.target-chip-row{display:flex;flex-wrap:wrap;gap:6px}
.target-chip{display:inline-flex;align-items:center;border:1px solid var(--border);border-radius:12px;overflow:hidden;font-size:11px;line-height:1;background:var(--surface)}
.target-chip-k{padding:5px 7px;color:var(--text3);font-weight:600;letter-spacing:.2px;background:color-mix(in srgb,var(--accent) 8%,transparent)}
.target-chip-v{padding:5px 8px;color:var(--text);font-weight:600;font-family:'Geist Mono',monospace}
.target-chip-anyof{display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.target-chip-anyof-label{font-size:10px;color:var(--text3);font-style:italic;letter-spacing:.3px}
/* Manual target builder rows */
.target-edit-row{display:flex;align-items:center;gap:8px;margin-bottom:8px}
.target-edit-label{flex:0 0 150px;font-size:12px;font-weight:600;color:var(--text2);letter-spacing:.2px}
.target-edit-row .form-input{flex:1;min-width:0}
/* Goal-date control (goal pacing): a small icon button per row — the date
   input itself lives in an anchored pop so it never squeezes the value. */
.goal-date-wrap{position:relative;display:inline-flex;flex-shrink:0}
.goal-date-btn{color:var(--text3)}
.goal-date-btn:hover{color:var(--text)}
.goal-date-btn--set{color:var(--accent)}
.goal-date-btn--set:hover{color:var(--accent)}
.goal-date-pop{position:absolute;top:calc(100% + 4px);right:0;z-index:40;display:flex;align-items:center;gap:4px;background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius-sm);padding:5px 6px;box-shadow:0 6px 18px rgba(0,0,0,.35)}
[hidden]{display:none!important}
.goal-date-pop[hidden]{display:none}
.goal-date-input{font-size:11px;width:132px}
.goal-date-ok{color:var(--green)}
.goal-date-ok:hover{color:var(--green);background:color-mix(in srgb,var(--green) 14%,transparent)}
.targets-popover-groupgoal,.modal-group-goal{display:flex;align-items:center;gap:8px;margin:2px 0 10px}
.modal-group-goal{margin:8px 0 0}
.targets-popover-groupgoal-hint{font-weight:400;color:var(--text3)}
.target-edit-remove{flex-shrink:0;font-size:14px;line-height:1;color:var(--text3)}
.target-edit-remove:hover{color:var(--red)}
.target-add-row{display:flex;align-items:center;gap:8px;margin-top:2px}
/* ── API tokens (Settings → Integrations) ─────────────────────────────── */
.token-row{display:flex;align-items:center;gap:10px;padding:8px 10px;background:var(--surface2);border:1px solid var(--border);border-radius:8px}
.token-row-main{display:flex;align-items:baseline;gap:8px;min-width:0;flex:1}
.token-row-name{font-size:12.5px;font-weight:600;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.token-row-prefix{font-family:'Geist Mono',monospace;font-size:11px;color:var(--text3)}
.token-row-meta{font-size:11px;color:var(--text3);white-space:nowrap}
.token-new-box{background:color-mix(in srgb,var(--amber) 8%,var(--surface2));border:1px solid color-mix(in srgb,var(--amber) 35%,var(--border));border-radius:8px;padding:10px 12px}
.token-new-head{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--text2);margin-bottom:8px}
.token-new-value{display:flex;align-items:center;gap:8px}
.token-new-value code{font-family:'Geist Mono',monospace;font-size:12px;color:var(--text);background:var(--surface);border:1px solid var(--border);border-radius:6px;padding:6px 10px;flex:1;overflow-x:auto;white-space:nowrap;user-select:all}
/* ── History view (flag-gated — FEATURES.history) ─────────────────────── */
.history-controls{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:14px}
.history-metric{max-width:180px}
.history-ranges{display:flex;gap:2px;background:var(--surface2);border:1px solid var(--border);border-radius:8px;padding:3px}
.history-range-btn{border:none;background:transparent;color:var(--text3);font-size:11.5px;font-weight:600;padding:4px 10px;border-radius:6px;cursor:pointer;letter-spacing:.2px}
.history-range-btn:hover{color:var(--text)}
.history-range-btn.active{background:var(--accent);color:#fff}
/* Rate/day is disabled for bounded metrics (Uptime) — dimmed and inert rather
   than removed, so the control set doesn't reflow when the metric changes. */
.history-range-btn:disabled{opacity:.35;cursor:default}
.history-range-btn:disabled:hover{color:var(--text3)}
.history-trackers{display:flex;gap:6px;flex-wrap:wrap}
/* Overlays / export dropdown menus + tracker select-all bar */
.history-menu-wrap{position:relative;display:inline-block}
.history-menu-btn{border:1px solid var(--border);background:var(--surface2);color:var(--text2);font-size:11.5px;font-weight:600;padding:5px 10px;border-radius:8px;cursor:pointer;letter-spacing:.2px}
.history-menu-btn:hover{color:var(--text)}
.history-menu{position:absolute;top:calc(100%+4px);left:0;z-index:30;min-width:170px;background:var(--surface);border:1px solid var(--border);border-radius:10px;padding:8px 10px;box-shadow:0 8px 24px rgba(0,0,0,.35);display:flex;flex-direction:column;gap:3px}
.history-menu[hidden]{display:none}
.history-menu label{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--text2);cursor:pointer;padding:2px 0}
.history-menu label:hover{color:var(--text)}
.history-menu label.is-disabled{opacity:.4;cursor:not-allowed}
.history-menu input[type=checkbox]{accent-color:var(--accent);cursor:pointer}
.history-menu-label{font-size:10px;text-transform:uppercase;letter-spacing:.5px;color:var(--text3);font-weight:700;margin-top:6px}
.history-menu-label:first-child{margin-top:0}
.history-menu-hint{text-transform:none;letter-spacing:0;font-weight:500}
.history-menu-item{text-align:left;background:transparent;border:none;color:var(--text);font-size:12.5px;padding:5px 6px;border-radius:6px;cursor:pointer}
.history-menu-item:hover{background:var(--surface2)}
.history-tracker-bar{display:flex;align-items:flex-start;gap:6px;flex-wrap:wrap;margin-bottom:14px}
/* Cap the chip wall so a large tracker list stays scrollable, not page-dominating. */
.history-tracker-bar .history-trackers{flex:1;min-width:0;max-height:118px;overflow-y:auto;padding-right:2px}
.history-selbtn{border:1px solid var(--border);background:var(--surface2);color:var(--text3);font-size:11px;font-weight:700;padding:4px 10px;border-radius:8px;cursor:pointer;letter-spacing:.3px}
.history-selbtn:hover{color:var(--text)}
.history-selbtn.active{color:var(--text);border-color:color-mix(in srgb,var(--accent) 45%,var(--border))}
.hc-event{cursor:default}
.hc-milestone{cursor:default}
.history-tracker-chip{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--border);background:var(--surface2);color:var(--text3);font-size:11.5px;font-weight:600;padding:4px 10px;border-radius:14px;cursor:pointer;opacity:.55}
.history-tracker-chip:hover{color:var(--text);opacity:.85}
.history-tracker-chip.active{color:var(--text);opacity:1;border-color:color-mix(in srgb,var(--accent) 40%,var(--border))}
.history-chip-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;display:inline-block}
.history-chart-card{background:var(--surface);border:1px solid var(--border);border-radius:12px;padding:14px}
.history-chart-svg{display:block;width:100%}
.hc-grid{stroke:var(--border);stroke-width:1;opacity:.5}
.hc-axis{stroke:var(--border);stroke-width:1}
.hc-ylabel{fill:var(--text3);font-size:10px;text-anchor:end;font-family:'Geist Mono',monospace}
.hc-xlabel{fill:var(--text3);font-size:10px;text-anchor:middle;font-family:'Geist Mono',monospace}
.hc-crosshair{stroke:var(--text3);stroke-width:1;stroke-dasharray:3 3;pointer-events:none}
.hc-hover-dot{pointer-events:none;stroke:var(--surface);stroke-width:1.5}
.hc-ref{stroke:var(--amber);stroke-width:1;stroke-dasharray:2 4;opacity:.9}
.hc-ref-label{fill:var(--amber);font-size:10px;font-weight:700;text-anchor:end;font-family:'Geist Mono',monospace}
.hc-pin{stroke:var(--amber);stroke-width:1;stroke-dasharray:5 3}
.hc-pin-label{fill:var(--amber);font-size:10px;font-weight:700;text-anchor:middle}
.hc-pin-dot{stroke:var(--surface);stroke-width:1.5}
.hc-hit{cursor:crosshair}
.history-empty{padding:48px 20px;text-align:center;font-size:12.5px;color:var(--text3);font-style:italic}
.history-readout{margin-top:10px;border-top:1px solid var(--border);padding-top:10px;display:flex;flex-direction:column;gap:5px;min-height:48px}
.history-readout-head{font-size:11px;color:var(--text3);letter-spacing:.3px;text-transform:uppercase;font-weight:600}
.history-readout-row{display:flex;align-items:center;gap:8px;font-size:12.5px;flex-wrap:wrap}
.history-readout-row .hr-name{font-weight:600;color:var(--text2);min-width:120px}
.history-readout-row .hr-val{font-family:'Geist Mono',monospace;color:var(--text)}
.history-readout-row .hr-delta{font-family:'Geist Mono',monospace;font-weight:700}
.history-readout-row .hr-delta.up{color:var(--green)}
.history-readout-row .hr-delta.down{color:var(--red)}
.history-readout-row .hr-rate{font-size:11.5px;color:var(--text3)}
.exp-perks-list{display:flex;flex-wrap:wrap;gap:5px;margin-top:4px}
.exp-perk-chip{font-size:10.5px;font-weight:600;padding:3px 8px;border-radius:10px;background:color-mix(in srgb,var(--accent) 10%,var(--surface2));color:var(--text);border:1px solid color-mix(in srgb,var(--accent) 30%,var(--border));letter-spacing:.15px;display:inline-flex;align-items:center;gap:5px;line-height:1.3}
.exp-perk-chip i{font-size:9px;opacity:.85}
.card-body{padding:12px 14px;display:flex;flex-direction:column;gap:10px}
.card-user{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.card-username{font-weight:600;font-size:13px}
.card-perk-icons{display:inline-flex;align-items:center;gap:5px;padding:2px 6px;border-radius:10px;background:var(--surface2);border:1px solid var(--border)}
/* ── Perk icon tooltip ─────────────────────────────────────────────────── */
.perk-icon-wrap{position:relative;display:inline-flex;align-items:center;cursor:default}
.perk-tip{
  position:absolute;bottom:calc(100% + 6px);left:50%;transform:translateX(-50%);
  white-space:nowrap;font-size:11px;font-weight:500;
  background:var(--surface2);color:var(--text);border:1px solid var(--border2);
  border-radius:5px;padding:3px 8px;pointer-events:none;
  opacity:0;transition:opacity .15s;z-index:50;
  box-shadow:0 4px 12px rgba(0,0,0,.4);
}
.perk-tip::after{
  content:'';position:absolute;top:100%;left:50%;transform:translateX(-50%);
  border:4px solid transparent;border-top-color:var(--border2);
}
.perk-icon-wrap:hover .perk-tip{opacity:1}
/* ── Table group badge perk popover ────────────────────────────────────── */
.td-group-wrap{display:inline-flex;align-items:center;gap:5px;position:relative}
.td-perk-icons{
  position:absolute;left:0;top:calc(100% + 5px);z-index:30;
  opacity:0;pointer-events:none;transition:opacity .15s;
  white-space:nowrap;
}
.td-group-wrap:hover .td-perk-icons{opacity:1;pointer-events:auto}
/* ── Event beacon amber tooltip ─────────────────────────────────────────── */
.event-beacon-tip{position:relative}
.event-tip{
  position:absolute;bottom:calc(100% + 7px);left:50%;transform:translateX(-50%);
  white-space:nowrap;font-size:11px;font-weight:600;letter-spacing:.01em;
  background:color-mix(in srgb,var(--amber) 15%,var(--surface2));
  color:var(--amber);
  border:1px solid color-mix(in srgb,var(--amber) 40%,transparent);
  border-radius:5px;padding:4px 10px;pointer-events:none;
  opacity:0;transition:opacity .15s;z-index:250;
  box-shadow:0 4px 12px rgba(0,0,0,.4);
}
.event-tip::after{
  content:'';position:absolute;top:100%;left:50%;transform:translateX(-50%);
  border:4px solid transparent;
  border-top-color:color-mix(in srgb,var(--amber) 40%,transparent);
}
.event-beacon-tip:hover .event-tip{opacity:1}
.stats-grid{display:grid;grid-template-columns:1fr 1fr 1fr;gap:5px}
.stat-item{background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius-sm);padding:6px 9px}
.stat-label{font-size:10px;color:var(--text3);font-weight:500;text-transform:uppercase;letter-spacing:.6px;margin-bottom:3px}
.stat-value{font-size:13px;font-weight:600;font-family:'Geist Mono',monospace;letter-spacing:-.3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.stat-value.green{color:var(--green)}.stat-value.red{color:var(--red)}.stat-value.amber{color:var(--amber)}.stat-value.blue{color:var(--blue)}.stat-value.purple{color:var(--purple)}.stat-value.teal{color:var(--teal)}.stat-value.orange{color:var(--orange)}.stat-value.pink{color:var(--pink)}.stat-value.text3{color:var(--text3)}
/* Stacked seed-time value: Y/M/W/D headline, h/m/s wrapped smaller on line 2 */
.stat-time-major{display:block}
.stat-time-minor{font-size:.78em;font-weight:500;opacity:.7}
.activity-row{display:flex;gap:8px}
.activity-pill{flex:1;display:flex;align-items:center;justify-content:center;gap:6px;background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius-sm);padding:8px 10px;font-size:13px;font-weight:500}
.activity-pill .num{font-family:'Geist Mono',monospace;font-weight:700}
/* ── Card targets / profile wrapper sections ──────────────────────────── */
.card-section-wrap{background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius-sm);padding:10px 12px}
.card-section-title{font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--text3);margin-bottom:6px}
.targets-section{display:flex;flex-direction:column;gap:9px}
.targets-heading{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.8px;color:var(--text3);display:flex;align-items:center;gap:8px}
.targets-heading::after{content:'';flex:1;height:1px;background:var(--border)}
.target-row{display:flex;flex-direction:column;gap:3px}
.target-header{display:flex;justify-content:space-between;align-items:baseline;gap:8px}
.target-lbl{font-size:11px;font-weight:500;text-transform:uppercase;letter-spacing:.6px;color:var(--text3)}
.target-vals{font-size:11px;font-family:'Geist Mono',monospace;color:var(--text2);white-space:nowrap}
.target-vals .tgt{color:var(--text3)}
/* Amber per-target time estimate chip + promotion headline (show_target_etas) */
.target-eta{font-size:11px;color:var(--amber);font-family:'Geist Mono',monospace;white-space:nowrap}
.targets-eta{font-size:10px;font-weight:600;color:var(--amber);font-family:'Geist Mono',monospace;white-space:nowrap;text-transform:none;letter-spacing:0}
.targets-eta--ready{color:var(--green)}
.progress-track{height:5px;background:var(--border);border-radius:3px;overflow:hidden}
.progress-fill{height:100%;border-radius:3px;transition:width .6s cubic-bezier(.4,0,.2,1);min-width:2px}
.progress-fill.green{background:var(--green);box-shadow:0 0 6px rgba(34,197,94,.4)}
.progress-fill.amber{background:var(--amber);box-shadow:0 0 6px rgba(245,158,11,.4)}
.progress-fill.red{background:var(--red);box-shadow:0 0 6px rgba(239,68,68,.4)}
.progress-fill.blue{background:var(--blue);box-shadow:0 0 6px rgba(59,130,246,.4)}
.progress-fill.teal{background:var(--teal);box-shadow:0 0 6px rgba(45,212,191,.4)}
.progress-fill.pink{background:var(--pink);box-shadow:0 0 6px rgba(236,72,153,.4)}
.progress-fill.purple{background:var(--purple);box-shadow:0 0 6px rgba(168,85,247,.4)}
.progress-fill.orange{background:var(--orange);box-shadow:0 0 6px rgba(249,115,22,.4)}
/* Untrackable requirement — the tracker's API can't report this stat. Shown
   dimmed, with an eye-off icon and a dashed placeholder bar (no fill). */
.target-row--unavail{opacity:.72}
.target-vals--unavail{display:inline-flex;align-items:center;gap:5px;color:var(--text3)}
.target-unavail-icon{flex:none;color:var(--text3);vertical-align:-2px}
.target-unavail-txt{font-style:italic;letter-spacing:.2px}
.progress-track--unavail{background:transparent;border:1px dashed var(--border);height:5px;border-radius:3px}
/* Goal pacing — compact chip after the ETA chip (cards/table, show_goal_chips)
   and the muted full line under a dated row on the Detail page
   (show_goal_pacing). Independent toggles; never both on the same row. */
.goal-chip{font-size:11px;font-weight:600;font-family:'Geist Mono',monospace;white-space:nowrap}
.goal-chip--ontrack{color:var(--green)}
.goal-chip--behind{color:var(--amber)}
.goal-chip--overdue{color:var(--red)}
.goal-chip--neutral{color:var(--text3);font-weight:500}
.target-goal-line{font-size:10px;color:var(--text3);font-family:'Geist Mono',monospace;margin-top:1px}
.progress-pct{font-size:10px;font-weight:600;font-family:'Geist Mono',monospace;color:var(--text3);text-align:right}
.card-footer{padding:10px 16px;border-top:1px solid var(--border);display:flex;align-items:center;justify-content:space-between;background:var(--surface2);gap:8px;flex-wrap:wrap}
.card-last-updated{font-size:11px;color:var(--text3)}
.card-hnr{font-size:12px;font-weight:500}
.scrape-limit-badge{font-size:10px;color:var(--amber);font-style:italic;opacity:.85;white-space:nowrap}
/* Setup states (missing credentials) — muted info, not a warning */
.scrape-limit-badge.setup{color:var(--text3);white-space:normal;line-height:1.35;flex:1;min-width:0}
.card-no-key{padding:28px 16px;text-align:center;display:flex;flex-direction:column;align-items:center;gap:10px;color:var(--text2)}
.card-no-key svg{opacity:.3}
.card-no-key p{font-size:13px;color:var(--text3)}
.card-error-msg{padding:12px 16px;background:var(--error-bg);border-radius:var(--radius-sm);border:1px solid var(--error-border);color:var(--red);font-size:12px;font-family:'Geist Mono',monospace;display:flex;align-items:center;gap:8px}
.skeleton{background:linear-gradient(90deg,var(--surface2) 25%,var(--border) 50%,var(--surface2) 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:4px}
@keyframes shimmer{0%{background-position:200% 0}100%{background-position:-200% 0}}

/* ══ TABLE VIEW ══ */
.section-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);overflow:visible;margin-bottom:16px}
.section-head{display:flex;align-items:center;justify-content:space-between;padding:14px 18px;border-bottom:1px solid var(--border);background:var(--surface2);border-radius:var(--radius) var(--radius) 0 0}
.section-head-title{font-size:14px;font-weight:600;letter-spacing:-.2px}
.section-head-sub{font-size:12px;color:var(--text3);margin-top:1px}
.section-head-right{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--text3)}

/* Horizontal scrollbar for the tracker table.
   A JS-injected mirror div above the table exposes the same scrollbar
   right under the column headers so it's always reachable without
   scrolling to the bottom of a long list. */
.table-scroll{
	overflow-x:auto;overflow-y:clip;border-radius:0 0 var(--radius) var(--radius)
}

/* Mirror scrollbar strip — injected above .table-scroll by JS.
   Overflows only horizontally to show the h-scrollbar, zero visible height. */
.table-scroll-mirror{
  overflow-x:auto;
  overflow-y:hidden;
  height:10px; /* exactly the scrollbar track height */
  /* Must sit above section-card's border-radius so clip it tight */
  border-bottom:1px solid var(--border);
}
.table-scroll-mirror-inner{
  height:1px; /* content just needs width — no visible content */
}
.tracker-table{width:100%;border-collapse:collapse;table-layout:auto}

.tracker-table thead th{
  position:sticky;top:0;z-index:10;
  padding:10px 10px;text-align:left;
  font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.6px;color:var(--text3);
  background:var(--surface2);border-bottom:2px solid var(--border2);
  white-space:nowrap;overflow:hidden;user-select:none;
}
.tracker-table thead th.sortable{cursor:pointer;transition:color .15s}
.tracker-table thead th.sortable:hover{color:var(--text2)}
.tracker-table thead th.sorted{color:var(--text)}
.tracker-table thead th.c-center{text-align:center}

/* sort indicator */
.sort-icon{display:inline-flex;flex-direction:column;gap:1px;margin-left:4px;opacity:.35;vertical-align:middle;position:relative;top:-1px}
th.sorted .sort-icon{opacity:1}
.sort-icon span{display:block;width:0;height:0;border-left:4px solid transparent;border-right:4px solid transparent}
.sort-icon .up{border-bottom:4px solid currentColor}
.sort-icon .dn{border-top:4px solid currentColor}
th.sort-asc .sort-icon .dn{opacity:.2}
th.sort-desc .sort-icon .up{opacity:.2}

.tracker-table tbody tr.tr-main{cursor:pointer;transition:background .12s}
.tracker-table tbody tr.tr-main:hover{position:relative;z-index:11}
.tracker-table tbody tr.tr-main:hover td{background:var(--table-hover)}
.tracker-table tbody tr.tr-main td{
  padding:10px 10px;border-bottom:1px solid var(--border);
  vertical-align:middle;overflow:visible;white-space:nowrap;font-size:13px;
}
.tracker-table tbody tr.tr-main td:first-child{padding-left:10px;text-align:center}
.tracker-table tbody tr.tr-main td.td-center{text-align:center}
.tracker-table tbody tr.tr-main td.td-mono{font-family:'Geist Mono',monospace;font-weight:500}
.td-tracker-wrap{display:flex;flex-direction:column;gap:2px;overflow:visible;min-width:0}
.td-tracker-name{font-weight:600;font-size:13px;display:flex;align-items:center;gap:4px;overflow:visible}
.td-name-text{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;flex:1}
.td-tracker-url{font-size:11px;color:var(--text3);font-family:'Geist Mono',monospace;text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;transition:color .15s}
.td-tracker-url:hover{color:var(--accent);text-decoration:underline}
.td-user-wrap{display:flex;flex-direction:column;gap:3px;overflow:visible;min-width:0}
.td-username{font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.expand-chev{color:var(--text3);transition:transform .2s;display:inline-block}
.expand-chev.open{transform:rotate(90deg)}

/* expanded row */
.tr-expanded{display:none}
.tr-expanded.visible{display:table-row}
.tr-expanded td{padding:0!important;border-bottom:2px solid var(--border2)!important;background:var(--surface2)}
/* The inner panel uses sticky+left:0 so it stays anchored to the left edge
   of the viewport when the user scrolls the table horizontally.
   max-width is capped at the scroll container width so it never overflows. */
.tr-expanded-inner{
  position:sticky;left:0;
  box-sizing:border-box;
  width:var(--table-scroll-w,100vw);
  max-width:100%;
  padding:16px 20px 18px 56px;
  overflow:hidden;
}
/* Capped rather than tracking the row width. Unbounded, an ultrawide gave
   auto-fill eleven 300px tracks for the two or three panels that exist, and
   stretched the connection strip's seven day-blocks to ~480px each. The cap is
   about what the row had before .main lost its own, so ordinary widths are
   unchanged. */
.expanded-cols{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:20px;align-items:start;max-width:var(--reading-max)}
/* Full-width band beneath the columns (the connection strip). Spanning every
   column keeps it out of the auto-fill flow, so it can't become a short third
   column that leaves the other two stretched. */
.expanded-full{grid-column:1/-1}
/* Below two comfortable columns, stack. A 2-column grid row is only as tall as
   its tallest cell, so an unequal pair (a long Stats list beside a short Info
   list) left a dead gap under the shorter one — most visible on phones. */
@media(max-width:820px){
  .expanded-cols{grid-template-columns:1fr;gap:16px}
  .tr-expanded-inner{padding:14px 16px}
}

/* ── Connection strip (expanded row) ──
   One block per UTC day, oldest→newest. Blocks rather than a line: the useful
   reading is categorical (which days broke), and a fixed count keeps every
   tracker's strip aligned regardless of how long it has been installed. */
.uptime-strip{display:flex;gap:3px;align-items:stretch;height:22px}
.uptime-block{flex:1;border-radius:2px;min-width:6px;transition:opacity .12s}
.uptime-block:hover{opacity:.75}
.uptime-block--ok{background:var(--green)}
.uptime-block--partial{background:var(--amber)}
.uptime-block--down{background:var(--red)}
/* "No contact attempted" — deliberately a faint outline, never a red block:
   a paused or newly-added tracker has no outage to report. */
.uptime-block--none{background:var(--surface2);border:1px dashed var(--border2);box-sizing:border-box}
.uptime-legend{margin-top:6px;font-size:11px;font-weight:600;font-family:'Geist Mono',monospace}
.exp-section-title{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.7px;color:var(--text3);margin-bottom:10px;display:flex;align-items:center;gap:8px}
.exp-section-title::after{content:'';flex:1;height:1px;background:var(--border)}
.exp-stat-list{display:flex;flex-direction:column;gap:7px}
.exp-stat{display:flex;align-items:center;justify-content:space-between;gap:8px}
.exp-stat-label{font-size:12px;color:var(--text3);flex-shrink:0}
.exp-stat-value{font-size:12px;font-family:'Geist Mono',monospace;font-weight:600;text-align:right;word-break:break-word}
.exp-stat-value.green{color:var(--green)}.exp-stat-value.red{color:var(--red)}.exp-stat-value.amber{color:var(--amber)}.exp-stat-value.blue{color:var(--blue)}.exp-stat-value.teal{color:var(--teal)}.exp-stat-value.purple{color:var(--purple)}.exp-stat-value.orange{color:var(--orange)}.exp-stat-value.pink{color:var(--pink)}
/* Muted per-stat "changed by X over the selected range" chip on the Tracker
   Detail page's Stats section — quieter than the amber .target-eta above,
   since it's a passive readout rather than a time-to-target estimate. */
.stat-delta-chip{font-size:10px;font-weight:500;color:var(--text3);font-family:'Geist Mono',monospace;white-space:nowrap}
.exp-targets{display:flex;flex-direction:column;gap:10px}
.table-empty-row td{padding:60px 20px!important;text-align:center;color:var(--text3);border:none!important}

/* ══ Column customizer ══ */
.col-customize-list{display:flex;flex-direction:column;gap:6px;max-height:380px;overflow-y:auto}
.col-item{display:flex;align-items:center;gap:10px;padding:8px 10px;background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius-sm);cursor:grab;user-select:none}
.col-item:active{cursor:grabbing}
.col-item.dragging-col{opacity:.4}
.col-item.drag-over-col{border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-glow)}
.col-item-drag{color:var(--text3);flex-shrink:0}
.col-item-label{flex:1;font-size:13px;font-weight:500;display:flex;align-items:center;gap:5px}
.col-item-toggle{width:32px;height:18px;border-radius:9px;background:var(--border2);position:relative;transition:background .2s;flex-shrink:0;cursor:pointer}
.col-item-toggle.on{background:var(--accent)}
.col-item-toggle::after{content:'';width:12px;height:12px;border-radius:50%;background:var(--toggle-thumb);position:absolute;top:3px;left:3px;transition:transform .2s;box-shadow:0 1px 3px rgba(0,0,0,.3)}
.col-item-toggle.on::after{transform:translateX(14px)}

/* ══ Modals ══ */
.modal-backdrop{position:fixed;inset:0;z-index:300;background:var(--overlay-bg);backdrop-filter:blur(4px);display:flex;align-items:center;justify-content:center;padding:16px;opacity:0;pointer-events:none;transition:opacity .2s}
.modal-backdrop.open{opacity:1;pointer-events:all}
.modal{background:var(--surface);border:1px solid var(--border2);border-radius:12px;width:100%;max-width:760px;max-height:92vh;display:flex;flex-direction:column;box-shadow:0 24px 64px rgba(0,0,0,.6);transform:translateY(12px) scale(.98);transition:transform .2s;overflow:hidden}
.modal-backdrop.open .modal{transform:none}
.modal-header{display:flex;align-items:center;justify-content:space-between;padding:18px 20px;border-bottom:1px solid var(--border);background:var(--surface2);flex-shrink:0}
.modal-title{font-size:16px;font-weight:700;letter-spacing:-.3px}
.modal-close{background:none;border:none;cursor:pointer;color:var(--text3);padding:4px;border-radius:4px;font-size:20px;line-height:1;transition:color .15s}
.modal-close:hover{color:var(--text)}
.modal-body{padding:20px;display:flex;flex-direction:column;gap:14px;overflow-y:auto}
.modal-footer{padding:16px 20px;border-top:1px solid var(--border);display:flex;gap:8px;justify-content:flex-end;background:var(--surface2);flex-shrink:0}
.modal-divider{display:flex;align-items:center;gap:10px;margin:2px 0}
.modal-divider-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.8px;color:var(--text3);white-space:nowrap}
.modal-divider-line{flex:1;height:1px;background:var(--border)}
.modal-def-header{background:var(--surface2);border:1px solid var(--border2);border-radius:8px;padding:10px 13px;display:flex;flex-direction:column;gap:5px}
.modal-def-name-row{display:flex;align-items:center;gap:8px}
.modal-def-name-text{font-size:14px;font-weight:700;color:var(--text)}
.modal-def-abbr{font-size:11px;font-weight:600;color:var(--text3);background:var(--surface3);border:1px solid var(--border2);border-radius:4px;padding:1px 6px;letter-spacing:.3px}
.modal-def-meta-row{display:flex;align-items:center;gap:8px}
.modal-def-type-badge{font-size:11px;font-weight:600;color:var(--purple);background:var(--accent-bg-sm);border:1px solid var(--accent-border-sm);border-radius:4px;padding:1px 7px}
.modal-def-url-text{font-size:11px;color:var(--text3)}
.form-group{display:flex;flex-direction:column;gap:6px}
.form-row{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.form-label{font-size:12px;font-weight:600;color:var(--text2);letter-spacing:.3px;text-transform:uppercase}
.form-label .opt{color:var(--text3);font-weight:400;text-transform:none;letter-spacing:0;font-size:11px}
.form-input{background:var(--surface2);border:1px solid var(--border2);border-radius:var(--radius-sm);padding:9px 12px;color:var(--text);font-family:inherit;font-size:13px;outline:none;transition:border-color .15s,box-shadow .15s;width:100%}
.form-input:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-glow)}
.form-input::placeholder{color:var(--text3)}
input[type="date"].form-input::-webkit-calendar-picker-indicator{filter:invert(.5);cursor:pointer}
.form-hint{font-size:11px;color:var(--text3)}
.form-toggle{display:flex;align-items:center;gap:10px;cursor:pointer}
.toggle-track{width:36px;height:20px;border-radius:10px;background:var(--border2);position:relative;transition:background .2s;flex-shrink:0}
.toggle-track.on{background:var(--accent)}
.toggle-thumb{width:14px;height:14px;border-radius:50%;background:var(--toggle-thumb);position:absolute;top:3px;left:3px;transition:transform .2s;box-shadow:0 1px 3px rgba(0,0,0,.3)}
.toggle-track.on .toggle-thumb{transform:translateX(16px)}

/* delete confirmation popup */
.delete-popup-backdrop{position:fixed;inset:0;z-index:310;display:flex;align-items:center;justify-content:center;padding:16px;background:var(--overlay-bg-sm);backdrop-filter:blur(2px);opacity:0;pointer-events:none;transition:opacity .15s}
.delete-popup-backdrop.open{opacity:1;pointer-events:all}
.delete-popup{background:var(--surface);border:1px solid var(--border2);border-radius:12px;width:100%;max-width:360px;box-shadow:0 24px 64px rgba(0,0,0,.7);padding:24px;transform:scale(.95);transition:transform .15s;text-align:center}
.delete-popup-backdrop.open .delete-popup{transform:none}
.delete-popup-icon{width:44px;height:44px;border-radius:50%;background:var(--error-bg-lg);border:1px solid var(--error-border-md);display:flex;align-items:center;justify-content:center;margin:0 auto 14px}
.delete-popup-title{font-size:16px;font-weight:700;margin-bottom:6px}
.delete-popup-body{font-size:13px;color:var(--text2);margin-bottom:20px;line-height:1.5}
.delete-popup-body strong{color:var(--text)}
.delete-popup-btns{display:flex;gap:8px;justify-content:center}

/* autofill button */
.btn-autofill{
  display:inline-flex;align-items:center;gap:5px;
  padding:3px 9px;border-radius:var(--radius-sm);border:1px solid var(--border);
  background:var(--surface2);color:var(--text2);font-size:11px;font-weight:500;
  cursor:pointer;transition:all .15s;white-space:nowrap;flex-shrink:0;
}
.btn-autofill:hover{background:var(--surface3);color:var(--text);border-color:var(--purple)}
.btn-autofill:disabled{opacity:.45;cursor:default}
.btn-autofill:hover{background:color-mix(in srgb,var(--accent) 20%,transparent)}
.btn-autofill.visible{display:inline-flex}

/* ── Toasts ── */
.toast-container{position:fixed;bottom:20px;right:20px;z-index:999;display:flex;flex-direction:column;gap:8px;pointer-events:none}
.toast{background:var(--surface2);border:1px solid var(--border2);border-radius:var(--radius-sm);padding:12px 16px;font-size:13px;max-width:320px;box-shadow:0 8px 24px rgba(0,0,0,.4);display:flex;align-items:center;gap:8px;animation:toastIn .25s ease forwards;pointer-events:all}
.toast.success{border-left:3px solid var(--green)}
.toast.error{border-left:3px solid var(--red)}
.toast.warning{border-left:3px solid var(--amber)}
@keyframes toastIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

/* ══ QUI Live Stats Bar ══ */
.qui-bar{
  display:flex;align-items:center;gap:12px;
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius);padding:14px 20px;
  margin-bottom:16px;flex-wrap:wrap;row-gap:10px;
}
.qui-bar.qui-hidden{display:none}
.qui-section{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.qui-bar-label{
  font-size:10px;font-weight:700;letter-spacing:.8px;text-transform:uppercase;
  color:var(--text3);display:flex;align-items:center;gap:5px;flex-shrink:0;white-space:nowrap;
}
.qui-bar-sep{width:1px;height:32px;background:var(--border);flex-shrink:0}
/* Connection */
.qui-conn{display:flex;align-items:center;gap:5px;font-size:11px;color:var(--text3);white-space:nowrap}
.qui-conn .sdot{width:6px;height:6px}
/* Speed pills */
.qui-speed-group{display:flex;align-items:center;gap:4px}
.qui-speed-pill{
  display:flex;align-items:center;gap:5px;
  background:var(--surface2);border:1px solid var(--border);
  border-radius:var(--radius-sm);padding:6px 12px;white-space:nowrap;
}
.qui-speed-label{font-size:10px;color:var(--text3);font-weight:600;letter-spacing:.4px;text-transform:uppercase}
.qui-speed-value{
  font-size:13px;font-weight:700;font-family:'Geist Mono',monospace;letter-spacing:-.3px;min-width:80px;
}
.qui-speed-value.dn{color:var(--qui-dl-color)}
.qui-speed-value.up{color:var(--qui-ul-color)}
/* QUI icon colour classes — SVG fill/stroke set via class so CSS variables reliably apply */
.qui-icon-dl{stroke:var(--qui-dl-color)}
.qui-icon-ul{stroke:var(--qui-ul-color)}
.qui-icon-free{fill:var(--qui-free-color)}
.qui-icon-ratio{fill:var(--qui-ratio-icon-color)}
.qui-icon-size{fill:var(--qui-size-color)}
.qi-total-size-val{color:var(--qui-size-color)}
/* Alt speed limit pill — only shown when alt speeds active */
.qui-alt-pill{
  display:flex;align-items:center;gap:4px;
  background:var(--error-bg-lg);border:1px solid var(--error-border-lg);
  border-radius:var(--radius-sm);padding:6px 10px;white-space:nowrap;cursor:default;
}
.qui-alt-value{
  font-size:12px;font-weight:700;font-family:'Geist Mono',monospace;
  color:var(--red);letter-spacing:-.2px;
}
.qui-alt-pill svg{color:var(--red);flex-shrink:0}
/* Meta pills (free space, global ratio) */
.qui-meta-pill{
  display:flex;align-items:center;gap:5px;
  background:var(--surface2);border:1px solid var(--border);
  border-radius:var(--radius-sm);padding:6px 12px;white-space:nowrap;
}
.qui-meta-label{font-size:10px;color:var(--text3);font-weight:600;letter-spacing:.4px;text-transform:uppercase}
.qui-meta-value{
  font-size:13px;font-weight:700;font-family:'Geist Mono',monospace;letter-spacing:-.3px;color:var(--text);
}
.qi-total-size-val{color:var(--qui-size-color) !important;}
/* Torrent count pills */
.qui-count-pill{
  display:flex;align-items:center;gap:5px;
  background:var(--surface2);border:1px solid var(--border);
  border-radius:var(--radius-sm);padding:6px 10px;white-space:nowrap;
}
.qui-count-label{font-size:10px;font-weight:600;letter-spacing:.4px;text-transform:uppercase;color:var(--text3)}
.qui-count-value{font-size:13px;font-weight:700;font-family:'Geist Mono',monospace;color:var(--text)}

/* ══ QUI instance rows in settings ══ */
.qui-inst-bar{margin-bottom:10px}
.qui-inst-bar:last-child{margin-bottom:16px}
.qui-inst-row{
  display:flex;align-items:center;gap:8px;
  padding:7px 10px;border-radius:var(--radius-sm);
  background:var(--surface2);border:1px solid var(--border);
  cursor:pointer;user-select:none;
  transition:border-color .15s;
}
.qui-inst-row:hover{border-color:var(--accent)}
.qui-inst-row input[type=checkbox]{
  width:14px;height:14px;flex-shrink:0;cursor:pointer;accent-color:var(--accent);
}
.qui-inst-label{font-size:12px;font-weight:600;color:var(--text);flex:1}
.qui-inst-host{font-size:11px;color:var(--text3);font-family:'Geist Mono',monospace;
  max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}

/* ══ Settings modal ══ */
.settings-section-label{
  font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.8px;
  color:var(--text3);padding:8px 0 4px;border-bottom:1px solid var(--border);
  margin-bottom:6px;
}

/* ══ Profile Stats (scraped from /users/{username}) ══ */
.prof-list{
  display:flex;flex-direction:column;gap:0;margin-bottom:8px;
}
.prof-row{
  display:grid;grid-template-columns:110px 1fr;align-items:baseline;
  padding:3px 4px;border-bottom:1px solid var(--border);gap:8px;
  min-height:22px;
}
.prof-row:last-child{border-bottom:none}
.prof-label{
  font-size:11px;color:var(--text3);
  white-space:nowrap;flex-shrink:0;
  padding-top:1px;
}
.prof-val{
  font-size:12px;font-weight:600;font-family:'Geist Mono',monospace;
  text-align:right;white-space:nowrap;
}
.prof-footer{
  display:flex;align-items:center;gap:8px;margin-top:6px;flex-wrap:wrap;
}
.prof-meta{font-size:10px;color:var(--text3);font-style:italic}
.prof-link{font-size:11px;color:var(--blue);text-decoration:none;margin-left:auto}
.prof-link:hover{text-decoration:underline}
.prof-refresh{font-size:10px!important;padding:2px 6px!important}
.prof-hint{
  display:flex;align-items:center;gap:8px;
  font-size:12px;color:var(--text3);padding:6px 0;flex-wrap:wrap;
}
.prof-hint.error svg{flex-shrink:0}

/* ── Sync-from-profile badge on pre-filled modal fields ── */
.sync-badge{
  font-size:10px;color:var(--teal);font-weight:500;
  margin-left:6px;opacity:.85;pointer-events:none;
  letter-spacing:.02em;
}

/* ── Tracker favicons ───────────────────────────────────────────────────── */
.tracker-favicon{
  width:14px;height:14px;border-radius:2px;
  object-fit:contain;flex-shrink:0;
}
.card-user{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.td-tracker-wrap{display:flex;align-items:center;gap:5px}

/* ── Private mode — blur usernames ─────────────────────────────────────── */
.private-mode .private-blur{
  filter:blur(5px);
  user-select:none;
  transition:filter .2s;
  padding:0 6px;
  margin:0 -6px;
  display:inline-block;
}
/* When the blur is on the inner span of a styled username, the parent needs overflow visible */
.private-mode .username-inner.private-blur{
  display:inline-flex;
  padding:0 6px;
  margin:0 -6px;
}
/* Prevent the outer wrapper (which may have overflow:hidden) from clipping the blur expansion */
.private-mode .td-username:has(.private-blur),
.private-mode .card-username:has(.private-blur){
  overflow:visible;
  text-overflow:clip;
}
.private-mode .private-blur:hover{
  filter:blur(0);
}

/* ── Active event beacon ─────────────────────────────────────────────────── */
.event-beacon{
  display:inline-flex;align-items:center;justify-content:center;
  width:18px;height:18px;border-radius:50%;
  background:color-mix(in srgb,var(--amber) 18%,transparent);
  border:1px solid color-mix(in srgb,var(--amber) 45%,transparent);
  margin-left:6px;vertical-align:middle;
  flex-shrink:0;cursor:help;
  position:relative;z-index:1;
  /* Soft pulse to draw attention without being distracting */
  animation:event-pulse 2.8s ease-in-out infinite;
}
.event-beacon svg{display:block}
@keyframes event-pulse{
  0%,100%{box-shadow:0 0 0 0 color-mix(in srgb,var(--amber) 40%,transparent)}
  50%{box-shadow:0 0 0 4px transparent}
}
/* Tooltip handled by native title attribute — no extra markup needed */

/* ── H&R row highlight ───────────────────────────────────────────────────── */
.tracker-table tbody tr.tr-main.hnr-row td{
  background:color-mix(in srgb,var(--red) 6%,transparent);
}
.tracker-table tbody tr.tr-main.hnr-row:hover td{
  background:color-mix(in srgb,var(--red) 10%,transparent);
}
.tracker-table tbody tr.tr-main.hnr-row td:first-child{
  box-shadow:inset 3px 0 0 var(--red);
}

/* ── Expanded row event banner ───────────────────────────────────────────── */
.exp-event-banner{
  display:flex;align-items:center;gap:8px;
  padding:7px 14px;margin-bottom:14px;
  background:color-mix(in srgb,var(--amber) 10%,transparent);
  border:1px solid color-mix(in srgb,var(--amber) 30%,transparent);
  border-radius:6px;
  font-size:12px;font-weight:500;color:var(--amber);
  letter-spacing:.01em;
}
.exp-event-text{
  min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  /* No flex:1 — sits tight next to the timer */
}
.exp-event-timer-wrap{
  display:flex;align-items:center;gap:8px;
  flex-shrink:0;
  /* margin-left:auto removed — timer follows text directly */
}
.exp-event-ends-spacer{
  flex:1; /* pushes end-date to the far right */
}
.exp-event-timer{
  font-family:'Geist Mono',monospace;
  font-size:11px;font-weight:600;
  background:color-mix(in srgb,var(--amber) 15%,transparent);
  border:1px solid color-mix(in srgb,var(--amber) 35%,transparent);
  border-radius:4px;padding:2px 7px;
  white-space:nowrap;letter-spacing:.04em;
}
.exp-event-ends{
  font-size:10px;font-weight:400;
  color:color-mix(in srgb,var(--amber) 70%,var(--text3));
  white-space:nowrap;
  margin-left:auto; /* end date stays at right edge */
}
/* Extras from the structured active_events list (expanded UNIT3D stats). The
   banner keeps its single-line shape — the description is allowed to truncate,
   while the name, the user's standing and the countdown never do. */
/* The name holds its width only when there's a DESCRIPTION beside it to give
   ground instead. Everywhere else — the table row and grid card banners, whose
   single text span carries the tracker's whole announcement — it has to be the
   thing that shrinks, or a long message pushes the countdown and end date off
   the right edge. Those two matter more than the message: a truncated headline
   still tells you what's running, and the tracker itself has the detail, but a
   missing end time can't be recovered by reading harder. */
.exp-event-banner.has-desc .exp-event-text{flex-shrink:0}
.exp-event-link{color:inherit;text-decoration:underline;text-underline-offset:2px}
.exp-event-link:hover{text-decoration-thickness:2px}
/* Shrinks but never GROWS. With flex:1 it absorbed all the slack and pushed the
   countdown to the far edge, so a banner with a description laid out completely
   differently from one without — on an ultrawide, half a metre apart. Nothing
   in the banner grows now, so every countdown sits just after its own content,
   which is what the single-banner design has always done. */
.exp-event-desc{
  min-width:0;flex:0 1 auto;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  font-size:11px;font-weight:400;
  color:color-mix(in srgb,var(--amber) 60%,var(--text3));
}
.exp-event-progress{
  flex-shrink:0;font-size:10.5px;font-weight:600;
  background:color-mix(in srgb,var(--amber) 15%,transparent);
  border-radius:4px;padding:2px 7px;white-space:nowrap;
}
.exp-event-status{
  margin-left:6px;font-size:9.5px;font-weight:700;
  text-transform:uppercase;letter-spacing:.06em;opacity:.75;
}
/* Not running yet — present, but visibly not the thing happening now. */
.exp-event-banner.is-upcoming{
  background:color-mix(in srgb,var(--text3) 8%,transparent);
  border-color:color-mix(in srgb,var(--text3) 25%,transparent);
  color:var(--text3);
}
.exp-event-banner.is-upcoming .exp-event-timer,
.exp-event-banner.is-upcoming .exp-event-progress{
  background:color-mix(in srgb,var(--text3) 12%,transparent);
  border-color:color-mix(in srgb,var(--text3) 30%,transparent);
}
.exp-event-banner.is-upcoming .exp-event-desc,
.exp-event-banner.is-upcoming .exp-event-ends{color:var(--text3)}

/* ── Mock / test tracker badge ──────────────────────────────────────────── */
.mock-badge{
  display:inline-block;
  font-size:9px;font-weight:700;letter-spacing:.06em;
  padding:1px 5px;border-radius:3px;
  background:var(--amber-bg);
  border:1px solid var(--amber-border);
  color:var(--amber);
  vertical-align:middle;margin-left:6px;
  text-transform:uppercase;
}

/* ── Theme selector (settings modal) ───────────────────────────────────── */
.theme-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:8px;margin-top:4px}
.theme-option{display:flex;flex-direction:column;align-items:center;gap:6px;padding:10px 8px;border-radius:var(--radius-sm);border:2px solid var(--border);background:var(--surface2);cursor:pointer;transition:border-color .15s,transform .1s;user-select:none}
.theme-option:hover{border-color:var(--border2);transform:translateY(-1px)}
.theme-option.active{border-color:var(--accent);background:var(--surface3)}
.theme-option.active .theme-option-name{color:var(--accent)}
.theme-swatch{width:100%;height:36px;border-radius:4px;overflow:hidden;display:flex;gap:2px;padding:3px}
.theme-swatch-col{flex:1;border-radius:2px}
.theme-option-name{font-size:11px;font-weight:600;color:var(--text2);text-align:center;line-height:1.3;letter-spacing:.1px}

/* ── Theme live preview (settings) ─────────────────────────────────────── */
.theme-preview{margin:0 0 18px}
.theme-preview-label{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.6px;color:var(--text3);margin-bottom:8px}
.theme-preview-card{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:14px;position:relative;overflow:hidden;box-shadow:var(--shadow)}
.theme-preview-card::after{content:'';position:absolute;top:0;left:0;right:0;height:2px;background:var(--accent);opacity:.7}
.theme-preview-head{display:flex;align-items:center;gap:8px;margin-bottom:12px}
.theme-preview-name{display:inline-flex;align-items:center;gap:7px;font-size:13px;font-weight:600;color:var(--text);margin-right:auto}
.theme-preview-dot{width:9px;height:9px;border-radius:50%;background:var(--accent)}
.theme-preview-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(90px,1fr));gap:8px}
.theme-preview-actions{display:flex;align-items:center;gap:8px;margin-top:12px;flex-wrap:wrap}
.theme-preview-actions .btn{cursor:default}
.theme-preview-srcs{display:inline-flex;align-items:center;font-size:11px;color:var(--text3);margin-left:auto}

/* ── Stat source indicators (settings.show_stat_sources) ─────────────── */
.stat-src{display:inline-block;width:6px;height:6px;border-radius:50%;margin-left:5px;vertical-align:middle;flex-shrink:0;opacity:.85;cursor:help}
.stat-src--api{background:var(--blue)}
.stat-src--scrape{background:var(--amber)}
.stat-src--manual{background:var(--text3)}
.stat-src--qui{background:var(--pink)}

/* ── Offline tracker indicator (stale data still rendered) ─────────────── */
.sdot--offline{opacity:.45;filter:saturate(.55);cursor:help}

/* ── Profile link (expanded row info + card header) ─────────────────────── */
.card-profile-link{font-size:11px;color:var(--blue);text-decoration:none;white-space:nowrap;flex-shrink:0}
.card-profile-link:hover{text-decoration:underline}
.exp-profile-link{color:var(--blue);text-decoration:none}
.exp-profile-link:hover{text-decoration:underline}

/* ── Missing-credential scrape hint (setup state, not an error) ─────────── */
.scrape-setup-hint{
  margin-top:8px;padding:6px 10px;border-radius:var(--radius-sm);
  background:var(--surface3);border:1px solid var(--border);
  font-size:11px;color:var(--text3);font-style:italic;line-height:1.4;
}

/* ── Targets quick-edit (pencil + anchored popover) ─────────────────────── */
.targets-edit-btn{padding:2px 5px!important;font-size:10px;flex-shrink:0;color:var(--text3)}
.targets-edit-btn:hover{color:var(--text)}
.targets-popover{
  position:fixed;z-index:400;width:300px;
  background:var(--surface);border:1px solid var(--border2);border-radius:var(--radius-sm);
  box-shadow:0 12px 36px rgba(0,0,0,.55);padding:12px;
}
.targets-popover-title{font-size:12px;font-weight:700;letter-spacing:-.1px;margin-bottom:8px}
.targets-popover-actions{display:flex;gap:8px;justify-content:flex-end;margin-top:10px}
.targets-popover-rows{max-height:230px;overflow-y:auto;margin-bottom:8px}
.targets-popover-rows:empty{margin-bottom:0}
.targets-popover-rows .target-edit-row{gap:6px;margin-bottom:6px}
.targets-popover-rows .target-edit-label{flex:0 0 92px;font-size:11px}
.targets-popover-add{display:flex;gap:6px;align-items:center}
.targets-popover-add .form-input{flex:1;min-width:0}

/* ── any_of OR-requirements (targets sections) ──────────────────────────── */
.anyof-wrap{display:flex;flex-direction:column;gap:8px;margin-top:2px;padding:8px 10px;border:1px dashed var(--border2);border-radius:var(--radius-sm)}
.anyof-label{font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.7px;color:var(--text3)}
.anyof-alt{display:flex;flex-direction:column;gap:8px}
.anyof-or{
  display:flex;align-items:center;gap:8px;
  font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.7px;color:var(--text3);
}
.anyof-or::before,.anyof-or::after{content:'';flex:1;height:1px;background:var(--border)}

/* ── Opt-out blocking notice (tracker asked not to be supported) ────────── */
.optout-notice{
  padding:10px 14px;border-radius:var(--radius-sm);
  background:var(--error-bg);border:1px solid var(--error-border-md);
  color:var(--red);font-size:12.5px;line-height:1.5;
}
.prowlarr-badge.optout{color:var(--red);border-color:var(--error-border-md);background:var(--error-bg)}

/* ══ SETTINGS PAGE (full-page view at #/settings) ══ */
#settings-page{display:none}
.settings-header{display:flex;align-items:center;gap:16px;margin-bottom:20px;flex-wrap:wrap}
.settings-back{
  display:inline-flex;align-items:center;gap:6px;
  font-size:13px;font-weight:500;color:var(--text2);text-decoration:none;
  padding:6px 12px;border:1px solid var(--border);border-radius:var(--radius-sm);
  background:var(--surface);transition:color .15s,border-color .15s,background .15s;
}
.settings-back:hover{color:var(--text);border-color:var(--border2);background:var(--surface2)}
/* Settings is a form, not a dashboard — capped so an ultrawide doesn't put a
   toggle a third of a metre from the label it belongs to. The tracker table
   inside it scrolls within this width as it always did. */
/* 132px, not 190px: the widest label ("Integrations") is 73px, plus 28px of
   button padding — so 190px left nearly half the rail empty and took the width
   from the content beside it. */
.settings-layout{display:grid;grid-template-columns:132px minmax(0,1fr);gap:20px;align-items:start;max-width:var(--reading-max)}
.settings-tabs{display:flex;flex-direction:column;gap:4px;position:sticky;top:78px}
.settings-tab{
  text-align:left;padding:9px 14px;border-radius:var(--radius-sm);
  border:1px solid transparent;background:transparent;color:var(--text2);
  font-family:inherit;font-size:13px;font-weight:500;cursor:pointer;
  transition:background .15s,color .15s,border-color .15s;
  border-left:2px solid transparent;
}
.settings-tab:hover{background:var(--surface2);color:var(--text)}
.settings-tab.active{
  background:var(--surface2);color:var(--text);
  border-left-color:var(--accent);border-color:var(--border);border-left:2px solid var(--accent);
}
.settings-content{
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);
  padding:20px;min-height:420px;display:flex;flex-direction:column;min-width:0;
}
.settings-panel{display:flex;flex-direction:column;gap:14px}
@media(max-width:900px){
  .settings-layout{grid-template-columns:1fr;gap:12px}
  .settings-tabs{position:static;flex-direction:row;overflow-x:auto;padding-bottom:4px}
  .settings-tab{white-space:nowrap;border-left:2px solid transparent}
  .settings-tab.active{border-left:2px solid var(--accent)}
}

/* ── Trackers tab: configured trackers table ── */
.trk-head{display:flex;align-items:center;gap:12px;margin-bottom:10px}
.trk-table-wrap{border:1px solid var(--border);border-radius:var(--radius-sm);overflow-x:auto}
.trk-table{width:100%;border-collapse:collapse}
.trk-table thead th{
  padding:8px 10px;text-align:left;font-size:11px;font-weight:600;
  text-transform:uppercase;letter-spacing:.6px;color:var(--text3);
  background:var(--surface2);border-bottom:1px solid var(--border2);white-space:nowrap;
}
/* Sortable column headers — a bare button that inherits the th's styling, so
   the header row looks unchanged until you hover it. */
.trk-table thead th:has(.trk-sort){padding:0}
.trk-sort{
  display:flex;align-items:center;gap:5px;width:100%;padding:8px 10px;
  background:none;border:none;cursor:pointer;font:inherit;letter-spacing:inherit;
  text-transform:inherit;color:inherit;text-align:left;
}
.trk-sort:hover{color:var(--text2);background:var(--surface3)}
.trk-sort.active{color:var(--accent)}
.trk-sort-ind{font-size:8px;line-height:1}
.trk-table tbody td{padding:8px 10px;border-bottom:1px solid var(--border);font-size:13px;vertical-align:middle;white-space:nowrap}
/* ── Tracker identity cell ────────────────────────────────────────────────
   The URL moved under the name: it is long, it is the widest column when it
   has its own, and sorting by it was never worth the header it cost. */
.trk-id{display:flex;align-items:center;gap:9px;min-width:0}
.trk-id-text{min-width:0;display:flex;flex-direction:column;gap:1px}
.trk-id-top{display:flex;align-items:center;gap:6px;min-width:0}
.trk-id-url{
  font-size:11px;color:var(--text3);font-family:'Geist Mono',monospace;text-decoration:none;
  max-width:210px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}
.trk-id-url:hover{color:var(--accent);text-decoration:underline}
/* Fixed box whether the icon loads or not — a missing favicon that collapses
   to nothing drags that one row's name out of line with every other. */
.trk-fav{width:16px;height:16px;flex-shrink:0;border-radius:3px;object-fit:contain}
.trk-fav-ph{
  display:inline-block;background-color:currentColor;color:var(--text3);opacity:.4;
  -webkit-mask:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Ccircle%20cx%3D%228%22%20cy%3D%228%22%20r%3D%227.1%22%20fill%3D%22none%22%20stroke%3D%22%23000%22%20stroke-width%3D%221.4%22%2F%3E%3Cellipse%20cx%3D%228%22%20cy%3D%228%22%20rx%3D%223.2%22%20ry%3D%227.1%22%20fill%3D%22none%22%20stroke%3D%22%23000%22%20stroke-width%3D%221.4%22%2F%3E%3Cpath%20d%3D%22M1.2%208h13.6%22%20stroke%3D%22%23000%22%20stroke-width%3D%221.4%22%2F%3E%3C%2Fsvg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Ccircle%20cx%3D%228%22%20cy%3D%228%22%20r%3D%227.1%22%20fill%3D%22none%22%20stroke%3D%22%23000%22%20stroke-width%3D%221.4%22%2F%3E%3Cellipse%20cx%3D%228%22%20cy%3D%228%22%20rx%3D%223.2%22%20ry%3D%227.1%22%20fill%3D%22none%22%20stroke%3D%22%23000%22%20stroke-width%3D%221.4%22%2F%3E%3Cpath%20d%3D%22M1.2%208h13.6%22%20stroke%3D%22%23000%22%20stroke-width%3D%221.4%22%2F%3E%3C%2Fsvg%3E") center/contain no-repeat;
}
.trk-td-caps{white-space:nowrap}
.trk-table tbody tr:last-child td{border-bottom:none}
.trk-row-disabled .trk-td-name,.trk-row-disabled .trk-td-type,.trk-row-disabled .trk-td-caps,.trk-row-disabled .trk-td-def{opacity:.45}
.trk-toggle{cursor:pointer}
.trk-name{font-weight:600}
.trk-abbr-badge{
  font-size:10px;font-weight:600;color:var(--text3);background:var(--surface3);
  border:1px solid var(--border2);border-radius:4px;padding:1px 5px;margin-left:6px;letter-spacing:.3px;
}
.trk-td-url a{font-size:12px;color:var(--text3);font-family:'Geist Mono',monospace;text-decoration:none;max-width:260px;overflow:hidden;text-overflow:ellipsis;display:inline-block;vertical-align:middle}
.trk-td-url a:hover{color:var(--accent);text-decoration:underline}
.trk-td-type{font-size:12px;color:var(--text2)}
.trk-def-badge{
  font-size:11px;font-weight:600;padding:2px 7px;border-radius:20px;
  background:var(--accent-bg-sm);color:var(--accent);border:1px solid var(--accent-border-sm);
  font-family:'Geist Mono',monospace;letter-spacing:.2px;
}
.trk-def-badge.manual{background:var(--surface3);color:var(--text3);border-color:var(--border2)}
/* No def and no type chosen — nothing is being collected at all. */
.trk-def-badge.needs-type{
  background:color-mix(in srgb,var(--amber) 16%,transparent);
  color:var(--amber);border-color:color-mix(in srgb,var(--amber) 40%,transparent);
  cursor:help;
}
/* Opt-out badge — an already-added tracker whose operator has since asked not
   to be supported. Stronger than the amber approval warning: Yata has stopped
   all traffic to it, so it reads as blocked (red). */
.trk-optout-badge{
  font-size:11px;font-weight:600;padding:2px 7px;border-radius:20px;margin-left:6px;
  color:var(--red);border:1px solid var(--error-border-md);background:var(--error-bg);
  letter-spacing:.2px;cursor:help;
}
/* Unread mail/notification flags (scraped header presence, Display toggle) */
.unread-flag{color:var(--amber);font-size:10px;margin-left:5px;cursor:help}

/* qui integration options — inert while the integration is toggled off */
.qui-options-disabled{opacity:.4;pointer-events:none;user-select:none}

/* Def staff-approval warning — shown wherever a non-approved def appears */
.approval-warn{color:var(--amber);font-size:11px;margin-left:6px;cursor:help}
.approval-warn.informal{opacity:.75}
.prowlarr-badge.approval{color:var(--amber);border-color:var(--amber);background:transparent;cursor:help}
.modal-def-approval{
  font-size:11px;color:var(--amber);margin-top:6px;display:flex;align-items:center;gap:2px;
}
.modal-def-approval .approval-warn{margin-left:0;margin-right:4px}

/* About: app / defs / pathways version grid + update badges */
.ver-grid{display:flex;flex-direction:column;gap:6px}
.ver-row{display:flex;align-items:center;gap:10px}
.ver-label{font-size:12px;color:var(--text3);width:82px;flex-shrink:0}
.ver-val{font-size:12px;font-weight:600;color:var(--accent);background:var(--surface2);border:1px solid var(--border);border-radius:6px;padding:2px 9px;font-family:'Geist Mono',monospace}
.ver-badge{font-size:11px}
.ver-badge.ok{color:var(--green)}
.ver-badge.out{color:var(--amber);font-weight:600}

/* Inline text links that follow the theme accent instead of browser blue */
.link-accent{color:var(--accent);text-decoration:none}
.link-accent:hover{text-decoration:underline}

.trk-td-actions{text-align:right}
.trk-td-actions .btn{margin-left:6px}
/* ── Row actions ──────────────────────────────────────────────────────────
   Icon-only, name on hover. Three labelled buttons per row was the widest
   thing in the table and the same three words twenty times over. */
.trk-act{
  width:28px;height:28px;padding:0;border-radius:var(--radius-sm);
  border:1px solid var(--border);background:var(--surface2);color:var(--text3);
  cursor:pointer;transition:color .15s,border-color .15s,background .15s;
  display:inline-flex;align-items:center;justify-content:center;font-size:12px;
}
.trk-act + .trk-act{margin-left:5px}
.trk-act:hover{color:var(--text);border-color:var(--accent);background:var(--surface3)}
.trk-act:disabled{opacity:.4;cursor:default}
.trk-act:disabled:hover{color:var(--text3);border-color:var(--border);background:var(--surface2)}
/* Delete keeps its distance and its colour: next to Edit and identical to it
   is how the wrong one gets clicked. */
.trk-act-danger{margin-left:14px!important;color:var(--red);border-color:var(--error-border-md)}
.trk-act-danger:hover{color:var(--red);border-color:var(--red);background:var(--error-bg)}
.trk-del-btn:hover{color:var(--red);border-color:var(--error-border-md)}
.trk-del-confirm{font-size:12px;color:var(--red);margin-right:4px}
.trk-empty{padding:28px 16px!important;text-align:center;color:var(--text3);font-size:13px;white-space:normal!important}

/* ── Tracker connectivity test (table pills + edit-panel detail rows) ── */
.trk-test-untested{font-size:11px;color:var(--text3);font-style:italic;display:inline-flex;align-items:center;gap:5px}
.trk-test-pills{display:inline-flex;gap:5px;flex-wrap:wrap}
.trk-test-pill{
  font-size:10.5px;font-weight:600;letter-spacing:.2px;padding:2px 7px;border-radius:20px;
  display:inline-flex;align-items:center;gap:4px;border:1px solid;white-space:nowrap;
}
.trk-test-pill i{font-size:9.5px}
.trk-test-pill.ok  {color:var(--green);background:color-mix(in srgb,var(--green) 12%,transparent);border-color:color-mix(in srgb,var(--green) 35%,transparent)}
.trk-test-pill.fail{color:var(--red);  background:color-mix(in srgb,var(--red) 12%,transparent);  border-color:color-mix(in srgb,var(--red) 35%,transparent)}
.trk-test-pill.cfg {color:var(--amber);background:color-mix(in srgb,var(--amber) 12%,transparent);border-color:color-mix(in srgb,var(--amber) 35%,transparent)}
/* --yellow is new. :root in this file defines it, so every existing theme —
   including one a user wrote before it existed — inherits a working value; the
   var(..., var(--amber)) fallback is belt-and-braces for a theme that somehow
   sees neither. */
.trk-test-pill.wait{color:var(--yellow,var(--amber));background:color-mix(in srgb,var(--yellow,var(--amber)) 12%,transparent);border-color:color-mix(in srgb,var(--yellow,var(--amber)) 35%,transparent)}
.trk-test-pill.na  {color:var(--text3);background:var(--surface3);border-color:var(--border2)}

/* Edit-panel detailed result block */
.modal-test-result{
  margin:0 0 12px;padding:10px 14px;border-radius:var(--radius-sm);
  background:var(--surface2);border:1px solid var(--border);display:flex;flex-direction:column;gap:6px;
}
.trk-test-row{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--text2)}
.trk-test-row i{font-size:13px;width:14px;text-align:center}
.trk-test-row.ok   i{color:var(--green)}
.trk-test-row.fail i{color:var(--red)}
.trk-test-row.cfg  i{color:var(--amber)}
.trk-test-row.wait i{color:var(--yellow,var(--amber))}
.trk-test-row.na   i{color:var(--text3)}
.trk-test-label{font-weight:600;color:var(--text);min-width:96px}
.trk-test-word{font-weight:600}
.trk-test-row.ok   .trk-test-word{color:var(--green)}
.trk-test-row.fail .trk-test-word{color:var(--red)}
.trk-test-row.cfg  .trk-test-word{color:var(--amber)}
.trk-test-row.wait .trk-test-word{color:var(--yellow,var(--amber))}
.trk-test-fields{color:var(--text3);font-size:11.5px}
.trk-test-reason{color:var(--text3);font-size:11.5px}

/* ── Trackers tab: inline add/edit panel (replaces tracker modal) ── */
.tracker-panel-head{display:flex;align-items:center;gap:12px;padding-bottom:12px;border-bottom:1px solid var(--border);margin-bottom:14px}
.tracker-panel-title{font-size:15px;font-weight:700;letter-spacing:-.2px}
.tracker-panel-body{display:flex;flex-direction:column;gap:14px}
.tracker-panel-footer{display:flex;gap:8px;justify-content:flex-end;align-items:center;padding-top:14px;border-top:1px solid var(--border);margin-top:14px}
.tracker-delete-confirm{
  display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  margin-top:14px;padding:12px 14px;border-radius:var(--radius-sm);
  background:var(--error-bg);border:1px solid var(--error-border-md);
}
.tracker-delete-title{font-size:13px;font-weight:700;color:var(--red);margin-bottom:2px}
.tracker-delete-body{font-size:12px;color:var(--text2);line-height:1.45}
.tracker-delete-body strong{color:var(--text)}

/* ── Trackers tab: Prowlarr import ── */
.prowlarr-section{margin-top:18px;border-top:1px solid var(--border);padding-top:12px}
.prowlarr-toggle{
  display:inline-flex;align-items:center;gap:7px;background:none;border:none;cursor:pointer;
  font-family:inherit;font-size:13px;font-weight:600;color:var(--text2);padding:4px 0;
  transition:color .15s;
}
.prowlarr-toggle:hover{color:var(--text)}
.prowlarr-results{display:flex;flex-direction:column;gap:6px;max-height:340px;overflow-y:auto}
.prowlarr-row{
  display:flex;align-items:center;gap:10px;padding:8px 10px;
  background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius-sm);
  cursor:pointer;user-select:none;transition:border-color .15s;flex-wrap:wrap;
}
.prowlarr-row:hover{border-color:var(--accent)}
.prowlarr-row.disabled{opacity:.5;cursor:default}
.prowlarr-row.disabled:hover{border-color:var(--border)}
.prowlarr-row input[type=checkbox]{width:14px;height:14px;flex-shrink:0;cursor:pointer;accent-color:var(--accent)}
.prowlarr-row.disabled input[type=checkbox]{cursor:default}
.prowlarr-name{font-size:13px;font-weight:600;color:var(--text)}
.prowlarr-url{font-size:11px;color:var(--text3);font-family:'Geist Mono',monospace;overflow:hidden;text-overflow:ellipsis;max-width:240px}
.prowlarr-badges{display:inline-flex;gap:5px;margin-left:auto;flex-wrap:wrap}
.prowlarr-badge{font-size:10px;font-weight:600;padding:1px 7px;border-radius:20px;letter-spacing:.2px;border:1px solid}
.prowlarr-badge.def{color:var(--green);border-color:color-mix(in srgb,var(--green) 35%,transparent);background:color-mix(in srgb,var(--green) 10%,transparent)}
.prowlarr-badge.key{color:var(--blue);border-color:var(--blue-border);background:var(--blue-bg)}
.prowlarr-badge.privacy{color:var(--text3);border-color:var(--border2);background:var(--surface3)}
.prowlarr-badge.added{color:var(--amber);border-color:var(--amber-border);background:var(--amber-bg)}

/* ── Pathways view ──────────────────────────────────────────────────────── */
/* Target combobox (filterable dropdown) */
.pw-combo{position:relative;width:280px;max-width:100%}
.pw-combo-list{
  position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:60;
  background:var(--surface2);border:1px solid var(--border2);border-radius:var(--radius-sm);
  box-shadow:var(--shadow);max-height:320px;overflow-y:auto;padding:4px;
}
.pw-combo-item{
  display:flex;align-items:center;gap:7px;padding:6px 9px;border-radius:4px;
  font-size:13px;color:var(--text);cursor:pointer;
}
.pw-combo-item:hover{background:var(--surface3)}
.pw-combo-item.selected{background:var(--accent-bg-sm)}
.pw-combo-item.disabled{color:var(--text3);cursor:default}
.pw-combo-item.disabled:hover{background:transparent}
.pw-combo-abbr{font-size:11px;color:var(--text3);font-family:'Geist Mono',monospace}
.pw-combo-note{font-size:11px;color:var(--text3);margin-left:auto;font-style:italic}
.pw-combo-sep{
  font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:.06em;
  color:var(--text3);padding:8px 9px 3px;border-top:1px solid var(--border);margin-top:4px;
}
.pw-combo-empty{font-size:12px;color:var(--text3);font-style:italic;padding:8px 9px}
/* ── Tracker Detail (drill-down page) ─────────────────────────────────── */
.tracker-name-link{cursor:pointer}
.tracker-name-link:hover{color:var(--accent);text-decoration:underline;text-underline-offset:2px}
.detail-header{
  display:flex;align-items:center;gap:12px;margin-bottom:14px;flex-wrap:wrap;
}
.detail-favicon{width:22px;height:22px;flex-shrink:0;border-radius:4px}
.detail-title-wrap{min-width:0;flex:1}
.detail-title{
  font-size:19px;font-weight:700;color:var(--text);
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
}
.detail-sub{
  display:flex;gap:12px;align-items:center;flex-wrap:wrap;
  font-size:11.5px;color:var(--text3);margin-top:3px;
}
.detail-actions{display:flex;gap:6px;align-items:center}
.detail-controls{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  margin-bottom:12px;flex-wrap:wrap;
}
.detail-controls-right{display:flex;align-items:center;gap:8px}
/* Built-in chart hover tooltip (mini-charts) */
.hc-tip{
  position:absolute;pointer-events:none;z-index:5;
  background:var(--surface2);border:1px solid var(--border2);border-radius:6px;
  padding:4px 7px;font-size:10.5px;color:var(--text);white-space:nowrap;
  box-shadow:0 4px 14px rgba(0,0,0,.4);
}
.hc-tip-date{font-size:9.5px;color:var(--text3);margin-bottom:2px}
.hc-tip-row{display:flex;align-items:center;gap:5px;line-height:1.5}
.hc-tip-row b{font-weight:700}
.hc-tip-dot{width:7px;height:7px;border-radius:50%;flex-shrink:0}
/* auto-FIT, not auto-fill: an ultrawide fits ten 320px tracks but the page only
   ever has six charts, and auto-fill left the last four as dead columns with
   the charts stranded at 320px. Collapsing them lets the six share the row. */
.detail-charts{
  display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));
  gap:12px;margin-bottom:16px;
}
.detail-chart-card{
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius-sm);padding:10px 12px 6px;
}
.detail-chart-head{
  display:flex;align-items:center;justify-content:space-between;
  font-size:12px;font-weight:600;color:var(--text2);margin-bottom:4px;
}
.detail-chart-open{
  background:none;border:none;cursor:pointer;color:var(--text3);
  font-size:11px;padding:2px 5px;border-radius:4px;
}
.detail-chart-open:hover{color:var(--accent);background:var(--surface2)}
.detail-chart{min-height:60px}
/* Label→value lists, so capped: auto-fit would happily stretch the three
   columns to 1100px each on an ultrawide, putting every value a screen's width
   from its label. The charts above are free to use the whole row. */
/* Masonry columns rather than a grid. With a grid, a card that wraps to the
   next row starts below the TALLEST card in the row above — so on a narrow
   screen the timelines card sat in a lane of its own with a stretch of empty
   space beside the short Stats card. Balanced columns tuck it up instead.
   Cards are body-appended for popovers, so nothing is clipped by the
   multi-column context. */
.detail-cols{
  columns:4 280px;column-gap:16px;max-width:var(--reading-max);
}
.detail-col{
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius-sm);padding:14px 16px;
  /* A card must never be split down the middle across a column boundary. */
  break-inside:avoid;-webkit-column-break-inside:avoid;
  margin-bottom:16px;
}
.detail-empty{font-size:11.5px;color:var(--text3);font-style:italic}
.detail-menu-hint{font-size:10px;color:var(--text3);padding:6px 4px 2px;font-style:italic}
.detail-route{margin-bottom:9px;font-size:12.5px;color:var(--text)}
.detail-route-to{font-weight:600;margin-right:8px}
.detail-route-fav{color:var(--amber);font-size:11px;margin-right:8px}
.detail-route-reqs{font-size:10.5px;color:var(--text3);margin-top:2px}
.detail-events{display:flex;flex-direction:column;gap:7px}
.detail-event{display:flex;align-items:baseline;gap:8px;font-size:12.5px;color:var(--text)}
.detail-event-detail{flex:1;min-width:0}
/* The date never wraps: "25 Jul 2026" breaking across two lines in a narrow
   column read as a rendering fault. The description wraps instead. */
.detail-event-when{margin-left:auto;font-size:10.5px;color:var(--text3);white-space:nowrap}

.card-rules{
  display:flex;align-items:center;gap:6px;margin-top:8px;
  font-size:10.5px;color:var(--text3);
}
.card-rules i{font-size:10px;opacity:.7}
.pw-combo-chips{
  display:flex;gap:5px;padding:2px 5px 7px;border-bottom:1px solid var(--border);
  margin-bottom:4px;position:sticky;top:-4px;background:var(--surface2);z-index:1;
}
.pw-chip-filter{
  font-size:10.5px;font-weight:600;padding:3px 9px;border-radius:999px;cursor:pointer;
  background:var(--surface3);border:1px solid var(--border2);color:var(--text2);
}
.pw-chip-filter:hover{color:var(--text)}
.pw-chip-filter.on{background:var(--accent-bg-sm);border-color:var(--accent);color:var(--accent)}
.pw-met-dot{
  font-size:10px;font-weight:700;color:var(--green);white-space:nowrap;
  background:color-mix(in srgb,var(--green) 12%,transparent);
  border-radius:999px;padding:1px 7px;
}
.pw-item-actions{margin-left:auto;display:flex;gap:2px;align-items:center}
.pw-act{
  background:none;border:none;cursor:pointer;color:var(--text3);font-size:13px;
  padding:1px 4px;border-radius:4px;line-height:1;opacity:.55;
}
.pw-combo-item:hover .pw-act{opacity:1}
.pw-act:hover{color:var(--text);background:var(--surface2)}
.pw-act-fav.on{color:var(--amber);opacity:1}
.pw-act-hide i{font-size:11px}
.pw-item-muted .pw-combo-name{color:var(--text3)}
.pw-def-badge{
  font-size:9px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  padding:1px 5px;border-radius:3px;
  color:var(--green);
  border:1px solid color-mix(in srgb,var(--green) 35%,transparent);
  background:color-mix(in srgb,var(--green) 10%,transparent);
}

/* Path cards */
.pw-loading{color:var(--text3);font-size:13px;font-style:italic;padding:24px 4px}
.pw-path-card{
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);
  padding:14px 16px;margin-bottom:12px;
}
.pw-path-card.pw-best{border-color:var(--accent-border);box-shadow:0 0 0 1px var(--accent-border),0 4px 16px var(--accent-glow)}
.pw-path-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:10px}
.pw-best-badge{
  font-size:10px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  padding:2px 8px;border-radius:20px;
  background:var(--accent-bg-md);color:var(--accent);border:1px solid var(--accent-border-sm);
}
.pw-eta{font-size:14px;font-weight:700;color:var(--text);font-family:'Geist Mono',monospace}
.pw-eta-ready{color:var(--green)}
.pw-unknown-note{font-size:11px;color:var(--text3);font-style:italic}
.pw-hops{font-size:11px;color:var(--text3);margin-left:auto}

/* Chain of chips */
.pw-chain{display:flex;align-items:center;gap:6px;flex-wrap:wrap}
.pw-arrow{color:var(--text3);font-size:13px;flex-shrink:0}
.pw-chip{
  display:inline-flex;align-items:center;gap:6px;padding:5px 11px;
  font-size:12px;font-weight:600;color:var(--text);
  background:var(--surface2);border:1px solid var(--border2);border-radius:20px;
  white-space:nowrap;
}
.pw-chip-favicon{width:13px;height:13px;flex-shrink:0;border-radius:2px}
.pw-chip-step{cursor:pointer;transition:border-color .15s,background .15s}
.pw-chip-step:hover{border-color:var(--accent)}
.pw-chip-step.expanded{background:var(--surface3);border-color:var(--accent-border-md)}
.pw-chip-step.expanded .pw-chip-chev{transform:rotate(180deg)}
.pw-chip-chev{flex-shrink:0;color:var(--text3);transition:transform .15s}
.pw-chip-target{border-color:var(--accent-border-md);background:var(--accent-bg-sm)}
.pw-chip-est{font-size:11px;color:var(--amber);font-weight:700;cursor:help}
/* Start chip for a DISABLED tracker: muted + dashed so it reads as "listed,
   but nothing here is measured". Pairs with the "Timeline unknown" ETA. */
.pw-chip-start--disabled{
  border-style:dashed;color:var(--text3);
  background:color-mix(in srgb,var(--text3) 8%,var(--surface2));
}
.pw-chip-start--disabled .pw-chip-favicon{opacity:.55}
.pw-chip-disabled-tag{
  font-size:9px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--text3);border:1px solid var(--border2);border-radius:4px;
  padding:1px 4px;margin-left:2px;
}

/* Expanded step details */
.pw-step-detail{
  margin-top:10px;padding:10px 12px;
  background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius-sm);
}
.pw-step-detail-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:8px}
.pw-step-route{font-size:12px;font-weight:600;color:var(--text)}
.pw-est-badge{
  font-size:9px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  padding:1px 6px;border-radius:3px;cursor:help;
  background:var(--amber-bg);border:1px solid var(--amber-border);color:var(--amber);
}
.pw-updated{font-size:11px;color:var(--text3);margin-left:auto;white-space:nowrap}
.pw-reqs-raw{
  font-size:12px;color:var(--text2);line-height:1.5;
  padding:7px 10px;border-left:2px solid var(--border2);
  background:var(--table-hover);border-radius:0 4px 4px 0;margin-bottom:8px;
}
.pw-reqs-raw-empty{font-style:italic;color:var(--text3)}
/* Def-sourced invite-requirement note (distinct from the community text). */
.pw-def-note{
  font-size:11.5px;color:var(--text2);line-height:1.5;
  padding:7px 10px;border-left:2px solid color-mix(in srgb,var(--amber) 55%,transparent);
  background:color-mix(in srgb,var(--amber) 7%,transparent);
  border-radius:0 4px 4px 0;margin-bottom:8px;
}
.pw-def-note i{color:var(--amber)}
.pw-req-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px}
.pw-req{display:flex;align-items:baseline;gap:8px;font-size:12px;color:var(--text2)}
.pw-req-icon{
  width:16px;flex-shrink:0;text-align:center;font-weight:700;
  font-family:'Geist Mono',monospace;
}
.pw-req--met .pw-req-icon{color:var(--green)}
.pw-req--eta .pw-req-icon{color:var(--amber)}
.pw-req--unknown .pw-req-icon{color:var(--text3)}
.pw-req--unknown{cursor:help}
.pw-req-eta{font-size:11px;color:var(--amber);font-family:'Geist Mono',monospace;white-space:nowrap}

/* No-path notice + suggestions */
.pw-notice{
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);
  padding:16px 18px;margin-bottom:12px;
}
.pw-notice-title{font-size:14px;font-weight:600;color:var(--text)}
.pw-notice-sub{font-size:12px;color:var(--text2);margin-top:4px}
.pw-suggestions{display:flex;flex-direction:column;gap:8px}
.pw-suggestion{
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-sm);
  padding:10px 14px;
}
.pw-suggestion-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-bottom:4px}
.pw-suggestion-name{font-size:13px;font-weight:600;color:var(--text)}
.pw-suggestion-days{font-size:11px;color:var(--amber)}
.pw-suggestion .pw-reqs-raw{margin-bottom:0;margin-top:6px}

/* Disclosure footer (REQUIRED — always visible) */
.pw-disclosure{
  margin-top:20px;padding:10px 14px;
  font-size:11px;color:var(--text3);line-height:1.6;
  border:1px solid var(--border);border-radius:var(--radius-sm);
  background:var(--table-hover);
}
.pw-disclosure a{color:var(--blue);text-decoration:none}
.pw-disclosure a:hover{text-decoration:underline}
/* Source credit sits below the estimates explainer with a dividing line break */
.pw-disclosure-credit{margin-top:8px;padding-top:8px;border-top:1px dashed var(--border)}

/* ── Pathways: per-class requirement breakdowns with progress bars ───────── */
.pw-req-classes { display: block; }
.pw-class-req-label { display: flex; align-items: center; gap: 6px; font-size: 12px; font-weight: 600; color: var(--text2); margin-bottom: 6px; }
.pw-plus-hint { color: var(--text3); cursor: help; font-size: 11px; }
.pw-class-section { margin: 6px 0 10px 18px; padding: 8px 10px; background: var(--surface2); border: 1px solid var(--border); border-radius: 8px; }
.pw-class-head { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; font-size: 12px; font-weight: 600; color: var(--text); }
.pw-fastest-badge { font-size: 10px; font-weight: 600; text-transform: uppercase; letter-spacing: .4px; color: var(--green); border: 1px solid var(--green); border-radius: 4px; padding: 1px 5px; opacity: .85; }
.pw-req-bar { display: block; padding: 4px 0; }
.pw-req-bar .target-header { margin-bottom: 3px; }
.pw-req-bar .pw-req-eta { margin-left: 8px; }
.pw-req-icon--met { color: var(--green); }
.pw-req-icon--eta { color: var(--amber); }
.pw-req-icon--unknown { color: var(--text3); }
.pw-class-section .anyof-wrap { margin-top: 6px; }

/* A route-level "A or B and C" requirement: header line + the same "One of"
   block the class breakdowns use, so alternatives read the same wherever
   they appear. */
.pw-req-anyof { display: block; }
.pw-req-anyof .anyof-wrap { margin: 6px 0 4px 18px; }

/* Pathways: requirements Yata can't measure — the tracker doesn't report the
   stat, the text was never a stat ("2 more proofs"), or there's no group data
   for the class. Same visual language as an untrackable target row (reason +
   empty dashed track, no bar), kept as its own rules because these are invite
   requirements rather than tracked targets and can diverge. Never green:
   unmeasurable is not met. */
.pw-req--unavail { display: block; padding: 4px 0; opacity: .72; cursor: help; }
.pw-req--unavail .target-header { margin-bottom: 3px; }
.pw-unavail-vals { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-family: 'Geist Mono', monospace; color: var(--text3); white-space: nowrap; }
.pw-unavail-icon { flex: none; color: var(--text3); vertical-align: -2px; }
.pw-unavail-txt { font-style: italic; letter-spacing: .2px; }
.pw-track--unavail { height: 5px; border-radius: 3px; background: transparent; border: 1px dashed var(--border); }

/* Pathways: estimates are amber (matching in-hop estimate chips); lower
   bounds carry a "+". Ready state stays green. */
.pw-eta { color: var(--amber); }
.pw-eta-ready { color: var(--green); }
.pw-req-eta { color: var(--amber); font-size: 11px; white-space: nowrap; margin-left: 6px; }

/* ── Login gate ──────────────────────────────────────────────────────────── */
.login-overlay{
  position:fixed;inset:0;z-index:1000;
  display:flex;align-items:center;justify-content:center;padding:20px;
  background:var(--bg);
}
.login-card{
  width:100%;max-width:360px;
  background:var(--surface);border:1px solid var(--border);
  border-radius:var(--radius);box-shadow:var(--shadow);
  padding:26px 24px;
}
.login-logo{
  display:flex;align-items:center;justify-content:center;gap:9px;
  font-size:18px;font-weight:700;color:var(--text);margin-bottom:4px;
}
.login-title{
  text-align:center;font-size:13px;color:var(--text3);
  margin-bottom:20px;letter-spacing:.3px;
}
.login-error{
  font-size:12px;color:var(--red);
  background:var(--error-bg-md);border:1px solid var(--error-border-md);
  border-radius:var(--radius-sm);padding:8px 10px;margin-bottom:12px;
}

/* ── Logs settings tab ───────────────────────────────────────────────────── */
.log-toolbar{
  display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:10px;
}
.log-tool-item{display:flex;align-items:center;gap:6px}
.log-view{
  height:60vh;min-height:280px;overflow-y:auto;
  background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-sm);
  padding:8px 10px;
  font-family:'Geist Mono',monospace;font-size:11.5px;line-height:1.55;
}
.log-empty{color:var(--text3);font-style:italic;font-family:'Geist',sans-serif;font-size:12px;padding:6px 2px}
.log-line{display:flex;gap:8px;white-space:pre-wrap;word-break:break-word;padding:1px 0}
.log-line:hover{background:var(--table-hover)}
.log-time{color:var(--text3);flex-shrink:0}
.log-lvl{flex-shrink:0;font-weight:600;width:30px}
.log-msg{color:var(--text2);flex:1}
.log-trace .log-lvl{color:var(--text3)}
.log-debug .log-lvl{color:var(--purple)}
.log-info  .log-lvl{color:var(--blue)}
.log-warn  .log-lvl{color:var(--amber)}
.log-warn  .log-msg{color:var(--text)}
.log-error .log-lvl{color:var(--red)}
.log-error .log-msg{color:var(--red)}

/* ── Alerts settings tab ─────────────────────────────────────────────────── */
.alerts-subhead{font-size:13px;font-weight:600;color:var(--text);margin-bottom:4px}
.alerts-card{
  background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius-sm);
  padding:10px 12px;margin-bottom:10px;
}
.alerts-row{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.alerts-inline{display:inline-flex;align-items:center;gap:5px;font-size:12px;color:var(--text2);white-space:nowrap}
.alerts-inline input[type=checkbox]{accent-color:var(--accent)}
.alerts-conds{margin:8px 0 0 0;padding:8px 10px;background:var(--bg);border-radius:var(--radius-sm)}
.cond-row .form-input{padding:4px 8px}

/* Alerts: Include/Exclude segment + tracker chips */
.seg{display:inline-flex;border:1px solid var(--border);border-radius:var(--radius-sm);overflow:hidden}
.seg-btn{background:var(--surface);color:var(--text3);border:none;padding:4px 12px;font-size:12px;font-weight:600;cursor:pointer}
.seg-btn.active{background:var(--accent);color:var(--btn-primary-text)}
.tracker-chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.tracker-chip{
  background:var(--surface);color:var(--text2);
  border:1px solid var(--border);border-radius:20px;
  padding:3px 11px;font-size:12px;cursor:pointer;transition:all .12s;
}
.tracker-chip:hover{border-color:var(--accent-border)}
.tracker-chip.selected{
  background:var(--accent-bg-md);color:var(--accent);
  border-color:var(--accent-border-md);font-weight:600;
}

/* Alerts: searchable multi-select (chips + dropdown) */
.ms{position:relative;flex:1;min-width:180px}
.ms-control{
  display:flex;align-items:center;gap:6px;min-height:32px;
  background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-sm);
  padding:3px 8px;cursor:pointer;
}
.ms-control:hover{border-color:var(--accent-border)}
.ms-chips{display:flex;flex-wrap:wrap;gap:5px;flex:1}
.ms-placeholder{font-size:12px;color:var(--text3)}
.ms-chip{
  display:inline-flex;align-items:center;gap:5px;
  background:var(--accent-bg-md);color:var(--accent);
  border:1px solid var(--accent-border-sm);border-radius:14px;
  padding:1px 8px;font-size:11.5px;font-weight:600;
}
.ms-chip button{background:none;border:none;color:inherit;cursor:pointer;font-size:11px;padding:0;line-height:1;opacity:.7}
.ms-chip button:hover{opacity:1}
.ms-caret{color:var(--text3);font-size:10px;flex-shrink:0}
.ms-dropdown{
  position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:200;
  background:var(--surface2);border:1px solid var(--border2);border-radius:var(--radius-sm);
  box-shadow:var(--shadow);padding:6px;
}
.ms-search{
  width:100%;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius-sm);
  color:var(--text);font-size:12px;padding:5px 8px;margin-bottom:6px;
}
.ms-options{max-height:220px;overflow-y:auto;display:flex;flex-direction:column;gap:1px}
.ms-option{
  display:flex;align-items:center;justify-content:space-between;
  padding:5px 8px;border-radius:var(--radius-sm);font-size:12.5px;color:var(--text2);cursor:pointer;
}
.ms-option:hover{background:var(--table-hover)}
.ms-option.selected{color:var(--accent);font-weight:600}
.ms-option .ms-check{opacity:0;color:var(--accent)}
.ms-option.selected .ms-check{opacity:1}
.ms-empty{font-size:12px;color:var(--text3);font-style:italic;padding:6px 8px}

/* Alerts: collapsed destination rows */
.alerts-dest-row{
  display:flex;align-items:center;gap:10px;
  background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius-sm);
  padding:7px 12px;margin-bottom:8px;
}
.dest-row-name{font-size:13px;font-weight:600;color:var(--text)}
.dest-row-type{font-size:11px;color:var(--text3);background:var(--surface);border:1px solid var(--border);border-radius:12px;padding:1px 8px;white-space:nowrap}

/* Alerts: collapsed rule rows (scope callout + dry run). Rows wrap at narrow
   widths so the name/scope get a second line instead of being crushed. */
.alerts-rule-row{flex-wrap:wrap;row-gap:4px}
.alerts-rule-row .dest-row-name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:80px;max-width:220px}
.alerts-rule-row.rule-row-disabled .dest-row-name,
.alerts-rule-row.rule-row-disabled .rule-row-scope{opacity:.55}
.rule-row-scope{
  font-size:11px;color:var(--text3);min-width:0;flex:1 1 160px;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.rule-row-arrow{opacity:.6;margin:0 2px}
.alerts-dryrun{
  background:var(--surface);border:1px dashed var(--border);border-radius:var(--radius-sm);
  padding:8px 12px;margin:-2px 0 10px;font-size:12px;color:var(--text2);
}
.dryrun-disabled-note{color:var(--amber);font-size:11px;margin-bottom:6px}
.dryrun-row{display:flex;gap:8px;margin-top:5px;font-size:11px;color:var(--text3);align-items:baseline}
.dryrun-mark{width:12px;text-align:center;flex-shrink:0}
.dryrun-row.hit .dryrun-mark{color:var(--green)}
.dryrun-row.hit .dryrun-name{color:var(--text)}
.dryrun-name{font-weight:600;flex-shrink:0}
.dryrun-detail{overflow-wrap:anywhere}

/* Logs: display-level filter chips */
.log-levels{display:inline-flex;gap:5px;flex-wrap:wrap}
.log-lvl-chip{
  background:var(--surface);border:1px solid var(--border);border-radius:14px;
  color:var(--text3);font-size:11px;font-weight:600;letter-spacing:.3px;
  padding:2px 10px;cursor:pointer;opacity:.55;transition:all .12s;
  font-family:'Geist Mono',monospace;
}
.log-lvl-chip.selected{opacity:1}
.log-lvl-chip.log-lvl-trace.selected{color:var(--text2);border-color:var(--border2)}
.log-lvl-chip.log-lvl-debug.selected{color:var(--purple);border-color:color-mix(in srgb,var(--purple) 40%,transparent)}
.log-lvl-chip.log-lvl-info.selected{color:var(--blue);border-color:color-mix(in srgb,var(--blue) 40%,transparent)}
.log-lvl-chip.log-lvl-warn.selected{color:var(--amber);border-color:color-mix(in srgb,var(--amber) 40%,transparent)}
.log-lvl-chip.log-lvl-error.selected{color:var(--red);border-color:color-mix(in srgb,var(--red) 40%,transparent)}

/* Per-tracker scraping: operator-requested limits — an informational notice
   (amber), never red: it doesn't block saving, and red is reserved for the
   blocking validation errors under the inputs. */
.modal-scrape-req{
  font-size:12.5px;font-weight:500;color:var(--amber);
  background:var(--amber-bg);border:1px solid var(--amber-border);
  border-radius:var(--radius-sm);padding:7px 11px;margin-bottom:4px;
}
.form-input.input-error{border-color:var(--red);box-shadow:0 0 0 1px var(--red)}
/* Muted unit suffix beside a numeric input ("min", "per UTC day") — units
   live next to the field, constraints in ONE helper line under it. */
.input-unit{font-size:11px;color:var(--text3);font-weight:500;white-space:nowrap}

/* Login lockout recovery + first-run security nudge */
.login-locked{
  margin-top:14px;padding-top:14px;border-top:1px solid var(--border);
  font-size:12.5px;color:var(--amber);
}
.auth-nudge{
  display:flex;align-items:center;gap:10px;flex-wrap:wrap;
  padding:9px 20px;font-size:12.5px;color:var(--amber);
  background:color-mix(in srgb,var(--amber) 12%,var(--surface));
  border-bottom:1px solid color-mix(in srgb,var(--amber) 35%,transparent);
}
.auth-nudge-x{
  background:none;border:none;color:var(--amber);font-size:18px;line-height:1;
  cursor:pointer;opacity:.7;padding:0 2px;
}
.auth-nudge-x:hover{opacity:1}
.auth-nudge-dontwarn{
  color:var(--amber);border-color:color-mix(in srgb,var(--amber) 35%,transparent);
  background:none;white-space:nowrap;
}
.auth-nudge-dontwarn:hover{background:color-mix(in srgb,var(--amber) 14%,transparent)}

/* ── Tracker capability indicators ──────────────────────────────────────────
   Tri-state throughout: available via API (solid), via scraping only (amber
   outline), not available (dimmed + struck through). The third state has to
   look deliberate — a missing icon would read as "we didn't check". */
.cap-row{display:inline-flex;align-items:center;gap:4px;margin-left:6px;vertical-align:middle}
.cap-chip{
  display:inline-flex;align-items:center;gap:4px;padding:1px 6px;border-radius:9px;
  font-size:10.5px;font-weight:600;line-height:1.6;cursor:help;
  border:1px solid transparent;white-space:nowrap;
}
.cap-chip i{font-size:9px}
.cap-chip.cap-full{color:var(--green);background:color-mix(in srgb,var(--green) 14%,transparent);border-color:color-mix(in srgb,var(--green) 34%,transparent)}
.cap-chip.cap-part{color:var(--amber);background:color-mix(in srgb,var(--amber) 14%,transparent);border-color:color-mix(in srgb,var(--amber) 34%,transparent)}
.cap-chip.cap-none{color:var(--red);background:color-mix(in srgb,var(--red) 12%,transparent);border-color:color-mix(in srgb,var(--red) 32%,transparent)}
/* The "+N with scraping" half, deliberately quieter than the API figure it
   follows — scraping is conditional on a cookie the user may not have. */
.cap-plus{opacity:.7;font-size:9.5px;margin-left:3px}
.cap-icon{
  display:inline-flex;align-items:center;justify-content:center;
  width:17px;height:17px;border-radius:4px;font-size:9.5px;cursor:help;
}
.cap-icon.cap-on{color:var(--green);background:color-mix(in srgb,var(--green) 13%,transparent)}
.cap-icon.cap-scrape{color:var(--amber);background:color-mix(in srgb,var(--amber) 12%,transparent)}
.cap-icon.cap-off{color:var(--text3);opacity:.42}
.cap-icon.cap-off i{text-decoration:line-through}
.cap-icon.cap-apionly{color:var(--blue);background:color-mix(in srgb,var(--blue) 13%,transparent)}

/* Add-tracker modal: the row sits under the def's name/URL header. */
.modal-def-caps{margin-top:8px}
.modal-def-caps .cap-row{margin-left:0}

/* Detail page: collapsed by default, with the headline figure still on the
   summary line so the answer is one glance away and the detail one click. */
.cap-card{border-top:1px solid var(--border);padding-top:10px}
.cap-card-summary{
  display:flex;align-items:center;gap:8px;cursor:pointer;list-style:none;
  font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  color:var(--text3);
}
.cap-card-summary::-webkit-details-marker{display:none}
.cap-card-summary::before{
  content:'';border:4px solid transparent;border-left-color:currentColor;
  margin-right:-2px;transition:transform .15s ease;transform-origin:2px 50%;
}
.cap-card[open] > .cap-card-summary::before{transform:rotate(90deg)}
.cap-card-summary:hover{color:var(--text2)}
.cap-card-count{margin-left:auto;color:var(--text2);font-size:11px;letter-spacing:0}
.cap-card .cap-panel{margin-top:10px}
.cap-panel{display:flex;flex-direction:column;gap:8px;font-size:12px}
.cap-panel-empty{font-size:11.5px;color:var(--text3);line-height:1.5}
.cap-panel-row{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px}
.cap-panel-row--flag{justify-content:space-between}
.cap-panel-label{color:var(--text2)}
.cap-panel-label i{width:13px;margin-right:3px;opacity:.75}
.cap-panel-val{color:var(--text);font-weight:600;margin-left:auto}
.cap-panel-val.cap-api{color:var(--green)}
.cap-panel-val.cap-scrape{color:var(--amber)}
.cap-panel-val.cap-off{color:var(--text3);font-weight:500}
.cap-plus-txt{color:var(--text3);font-weight:500;font-size:11px}
.cap-bar{width:100%;height:4px;border-radius:2px;background:color-mix(in srgb,var(--text3) 22%,transparent);overflow:hidden}
.cap-bar-fill{height:100%;border-radius:2px;background:var(--green)}
.cap-panel-note{
  font-size:11.5px;line-height:1.5;color:var(--text2);padding:8px 10px;border-radius:5px;
  background:color-mix(in srgb,var(--amber) 9%,transparent);
  border:1px solid color-mix(in srgb,var(--amber) 26%,transparent);
}
.cap-panel-details summary{cursor:pointer;font-size:11.5px;color:var(--text3)}
.cap-panel-details summary:hover{color:var(--text2)}
.cap-stat-list{display:flex;flex-wrap:wrap;gap:4px;margin-top:7px}
.cap-stat-list span{
  padding:2px 6px;border-radius:4px;font-size:10.5px;color:var(--text2);
  background:var(--surface3);border:1px solid var(--border2);
}

/* Password strength meter — length only, no composition rules */
.pw-meter{margin-top:-2px}
.pw-meter-track{
  height:4px;border-radius:2px;overflow:hidden;
  background:color-mix(in srgb,var(--text3) 25%,transparent);
}
.pw-meter-fill{height:100%;border-radius:2px;transition:width .18s ease,background .18s ease}
.pw-meter-label{font-size:11px;margin-top:4px}

/* Grandfathered-password nudge in Settings → Account */
.acct-nudge{
  display:flex;align-items:flex-start;gap:9px;margin:10px 0 2px;padding:9px 11px;
  max-width:520px;font-size:12px;line-height:1.45;color:var(--text2);border-radius:6px;
  background:color-mix(in srgb,var(--amber) 10%,var(--surface));
  border:1px solid color-mix(in srgb,var(--amber) 30%,transparent);
}

/* Two-factor enrolment: instructions beside the QR, stacking when narrow */
.totp-enrol{
  display:flex;gap:20px;align-items:flex-start;flex-wrap:wrap;
  margin-top:14px;padding:14px;max-width:620px;border-radius:8px;
  background:var(--surface2,var(--surface));border:1px solid var(--border);
}
.totp-enrol-steps{flex:1 1 260px;min-width:0;font-size:12px;color:var(--text2)}
/* The QR carries its own white background — it must not be themed, inverted
   or filtered, or it stops scanning. */
.totp-qr{flex:0 0 168px;width:168px;line-height:0;border-radius:6px;overflow:hidden}
.totp-qr svg{width:100%;height:auto;display:block}
.totp-secret{
  display:inline-block;padding:6px 9px;border-radius:5px;font-size:13px;letter-spacing:.06em;
  color:var(--text);background:var(--bg);border:1px solid var(--border);
  user-select:all;word-break:break-all;max-width:100%;
}

/* Recovery codes — shown exactly once */
.recovery-codes{
  margin-top:14px;padding:14px;max-width:520px;border-radius:8px;font-size:12px;
  background:color-mix(in srgb,var(--amber) 8%,var(--surface));
  border:1px solid color-mix(in srgb,var(--amber) 32%,transparent);
}
.recovery-code-grid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(120px,1fr));gap:7px;
}
.recovery-code-grid code{
  padding:6px 8px;border-radius:5px;text-align:center;letter-spacing:.05em;
  font-size:12.5px;color:var(--text);background:var(--bg);border:1px solid var(--border);
  user-select:all;
}

/* ── Alerts panel ─────────────────────────────────────────────────────────
   Yata's own alert destination (ALERTS_PANEL_PLAN.md). A flag rather than a
   bell: envelope and bell already mean a TRACKER's own unread mail and
   notifications on the cards, and a second bell here would read as "unread
   across all trackers". */
.alerts-flag { position: relative; }
.alerts-flag.has-unread { color: var(--amber); }

.alerts-count {
  position: absolute; top: -3px; right: -3px;
  min-width: 15px; height: 15px; padding: 0 3px;
  border-radius: 8px; background: var(--amber); color: #1a1a1a;
  font-size: 9px; font-weight: 700; line-height: 15px; text-align: center;
  pointer-events: none;
}

.alerts-panel {
  /* fixed, not absolute: the topbar is sticky, so the panel has to be
     anchored to the VIEWPORT. As absolute it positioned against the document
     and scrolled off the top of the screen the moment the page moved.
     z-index clears the topbar's own 200 for the same reason — 58px is the
     header height. */
  position: fixed; top: 66px; right: 16px; z-index: 210;
  width: min(420px, calc(100vw - 32px));
  max-height: min(560px, calc(100vh - 90px));
  display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: 8px; box-shadow: 0 10px 32px rgba(0,0,0,.45);
}
/* An author `display` overrides the UA sheet's [hidden]{display:none}, so
   without this the panel ignores its own hidden attribute and never closes —
   the same guard .goal-date-pop and .history-menu already carry. */
.alerts-panel[hidden] { display: none; }

.alerts-panel-head {
  display: flex; gap: 6px; align-items: center;
  padding: 8px; border-bottom: 1px solid var(--border);
}
.alerts-search, .alerts-filter {
  background: var(--bg); color: var(--text);
  border: 1px solid var(--border2); border-radius: 5px;
  padding: 4px 7px; font-size: 12px; font-family: inherit;
}
.alerts-search { flex: 1 1 auto; min-width: 0; }
.alerts-filter { flex: 0 1 auto; max-width: 130px; }

.alerts-list { overflow-y: auto; flex: 1 1 auto; }

.alert-row {
  display: flex; align-items: flex-start; gap: 6px;
  padding: 9px 10px; border-bottom: 1px solid var(--border);
}
.alert-row:last-child { border-bottom: 0; }
/* The unread marker is a left edge, not a background wash: a list that is
   mostly unread should still read as a list. */
.alert-row.unread { border-left: 2px solid var(--amber); padding-left: 8px; }
.alert-row-main { flex: 1 1 auto; min-width: 0; }
.alert-row-top { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
.alert-rule { font-size: 12px; font-weight: 600; color: var(--text); }
.alert-when { font-size: 11px; color: var(--text3); white-space: nowrap; }
.alert-body { font-size: 12px; color: var(--text2); margin-top: 2px; word-break: break-word; }
.alert-where { font-size: 11px; color: var(--text3); margin-top: 2px; }

.alert-clear {
  flex: 0 0 auto; background: none; border: 0; cursor: pointer;
  color: var(--text3); font-size: 15px; line-height: 1; padding: 0 2px;
}
.alert-clear:hover { color: var(--text); }

.alerts-empty { padding: 26px 16px; text-align: center; font-size: 12px; color: var(--text3); }
.alerts-empty-sub { font-size: 11px; opacity: .8; }
.alerts-more { padding: 8px; border-top: 1px solid var(--border); text-align: center; }

/* The notification centre in the destinations list: built in, so it shows what
   it is instead of Edit/Delete controls that have nothing to act on. */
.dest-row-builtin { font-size: 11px; color: var(--text3); font-style: italic; }
@container (max-width: 420px) { .dest-row-builtin { display: none; } }

/* ══ SETTINGS DESIGN LANGUAGE ══════════════════════════════════════════════
   Six primitives every settings page is built from. See SETTINGS_DESIGN_PLAN.md.

   Colour comes only from existing tokens — no new custom properties, so all
   twelve themes (which are pure token blocks with no element selectors) keep
   working untouched. Spacing uses literals deliberately: a theme should decide
   colour, not layout. */

/* ── Page header ──────────────────────────────────────────────────────────
   The title had no weight and read as chrome, because the sidebar was the
   thing telling you where you were. */
.set-head { display: flex; align-items: flex-start; gap: 14px; margin-bottom: 22px; }
.set-eyebrow {
  font-size: 11px; font-weight: 600; letter-spacing: .8px; text-transform: uppercase;
  color: var(--text3); margin-bottom: 2px;
}
.set-head-text { min-width: 0; }
.set-title {
  font-size: 24px; font-weight: 650; letter-spacing: -.4px;
  color: var(--text); margin: 0 0 4px;
}
.set-lede {
  font-size: 13px; line-height: 1.5; color: var(--text2);
  margin: 0; max-width: 68ch;
}

/* ── Section ──────────────────────────────────────────────────────────────
   The unit of layout: sections flow into columns, never their contents. */
/* A container, so field rows inside can respond to the width of their COLUMN
   rather than of the viewport. With auto-fit columns the two are unrelated: a
   section can be 340px wide on a 2560px screen, and a viewport media query
   would happily keep a 190px label column in it. */
.set-section { min-width: 0; container-type: inline-size; }
.set-section + .set-section { margin-top: 26px; }
.set-section-head { margin-bottom: 12px; }
.set-section-title {
  font-size: 13px; font-weight: 650; letter-spacing: .3px; text-transform: uppercase;
  color: var(--text); margin: 0;
}
.set-section-note {
  font-size: 12px; line-height: 1.5; color: var(--text3);
  margin: 3px 0 0; max-width: 62ch;
}

/* ── Column flow ──────────────────────────────────────────────────────────
   auto-fit decides the count from available width: one column on a phone,
   several on an ultrawide, with no breakpoint list to keep in step. A section
   that cannot survive being narrow opts out with .set-span. */
.set-grid {
  display: grid;
  /* min(320px, 100%), not a bare 320px: on a narrow screen the minimum wins
     and the track overflows its container, pushing the card past the viewport
     edge. Capping the minimum at the available width makes the last step down
     graceful instead. */
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
  gap: 22px 26px; align-items: start;
}
.set-grid > .set-section + .set-section { margin-top: 0; }
/* A section that spans every column. Use sparingly: a spanning item forces the
   tracks to exist, so auto-fit can no longer collapse an empty one — two
   sections in a grid that could fit three then sit in two-thirds of the width
   with dead space beside them. A full-width block is usually better placed
   AFTER the grid than inside it. */
.set-span { grid-column: 1 / -1; }
/* One grid cell holding several stacked sections — for pairing a short group
   with another so a column is not left half empty beside a tall neighbour. */
.set-stack { min-width: 0; }
.set-grid + .set-section { margin-top: 26px; }

/* ── Field row ────────────────────────────────────────────────────────────
   A fixed label column so labels align down a page. Below 520px it stacks —
   the label and its control stay together either way, which is the one thing
   the column flow must never break. */
.set-field {
  display: grid; grid-template-columns: minmax(120px, 190px) minmax(0, 1fr);
  gap: 6px 14px; align-items: center; padding: 7px 0;
}
.set-field + .set-field { border-top: 1px solid var(--border); }
.set-field-label { font-size: 13px; font-weight: 500; color: var(--text); }
.set-field-hint {
  grid-column: 2; font-size: 11px; line-height: 1.45; color: var(--text3); margin-top: -2px;
}
.set-field-control { display: flex; align-items: center; gap: 8px; min-width: 0; flex-wrap: wrap; }
/* Full-width controls (a select, a text input) should fill their column
   rather than sitting at some arbitrary intrinsic width. */
.set-field-control > .form-input:only-child { flex: 1 1 auto; min-width: 0; }
/* Narrow COLUMN: stack the label above its control. */
@container (max-width: 420px) {
  .set-field { grid-template-columns: minmax(0, 1fr); gap: 3px; }
  .set-field-hint { grid-column: 1; }
}
/* Narrow VIEWPORT: same, for anything not inside a .set-section container. */
@media (max-width: 520px) {
  .set-field { grid-template-columns: minmax(0, 1fr); gap: 3px; }
  .set-field-hint { grid-column: 1; }
}

/* ── Split layout ─────────────────────────────────────────────────────────
   Settings on the left, a pinned aside on the right. Built for Display, where
   the preview card exists to answer "what does this toggle do?" — which it can
   only do while it is still on screen once you have scrolled to the toggle.
   Below 1080px it stacks, aside first, and stops sticking: a pinned panel on a
   short screen takes more than it gives. */
.set-split { display: grid; grid-template-columns: minmax(0, 1fr) 330px; gap: 26px; align-items: start; }
.set-split-main { min-width: 0; }
/* The ASIDE stretches to the row height and the first thing in it pins, rather
   than pinning the aside itself. Pinning the whole aside only works while its
   content is shorter than the viewport — preview plus twelve swatches is not,
   so it drifted off the top instead of holding. Stretching gives the sticky
   child the full scroll range of the settings beside it. */
.set-split-side { min-width: 0; align-self: stretch; }
.set-split-side > .set-section:first-child { position: sticky; top: 78px; z-index: 1; }
/* The preview sits on a surface of its own so the swatches cannot show through
   as they scroll underneath it. */
.set-split-side > .set-section:first-child { background: var(--surface); }
@media (max-width: 1080px) {
  .set-split { grid-template-columns: minmax(0, 1fr); gap: 20px; }
  .set-split-side { align-self: auto; order: -1; }
  .set-split-side > .set-section:first-child { position: static; }
}

/* ── Toggle row ───────────────────────────────────────────────────────────
   A switch, a short label, and an info affordance carrying the detail.
   The Display page had 15 of these each with a 77-258 character paragraph
   under it, which is most of why it scrolled forever — and for the settings
   the preview now demonstrates, the paragraph was explaining something the
   user could simply be shown. */
.set-toggle {
  /* 5px gap plus 5px on the switch: the switch stays visually separate at
     10px, while the info marker sits 5px from the label it belongs to. */
  display: flex; align-items: center; gap: 5px;
  padding: 8px 0; cursor: pointer; min-width: 0;
}
.set-toggle > .toggle-track { margin-right: 5px; }
.set-toggle + .set-toggle { border-top: 1px solid var(--border); }
/* A radio group following a run of toggles needs air, or its bold heading
   butts straight against the last switch. */
.set-toggle + .form-group { margin-top: 14px; }
.set-toggle-label { font-size: 13px; color: var(--text); min-width: 0; }
/* Sits against its label, NOT pushed to the trailing edge with margin-left:
   auto — in a 435px column that parked it a long way from the words it
   explains, reading as a stray control rather than a footnote.

   Drawn as a masked SVG rather than a bordered box with an "i" in it. A letter
   cannot optically centre in a 13px circle: it carries asymmetric side
   bearings and the font's descender space, so it sat low and left at 100%
   however correct it looked zoomed in. The mask paints with currentColor, so
   it still follows the theme. */
.set-info {
  flex-shrink: 0; width: 14px; height: 14px;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Ccircle%20cx%3D%228%22%20cy%3D%228%22%20r%3D%227.15%22%20fill%3D%22none%22%20stroke%3D%22%23000%22%20stroke-width%3D%221.5%22%2F%3E%3Ccircle%20cx%3D%228%22%20cy%3D%224.5%22%20r%3D%221.05%22%2F%3E%3Crect%20x%3D%227.05%22%20y%3D%226.6%22%20width%3D%221.9%22%20height%3D%225.3%22%20rx%3D%22.95%22%2F%3E%3C%2Fsvg%3E") center / contain no-repeat;
          mask: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2016%2016%22%3E%3Ccircle%20cx%3D%228%22%20cy%3D%228%22%20r%3D%227.15%22%20fill%3D%22none%22%20stroke%3D%22%23000%22%20stroke-width%3D%221.5%22%2F%3E%3Ccircle%20cx%3D%228%22%20cy%3D%224.5%22%20r%3D%221.05%22%2F%3E%3Crect%20x%3D%227.05%22%20y%3D%226.6%22%20width%3D%221.9%22%20height%3D%225.3%22%20rx%3D%22.95%22%2F%3E%3C%2Fsvg%3E") center / contain no-repeat;
  color: var(--text3); cursor: help;
  opacity: .7; transition: opacity .15s, color .15s;
  /* Inline-block so it also works inside a plain label or paragraph:
     an inline box ignores width/height and the mask collapses to
     nothing. A flex container blockifies its children, so every
     existing flex use is unchanged. */
  display: inline-block; vertical-align: -2px;
}
.set-toggle:hover .set-info { opacity: .95; }
.set-info:hover { color: var(--text); opacity: 1; }

/* ── Card ─────────────────────────────────────────────────────────────────
   A repeating item with its own actions: a destination, a rule. One toggle
   position, one action position. */
.set-card {
  background: var(--surface2); border: 1px solid var(--border);
  border-radius: var(--radius-sm); padding: 10px 12px;
}
.set-card + .set-card { margin-top: 8px; }
.set-card-head { display: flex; align-items: center; gap: 10px; min-width: 0; }
.set-card-name {
  font-size: 13px; font-weight: 600; color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.set-card-meta { font-size: 11px; color: var(--text3); white-space: nowrap; }
/* The scope line is the first thing to give up room when a card gets narrow —
   the name and the actions both matter more. */
.set-card-head { flex-wrap: wrap; row-gap: 4px; }
.set-card-head > .rule-row-scope { overflow: hidden; text-overflow: ellipsis; min-width: 0; }
@container (max-width: 560px) { .set-card-head > .rule-row-scope { display: none; } }
.set-card-actions { margin-left: auto; display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.set-card-body { margin-top: 10px; }
.set-card.is-off { opacity: .62; }

/* Two-up inside a card body. Used to put the connection fields beside the
   instance list they produce, so cause and effect are read together rather
   than one scrolled past the other. Same auto-fit rule as .set-grid, so the
   pair stacks on its own once the card is narrow. */
.set-card-cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(240px, 100%), 1fr));
  gap: 14px 22px; align-items: start;
}
/* A heading inside a card body. Quieter than a section title, because the card
   head already says what this belongs to. */
.set-subhead { display: flex; align-items: center; gap: 8px; margin-bottom: 7px; min-height: 24px; }
.set-subhead-title {
  font-size: 11px; font-weight: 700; text-transform: uppercase;
  letter-spacing: .6px; color: var(--text3);
}
.set-subhead > .btn-autofill { margin-left: auto; }
/* Small controls that belong together, packed rather than spread. .set-card-cols
   puts each item at a column edge, which is right for two blocks of equal
   weight and wrong for two short fields — it leaves one looking stranded on
   the far side of a gap. */
.set-card-row { display: flex; flex-wrap: wrap; gap: 14px 34px; align-items: flex-start; margin-top: 16px; }
.set-card-row > .form-group { min-width: 0; }
/* A card is already --surface2, so anything sitting on it needs the next step
   in or the two read as one flat block. */
.set-card .qui-inst-row,
.set-card .btn-autofill { background: var(--surface3); }

/* ── Page actions ─────────────────────────────────────────────────────────
   Save and the secondary actions, separated from the content above so a long
   page ends deliberately rather than just stopping. */
.set-actions {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  margin-top: 24px; padding-top: 16px; border-top: 1px solid var(--border);
}

/* ── Empty state ──────────────────────────────────────────────────────────
   Says what would be here and why, rather than only that there is nothing. */
.set-empty {
  border: 1px dashed var(--border2); border-radius: var(--radius-sm);
  padding: 16px; text-align: center; font-size: 12px; color: var(--text3);
}

/* ── Result panel ─────────────────────────────────────────────────────────
   A transient answer to a question the user asked — so it is capped, scrolls
   inside itself, and can be dismissed. It used to render a row per tracker
   with no lid and no way to close it. */
.set-result {
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface3); margin-top: 10px; overflow: hidden;
}
.set-result-head {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px; font-size: 12px; color: var(--text2);
}
.set-result-summary {
  background: none; border: 0; padding: 0; margin: 0; cursor: pointer;
  font: inherit; color: var(--text); text-align: left; display: flex;
  align-items: center; gap: 7px; flex: 1; min-width: 0;
}
.set-result-caret { transition: transform .15s; color: var(--text3); font-size: 10px; }
.set-result[data-open="1"] .set-result-caret { transform: rotate(90deg); }
.set-result-body {
  max-height: 260px; overflow-y: auto;
  border-top: 1px solid var(--border); padding: 6px 10px 10px;
}
.set-result[data-open="0"] .set-result-body { display: none; }
.set-result-x {
  background: none; border: 0; cursor: pointer; color: var(--text3);
  font-size: 16px; line-height: 1; padding: 0 2px;
}
.set-result-x:hover { color: var(--text); }

/* ── Logs tab additions ───────────────────────────────────────────────────
   Search filters the lines already fetched, so it costs no request and keeps
   working while the view is paused. */
.log-search { flex: 0 1 220px; min-width: 120px; font-size: 12px; padding: 4px 8px; }
.log-count { font-size: 11px; color: var(--text3); white-space: nowrap; }
.log-hit { background: var(--accent-glow); color: var(--text); border-radius: 2px; padding: 0 1px; }
.log-path-line { font-size: 11px; color: var(--text3); margin: 6px 0 0; }
.log-path-line code { color: var(--text2); }

/* ── Integrations tab ─────────────────────────────────────────────────────
   Layout that used to live in inline styles on the markup. */
.qui-inst-list { display: flex; flex-direction: column; gap: 6px; min-height: 32px; }
.qui-inst-note { font-size: 12px; color: var(--text3); font-style: italic; }
.token-list { display: flex; flex-direction: column; gap: 6px; margin-bottom: 10px; min-height: 20px; }
.token-create { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }

/* ── Capability colour key ────────────────────────────────────────────────
   Sits under the table it explains. The icons are the real ones at the real
   size, so the key matches what is on screen rather than describing it. */
.cap-legend{
  display:flex;align-items:center;flex-wrap:wrap;gap:6px 16px;
  margin-top:10px;padding:8px 12px;
  border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface2);
}
.cap-legend-title{
  font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.7px;color:var(--text3);
}
.cap-legend-item{display:inline-flex;align-items:center;gap:6px;font-size:11.5px;color:var(--text3)}
.cap-legend-item .cap-icon i{font-size:7px}
.cap-legend-sep{width:1px;align-self:stretch;background:var(--border)}

/* ── Import connection ────────────────────────────────────────────────────
   Set once, then left alone — so it collapses to a line saying what is saved
   rather than holding an address and a password field open forever. */
.imp-conn{display:flex;align-items:center;gap:10px;margin-top:10px;flex-wrap:wrap}
.imp-conn-label{
  font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.7px;color:var(--text3);
}
.imp-conn-value{
  font-size:12px;color:var(--text2);font-family:'Geist Mono',monospace;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;flex:1;
}
.imp-conn-value.is-unset{font-family:inherit;font-style:italic;color:var(--text3)}
.imp-conn-fields{margin-top:10px}

/* ── Import badges ────────────────────────────────────────────────────────
   Each of these answers a different question, so each gets its own colour.
   They were all the same amber, which made the one that blocks collection
   ("needs type") no louder than the one that is merely informational. */
.prowlarr-badge.needs-type,
.trk-def-badge.needs-type{color:var(--red);border-color:var(--error-border-md);background:var(--error-bg)}
/* Purple sat too close to the accent and to the def badge beside it. Pink is
   a token every theme already defines and nothing else on this page uses. */
.prowlarr-badge.privacy-private{color:var(--pink);border-color:color-mix(in srgb,var(--pink) 42%,transparent);background:color-mix(in srgb,var(--pink) 13%,transparent)}
.prowlarr-badge.privacy-public,
.prowlarr-badge.privacy-semi-private{color:var(--text3);border-color:var(--border2);background:var(--surface3)}
.prowlarr-badge.added{color:var(--green);border-color:color-mix(in srgb,var(--green) 38%,transparent);background:color-mix(in srgb,var(--green) 12%,transparent)}

/* ── Trackers tab: section heads and imports ──────────────────────────────
   The table's head is a .set-section-head like every other page, with the
   toolbar buttons riding on its trailing edge. */
.trk-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.trk-import-section{margin-top:26px}
/* The section owns the heading now, so the first collapsible must not draw a
   second rule above itself right underneath it. */
.trk-import-section .prowlarr-section:first-of-type{margin-top:0;border-top:none;padding-top:0}
.imp-toggle-name{font-weight:600}
.imp-toggle-hint{font-size:11px;color:var(--text3);font-weight:400}

/* ── Edit-tracker panel: section heads ────────────────────────────────────
   The panel used its own divider style while every settings page moved to
   .set-section-head. One dialog written in a second dialect is how a design
   language stops being one. */
.modal-sec-head{margin:18px 0 12px}
.modal-sec-head:first-child{margin-top:0}
.modal-sec-head .set-section-title{font-size:12px}

/* ── Manual targets ───────────────────────────────────────────────────────
   A set target is a chip — the same chip a group's requirements are drawn
   with, because they are the same kind of fact. Four stacked text boxes made
   the manual mode look like a different feature from the group mode, and made
   a page of settled values look unfinished. The fields appear for the one
   target being edited and nowhere else. */
/* Chips flow along a row the way a group's requirements do, rather than
   stacking one per line with a screen of empty space beside each. Shared by
   manual targets and manual stats — the same shape of thing, so the same
   treatment. */
.chip-items{display:flex;flex-wrap:wrap;align-items:flex-start;gap:8px;margin-bottom:10px}
.chip-item{min-width:0;flex:0 1 auto}
/* The one being edited takes a full row: a text field and a date picker do not
   belong in a wrap with chips. */
.chip-item[data-editing="1"]{flex:1 0 100%}
.chip-item-view{
  display:inline-flex;align-items:center;gap:6px;
  padding:3px 4px 3px 3px;border-radius:14px;
  background:var(--surface2);border:1px solid var(--border);
}
.chip-item-by{font-size:10.5px;color:var(--text3);padding-right:2px;white-space:nowrap}
/* Always drawn, never revealed on hover: buttons that appear on hover reflow a
   wrapping row under the cursor, and a control you cannot see is one you have
   to discover. Quiet by default instead. */
.chip-item-acts{display:flex;gap:3px}
.trk-act-xs{
  width:22px;height:22px;font-size:10px;border-radius:50%;
  border-color:transparent;background:transparent;
}
.chip-item-view:hover .trk-act-xs{border-color:var(--border)}
.chip-item-edit{display:flex;align-items:center;gap:8px;flex-wrap:wrap;width:100%}
.chip-item-edit .form-input[data-chip-input]{flex:1;min-width:120px}
/* Inside a chip the border is the chip's, so the segment must not draw its own
   rounded ends over it. */
.chip-item-view .target-chip{border:none;background:transparent}
.chip-item-view .target-chip-v{padding-right:4px}

/* ── Panel field pairs ────────────────────────────────────────────────────
   A username, a date, a scrape count: short values that were each getting a
   full-width box, so the panel read as a very long column of half-empty
   fields. Long secrets (API key, cookie header) stay full width, because they
   genuinely are long. */
.modal-fields{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(min(260px,100%),1fr));
  gap:0 20px;
}
/* Saving no longer closes the panel, so Save has to say it worked. */
#modal-save-btn.is-saved{background:var(--green);border-color:var(--green);color:var(--btn-primary-text)}

/* ── General tab: hostnames ───────────────────────────────────────────────
   One chip per host. A comma-separated run in a single box hides a typo in
   the middle of it, and gives no way to remove one name without editing a
   string. Nothing changed on disk — the stored value was always a list. */
.host-list{display:flex;flex-wrap:wrap;gap:6px;margin-bottom:8px;min-height:26px;align-items:center}
.host-chip{
  display:inline-flex;align-items:center;gap:2px;
  padding:3px 3px 3px 9px;border-radius:14px;
  background:var(--surface2);border:1px solid var(--border);
  font-size:11.5px;font-family:'Geist Mono',monospace;color:var(--text);
}
.host-chip-x{
  width:18px;height:18px;border:0;border-radius:50%;background:transparent;
  color:var(--text3);cursor:pointer;font-size:14px;line-height:1;
  display:inline-flex;align-items:center;justify-content:center;
}
.host-chip-x:hover{color:var(--red);background:var(--error-bg)}
.host-empty{font-size:11.5px;color:var(--text3);font-style:italic}
.host-add{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.host-add .form-input{max-width:300px}

/* ── General tab: account confirm panels ──────────────────────────────────
   A password box on screen for an action nobody is taking is noise, and with
   three of them for three different actions it is also an invitation to type
   a password into the wrong one. The field appears when the action is asked
   for. */
.acct-danger-row{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-top:14px}
.acct-danger-row .form-hint{margin:0}
.acct-danger-btn{color:var(--red);border-color:var(--error-border-md)}
.acct-danger-btn:hover{color:var(--red);border-color:var(--red);background:var(--error-bg)}
.acct-panel{
  display:flex;gap:8px;align-items:center;flex-wrap:wrap;
  margin-top:10px;padding:10px 12px;
  border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--surface2);
}
