/* ============================================================
   EVORI — panel design system
   Ops/control-room aesthetic: layered dark, brand electric-blue,
   monospace telemetry, orbital signature (from the logo "O").
   One stylesheet → every page. Class names kept stable so the
   whole panel lifts at once, then pages get progressively polished.
   ============================================================ */

:root {
  color-scheme: dark;

  /* neutrals — deep near-black scale (blacker canvas, layered surfaces) */
  --bg:        #030304;
  --surface-1: #08080A;   /* sidebar / topbar */
  --surface-2: #0C0D10;   /* panels */
  --surface-3: #15161C;   /* raised: inputs, hovers */
  --surface-4: #1B1C23;   /* input hover */
  --line:      rgba(255,255,255,.09);
  --line-2:    rgba(255,255,255,.055);

  /* text — 100 / 66 / 44 */
  --ink:   #EDEFF3;
  --ink-2: #A4A9B4;
  --ink-3: #686D79;

  /* brand — electric blue (EVORI mark). CTA / selection only. */
  --accent:      #2E7DFF;
  --accent-h:    #1E6BF0;
  --accent-ink:  #FFFFFF;
  --accent-soft: rgba(46,125,255,.14);
  --accent-line: rgba(46,125,255,.36);
  --accent-glow: rgba(46,125,255,.42);

  /* semantic — green = live telemetry (means "farming/online") */
  --live:      #35D6A0;
  --live-soft: rgba(53,214,160,.14);
  --warn:      #F5B23E;
  --warn-soft: rgba(245,178,62,.14);
  --bad:       #FF5B6B;
  --bad-soft:  rgba(255,91,107,.13);

  /* radii */
  --r-xs: 8px; --r-sm: 10px; --r: 13px; --r-lg: 16px; --r-xl: 20px;

  /* motion — feedback / continuity / hierarchy only */
  --fast: 120ms; --base: 200ms; --slow: 340ms;
  --ease-out:    cubic-bezier(.22,.61,.36,1);
  --ease-in-out: cubic-bezier(.65,0,.35,1);

  /* type */
  --sans: 'Inter', -apple-system, 'Segoe UI', Roboto, system-ui, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;

  --sidebar-w: 258px;

  /* legacy token aliases — older inline styles still resolve to the new scale */
  --card: var(--surface-2); --card2: var(--surface-3);
  --border: var(--line); --border-2: var(--line-2);
  --mute: var(--ink-2); --mute2: var(--ink-3);
  --acc-soft: var(--accent-soft); --acc-bord: var(--accent-line);
  --good: var(--live); --good-bg: var(--live-soft);
  --red: var(--bad); --accent2: var(--accent-h);
}

* { box-sizing: border-box; }
html, body { height: 100%; }
/* reserve the scrollbar gutter permanently on the page scroller. Without it, a
   short page has no vertical scrollbar and a tall one does — so navigating
   between them changes the viewport width, and the flex `.main` visibly shifts
   sideways on every button/link click. */
html { background: var(--bg); font-family: var(--sans); scrollbar-gutter: stable; }
body {
  margin: 0; color: var(--ink); background: var(--bg);
  font: 400 14px/1.55 var(--sans);
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
  display: flex; min-height: 100%;
}
a { color: inherit; text-decoration: none; }
/* form controls don't inherit font-family by default → they fall back to the UA
   serif (Times New Roman). Force the sans everywhere so nothing leaks serif. */
button, input, textarea, select, optgroup, option {
  font-family: var(--sans); font-size: inherit; line-height: inherit;
}
::selection { background: var(--accent-soft); }
:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-glow); border-radius: var(--r-xs); }

/* thin custom scrollbars */
* { scrollbar-width: thin; scrollbar-color: rgba(255,255,255,.14) transparent; }
*::-webkit-scrollbar { width: 9px; height: 9px; }
*::-webkit-scrollbar-thumb { background: rgba(255,255,255,.12); border-radius: 20px; border: 2px solid transparent; background-clip: content-box; }
*::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,.22); background-clip: content-box; }

/* ---------------- Sidebar ---------------- */
.sidebar {
  width: var(--sidebar-w); flex-shrink: 0;
  background: var(--surface-1);
  border-right: 1px solid var(--line-2);
  height: 100vh; position: sticky; top: 0;
  display: flex; flex-direction: column;
  padding: 0 12px 14px; overflow-y: auto;
  /* symmetric gutter: when the nav is tall enough to scroll, the classic
     scrollbar reserves equal space both sides so the centered logo doesn't
     drift left (headless uses overlay scrollbars, so this is invisible there). */
  scrollbar-gutter: stable both-edges;
  transition: transform 220ms cubic-bezier(.2, .8, .2, 1);
}
/* brand area — logo has its OWN class, never a global img rule.
   Centered on the FULL sidebar (padding 0), not aligned to nav's left edge.
   Bigger logo lives in a taller brand zone so it can't overflow into nav. */
.brand { padding: 0; height: 96px; flex: none; display: flex; align-items: center; justify-content: center; }
.brand-logo { display: block; width: 168px; height: auto; margin-inline: auto; }
/* explicit (narrow) transitions — never `all`, so hover/layout can't animate oddly */
.brand, .brand-logo { transition: opacity 160ms ease, transform 160ms ease; }

/* explicit narrow transitions on elements devtools reports as `all` (its default) — never `all` */
.nav-group, .nav-label, .panel, .card, .aside-card { transition: background-color 160ms ease, border-color 160ms ease; }
.nav-link svg, .icon-btn svg, .btn svg, .logout svg, .chev { transition: color 160ms ease, transform 160ms ease; }
/* also the primitives inside icons (rect/path/circle) so none inherit the `all` default */
svg *, .nav-link svg * { transition: color 160ms ease, transform 160ms ease, fill 160ms ease, stroke 160ms ease; }
.nav-group { margin-bottom: 4px; }
.nav-label {
  font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: .13em;
  color: var(--ink-3); padding: 15px 12px 7px;
}
/* first nav sits a comfortable ~22px below the logo, not cramped */
.nav-group:first-of-type .nav-label { padding-top: 4px; }
.nav-link {
  position: relative; display: flex; align-items: center; gap: 11px;
  padding: 9px 12px; border-radius: var(--r-sm);
  color: var(--ink-2); font-size: 13.5px; font-weight: 500; margin-bottom: 1px;
  transition: background-color 160ms var(--ease-out), color 160ms var(--ease-out), transform 160ms var(--ease-out);
}
.nav-link svg { width: 18px; height: 18px; flex-shrink: 0; opacity: .85; stroke-width: 1.75px; }
.nav-link:hover { background: rgba(255,255,255,.045); color: var(--ink); transform: translateX(3px); }
.nav-link.active { background: var(--accent-soft); color: #fff; }
.nav-link.active svg { opacity: 1; color: var(--accent); }
/* signature: active marker = short accent bar (means "you are here") */
.nav-link.active::before {
  content: ""; position: absolute; left: -12px; top: 50%; transform: translateY(-50%);
  width: 3px; height: 17px; border-radius: 0 3px 3px 0;
  background: var(--accent); box-shadow: 0 0 10px var(--accent-glow);
}

.side-bottom { margin-top: auto; padding-top: 10px; }
.user-card {
  display: flex; align-items: center; gap: 11px; padding: 11px; border-radius: var(--r);
  background: rgba(255,255,255,.04); border: 1px solid var(--line-2); margin-top: 6px;
  transition: border-color var(--fast), background var(--fast);
}
.user-card:hover { border-color: var(--line); background: rgba(255,255,255,.055); }
/* avatar = the same EV orbit mark as the favicon/app icon (one visual family) */
.user-card .ava {
  width: 36px; height: 36px; border-radius: 10px; flex-shrink: 0; overflow: hidden;
  border: 1px solid var(--line-2); background: #0a0d14;
  display: flex; align-items: center; justify-content: center;
}
.user-card .ava img { width: 100%; height: 100%; object-fit: cover; display: block; }
.user-card .nm { font-size: 13px; font-weight: 600; line-height: 1.15; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.user-card .tg { font-size: 11px; color: var(--ink-3); margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.user-card .logout { flex-shrink: 0; display: flex; align-items: center; justify-content: center; width: 34px; height: 34px; padding: 0; border-radius: 10px; color: var(--ink-3); transition: color var(--fast), background var(--fast); }
.user-card .logout svg { width: 17px; height: 17px; }
.user-card .logout:hover { color: var(--bad); background: var(--bad-soft); }
.user-card .logout:focus-visible { box-shadow: 0 0 0 3px var(--accent-glow); }

/* ---------------- Main / topbar ---------------- */
.main { flex: 1; min-width: 0; display: flex; flex-direction: column; min-height: 100vh; }
.topbar {
  position: sticky; top: 0; z-index: 20;
  padding: 15px 30px; display: flex; align-items: center; gap: 10px;
  background: color-mix(in srgb, var(--bg) 82%, transparent);
  backdrop-filter: saturate(140%) blur(14px);
  border-bottom: 1px solid var(--line-2);
}
.topbar .spacer { flex: 1; }
.icon-btn {
  position: relative; color: var(--ink-2); display: flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; padding: 0; border-radius: 12px;
  background: rgba(255,255,255,.04); border: 1px solid var(--line-2);
  transition: color var(--fast), background var(--fast), border-color var(--fast);
}
.icon-btn:hover { color: var(--ink); background: rgba(255,255,255,.07); }
.icon-btn svg { width: 18px; height: 18px; }
.icon-btn .count {
  position: absolute; top: -6px; right: -6px; min-width: 17px; height: 17px; padding: 0 4px;
  background: var(--accent); color: #fff; font: 700 10px/17px var(--mono); text-align: center;
  border-radius: 999px; border: 2px solid var(--bg);
}
/* hover tooltip for icon-only controls (keeps aria-label for a11y) */
[data-tip] { position: relative; }
[data-tip]::after {
  content: attr(data-tip); position: absolute; z-index: 60; left: 50%; top: calc(100% + 8px);
  transform: translateX(-50%) translateY(-3px);
  background: var(--surface-4); color: var(--ink); border: 1px solid var(--line);
  font: 500 11.5px var(--sans); white-space: nowrap; padding: 5px 9px; border-radius: 8px;
  box-shadow: 0 8px 24px -8px rgba(0,0,0,.7);
  opacity: 0; pointer-events: none; transition: opacity 120ms ease, transform 120ms ease;
}
[data-tip]:hover::after, [data-tip]:focus-visible::after { opacity: 1; transform: translateX(-50%) translateY(0); }
/* logout sits at the sidebar bottom → point the tooltip up so it isn't clipped */
.user-card .logout[data-tip]::after { top: auto; bottom: calc(100% + 8px); transform: translateX(-50%) translateY(3px); }
.user-card .logout[data-tip]:hover::after, .user-card .logout[data-tip]:focus-visible::after { transform: translateX(-50%) translateY(0); }

.balance-pill {
  display: flex; align-items: center; gap: 10px; padding: 7px 13px 7px 9px; border-radius: var(--r-sm);
  background: rgba(255,255,255,.04); border: 1px solid var(--line-2);
  transition: border-color var(--fast), background var(--fast);
}
.balance-pill:hover { border-color: var(--accent-line); background: var(--accent-soft); }
.balance-pill .ic {
  width: 27px; height: 27px; border-radius: 7px; background: var(--accent-soft);
  border: 1px solid var(--accent-line); color: var(--accent);
  display: flex; align-items: center; justify-content: center;
}
.balance-pill .lab { font: 700 9px/1 var(--sans); color: var(--ink-3); text-transform: uppercase; letter-spacing: .12em; }
.balance-pill .val { font: 700 14px/1 var(--mono); color: var(--ink); margin-top: 5px; font-variant-numeric: tabular-nums; }

.content { padding: 26px 34px 72px; max-width: 1200px; width: 100%; margin-inline: auto; }

/* page-enter: subtle rise+fade (continuity between pages) */
@keyframes pageIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.content { animation: pageIn 220ms var(--ease-out) both; }

/* ---------------- Live viewer ---------------- */
.live-frame { position: relative; aspect-ratio: 16 / 9; width: 100%; background: #000; border: 1px solid var(--line); border-radius: 14px; overflow: hidden; }
.live-frame img { width: 100%; height: 100%; object-fit: contain; display: none; }
.live-frame.has-frame img { display: block; }
.live-empty { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; text-align: center; padding: 24px; }
.live-frame.has-frame .live-empty { display: none; }
.live-empty h3 { margin: 6px 0 0; font-size: 15px; font-weight: 600; }
.live-empty p { margin: 0; font-size: 12.5px; color: var(--ink-3); max-width: 320px; line-height: 1.5; }
.live-refresh { position: absolute; top: 10px; right: 10px; width: 26px; height: 26px; border-radius: 8px; background: rgba(0,0,0,.55); display: flex; align-items: center; justify-content: center; color: #fff; opacity: 0; transition: opacity .2s ease; pointer-events: none; }
.live-refresh.on { opacity: 1; }
.live-refresh .btn-spin { width: 14px; height: 14px; margin: 0; }

/* interactive surfaces only — a card lifts on hover if (and only if) it's clickable */
.interactive-card { transition: transform 180ms var(--ease-out), border-color 180ms var(--ease-out), box-shadow 180ms var(--ease-out); }
.interactive-card:hover { transform: translateY(-2px); border-color: rgba(255,255,255,.16); box-shadow: 0 14px 36px rgba(0,0,0,.22); }

/* accessibility: honour reduced-motion — kill transforms, loops, page-enter, smooth-scroll */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }
}

/* ---------------- Headings ---------------- */
.crumb { font-size: 12.5px; color: var(--ink-3); margin-bottom: 10px; }
.crumb a { color: var(--ink-2); transition: color var(--fast); }
.crumb a:hover { color: var(--accent); }
.crumb span { color: var(--ink); font-weight: 500; }
.page-title { font-size: 25px; font-weight: 700; letter-spacing: 0; margin: 0 0 20px; text-wrap: balance; }
.page-head { display: flex; align-items: center; justify-content: space-between; gap: 16px; margin-bottom: 20px; }
.page-head .page-title { margin: 0; }
.page-sub { color: var(--ink-2); font-size: 13.5px; margin: -12px 0 22px; max-width: 60ch; }

/* ---------------- Panels (real containers only) ---------------- */
.card, .panel {
  background: var(--surface-2); border: 1px solid var(--line-2);
  border-radius: var(--r-lg); padding: 20px; margin-bottom: 16px;
}
.card-title, .panel-title { font-size: 14.5px; font-weight: 600; letter-spacing: 0; margin: 0 0 4px; }
.card-sub, .panel-sub { font-size: 13px; color: var(--ink-2); margin: 0 0 16px; }
.panel-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-bottom: 16px; }
.panel-head > :first-child { margin-bottom: 0; }
.panel-head .panel-title, .panel-head .card-sub { margin: 0; }

/* ---------------- Stat tiles (instrument readouts, not fat cards) --- */
.stat-grid { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 13px; margin-bottom: 18px; }
.stat {
  background: var(--surface-2); border: 1px solid var(--line-2); border-radius: var(--r-lg);
  padding: 16px 17px; position: relative; overflow: hidden;
  transition: border-color 180ms var(--ease-out), transform 180ms var(--ease-out), box-shadow 180ms var(--ease-out);
}
/* only the clickable dashboard tiles (a.stat) lift; static div.stat stays put */
a.stat:hover { border-color: var(--accent-line); transform: translateY(-2px); box-shadow: 0 14px 36px rgba(0,0,0,.22); }
.stat .k { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .1em; color: var(--ink-3); display: flex; align-items: center; gap: 7px; }
.stat .v { font: 700 27px/1 var(--mono); letter-spacing: 0; margin-top: 13px; font-variant-numeric: tabular-nums; color: var(--ink); }
.stat .v small { font-size: 15px; color: var(--ink-3); font-weight: 600; }
.stat .d { font-size: 12px; margin-top: 7px; color: var(--ink-3); font-variant-numeric: tabular-nums; }
.stat .d.up { color: var(--live); } .stat .d.down { color: var(--bad); }

/* ---------------- Tables (one DataTable, every page) ---------------- */
/* overflow-x:auto forces overflow-y to compute to auto → a stray vertical
   scrollbar. overflow-y:hidden stops that; padding-bottom then gives the last
   row breathing room AND a gutter so a horizontal scrollbar never clips it.
   (No negative bottom margin — that used to pull the panel edge over the row.) */
.table-wrap { overflow-x: auto; overflow-y: hidden; margin: 0 -20px; padding-bottom: 14px; border-radius: 12px; }
.table-wrap table { padding: 0 20px; }
table { width: 100%; border-collapse: collapse; }
th, td { text-align: left; padding: 11px 14px; border-bottom: 1px solid var(--line-2); white-space: nowrap; vertical-align: middle; }
tr:last-child td { border-bottom: 0; }
th { color: var(--ink-3); font-weight: 600; font-size: 10.5px; text-transform: uppercase; letter-spacing: .08em; }
tbody tr, table tr { transition: background var(--fast); }
tbody tr:hover td { background: rgba(255,255,255,.03); }
td .mono, td.mono, .mono { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.muted { color: var(--ink-3); }
.num { font-family: var(--mono); font-variant-numeric: tabular-nums; }

/* column sizing: one column absorbs slack, the rest pack to content.
   .col-grow → primary text column takes leftover width (dense, no lopsided gaps)
   .col-actions → trailing icon column shrinks and pins its content right */
th.col-grow, td.col-grow { width: 100%; }
th.col-actions, td.col-actions { width: 1%; text-align: right; white-space: nowrap; }
.row-actions { display: inline-flex; gap: 6px; justify-content: flex-end; align-items: center; }
/* truncate an over-long inline value inside a cell (tokens, urls) */
.cell-trunc { display: inline-block; max-width: 240px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; }
/* a flexible cell that GROWS to fill leftover width but truncates when squeezed
   (shows the full value on wide screens, ellipsis in a narrow column) */
td.cell-flex { width: 100%; max-width: 0; }
td.cell-flex > * { display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; vertical-align: middle; }

/* ---------------- Status dot + live pulse (signature) ---------------- */
.dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; margin-right: 8px; vertical-align: 1px; position: relative; }
.dot.on, .dot.live { background: var(--live); }
.dot.off { background: var(--ink-3); }
.dot.warn { background: var(--warn); }
.dot.on::after, .dot.live::after {
  content: ""; position: absolute; inset: -3px; border-radius: 50%;
  border: 1px solid var(--live); opacity: .0; animation: pulse 2.4s var(--ease-out) infinite;
}
@keyframes pulse { 0% { transform: scale(.7); opacity: .8; } 70%,100% { transform: scale(2.1); opacity: 0; } }

/* ---------------- Pills / badges ---------------- */
.pill-ok, .pill-fail, .pill-warn, .pill-mute, .badge, .status-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px; border-radius: 999px; font-size: 11.5px; font-weight: 600; line-height: 1.4;
  border: 1px solid transparent;
}
.pill-ok  { background: var(--live-soft); color: var(--live); border-color: rgba(53,214,160,.22); }
.pill-fail{ background: var(--bad-soft);  color: var(--bad);  border-color: rgba(255,91,107,.22); }
.pill-warn{ background: var(--warn-soft); color: var(--warn); border-color: rgba(245,178,62,.22); }
.pill-mute{ background: rgba(255,255,255,.05); color: var(--ink-2); border-color: var(--line-2); }
/* status chips read stronger with a leading colour dot (inherits the pill's colour) */
.pill-ok::before, .pill-fail::before, .pill-warn::before, .pill-mute::before {
  content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none;
}
.pill-mute::before { opacity: .7; }

code, .code {
  font: 12.5px var(--mono); background: var(--surface-3); border: 1px solid var(--line-2);
  padding: 2px 8px; border-radius: 7px; color: var(--ink-2); font-variant-numeric: tabular-nums;
}

/* ---------------- Forms ---------------- */
label.field { display: block; margin-bottom: 17px; }
label.field .lab, .field-lab { display: block; font-size: 12.5px; font-weight: 600; margin-bottom: 7px; color: var(--ink); }
label.field .lab .req, .req { color: var(--accent); }
label.field .help, .field-help { display: block; font-size: 12px; color: var(--ink-3); margin-top: 7px; }
input[type=text], input[type=email], input[type=password], input[type=number], select, textarea {
  background: var(--surface-3); border: 1px solid var(--line); color: var(--ink);
  min-height: 40px; padding: 9px 13px; border-radius: var(--r-sm); width: 100%; font: 400 14px var(--sans);
  outline: none; transition: border-color var(--fast), box-shadow var(--fast), background var(--fast);
}
textarea { min-height: 88px; line-height: 1.6; }
input::placeholder, textarea::placeholder { color: var(--ink-3); }
input:hover:not(:focus), select:hover:not(:focus), textarea:hover:not(:focus) {
  border-color: rgba(255,255,255,.18); background: var(--surface-4);
}
input:focus, select:focus, textarea:focus {
  border-color: var(--accent); background: var(--surface-3);
  box-shadow: 0 0 0 3px var(--accent-glow);
}
/* clean number field — no spinners */
input[type=number] { -moz-appearance: textfield; }
input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
.inline-form { display: inline; }
.row { display: flex; gap: 11px; align-items: center; }
input[type=checkbox] { accent-color: var(--accent); }

/* segmented control (radio group) */
.segmented { display: inline-flex; background: var(--surface-3); border: 1px solid var(--line); border-radius: var(--r-sm); padding: 3px; gap: 3px; }
.segmented input { position: absolute; opacity: 0; width: 0; height: 0; }
.segmented label {
  display: flex; flex-direction: column; align-items: center; gap: 1px; margin: 0;
  padding: 6px 16px; border-radius: 8px; font-size: 13px; font-weight: 600; color: var(--ink-2);
  cursor: pointer; transition: background var(--fast), color var(--fast); white-space: nowrap;
}
.segmented label small { font: 500 10px var(--sans); color: var(--ink-3); text-transform: none; letter-spacing: 0; }
/* stacked variant — full-width vertical options (e.g. machine-job action) */
.segmented.seg-stack { display: flex; flex-direction: column; align-items: stretch; width: 100%; gap: 3px; }
.segmented.seg-stack label { flex-direction: row; justify-content: flex-start; padding: 9px 13px; }
.segmented input:checked + label { background: var(--accent); color: #fff; }
.segmented input:checked + label small { color: rgba(255,255,255,.82); }
.segmented input:focus-visible + label { box-shadow: 0 0 0 3px var(--accent-glow); }
button:disabled, .btn:disabled { opacity: .45; cursor: not-allowed; box-shadow: none; }
button:disabled:hover, .btn:disabled:hover { background: var(--accent); transform: none; }

/* field-level validation for main-app forms */
.field.invalid input, .field.invalid select { border-color: var(--bad); box-shadow: 0 0 0 3px rgba(255,91,107,.14); }
.field-err { display: none; font-size: 12px; color: var(--bad); margin-top: 6px; }
.field.invalid .field-err { display: block; }
.field.invalid .field-help { display: none; }

/* proxy add-form: smooth reveal + test-connection feedback */
.proxy-reveal { overflow: hidden; max-height: 0; opacity: 0; transition: max-height 300ms var(--ease-out), opacity 200ms ease; }
.proxy-reveal.open { max-height: 720px; opacity: 1; }
.pf-toggle { width: 100%; justify-content: space-between; }
.pf-toggle .chev { transition: transform 240ms var(--ease-out); }
.pf-toggle[aria-expanded="true"] .chev { transform: rotate(180deg); }
.field-split { display: grid; grid-template-columns: 1fr 96px; gap: 11px; align-items: start; }
.btn-test { background: transparent; color: var(--ink); border: 1px solid var(--line); box-shadow: none; }
.btn-test:hover { background: var(--surface-3); border-color: rgba(255,255,255,.2); }
.test-result { display: none; align-items: center; gap: 8px; font-size: 12.5px; padding: 8px 11px; border-radius: var(--r-sm); margin-top: 10px; }
.test-result.show { display: flex; }
.test-result.ok  { background: var(--live-soft); color: var(--live); border: 1px solid rgba(53,214,160,.24); }
.test-result.err { background: var(--bad-soft);  color: var(--bad);  border: 1px solid rgba(255,91,107,.24); }
.test-result.load{ background: var(--surface-3); color: var(--ink-2); border: 1px solid var(--line-2); }

/* job progress bar */
.progress-bar { height: 6px; background: var(--surface-4); border-radius: 3px; overflow: hidden; margin-top: 7px; max-width: 160px; }
.progress-fill { height: 100%; background: var(--accent); border-radius: 3px; transition: width .3s ease; }

/* list search toolbar (bots / machines) */
.list-toolbar { display: flex; align-items: center; gap: 12px; padding: 2px 0 16px; }
.search-field { position: relative; display: flex; align-items: center; flex: 1; max-width: 340px; }
.search-field svg { position: absolute; left: 12px; color: var(--ink-3); pointer-events: none; }
.search-field input { padding-left: 34px; min-height: 38px; }

/* row name → detail link */
.row-link { font-weight: 500; transition: color 140ms ease; }
.row-link:hover { color: var(--accent); }

/* spinner state for icon buttons (sync) */
.btn-icon.spinning svg { animation: spin .7s linear infinite; }

/* CSS-only 7-day XP bar chart (/stats) */
.chart-7d { display: flex; align-items: flex-end; gap: 10px; height: 190px; padding: 6px 2px 0; }
.chart-col { flex: 1; display: flex; flex-direction: column; align-items: center; height: 100%; gap: 6px; min-width: 0; }
.chart-bar-wrap { flex: 1; width: 100%; display: flex; align-items: flex-end; justify-content: center; }
.chart-bar { width: 62%; max-width: 48px; min-height: 3px; border-radius: 6px 6px 0 0;
  background: linear-gradient(180deg, var(--accent), color-mix(in srgb, var(--accent) 45%, transparent));
  transition: height .45s var(--ease-out); }
.chart-bar.zero { background: var(--surface-4); }
.chart-val { font: 600 11px var(--mono); color: var(--ink-2); font-variant-numeric: tabular-nums; }
.chart-label { font-size: 10.5px; color: var(--ink-3); letter-spacing: .01em; }

/* map multi-select chips (job creation) */
.map-grid { display: flex; flex-wrap: wrap; gap: 7px; }
.map-chip { position: relative; margin: 0; cursor: pointer; }
.map-chip input { position: absolute; opacity: 0; width: 0; height: 0; }
.map-chip span { display: inline-block; padding: 6px 12px; border-radius: 999px; font-size: 12.5px; font-weight: 500;
  background: var(--surface-3); border: 1px solid var(--line); color: var(--ink-2);
  transition: background-color 140ms ease, border-color 140ms ease, color 140ms ease; }
.map-chip:hover span { border-color: var(--ink-3); }
.map-chip input:checked + span { background: var(--accent-soft); border-color: var(--accent-line); color: #fff; }
.map-chip input:focus-visible + span { box-shadow: 0 0 0 3px var(--accent-glow); }

/* dashboard bot-status summary */
.botsum { display: flex; flex-wrap: wrap; gap: 10px; }
.botsum-item { display: inline-flex; align-items: center; gap: 8px; padding: 9px 14px; border-radius: 10px;
  background: var(--surface-3); border: 1px solid var(--line-2); font-size: 13px; color: var(--ink-2);
  transition: background-color 140ms ease, border-color 140ms ease; }
.botsum-item:hover { background: var(--surface-4); border-color: var(--line); }
.botsum-item b { color: var(--ink); font-variant-numeric: tabular-nums; }
.botsum-item .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--ink-4); }

/* toggle rows (settings) */
.toggle-row { display: flex; align-items: flex-start; gap: 12px; padding: 13px 0; border-bottom: 1px solid var(--line-2); }
.toggle-row.last { border-bottom: 0; padding-bottom: 0; }
.toggle-row input[type=checkbox] { width: auto; margin-top: 2px; flex-shrink: 0; }
.toggle-row .lab { display: block; font-size: 13.5px; font-weight: 500; }
.toggle-row .help { display: block; font-size: 12px; color: var(--ink-3); margin-top: 3px; }

/* ---------------- Buttons ---------------- */
button, .btn {
  background: var(--accent); border: 1px solid transparent; color: var(--accent-ink);
  min-height: 40px; padding: 10px 17px; border-radius: var(--r-sm); font: 600 13.5px var(--sans);
  cursor: pointer; display: inline-flex; align-items: center; justify-content: center; gap: 8px; line-height: 1;
  box-shadow: 0 1px 0 rgba(255,255,255,.09) inset, 0 8px 20px -10px var(--accent-glow);
  transition: background var(--fast), transform var(--fast), box-shadow var(--fast), border-color var(--fast);
}
button:hover, .btn:hover { background: var(--accent-h); }
button:active, .btn:active { transform: scale(.975); }
/* radius + transition apply to the WHOLE button family so they hold on <a>
   too (ghost/sm anchors don't match the `button, .btn` selector otherwise → radius 0) */
.btn, .btn-ghost, .btn-danger, .btn-sm, .btn-icon {
  border-radius: var(--r-sm);
  transition: background-color var(--fast) var(--ease-out), border-color var(--fast) var(--ease-out),
              color var(--fast) var(--ease-out), transform var(--fast) var(--ease-out), box-shadow var(--fast) var(--ease-out);
}
.btn-ghost {
  background: rgba(255,255,255,.045); color: var(--ink); border: 1px solid var(--line);
  min-height: 0; padding: 8px 13px; font-size: 12.5px; font-weight: 500; box-shadow: none;
}
.btn-ghost:hover { background: rgba(255,255,255,.09); border-color: rgba(255,255,255,.16); }
.btn-danger { background: var(--bad-soft); color: var(--bad); border: 1px solid rgba(255,91,107,.25); box-shadow: none; }
.btn-danger:hover { background: rgba(255,91,107,.2); }
.btn-sm { min-height: 32px; padding: 6px 12px; font-size: 12px; }
.btn-icon { min-height: 0; padding: 7px; font-size: 12px; line-height: 0; }
.btn-icon svg { display: block; }
/* submit loading state: spinner + disabled while the request is in flight */
.btn-spin { display: inline-block; width: 13px; height: 13px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: spin .6s linear infinite; margin-right: 2px; vertical-align: -1px; }
button.is-loading, .btn.is-loading { cursor: progress; opacity: .9; }
select.compact { width: auto; font-size: 13px; }
.hint { color: var(--ink-3); font-size: 13px; margin-top: 13px; }

/* form footer: actions pinned bottom-right, hint may sit left (margin-right:auto) */
.form-footer {
  display: flex; align-items: center; justify-content: flex-end; gap: 12px;
  margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--line-2);
}
.form-footer .hint, .form-footer .foot-note { margin: 0 auto 0 0; }
.field-group { margin-bottom: 17px; }
.field-group > .field-lab { margin-bottom: 7px; }

/* ---------------- Empty state (orbital signature glyph) ------------ */
.empty { color: var(--ink-3); padding: 8px 0; }
.empty-state { text-align: center; padding: 46px 20px; color: var(--ink-3); }
.empty-state .orbit { margin: 0 auto 18px; }
.empty-state h3 { color: var(--ink-2); font-size: 15px; font-weight: 600; margin: 0 0 6px; }
.empty-state p { font-size: 13px; margin: 0 auto; max-width: 42ch; }

/* orbital ring — echoes the EVORI "O"; used in empty states & loaders */
.orbit { width: 46px; height: 46px; position: relative; color: var(--accent); }
.orbit .ring { width: 100%; height: 100%; border-radius: 50%; border: 1.5px solid var(--accent-line); }
.orbit .node { position: absolute; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 10px var(--accent-glow); }
.orbit .node.a { top: -3px; left: 50%; margin-left: -4px; }
.orbit .node.b { bottom: -3px; left: 50%; margin-left: -4px; }
.orbit.spin { animation: spin 3.2s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

/* progress bar (xp toward weekly cap etc.) */
.bar { height: 6px; border-radius: 4px; background: var(--surface-3); overflow: hidden; }
.bar > span { display: block; height: 100%; border-radius: 4px; background: var(--accent); box-shadow: 0 0 10px var(--accent-glow); transition: width var(--slow) var(--ease-out); }
.bar.live > span { background: var(--live); box-shadow: 0 0 10px rgba(53,214,160,.4); }

/* small helpers */
.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.stack > * + * { margin-top: 12px; }
.flex { display: flex; align-items: center; gap: 10px; }
.right { margin-left: auto; }

/* mobile chrome — hidden on desktop, shown in the drawer breakpoint */
.nav-toggle, .topbar-brand, .nav-overlay { display: none; }
/* the topbar logo is a plain link, never a button — no surface, no radius */
.topbar-brand { background: transparent; border: 0; border-radius: 0; transition: opacity 160ms ease; }

@media (max-width: 980px) {
  .stat-grid { grid-template-columns: repeat(2, 1fr); }
  .grid-2 { grid-template-columns: 1fr; }
}

@media (max-width: 760px) {
  /* --- sidebar becomes a slide-in drawer --- */
  .sidebar {
    position: fixed; left: 0; top: 0; z-index: 120; width: 266px;
    transform: translateX(-100%); transition: transform 220ms cubic-bezier(.2, .8, .2, 1);
    box-shadow: 0 0 60px rgba(0,0,0,.6); border-right: 1px solid var(--line);
  }
  body.nav-open .sidebar { transform: translateX(0); }
  .nav-overlay {
    display: block; position: fixed; inset: 0; z-index: 110; background: rgba(0,0,0,.6);
    opacity: 0; visibility: hidden; transition: opacity var(--base), visibility var(--base);
  }
  body.nav-open .nav-overlay { opacity: 1; visibility: visible; }

  /* --- topbar: hamburger + brand, compact --- */
  .topbar { position: sticky; padding: 10px 14px; gap: 10px; }
  .nav-toggle {
    display: inline-flex; align-items: center; justify-content: center; flex-shrink: 0;
    width: 38px; height: 38px; min-height: 0; padding: 0; border-radius: 12px;
    background: rgba(255,255,255,.05); border: 1px solid var(--line-2); color: var(--ink); box-shadow: none;
  }
  .nav-toggle:hover { background: rgba(255,255,255,.09); }
  .nav-toggle svg { width: 20px; height: 20px; }
  /* logo centered on the TRUE viewport center — 50vw includes the scrollbar
     gutter, so the logo lands identically whether the page scrolls or not
     (left:50% would drift when a vertical scrollbar narrows the topbar). */
  .topbar-brand {
    position: absolute; left: 50vw; transform: translateX(-50%);
    display: flex; align-items: center; pointer-events: none;
  }
  .topbar-logo { width: 112px; height: auto; display: block; }
  .topbar .env-status { display: none; }
  /* keep interactive chrome above the centered logo and clickable */
  .nav-toggle, .icon-btn, .balance-pill { position: relative; z-index: 2; }
  .balance-pill { padding: 6px 10px; }
  .balance-pill .lab { display: none; }
  /* trim right-side chrome so it never crosses the centered logo (390px is tight) */
  .topbar .balance-pill .ic { display: none; }
  .topbar .icon-btn { padding: 8px; }

  /* --- layout --- */
  .content { padding: 18px 14px 56px; }
  .page-title { font-size: 22px; }
  .page-head { flex-direction: column; align-items: stretch; gap: 12px; }
  .page-head .btn, .page-head .row { width: 100%; }
  .page-head .row { justify-content: stretch; }
  .page-head .row > * { flex: 1; justify-content: center; }
  .stat-grid { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .stat-grid .stat { min-height: 84px; padding: 14px; }
  .stat-grid .stat .v { font-size: 22px; }
  .card, .panel { padding: 16px; }
  /* keep the primary action reachable while scrolling a long mobile form */
  .sticky-foot {
    position: sticky; bottom: 0; z-index: 5;
    margin: 14px -16px 0; padding: 12px 16px calc(12px + env(safe-area-inset-bottom, 0px));
    background: var(--surface-2); border-top: 1px solid var(--line-2);
    border-radius: 0 0 var(--r-lg) var(--r-lg);
  }
  .content .empty-state { padding: 30px 14px; }
  .content .empty-state .orbit { width: 44px; height: 44px; }
  form { max-width: 100% !important; }
  form .row { flex-wrap: wrap; }
  form .row > select, form .row > input, form .row > button { flex: 1 1 140px; }

  /* --- data tables → stacked cards (labelled) --- */
  .as-cards table, .as-cards tbody, .as-cards tr, .as-cards td { display: block; }
  .as-cards { margin: 0; }
  .as-cards table { padding: 0; }
  .as-cards thead, .as-cards tr:first-child, .as-cards th { display: none; }
  .as-cards tr {
    border: 1px solid var(--line-2); border-radius: 14px; background: var(--surface-3);
    padding: 6px 16px; margin-bottom: 14px;
  }
  .as-cards tr:hover td { background: transparent; }
  .as-cards td {
    width: auto; display: flex; justify-content: space-between; align-items: center; gap: 16px;
    padding: 11px 0; border-bottom: 1px solid var(--line-2); white-space: normal; text-align: right;
  }
  .as-cards tr td:last-child { border-bottom: 0; }
  /* per-page: hide a column inside the mobile card (e.g. redundant ID/Description) */
  .as-cards .mob-hide { display: none; }
  .as-cards td::before {
    content: attr(data-label); color: var(--ink-3); font-size: 10.5px; font-weight: 600;
    text-transform: uppercase; letter-spacing: .06em; text-align: left; flex-shrink: 0;
  }
  .as-cards td[data-label=""]::before { content: none; }
  .as-cards td[data-label=""] { justify-content: flex-end; }
  .as-cards td .compact, .as-cards td select.compact { min-width: 0; width: auto; }
  /* card mode: flexible cell shows its value in full, no truncation */
  .as-cards td.cell-flex { width: auto; max-width: none; }
  .as-cards td.cell-flex > * { max-width: 100%; white-space: normal; }

  /* other tables keep horizontal scroll, margins matched to mobile padding */
  .table-wrap:not(.as-cards) { -webkit-overflow-scrolling: touch; margin: 0 -16px; }
  .table-wrap:not(.as-cards) table { padding: 0 16px; }
}

/* ============================================================
   POLISH PASS — native controls, table packing, small fixes
   ============================================================ */

/* Custom-styled <select> (kill the native OS dropdown look) */
select, select.compact {
  appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23A4A9B4' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>");
  background-repeat: no-repeat; background-position: right 11px center; background-size: 15px;
  padding-right: 34px; cursor: pointer;
}
select option { background: var(--surface-3); color: var(--ink); }

/* Custom file input button */
input[type=file] { font: 400 13px var(--sans); color: var(--ink-3); padding: 0; }
input[type=file]::file-selector-button {
  background: rgba(255,255,255,.05); color: var(--ink); border: 1px solid var(--line);
  padding: 9px 14px; border-radius: var(--r-sm); font: 600 12.5px var(--sans);
  margin-right: 12px; cursor: pointer; transition: background var(--fast), border-color var(--fast);
}
input[type=file]::file-selector-button:hover { background: rgba(255,255,255,.09); border-color: var(--accent-line); }

/* select inside a table cell keeps a usable width */
td .compact, td select.compact { min-width: 150px; }

/* Stat tiles never collapse when a value is short ("—", version) */
.stat { min-height: 96px; display: flex; flex-direction: column; }
.stat .v { margin-top: auto; }

/* User card: keep it on one row, never wrap the meta line */
.user-card { flex-wrap: nowrap; }
.user-card > div { min-width: 0; }
.user-card .tg { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* Empty-state orbit reads as an intentional mark, not stray dots */
.empty-state .orbit { width: 52px; height: 52px; }
.empty-state .orbit .ring { border-color: var(--accent-line); }

/* Topbar: a quiet live-status marker on the left so it isn't half-empty */
.env-status { display: flex; align-items: center; gap: 8px; font-size: 12px; font-weight: 500; color: var(--ink-2); }
.env-status .dot { margin: 0; }

/* inline autosave indicator (bots → machine allocation) */
.allocate-form { display: inline-flex; align-items: center; gap: 8px; }
.save-flash { font-size: 11px; font-weight: 600; opacity: 0; transition: opacity var(--fast); }
.save-flash.ok { color: var(--live); }
.save-flash.err { color: var(--bad); }
.save-flash.show { opacity: 1; }

/* copy-to-clipboard code chips */
.copyable { cursor: pointer; position: relative; }
.copyable:hover { border-color: var(--accent-line); color: var(--ink); }
.copyable.copied::after {
  content: "copied"; position: absolute; left: 50%; bottom: calc(100% + 6px); transform: translateX(-50%);
  background: var(--live); color: #04120c; font: 700 10px var(--sans); padding: 2px 7px; border-radius: 6px; white-space: nowrap;
}

/* skeleton shimmer (loading states) */
.skeleton { position: relative; overflow: hidden; background: var(--surface-3); border-radius: 6px; color: transparent !important; }
.skeleton::after { content: ""; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, rgba(255,255,255,.06), transparent); animation: shimmer 1.3s infinite; }
@keyframes shimmer { 100% { transform: translateX(100%); } }

/* drag-and-drop upload zone */
.dropzone { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px; text-align: center;
  border: 1.5px dashed var(--line); border-radius: var(--r); padding: 28px 20px; cursor: pointer; color: var(--ink-3);
  transition: border-color var(--fast), background var(--fast), color var(--fast); }
.dropzone:hover, .dropzone.drag { border-color: var(--accent-line); background: var(--accent-soft); color: var(--ink-2); }
.dropzone.has-file { border-style: solid; border-color: var(--accent-line); }
.dropzone input[type=file] { display: none; }
.dropzone svg { width: 26px; height: 26px; color: var(--ink-3); }
.dropzone.drag svg, .dropzone.has-file svg { color: var(--accent); }
.dz-text b { color: var(--ink); font-weight: 600; }
.dz-file { font: 12.5px var(--mono); color: var(--live); }

/* toast */
.toast-wrap { position: fixed; right: 20px; bottom: 20px; z-index: 200; display: flex; flex-direction: column; gap: 10px; }
.toast {
  display: flex; align-items: center; gap: 10px; min-width: 220px; max-width: 360px;
  background: var(--surface-3); border: 1px solid var(--line); border-left: 3px solid var(--accent);
  border-radius: var(--r-sm); padding: 12px 14px; font-size: 13px; color: var(--ink);
  box-shadow: 0 12px 40px -12px rgba(0,0,0,.7); animation: toastIn var(--base) var(--ease-out);
}
.toast.ok { border-left-color: var(--live); }
.toast.err { border-left-color: var(--bad); }
@keyframes toastIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }

/* confirm modal — dangerous actions (logout, delete, overwrite) */
.modal-overlay {
  position: fixed; inset: 0; z-index: 300; display: flex; align-items: center; justify-content: center; padding: 20px;
  background: rgba(3,3,4,.68); backdrop-filter: blur(3px);
  opacity: 0; visibility: hidden; transition: opacity var(--base), visibility var(--base);
}
.modal-overlay.show { opacity: 1; visibility: visible; }
.modal {
  width: 100%; max-width: 410px; background: var(--surface-3); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 22px 22px 18px; box-shadow: 0 24px 70px -20px rgba(0,0,0,.85);
  transform: translateY(10px) scale(.985); transition: transform var(--base) var(--ease-out);
}
.modal-overlay.show .modal { transform: none; }
.modal h3 { margin: 0 0 8px; font-size: 16px; font-weight: 600; letter-spacing: 0; }
.modal p { margin: 0; font-size: 13.5px; color: var(--ink-2); line-height: 1.55; }
.modal-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 22px; }

/* ============================================================
   WORK-AREA LAYOUT — main column + right aside (kills empty-right)
   ============================================================ */
.content-grid { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 22px; align-items: start; }
/* wider aside when the right column carries a primary action (e.g. Add proxy) */
.content-grid--wide { grid-template-columns: minmax(0, 1fr) 380px; gap: 24px; }
.content-grid > .main-col { min-width: 0; }
.content-grid > .aside-col { position: sticky; top: 82px; display: flex; flex-direction: column; gap: 16px; }
@media (max-width: 1080px) {
  .content-grid { grid-template-columns: 1fr; }
  .content-grid > .aside-col { position: static; }
}
/* stack that keeps desktop order but lifts the primary action first on mobile */
.jobs-stack { display: flex; flex-direction: column; gap: 22px; }
.jobs-stack > * { margin: 0; }
@media (max-width: 760px) {
  .jobs-stack > .js-create { order: -1; }
}

/* aside info card — quieter surface than a .panel */
.aside-card { background: var(--surface-2); border: 1px solid var(--line-2); border-radius: var(--r-lg); padding: 16px 17px; }
.aside-card .ac-title { font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .1em; color: var(--ink-3); margin: 0 0 12px; }
.ac-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--line-2); font-size: 13px; }
.ac-row:last-child { border-bottom: 0; }
.ac-row .k { color: var(--ink-3); }
.ac-row .v { color: var(--ink); font-weight: 500; font-variant-numeric: tabular-nums; text-align: right; }
.ac-note { font-size: 12.5px; color: var(--ink-3); line-height: 1.55; margin: 0; }
.ac-note + .ac-note { margin-top: 10px; }
.ac-note b { color: var(--ink-2); font-weight: 600; }
.ac-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 11px; }
.ac-list li { display: flex; gap: 9px; font-size: 12.5px; color: var(--ink-2); line-height: 1.5; }
.ac-list li svg { width: 15px; height: 15px; flex-shrink: 0; margin-top: 1px; color: var(--accent); }
/* quick-action links in an aside card */
.ac-links { display: flex; flex-direction: column; gap: 1px; }
.ac-link { display: flex; align-items: center; gap: 10px; padding: 9px 9px; margin: 0 -9px; border-radius: 10px;
  font-size: 13px; font-weight: 500; color: var(--ink-2);
  transition: background-color 140ms ease, color 140ms ease; }
.ac-link:hover { background: var(--surface-3); color: var(--ink); }
.ac-link > svg:first-child { width: 16px; height: 16px; flex: none; color: var(--ink-3); transition: color 140ms ease; }
.ac-link:hover > svg:first-child { color: var(--accent); }
.ac-link .go { margin-left: auto; width: 14px; height: 14px; color: var(--ink-4); opacity: .7; }

/* toggle switch (settings) */
.switch { position: relative; display: inline-block; width: 38px; height: 22px; flex-shrink: 0; }
.switch input { position: absolute; opacity: 0; width: 0; height: 0; }
.switch .track { position: absolute; inset: 0; border-radius: 999px; background: var(--surface-4); border: 1px solid var(--line); transition: background var(--fast), border-color var(--fast); cursor: pointer; }
.switch .track::after { content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: var(--ink-2); transition: transform var(--fast) var(--ease-out), background var(--fast); }
.switch input:checked + .track { background: var(--accent-soft); border-color: var(--accent-line); }
.switch input:checked + .track::after { transform: translateX(16px); background: var(--accent); }
.switch input:focus-visible + .track { box-shadow: 0 0 0 3px var(--accent-glow); }
.setting-row { display: flex; align-items: center; gap: 14px; padding: 13px 0; border-bottom: 1px solid var(--line-2); }
.setting-row:last-child { border-bottom: 0; }
/* grouped settings — labelled sections keep a long list scannable */
.set-group-label { font-size: 10.5px; font-weight: 600; text-transform: uppercase; letter-spacing: .1em; color: var(--ink-3); padding: 20px 0 6px; }
.set-group:first-of-type .set-group-label { padding-top: 4px; }
.set-group .setting-row:last-child { border-bottom: 0; }

/* ---- collapsible group (accordion on mobile, always-open label on desktop) ----
   JS (base.html) forces .grp open + adds .locked on desktop; on mobile it
   respects the authored `open` attribute and lets the summary toggle. */
details.grp { }
details.grp > summary { list-style: none; cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: 10px; }
details.grp > summary::-webkit-details-marker { display: none; }
details.grp > summary::marker { content: ""; }
.grp .chev { flex: none; width: 16px; height: 16px; color: var(--ink-3); transition: transform var(--fast) var(--ease-out); }
details.grp[open] > summary .chev { transform: rotate(180deg); }
details.grp.locked > summary { cursor: default; pointer-events: none; }
details.grp.locked > summary .chev { display: none; }
/* settings variant: summary IS the group label; keep the divider tidy */
.set-group.grp > summary { padding: 20px 0 6px; }
.set-group.grp[open] > summary { border-bottom: 0; }
.set-group.grp:first-of-type > summary { padding-top: 4px; }
/* aside-card variant: collapsed card is just its title (no trailing gap) */
.aside-card.grp:not([open]) > summary { margin-bottom: 0; }
/* panel-as-accordion: collapsed panel is just its title row */
.panel.grp > summary { cursor: pointer; }
.panel.grp:not([open]) > summary { margin-bottom: 0; }
/* desktop: flow settings groups into 2 columns so the panel isn't a tall strip */
@media (min-width: 761px) {
  .settings-groups { column-count: 2; column-gap: 34px; margin-top: 4px; }
  .settings-groups .set-group { break-inside: avoid; }
  .settings-groups .set-group.grp > summary,
  .settings-groups .set-group.grp:first-of-type > summary { padding-top: 12px; }
}
.setting-row .txt { flex: 1; min-width: 0; }
.setting-row .lab { display: block; font-size: 13.5px; font-weight: 500; }
.setting-row .help { display: block; font-size: 12px; color: var(--ink-3); margin-top: 3px; }

/* pricing cards (plans) */
.pricing { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 260px)); gap: 14px; }
.price-card { border: 1px solid var(--line-2); border-radius: var(--r-lg); padding: 18px; background: var(--surface-2); display: flex; flex-direction: column; }
.price-card .pc-name { font-size: 13px; font-weight: 600; text-transform: capitalize; color: var(--ink-2); }
.price-card .pc-price { font: 700 26px/1 var(--mono); letter-spacing: 0; margin: 9px 0 12px; }
.price-card .pc-price small { font: 500 13px var(--sans); color: var(--ink-3); letter-spacing: 0; }
.price-card .pc-feat { display: flex; align-items: center; gap: 8px; font-size: 12.5px; color: var(--ink-2); padding: 5px 0; }
.price-card .pc-feat svg { width: 14px; height: 14px; color: var(--accent); flex-shrink: 0; }

/* calm empty-state mark — small, framed, NEVER reads as a loader.
   Hard-capped so a stale/absent stylesheet can't balloon the inline SVG. */
.empty-ic { width: 56px; height: 56px; flex: none; margin: 0 auto 16px; border-radius: 14px;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  background: var(--surface-3); border: 1px solid var(--line); color: var(--ink-3); }
.empty-ic svg { width: 26px; height: 26px; max-width: 26px; max-height: 26px; }
@media (max-width: 760px) { .empty-ic { width: 48px; height: 48px; } .empty-ic svg { width: 24px; height: 24px; } }

/* amount preset chips (top-up) */
.presets { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; }
.preset { padding: 7px 14px; border-radius: var(--r-sm); background: var(--surface-3); border: 1px solid var(--line); color: var(--ink-2); font: 600 13px var(--mono); cursor: pointer; transition: border-color var(--fast), color var(--fast), background var(--fast); }
.preset:hover { border-color: var(--accent-line); color: var(--ink); }
.preset.on { background: var(--accent-soft); border-color: var(--accent-line); color: var(--accent); }

/* upload progress bar */
.upload-progress { height: 6px; border-radius: 4px; background: var(--surface-3); overflow: hidden; margin-top: 14px; display: none; }
.upload-progress.show { display: block; }
.upload-progress > span { display: block; height: 100%; width: 0; background: var(--accent); border-radius: 4px; box-shadow: 0 0 10px var(--accent-glow); transition: width .18s var(--ease-out); }

/* inert sidebar: no pointer while off-canvas (a11y + no stray clicks) */
.sidebar[inert] { pointer-events: none; }

/* ============ Phase 3 — UX polish ============ */

/* H2 · bot avatar (initial in a status-tinted circle) */
.bot-avatar { width: 28px; height: 28px; border-radius: 50%; flex: none;
  display: inline-flex; align-items: center; justify-content: center;
  font-weight: 600; font-size: 12.5px; background: var(--surface-3); color: var(--ink-2); }
.bot-avatar.clean { background: var(--live-soft); color: var(--live); }
.bot-avatar.ban { background: var(--bad-soft); color: var(--bad); }
.name-cell { display: inline-flex; align-items: center; gap: 10px; min-width: 0; }
.name-cell .row-link { min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* H4 fallback · hover on tables that have no <tbody> */
.table-wrap table tr:hover td { background: rgba(255,255,255,.03); }

/* G3 · sortable headers */
th[data-sort] { cursor: pointer; user-select: none; transition: color var(--fast); }
th[data-sort]:hover { color: var(--ink-2); }
th[data-sort]::after { content: "↕"; opacity: .3; margin-left: 5px; font-size: 10px; }
th.sort-asc::after { content: "↑"; opacity: .8; color: var(--accent); }
th.sort-desc::after { content: "↓"; opacity: .8; color: var(--accent); }

/* G2 · notifications bell dropdown */
.bell-wrap { position: relative; }
.bell-panel { position: absolute; top: calc(100% + 10px); right: 0; width: 328px; max-height: 420px;
  overflow: auto; background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r); box-shadow: 0 20px 48px rgba(0,0,0,.45); z-index: 210;
  opacity: 0; transform: translateY(-6px); pointer-events: none;
  transition: opacity 140ms var(--ease-out), transform 140ms var(--ease-out); }
.bell-panel.show { opacity: 1; transform: none; pointer-events: auto; }
.bell-head { padding: 13px 16px; font-weight: 600; font-size: 13px; border-bottom: 1px solid var(--line-2);
  position: sticky; top: 0; background: var(--surface-2); }
.bell-body { padding: 4px 0; }
.bell-item { display: flex; gap: 11px; padding: 10px 16px; align-items: flex-start; }
.bell-item + .bell-item { border-top: 1px solid var(--line-2); }
.bell-item .ic { flex: none; width: 26px; height: 26px; border-radius: 8px; display: flex; align-items: center;
  justify-content: center; background: var(--live-soft); color: var(--live); }
.bell-item .ic.x { background: var(--bad-soft); color: var(--bad); }
.bell-item .tx { min-width: 0; flex: 1; }
.bell-item .t { font-size: 13px; font-weight: 500; color: var(--ink); }
.bell-item .s { font-size: 11.5px; color: var(--ink-3); margin-top: 2px; }
.bell-item .tm { font-size: 11px; color: var(--ink-3); font-family: var(--mono); white-space: nowrap; }
.bell-empty { padding: 26px 16px; text-align: center; color: var(--ink-3); font-size: 12.5px; }
.bell-foot { display: block; padding: 11px 16px; text-align: center; font-size: 12.5px; font-weight: 500;
  color: var(--accent); border-top: 1px solid var(--line-2); position: sticky; bottom: 0; background: var(--surface-2); }
.bell-foot:hover { background: var(--surface-3); }

/* G4 · keyboard-shortcuts overlay */
.kbd-overlay { position: fixed; inset: 0; z-index: 400; display: none; align-items: center; justify-content: center;
  background: rgba(3,3,4,.66); backdrop-filter: blur(3px); padding: 20px; }
.kbd-overlay.show { display: flex; animation: fadeIn 140ms var(--ease-out); }
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
.kbd-card { width: 100%; max-width: 420px; background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r-lg); padding: 22px 24px; box-shadow: 0 24px 60px rgba(0,0,0,.5); }
.kbd-card h3 { margin: 0 0 16px; font-size: 15px; }
.kbd-row { display: flex; align-items: center; justify-content: space-between; padding: 7px 0; border-bottom: 1px solid var(--line-2); }
.kbd-row:last-child { border-bottom: 0; }
.kbd-row .lbl { font-size: 13px; color: var(--ink-2); }
kbd { display: inline-block; min-width: 20px; text-align: center; padding: 2px 7px; font: 600 11px var(--mono);
  color: var(--ink); background: var(--surface-3); border: 1px solid var(--line); border-bottom-width: 2px;
  border-radius: 6px; margin-left: 4px; }

/* ============ Phase 4 — scale, analytics, features ============ */

/* K1 · pagination */
.pagination { display: flex; align-items: center; justify-content: center; gap: 14px; padding: 16px 0 4px; }
.pg-btn { display: inline-flex; align-items: center; justify-content: center; min-width: 34px; height: 34px;
  padding: 0 12px; border-radius: var(--r-sm); border: 1px solid var(--line); background: var(--surface-3);
  color: var(--ink-2); font-weight: 600; transition: border-color var(--fast), color var(--fast), background var(--fast); }
.pg-btn:hover { border-color: var(--accent-line); color: var(--ink); }
.pg-btn.disabled { opacity: .4; pointer-events: none; }
.pg-info { font-size: 12.5px; color: var(--ink-3); font-variant-numeric: tabular-nums; }

/* M2 · bulk selection */
.col-check { width: 34px; text-align: center; }
.col-check input { cursor: pointer; }
/* the `hidden` attribute (JS toggles it at 0 selected) must win over this
   display:flex — a bare class selector otherwise leaves the empty bar visible. */
.bulk-bar[hidden] { display: none; }
.bulk-bar { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; padding: 11px 14px; margin-bottom: 12px;
  background: var(--accent-soft); border: 1px solid var(--accent-line); border-radius: var(--r-sm); }
.bulk-count { font-size: 13px; color: var(--ink); }
.bulk-controls { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-left: auto; }
.sr-lab { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ink-3); }

/* N3 · onboarding */
.onboarding { margin-bottom: 16px; }
.ob-head { margin-bottom: 14px; }
.ob-title { margin: 0; font-size: 17px; }
.ob-sub { margin: 4px 0 0; color: var(--ink-3); font-size: 13px; }
.ob-steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.ob-steps li { display: flex; align-items: center; gap: 12px; font-size: 13.5px; color: var(--ink-2); }
.ob-steps a { color: var(--ink); }
.ob-steps a:hover { color: var(--accent); }
.ob-num { flex: none; width: 26px; height: 26px; border-radius: 50%; display: inline-flex; align-items: center;
  justify-content: center; font: 700 12px var(--mono); background: var(--surface-3); color: var(--ink-2); border: 1px solid var(--line); }
.ob-steps li.done .ob-num { background: var(--live-soft); color: var(--live); border-color: transparent; }

/* L1 · activity feed */
.feed { list-style: none; margin: 0; padding: 0; }
.feed-item { display: flex; align-items: center; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--line-2); }
.feed-item:last-child { border-bottom: 0; }
.feed-ic { flex: none; width: 24px; height: 24px; border-radius: 7px; display: flex; align-items: center; justify-content: center;
  background: var(--live-soft); color: var(--live); }
.feed-ic.bad { background: var(--bad-soft); color: var(--bad); }
.feed-text { flex: 1; min-width: 0; font-size: 13px; color: var(--ink-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.feed-time { flex: none; font-size: 11.5px; }

/* L2/M3 · inline proportion bar under a label */
.minibar { display: block; height: 3px; margin-top: 5px; border-radius: 2px; background: var(--surface-3); overflow: hidden; }
.minibar > span { display: block; height: 100%; background: var(--accent); border-radius: 2px; }

/* ============ Phase 5 — subscription gating ============ */

/* subscription-expiry banner (spans content, above the page) */
.sub-warning { display: flex; align-items: center; gap: 10px; margin: 0 34px; margin-top: 18px;
  padding: 10px 16px; border-radius: var(--r-sm); font-size: 13px; color: var(--warn);
  background: var(--warn-soft); border: 1px solid color-mix(in srgb, var(--warn) 32%, transparent); }
.sub-warning svg { flex: none; }
.sub-warning b { color: var(--warn); font-variant-numeric: tabular-nums; }
.sub-warning a { margin-left: auto; font-weight: 600; color: var(--accent); white-space: nowrap; }
@media (max-width: 760px) { .sub-warning { margin: 14px 14px 0; } }

/* no-subscription gate */
.gate-wrap { min-height: 60vh; display: flex; align-items: center; justify-content: center; }
.gate-card { max-width: 460px; width: 100%; text-align: center; padding: 34px 30px; }
.gate-ic { width: 60px; height: 60px; margin: 0 auto 18px; border-radius: 16px; display: flex;
  align-items: center; justify-content: center; background: var(--warn-soft); color: var(--warn); }
.gate-title { font-size: 20px; margin: 0 0 10px; }
.gate-sub { color: var(--ink-2); font-size: 13.5px; line-height: 1.6; margin: 0 0 20px; }
.gate-form { display: flex; gap: 10px; }
.gate-form input { flex: 1; text-align: center; font-family: var(--mono); }
.gate-foot { margin: 16px 0 0; font-size: 12.5px; color: var(--ink-3); }
.gate-foot a { color: var(--accent); }
@media (max-width: 560px) { .gate-form { flex-direction: column; } }

/* new-machine landing: the one-time link token, front and centre */
.created-panel { border-color: rgba(53,214,160,.28); background:
  linear-gradient(180deg, rgba(53,214,160,.05), transparent 70%), var(--surface-2); }
.token-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 14px; }
.token-code { font: 600 15px/1 var(--mono); letter-spacing: .08em; padding: 12px 14px;
  background: var(--surface-3); border: 1px solid var(--line-2); border-radius: var(--r-sm);
  user-select: all; word-break: break-all; }

/* danger zone: irreversible actions, visually separated from settings */
.danger-zone { border-color: rgba(255,91,107,.28); }
.danger-zone .ac-title { color: var(--bad); }
