/* MY TenderSphere Scraper Hub — design system.
 *
 * Two themes off one token set. Dark is the default because this screen
 * is watched for long stretches on a wall display or second monitor, and
 * a bright surface at that duty cycle is tiring; light exists because
 * plenty of offices are bright enough that the reverse is true.
 *
 * Theme resolution, in order:
 *   1. [data-theme="light"|"dark"] on <html>  — an explicit choice, wins
 *   2. prefers-color-scheme                    — the system setting
 *   3. dark                                    — the default
 *
 * Every colour below is a token. No rule outside these blocks hardcodes
 * one, which is what makes the second theme a palette swap rather than a
 * parallel stylesheet that drifts.
 *
 * Status colour is always paired with an icon and a word. Colour is never
 * the only carrier of meaning, in either theme.
 */

:root {
  /* --- dark (default) --- */
  --bg:        #0b1020;
  --bg-2:      #111731;
  --surface:   #151c38;
  --surface-2: #1b2447;
  --line:      #26305c;
  --line-soft: #1e2749;

  --text:      #e8ecf8;
  --text-dim:  #98a3c7;
  --text-mute: #6b78a3;
  --on-accent: #ffffff;

  --brand:     #5b8cff;
  --brand-2:   #8b5cf6;
  --ok:        #2ee6a8;
  --warn:      #ffc046;
  --bad:       #ff5d6c;
  --info:      #4dd0f7;
  --partial:   #ff9f45;

  /* Tints derived per theme rather than with alpha over an unknown
     background — a translucent white that looks right on #0b1020 turns
     muddy on white. */
  --tint-brand:   rgba(91,140,255,.16);
  --tint-ok:      rgba(46,230,168,.13);
  --tint-warn:    rgba(255,192,70,.13);
  --tint-bad:     rgba(255,93,108,.14);
  --tint-info:    rgba(77,208,247,.14);
  --tint-partial: rgba(255,159,69,.14);
  --tint-violet:  rgba(139,92,246,.16);
  --tint-neutral: rgba(107,120,163,.14);

  --edge-brand:   rgba(91,140,255,.32);
  --edge-ok:      rgba(46,230,168,.28);
  --edge-warn:    rgba(255,192,70,.28);
  --edge-bad:     rgba(255,93,108,.30);
  --edge-info:    rgba(77,208,247,.30);
  --edge-partial: rgba(255,159,69,.30);
  --edge-violet:  rgba(139,92,246,.32);

  --track:     rgba(255,255,255,.08);
  --hover:     rgba(91,140,255,.05);
  --scrim:     rgba(4,7,18,.72);
  --shadow:    0 10px 34px rgba(0,0,0,.38);
  --shadow-lg: 0 18px 46px rgba(0,0,0,.50);

  --log-bg:    #060a16;
  --log-text:  #98a3c7;
  --log-time:  #50608f;
  --log-name:  #7f8cb8;
  --log-bad:   #ffb8c0;
  --log-hover: rgba(255,255,255,.035);
  --log-badbg: rgba(255,93,108,.055);
  /* Log-level colours are tuned against the dark log surface and are
     deliberately NOT redefined per theme -- that panel stays dark in both,
     so re-tinting these for light would make them wrong. */
  --log-ok:    #2ee6a8;
  --log-info:  #4dd0f7;
  --log-warn:  #ffc046;
  --log-err:   #ff5d6c;

  --scroll:      #2b3766;
  --scroll-hover:#3a4a83;
  --violet-text: #b794ff;
  --circuit-text:#ff8fa0;

  --glow-1: #1c2a5e;
  --glow-2: #2a1f56;

  --radius:    14px;
  --radius-sm: 9px;
  --sidebar-w: 244px;
  --topbar-h:  62px;

  color-scheme: dark;
}

/* Light, when the system asks for it and no explicit choice overrides. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    --bg:        #f4f6fb;
    --bg-2:      #ffffff;
    --surface:   #ffffff;
    --surface-2: #eef1f8;
    --line:      #d9dfec;
    --line-soft: #e7ebf4;

    --text:      #131b34;
    --text-dim:  #4c5877;
    --text-mute: #76819e;
    --on-accent: #ffffff;

    /* Darkened from the dark-theme hues: the same blue that reads bright
       on #0b1020 is barely legible on white, so each accent is the
       AA-contrast sibling rather than the identical value. */
    --brand:     #3257d8;
    --brand-2:   #7040d6;
    --ok:        #088156;
    --warn:      #9a6206;
    --bad:       #cf2436;
    --info:      #0a7ea4;
    --partial:   #b45309;

    --tint-brand:   rgba(50,87,216,.10);
    --tint-ok:      rgba(8,129,86,.11);
    --tint-warn:    rgba(154,98,6,.11);
    --tint-bad:     rgba(207,36,54,.10);
    --tint-info:    rgba(10,126,164,.10);
    --tint-partial: rgba(180,83,9,.11);
    --tint-violet:  rgba(112,64,214,.11);
    --tint-neutral: rgba(118,129,158,.13);

    --edge-brand:   rgba(50,87,216,.26);
    --edge-ok:      rgba(8,129,86,.26);
    --edge-warn:    rgba(154,98,6,.26);
    --edge-bad:     rgba(207,36,54,.26);
    --edge-info:    rgba(10,126,164,.26);
    --edge-partial: rgba(180,83,9,.26);
    --edge-violet:  rgba(112,64,214,.26);

    --track:     rgba(19,27,52,.10);
    --hover:     rgba(50,87,216,.05);
    --scrim:     rgba(19,27,52,.42);
    --shadow:    0 6px 20px rgba(19,27,52,.08);
    --shadow-lg: 0 16px 40px rgba(19,27,52,.16);

    /* The log console stays dark in both themes. It is a terminal, it is
       read as one, and the status colours were tuned against a dark
       ground — inverting it would cost legibility for consistency nobody
       asked for. */
    --log-bg:    #10162b;
    --log-text:  #c3cbe4;
    --log-time:  #7b87ad;
    --log-name:  #98a3c7;
    --log-bad:   #ffb8c0;
    --log-hover: rgba(255,255,255,.05);
    --log-badbg: rgba(255,93,108,.10);

    --scroll:      #c3cadb;
    --scroll-hover:#a8b2c9;
    --violet-text: #6d3fd1;
    --circuit-text:#c02234;

    --glow-1: #dbe4ff;
    --glow-2: #e7dcff;

    color-scheme: light;
  }
}

/* An explicit choice from the toggle wins over the system in both
   directions, which is why light is declared twice rather than only
   inside the media query. */
:root[data-theme="light"] {
  --bg:        #f4f6fb;
  --bg-2:      #ffffff;
  --surface:   #ffffff;
  --surface-2: #eef1f8;
  --line:      #d9dfec;
  --line-soft: #e7ebf4;

  --text:      #131b34;
  --text-dim:  #4c5877;
  --text-mute: #76819e;
  --on-accent: #ffffff;

  --brand:     #3257d8;
  --brand-2:   #7040d6;
  --ok:        #088156;
  --warn:      #9a6206;
  --bad:       #cf2436;
  --info:      #0a7ea4;
  --partial:   #b45309;

  --tint-brand:   rgba(50,87,216,.10);
  --tint-ok:      rgba(8,129,86,.11);
  --tint-warn:    rgba(154,98,6,.11);
  --tint-bad:     rgba(207,36,54,.10);
  --tint-info:    rgba(10,126,164,.10);
  --tint-partial: rgba(180,83,9,.11);
  --tint-violet:  rgba(112,64,214,.11);
  --tint-neutral: rgba(118,129,158,.13);

  --edge-brand:   rgba(50,87,216,.26);
  --edge-ok:      rgba(8,129,86,.26);
  --edge-warn:    rgba(154,98,6,.26);
  --edge-bad:     rgba(207,36,54,.26);
  --edge-info:    rgba(10,126,164,.26);
  --edge-partial: rgba(180,83,9,.26);
  --edge-violet:  rgba(112,64,214,.26);

  --track:     rgba(19,27,52,.10);
  --hover:     rgba(50,87,216,.05);
  --scrim:     rgba(19,27,52,.42);
  --shadow:    0 6px 20px rgba(19,27,52,.08);
  --shadow-lg: 0 16px 40px rgba(19,27,52,.16);

  --log-bg:    #10162b;
  --log-text:  #c3cbe4;
  --log-time:  #7b87ad;
  --log-name:  #98a3c7;
  --log-bad:   #ffb8c0;
  --log-hover: rgba(255,255,255,.05);
  --log-badbg: rgba(255,93,108,.10);

  --scroll:      #c3cadb;
  --scroll-hover:#a8b2c9;
  --violet-text: #6d3fd1;
  --circuit-text:#c02234;

  --glow-1: #dbe4ff;
  --glow-2: #e7dcff;

  color-scheme: light;
}

:root[data-theme="dark"] { color-scheme: dark; }

* { box-sizing: border-box; }
html, body { height: 100%; }

/* The `hidden` attribute only carries `display: none` from the UA
   stylesheet, so ANY class with an explicit display beats it. `.note` is
   `display: flex`, which meant the login page's error box was visible at
   all times -- showing "Sign-in failed" before the form had ever been
   submitted. Anything toggled with `el.hidden` needs this. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background:
    radial-gradient(1100px 620px at 12% -12%, var(--glow-1) 0%, transparent 58%),
    radial-gradient(900px 520px at 105% 0%, var(--glow-2) 0%, transparent 52%),
    var(--bg);
  background-attachment: fixed;
  color: var(--text);
  font: 14px/1.5 'Inter', 'Segoe UI', system-ui, -apple-system, sans-serif;
  -webkit-font-smoothing: antialiased;
  /* Switching theme repaints every surface at once; without this the
     change reads as a flicker rather than a transition. */
  transition: background-color .2s ease, color .2s ease;
}

a { color: inherit; text-decoration: none; }
::selection { background: var(--brand); color: var(--on-accent); }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--scroll); border-radius: 6px; border: 2px solid transparent; background-clip: content-box; }
::-webkit-scrollbar-thumb:hover { background: var(--scroll-hover); background-clip: content-box; }

/* ==================================================================
   Shell
   ================================================================== */

.shell { display: grid; grid-template-columns: var(--sidebar-w) 1fr; min-height: 100vh; }

/* The mobile scrim is a child of .shell, so it is a grid item unless told
   otherwise. Without this it silently occupies the second column on
   desktop and pushes .main onto a second row -- the sidebar renders
   correctly, the entire rest of the app renders underneath it in a
   244px-wide strip, and every control in the top bar becomes unclickable.
   It is given position:fixed only inside the <=1100px block below. */
.sidebar-scrim { display: none; }

.sidebar {
  position: sticky; top: 0; height: 100vh;
  display: flex; flex-direction: column;
  background: var(--bg-2);
  border-right: 1px solid var(--line-soft);
  z-index: 40;
}

.brand { display: flex; align-items: center; gap: 11px; padding: 18px 18px 16px; }
.brand-mark {
  width: 38px; height: 38px; border-radius: 11px; flex: none;
  display: grid; place-items: center;
  background: linear-gradient(135deg, var(--brand), var(--brand-2));
  color: var(--on-accent);
  box-shadow: 0 6px 18px var(--edge-brand);
  font-size: 19px;
}
.brand-text { min-width: 0; }
.brand-text b { display: block; font-size: 13.5px; font-weight: 700; letter-spacing: .2px; line-height: 1.25; }
.brand-text span { display: block; font-size: 10.5px; color: var(--text-mute); letter-spacing: .5px; text-transform: uppercase; }

.nav { flex: 1; overflow-y: auto; padding: 6px 10px 14px; }
.nav-group { margin-bottom: 16px; }
.nav-label { padding: 8px 10px 6px; font-size: 10px; font-weight: 700; letter-spacing: 1.1px; text-transform: uppercase; color: var(--text-mute); }

.nav-item {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 11px; margin-bottom: 2px;
  border-radius: var(--radius-sm);
  color: var(--text-dim); font: inherit; font-size: 13.5px; font-weight: 500;
  cursor: pointer; border: 0; width: 100%; text-align: left;
  background: none; transition: background .14s, color .14s;
}
.nav-item:hover { background: var(--surface-2); color: var(--text); }
.nav-item.active { background: var(--tint-brand); color: var(--brand); font-weight: 650; box-shadow: inset 2px 0 0 var(--brand); }
.nav-item .ico { width: 17px; text-align: center; font-size: 14px; flex: none; }
.nav-item .count {
  margin-left: auto; font-size: 11px; font-weight: 700;
  padding: 1px 7px; border-radius: 999px;
  background: var(--surface-2); color: var(--text-dim);
}
.nav-item.active .count { background: var(--brand); color: var(--on-accent); }
.nav-item .count.hot { background: var(--tint-bad); color: var(--bad); }

.sidebar-foot { padding: 12px; border-top: 1px solid var(--line-soft); }
.user-chip { display: flex; align-items: center; gap: 9px; padding: 8px 9px; border-radius: var(--radius-sm); background: var(--surface-2); }
.avatar { width: 30px; height: 30px; border-radius: 9px; flex: none; display: grid; place-items: center; background: linear-gradient(135deg, var(--brand), var(--brand-2)); color: var(--on-accent); font-weight: 700; font-size: 12px; }
.user-chip .who { min-width: 0; flex: 1; }
.user-chip .who b { display: block; font-size: 12.5px; }
.user-chip .who span { display: block; font-size: 10.5px; color: var(--text-mute); }
.icon-btn { border: 1px solid var(--line); background: var(--surface); color: var(--text-dim); border-radius: 8px; padding: 6px 8px; cursor: pointer; transition: .14s; font-size: 13px; display: inline-flex; align-items: center; justify-content: center; }
.icon-btn svg, .btn svg { display: block; }
.icon-btn:hover { color: var(--brand); border-color: var(--brand); }

.main { min-width: 0; display: flex; flex-direction: column; }

.topbar {
  position: sticky; top: 0; z-index: 30;
  height: var(--topbar-h);
  display: flex; align-items: center; gap: 12px;
  padding: 0 20px;
  background: var(--bg-2);
  border-bottom: 1px solid var(--line-soft);
}
.burger { display: none; }
.page-title { min-width: 0; }
.page-title h1 { margin: 0; font-size: 16.5px; font-weight: 700; letter-spacing: .1px; }
.page-title p { margin: 1px 0 0; font-size: 11.5px; color: var(--text-mute); }
.topbar-right { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }

.content { padding: 20px; max-width: 1760px; width: 100%; }

/* ==================================================================
   Pills, badges
   ================================================================== */

.pill {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 5px 11px; border-radius: 999px;
  font-size: 11.5px; font-weight: 600; white-space: nowrap;
  background: var(--surface-2); color: var(--text-dim);
  border: 1px solid var(--line);
}
.pill.ok   { background: var(--tint-ok);   color: var(--ok);   border-color: var(--edge-ok); }
.pill.warn { background: var(--tint-warn); color: var(--warn); border-color: var(--edge-warn); }
.pill.bad  { background: var(--tint-bad);  color: var(--bad);  border-color: var(--edge-bad); }
.pill .dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.pill .dot.live { animation: pulse 1.7s ease-in-out infinite; }
@keyframes pulse { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: .35; transform: scale(.82); } }

.badge {
  display: inline-flex; align-items: center; gap: 5px;
  padding: 3px 9px; border-radius: 999px;
  font-size: 11px; font-weight: 700; white-space: nowrap;
  border: 1px solid transparent;
}
.badge .g { font-size: 10px; line-height: 1; }
.b-running  { background: var(--tint-info);    color: var(--info);         border-color: var(--edge-info); }
.b-queued   { background: var(--tint-warn);    color: var(--warn);         border-color: var(--edge-warn); }
.b-success  { background: var(--tint-ok);      color: var(--ok);           border-color: var(--edge-ok); }
.b-partial  { background: var(--tint-partial); color: var(--partial);      border-color: var(--edge-partial); }
.b-failed   { background: var(--tint-bad);     color: var(--bad);          border-color: var(--edge-bad); }
.b-stale    { background: var(--tint-bad);     color: var(--bad);          border-color: var(--bad); border-style: dashed; }
.b-retry    { background: var(--tint-violet);  color: var(--violet-text);  border-color: var(--edge-violet); }
.b-paused   { background: var(--tint-neutral); color: var(--text-dim);     border-color: var(--line); }
.b-disabled { background: var(--tint-neutral); color: var(--text-mute);    border-color: var(--line-soft); }
.b-circuit  { background: var(--tint-bad);     color: var(--circuit-text); border-color: var(--edge-bad); }
.b-idle     { background: var(--tint-neutral); color: var(--text-mute);    border-color: var(--line-soft); }
.b-new      { background: var(--tint-violet);  color: var(--violet-text); border-color: var(--edge-violet); }

/* Settings toggles */
.toggle-row { display: flex; align-items: flex-start; gap: 14px; padding: 14px 0; border-bottom: 1px solid var(--line-soft); }
.toggle-row:last-child { border-bottom: 0; }
.toggle-row .copy { flex: 1; min-width: 0; }
.toggle-row .copy b { display: block; font-size: 13.5px; margin-bottom: 3px; }
.toggle-row .copy span { font-size: 12px; color: var(--text-mute); line-height: 1.6; }
.switch { position: relative; flex: none; width: 46px; height: 26px; cursor: pointer; }
.switch input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; z-index: 2; }
.switch .track { position: absolute; inset: 0; border-radius: 999px; background: var(--track); border: 1px solid var(--line); transition: background .18s, border-color .18s; }
.switch .knob { position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: var(--text-mute); transition: transform .18s, background .18s; }
.switch input:checked ~ .track { background: var(--brand); border-color: var(--brand); }
.switch input:checked ~ .knob { transform: translateX(20px); background: var(--on-accent); }
.switch input:focus-visible ~ .track { box-shadow: 0 0 0 3px var(--tint-brand); }
.switch.danger input:checked ~ .track { background: var(--bad); border-color: var(--bad); }

/* ==================================================================
   Cards
   ================================================================== */

.panel {
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  overflow: hidden;
}
.panel-head {
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 14px 18px; border-bottom: 1px solid var(--line-soft);
}
.panel-head h2 { margin: 0; font-size: 13.5px; font-weight: 700; letter-spacing: .2px; }
.panel-head .sub { font-size: 11.5px; color: var(--text-mute); }
.panel-head .right { margin-left: auto; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.panel-body { padding: 18px; }

.grid { display: grid; gap: 14px; }
.grid.kpi { grid-template-columns: repeat(auto-fit, minmax(168px, 1fr)); }
.grid.two { grid-template-columns: repeat(auto-fit, minmax(360px, 1fr)); }

.kpi-card {
  position: relative; overflow: hidden;
  padding: 16px 17px;
  background: var(--surface);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  cursor: pointer;
  transition: transform .16s, border-color .16s, box-shadow .16s;
}
.kpi-card::after {
  content: ''; position: absolute; inset: 0 auto 0 0; width: 3px;
  background: var(--accent, var(--brand)); opacity: .85;
}
.kpi-card:hover { transform: translateY(-2px); border-color: var(--accent, var(--brand)); box-shadow: var(--shadow-lg); }
.kpi-card.active { border-color: var(--accent, var(--brand)); box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent, var(--brand)) 26%, transparent); }
.kpi-card.static { cursor: default; }
.kpi-card.static:hover { transform: none; box-shadow: var(--shadow); border-color: var(--line-soft); }
.kpi-top { display: flex; align-items: center; gap: 7px; margin-bottom: 7px; }
.kpi-top .ico { font-size: 13px; color: var(--accent, var(--brand)); }
.kpi-top .label { font-size: 10.5px; font-weight: 700; letter-spacing: .8px; text-transform: uppercase; color: var(--text-mute); }
.kpi-value { font-size: 27px; font-weight: 750; letter-spacing: -.6px; line-height: 1.06; font-variant-numeric: tabular-nums; }
.kpi-foot { margin-top: 5px; font-size: 11px; color: var(--text-mute); }

.meter { margin-top: 9px; }
.meter-track { height: 6px; border-radius: 999px; background: var(--track); overflow: hidden; }
.meter-fill { height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--brand), var(--brand-2)); transition: width .55s cubic-bezier(.4,0,.2,1); }
.meter-fill.warn { background: var(--warn); }
.meter-fill.bad  { background: var(--bad); }

.spark { display: flex; align-items: flex-end; gap: 2px; height: 46px; margin-top: 10px; }
.spark i {
  flex: 1; min-width: 2px; border-radius: 2px 2px 0 0;
  background: linear-gradient(180deg, var(--brand), var(--tint-brand));
  transition: height .4s;
}
.spark i.empty { background: var(--track); }
.spark i.future { background: var(--track); opacity: .45; }

/* ==================================================================
   Tables
   ================================================================== */

.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; }
thead th {
  position: sticky; top: 0; z-index: 2;
  background: var(--surface-2);
  text-align: left; padding: 10px 13px; white-space: nowrap;
  font-size: 10px; font-weight: 700; letter-spacing: .9px; text-transform: uppercase;
  color: var(--text-mute); border-bottom: 1px solid var(--line);
}
tbody td { padding: 11px 13px; border-bottom: 1px solid var(--line-soft); vertical-align: middle; font-size: 13px; }
tbody tr { transition: background .12s; }
tbody tr:hover { background: var(--hover); }
tbody tr:last-child td { border-bottom: 0; }
td.num { text-align: right; font-variant-numeric: tabular-nums; }
td.nowrap, th.nowrap { white-space: nowrap; }
.cell-title { font-weight: 650; }
.cell-sub { display: block; font-size: 10.5px; color: var(--text-mute); font-family: ui-monospace, 'Cascadia Code', Consolas, monospace; }
.muted { color: var(--text-mute); }
.mono { font-family: ui-monospace, 'Cascadia Code', Consolas, monospace; font-size: 11.5px; }
.err-text { color: var(--bad); font-size: 11.5px; display: inline-block; max-width: 210px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: bottom; }

.bar { min-width: 96px; }
.bar-track { height: 5px; border-radius: 999px; background: var(--track); overflow: hidden; }
.bar-fill { height: 100%; border-radius: 999px; background: var(--info); transition: width .4s; }
.bar-fill.partial { background: var(--partial); }
.bar-fill.failed  { background: var(--bad); }
.bar-label { display: block; margin-top: 4px; font-size: 10.5px; color: var(--text-mute); font-variant-numeric: tabular-nums; }

/* ==================================================================
   Controls
   ================================================================== */

.btn {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 13px; border-radius: var(--radius-sm);
  border: 1px solid var(--line); background: var(--surface-2);
  color: var(--text-dim); font: inherit; font-size: 12.5px; font-weight: 600;
  cursor: pointer; transition: .14s; white-space: nowrap;
}
.btn:hover:not(:disabled) { color: var(--brand); border-color: var(--brand); }
.btn:disabled { opacity: .42; cursor: not-allowed; }
.btn.primary { background: linear-gradient(135deg, var(--brand), var(--brand-2)); border-color: transparent; color: var(--on-accent); }
.btn.primary:hover:not(:disabled) { filter: brightness(1.08); color: var(--on-accent); }
.btn.danger { color: var(--bad); border-color: var(--edge-bad); }
.btn.danger:hover:not(:disabled) { background: var(--tint-bad); border-color: var(--bad); color: var(--bad); }
.btn.sm { padding: 4px 9px; font-size: 11.5px; }
.btn.icon { padding: 6px 9px; }

input, select, textarea {
  background: var(--bg-2); color: var(--text);
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 7px 11px; font: inherit; font-size: 12.5px; outline: none;
  transition: border-color .14s, box-shadow .14s;
}
input:focus, select:focus, textarea:focus { border-color: var(--brand); box-shadow: 0 0 0 3px var(--tint-brand); }
input.bad { border-color: var(--bad); background: var(--tint-bad); }
input::placeholder { color: var(--text-mute); }
.search { min-width: 210px; }
label.field { display: block; font-size: 12px; color: var(--text-dim); }
label.field > input, label.field > select { width: 100%; margin-top: 5px; }
.hint { display: block; margin-top: 4px; font-size: 10.5px; color: var(--text-mute); }

/* ==================================================================
   Log console — stays dark in both themes; see the token block above.
   ================================================================== */

.logs {
  background: var(--log-bg);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-sm);
  padding: 12px 14px;
  font-family: ui-monospace, 'Cascadia Code', Consolas, monospace;
  font-size: 11.5px; line-height: 1.62;
  height: 300px; overflow-y: auto;
  scroll-behavior: smooth;
  color: var(--log-text);
}
.logs.tall { height: 440px; }
.log-line { display: flex; gap: 10px; padding: 2px 6px; border-radius: 5px; border-left: 2px solid transparent; }
.log-line:hover { background: var(--log-hover); }
.log-time { color: var(--log-time); flex: none; font-variant-numeric: tabular-nums; }
.log-tag { flex: none; width: 122px; font-weight: 700; font-size: 10.5px; letter-spacing: .3px; }
.log-msg { flex: 1; min-width: 0; color: var(--log-text); word-break: break-word; }
.log-scraper { flex: none; width: 160px; color: var(--log-name); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.lv-ok    { border-left-color: var(--log-ok); }   .lv-ok .log-tag   { color: var(--log-ok); }
.lv-info  { border-left-color: var(--log-info); } .lv-info .log-tag { color: var(--log-info); }
.lv-warn  { border-left-color: var(--log-warn); } .lv-warn .log-tag { color: var(--log-warn); }
.lv-error { border-left-color: var(--log-err); background: var(--log-badbg); }
.lv-error .log-tag { color: var(--log-err); } .lv-error .log-msg { color: var(--log-bad); }
.logs-empty { color: var(--log-time); padding: 22px; text-align: center; }

/* ==================================================================
   Drawer / modal
   ================================================================== */

.scrim { position: fixed; inset: 0; background: var(--scrim); backdrop-filter: blur(4px); z-index: 80; display: none; }
.scrim.open { display: block; animation: fade .16s ease; }
@keyframes fade { from { opacity: 0; } }

.drawer {
  position: absolute; right: 0; top: 0; bottom: 0;
  width: min(940px, 100%);
  display: flex; flex-direction: column;
  background: var(--bg); border-left: 1px solid var(--line);
  box-shadow: var(--shadow-lg);
  animation: slide .22s cubic-bezier(.32,.72,.4,1);
}
@keyframes slide { from { transform: translateX(26px); opacity: .4; } }
.drawer-head { display: flex; align-items: flex-start; gap: 14px; padding: 17px 20px; border-bottom: 1px solid var(--line-soft); background: var(--bg-2); }
.drawer-head h2 { margin: 0 0 3px; font-size: 16px; }
.drawer-tabs { display: flex; gap: 3px; padding: 0 14px; border-bottom: 1px solid var(--line-soft); overflow-x: auto; background: var(--bg-2); }
.drawer-tabs button { border: 0; background: none; color: var(--text-mute); padding: 11px 12px; font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; border-bottom: 2px solid transparent; white-space: nowrap; }
.drawer-tabs button:hover { color: var(--text-dim); }
.drawer-tabs button.active { color: var(--brand); border-bottom-color: var(--brand); }
.drawer-body { flex: 1; overflow-y: auto; padding: 18px; }
.dtab { display: none; } .dtab.active { display: block; }

.modal {
  position: absolute; top: 50%; left: 50%; transform: translate(-50%,-50%);
  width: min(480px, 94vw); padding: 22px;
  background: var(--bg-2); border: 1px solid var(--line);
  border-radius: var(--radius); box-shadow: var(--shadow-lg);
}
.modal h3 { margin: 0 0 8px; font-size: 15.5px; }
.modal p { margin: 0; color: var(--text-dim); font-size: 13px; }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 18px; }

.kv { display: grid; grid-template-columns: 168px 1fr; gap: 7px 14px; font-size: 12.5px; }
.kv dt { color: var(--text-mute); }
.kv dd { margin: 0; min-width: 0; word-break: break-word; }

.note { border-radius: var(--radius-sm); padding: 11px 13px; font-size: 12.5px; display: flex; gap: 10px; align-items: flex-start; }
.note.warn { background: var(--tint-warn); border: 1px solid var(--edge-warn); color: var(--warn); }
.note.bad  { background: var(--tint-bad);  border: 1px solid var(--edge-bad);  color: var(--bad); }
.note.info { background: var(--tint-info); border: 1px solid var(--edge-info); color: var(--info); }
.note b { display: block; margin-bottom: 2px; }

#toast {
  position: fixed; right: 20px; bottom: 20px; z-index: 200;
  display: none; align-items: center; gap: 10px;
  padding: 12px 16px; border-radius: var(--radius-sm);
  background: var(--surface); border: 1px solid var(--line);
  box-shadow: var(--shadow-lg); font-size: 13px; max-width: 400px;
  color: var(--text);
}
#toast.show { display: flex; animation: rise .22s cubic-bezier(.32,.72,.4,1); }
#toast.err { border-color: var(--edge-bad); color: var(--bad); }
@keyframes rise { from { transform: translateY(10px); opacity: 0; } }

.empty { padding: 44px 20px; text-align: center; color: var(--text-mute); }
.empty .big { font-size: 30px; margin-bottom: 8px; opacity: .5; }

.view { display: none; } .view.active { display: block; }
.row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.pager { display: flex; justify-content: center; align-items: center; gap: 14px; padding: 14px; }

.skeleton { background: linear-gradient(90deg, var(--surface) 25%, var(--surface-2) 50%, var(--surface) 75%); background-size: 200% 100%; animation: shimmer 1.3s infinite; border-radius: 6px; }
@keyframes shimmer { to { background-position: -200% 0; } }

/* ==================================================================
   Responsive — the console gets opened on phones during an incident.
   ================================================================== */

@media (max-width: 1100px) {
  .shell { grid-template-columns: 1fr; }
  .sidebar {
    position: fixed; left: 0; top: 0; bottom: 0; width: 270px;
    transform: translateX(-100%); transition: transform .22s cubic-bezier(.32,.72,.4,1);
  }
  .sidebar.open { transform: translateX(0); box-shadow: var(--shadow-lg); }
  .burger { display: inline-flex; }
  .sidebar-scrim { position: fixed; inset: 0; background: var(--scrim); z-index: 35; display: none; }
  .sidebar-scrim.open { display: block; }
}

@media (max-width: 720px) {
  .content { padding: 14px; }
  .topbar { padding: 0 14px; gap: 8px; }
  .page-title p { display: none; }
  .grid.kpi { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 10px; }
  .kpi-value { font-size: 22px; }
  .kpi-card { padding: 13px 14px; }
  .search { min-width: 0; width: 100%; }
  .panel-head { padding: 12px 14px; }
  .panel-body { padding: 14px; }
  .kv { grid-template-columns: 1fr; gap: 2px 0; }
  .kv dt { margin-top: 8px; }
  .log-scraper { display: none; }
  .log-tag { width: 92px; }
  .drawer { width: 100%; }
  .modal { width: 94vw; padding: 18px; }
}

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