/* ============================================================================
   SAARTHIOS WORKFORCE DESIGN SYSTEM — the portable layer.
   Extracted 2026-10-12 from the Workforce Recruitment console
   (recruitment/console/static/app.css), which remains the source of truth.

   Brand: crimson #ca252b (primary) · blue #1863dc (information) · green #178a52 (success)
          · amber #b7791f (caution — deliberately NOT the alarm colour).
   Type:  the SaarthiOS suite chassis (suite.css, loaded first): Archivo for everything readable,
          headings at a moderately condensed width; Martian Mono, condensed to 75%, for data
          labels and timestamps. Status inks and the corner scale also come from the chassis.

   WHAT IS IN HERE: tokens, typography, the app shell (sidebar + topbar), the "waiting"
   vocabulary (nav rail + skeletons), surfaces (panel/stat/dossier), status stamps, buttons,
   chips, segmented controls, period filter, choice cards, tables, entrance motion, and the
   browser surfaces (selection, focus ring, scrollbar) that otherwise belong to no design system.

   WHAT IS NOT: anything specific to one product — the track switcher, the candidate timeline
   drawer, the Leaflet map, the floating chat widget. Those live in the product's own stylesheet.

   DEPENDENCIES: the three Google fonts (see the <head> block in the guide) and, optionally,
   Tailwind for layout utilities. Every colour here is a CSS custom property, so a product with
   a different brand overrides :root and nothing else.
   ============================================================================ */

:root{
  --paper:#ffffff; --bg:#f4f2ee; --bg-2:#faf9f6; --raise:#ffffff;
  --line:#e7e3db; --line-2:#d9d4ca;
  --ink:#17181c; --ink-soft:#3a3d44; --muted:#6b7178; --faint:#9aa0a8;
  --red:#ca252b; --red-2:#e23b40; --red-deep:var(--s-alarm); --red-soft:#f3d9d8; --red-tint:#fbecec;
  --blue:var(--s-info); --blue-soft:#e4edfb;
  --green:var(--s-ok); --green-soft:#dff0e6;
  /* Amber = "caution, not alarm": allowlisted sending, paused campaigns, SEED chips.
     Distinct from red so a genuine LIVE-SENDING warning still stands out on its own. */
  --amber:#b7791f; --amber-deep:var(--s-warn); --amber-soft:#f2e3c4; --amber-tint:#fdf6e7;
  --p-accent:var(--red); --p-on-accent:#fff; --p-ink:var(--ink); --p-ink-soft:var(--ink-soft); --p-mark-product:var(--red-deep);
  --shadow-sm:0 1px 2px rgba(20,18,16,.05);
  --shadow:0 1px 2px rgba(20,18,16,.05), 0 16px 38px -26px rgba(40,20,12,.32);
}
*{ box-sizing:border-box }
html{ scroll-behavior:smooth }
body{ margin:0; color:var(--ink); background:var(--bg);
  font-family:"Archivo", system-ui, sans-serif; font-size:14px; line-height:1.5;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility; }

/* atmosphere — soft, light ------------------------------------------------- */
.bg-atmos{ position:fixed; inset:0; z-index:-3; pointer-events:none;
  background:
    radial-gradient(110% 70% at 8% -10%, rgba(202,37,43,.07), transparent 55%),
    radial-gradient(80% 60% at 100% -6%, rgba(24,99,220,.05), transparent 52%),
    linear-gradient(180deg,#f6f4f0,#efece6); }
.bg-grid{ position:fixed; inset:0; z-index:-2; pointer-events:none; opacity:.6;
  background-image:
    linear-gradient(rgba(23,24,28,.035) 1px, transparent 1px),
    linear-gradient(90deg, rgba(23,24,28,.035) 1px, transparent 1px);
  background-size:48px 48px; mask-image:radial-gradient(120% 100% at 50% 0%, #000 50%, transparent 100%); }
.bg-grain{ display:none }

/* typography --------------------------------------------------------------- */
.font-display{ font-family:"Archivo",sans-serif; font-variation-settings:"wdth" 86; font-weight:700; letter-spacing:-.01em; }
/* `.display` was used by 13 templates for their page headings and defined NOWHERE, so every
   heading in the console silently fell back to the body face. The brand's display voice was simply
   not on screen. Alias, not a new primitive. */
.display{ font-family:"Archivo",sans-serif; font-variation-settings:"wdth" 86; font-weight:700; letter-spacing:-.015em; }

/* Browser surfaces we did not draw still carry the design: left at their defaults they belong to no
   design system at all. Selection and the focus ring come from the brand, not from Chrome. */
::selection{ background:var(--red-soft); color:var(--red-deep) }
/* "serif" is the same reading face, kept as a class so existing markup keeps working. */
.serif{ font-family:"Archivo", sans-serif; }
h1,h2,h3{ font-family:"Archivo",sans-serif; font-variation-settings:"wdth" 86; font-weight:700; letter-spacing:-.012em; color:var(--ink); }
.kicker{ font-family:"Martian Mono",monospace; font-stretch:75%; font-size:10px; letter-spacing:.22em; text-transform:uppercase; color:var(--faint); }
.num{ font-family:"Martian Mono",monospace; font-stretch:75%; font-variant-numeric:tabular-nums; }
a{ color:inherit; text-decoration:none }

/* masthead ----------------------------------------------------------------- */
.masthead{ position:sticky; top:0; z-index:40; backdrop-filter:blur(8px);
  background:rgba(255,255,255,.86); border-bottom:1px solid var(--line); }
.seal{ height:30px;width:30px;display:grid;place-items:center;border-radius:6px;
  background:var(--p-accent); color:var(--p-on-accent); font-family:"Archivo",sans-serif; font-weight:800; font-variation-settings:"wdth" 75;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.16); }
.navtab{ padding:6px 12px; border-radius:6px; font-family:"Martian Mono",monospace; font-stretch:75%; font-size:10.5px; letter-spacing:.14em; text-transform:uppercase; color:var(--muted); }
.navtab:hover{ color:var(--ink); background:rgba(23,24,28,.04) }
.navtab.on{ color:var(--red); background:var(--red-tint); box-shadow:inset 0 0 0 1px var(--red-soft) }

/* ============================================================================
   The shell: a full-height left column, content to its right.
   The sidebar carries identity (brand at the head, the signed-in account at the foot) and the whole
   nav; the bar above the content carries only where you are and whether we are sending. The track
   dropdown that used to live up there is gone — the sidebar's group header states the scope now, so
   a page can no longer be silently filtered (or, worse, labelled "Organic" over all-track figures).
   ============================================================================ */
:root{ --side-w:246px; --side-w-collapsed:64px; --label:#5f666e; }
.shell{ display:flex; align-items:stretch; min-height:100vh; }
.sidebar{ position:sticky; top:0; align-self:flex-start; flex:0 0 var(--side-w);
  width:var(--side-w); height:100vh; display:flex; flex-direction:column;
  padding:18px 12px 14px; border-right:1px solid var(--line); background:#fdfcfa;
  overflow-y:auto; overflow-x:hidden;
  transition:flex-basis .18s ease, width .18s ease; }
body.nav-collapsed .sidebar{ flex-basis:var(--side-w-collapsed); width:var(--side-w-collapsed); }

.sidebar .brand{ display:flex; align-items:center; gap:11px; padding:2px 12px 0; }
.brand-text{ min-width:0 }
.brand-name{ display:block; font-family:"Archivo",sans-serif; font-weight:600;
  font-size:15.5px; letter-spacing:-.02em; line-height:1.15; white-space:nowrap; }
.brand-sub{ font-family:"Martian Mono",monospace; font-stretch:75%; font-size:10px; letter-spacing:.17em;
  text-transform:uppercase; color:var(--label); white-space:nowrap; }
body.nav-collapsed .brand-text{ display:none }
body.nav-collapsed .sidebar .brand{ justify-content:center; padding:2px 0 0 }

.sidebar nav{ display:flex; flex-direction:column; gap:2px; margin-top:20px; }
.navgroup{ display:flex; flex-direction:column; gap:2px;
  margin-top:16px; padding-top:13px; border-top:1px solid var(--line); }
.grouphead{ display:block; padding:0 12px 7px; font-family:"Martian Mono",monospace; font-stretch:75%;
  font-size:10px; letter-spacing:.2em; text-transform:uppercase; color:var(--label); }
/* Each group is tinted by what it scopes: the track in the brand crimson, the engine in the
   information blue it already uses for cross-track figures. */
.grouphead-track{ color:var(--red-deep) }
.grouphead-engine{ color:var(--blue) }
body.nav-collapsed .grouphead{ font-size:0; padding:0 0 4px }
body.nav-collapsed .grouphead::after{ content:"·"; font-size:13px; letter-spacing:0;
  display:block; text-align:center }

/* One grid per item: a fixed icon column, the label, then whatever rides at the end (the BH Log
   count). A fixed first column is what keeps every label starting at the same x — with a flex row
   it drifted with whatever each icon happened to draw. */
.side-link{ display:grid; grid-template-columns:18px 1fr auto; align-items:center; gap:11px;
  padding:8px 12px; border-radius:6px; min-height:36px; color:var(--ink-soft);
  font-family:"Archivo",sans-serif; font-weight:600; font-size:13.5px;
  transition:background .14s, color .14s; }
.side-label{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.side-link:hover{ color:var(--ink); background:rgba(23,24,28,.05); }
.side-link.on{ color:var(--red-deep); background:var(--red-tint); }
.side-link.on.engine{ color:var(--ink); background:var(--blue-soft); }
.side-link svg{ width:18px; height:18px; }
.side-away{ font-weight:500; color:var(--muted); font-family:"Archivo",sans-serif;
  font-size:13px; }
.side-badge{ margin-left:auto; font-family:"Martian Mono",monospace; font-stretch:75%; font-size:10.5px;
  color:var(--amber-deep); background:var(--amber-tint); border-radius:6px; padding:1px 7px; }
body.nav-collapsed .side-label,
body.nav-collapsed .side-badge{ display:none }
body.nav-collapsed .side-link{ grid-template-columns:18px; justify-content:center;
  padding:8px 0 }

/* The account sits at the foot whatever the nav's length — margin-top:auto, not a fixed height. */
.sidefoot{ margin-top:auto; padding-top:13px; border-top:1px solid var(--line); }
.account{ display:flex; align-items:center; gap:10px; padding:11px 12px 0; }
.avatar{ height:31px; width:31px; flex:0 0 31px; display:grid; place-items:center;
  border-radius:50%; background:#efece6; border:1px solid var(--line-2);
  font-family:"Archivo",sans-serif; font-weight:600; font-size:11.5px;
  color:var(--ink-soft); }
.account-text{ min-width:0 }
.account-name{ display:block; font-size:13px; font-weight:600; line-height:1.3;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.account-role{ font-family:"Martian Mono",monospace; font-stretch:75%; font-size:10.5px; color:var(--muted);
  white-space:nowrap; }
.btn-signout{ display:block; margin:11px 12px 0; padding:8px 11px; min-height:36px;
  text-align:center; font-size:12.5px; color:var(--ink-soft); background:var(--paper);
  border:1px solid var(--line-2); border-radius:6px;
  transition:border-color .14s, color .14s; }
.btn-signout:hover{ border-color:var(--red); color:var(--red-deep); }
body.nav-collapsed .account-text{ display:none }
body.nav-collapsed .account{ justify-content:center; padding:11px 0 0 }
body.nav-collapsed .btn-signout{ margin:11px 0 0; font-size:0; padding:8px 0 }
body.nav-collapsed .btn-signout::after{ content:"⏻"; font-size:13px }

.main-area{ flex:1 1 auto; min-width:0; display:flex; flex-direction:column; }
.topbar{ position:sticky; top:0; z-index:40; display:flex; align-items:center; gap:12px;
  padding:9px 22px; background:rgba(255,255,255,.88); backdrop-filter:blur(8px);
  border-bottom:1px solid var(--line); }
.topbar .grow{ flex:1 1 auto }
.crumb{ font-family:"Martian Mono",monospace; font-stretch:75%; font-size:10.5px; letter-spacing:.16em;
  text-transform:uppercase; color:var(--label); }
.side-toggle{ display:grid; place-items:center; height:34px; width:34px; border-radius:6px;
  color:var(--muted); background:transparent; border:1px solid transparent; cursor:pointer }
.side-toggle:hover{ color:var(--ink); background:rgba(23,24,28,.05); border-color:var(--line) }
.side-toggle svg{ width:19px; height:19px }

/* Send state: the one thing an operator must never have to go and look up. */
.livepill{ display:inline-flex; align-items:center; gap:7px; font-family:"Martian Mono",monospace; font-stretch:75%;
  font-size:11px; letter-spacing:.04em; padding:4px 11px; border-radius:6px;
  color:var(--red-deep); background:var(--red-tint); border:1px solid var(--red-soft); }
.livepill-warn{ color:var(--amber-deep); background:var(--amber-tint);
  border-color:var(--amber-soft); }
.livepill .pulse{ height:7px; width:7px; border-radius:50%; background:var(--red);
  box-shadow:0 0 0 0 rgba(202,37,43,.5); animation:livepulse 2.6s ease-out infinite; }
@keyframes livepulse{ 70%,100%{ box-shadow:0 0 0 7px rgba(202,37,43,0) } }

/* At phone width the column becomes a strip above the content; nothing is sticky or 100vh. */
@media (max-width:820px){
  .shell{ flex-direction:column }
  .sidebar{ position:static; height:auto; width:100%; flex-basis:auto; border-right:0;
    border-bottom:1px solid var(--line) }
  .sidebar nav{ flex-direction:row; flex-wrap:wrap }
  .navgroup{ flex-direction:row; flex-wrap:wrap; align-items:center }
  .grouphead{ padding:0 8px 0 2px }
  .sidefoot{ margin-top:14px; display:flex; align-items:center; gap:10px; flex-wrap:wrap }
  .account{ padding:0 } .btn-signout{ margin:0 }
}

/* ---- Conversation-intelligence page head --------------------------------------------------
   Full width: the title takes the room it needs and the reading time sits at the far end, held
   apart by a hairline so it reads as a fact about the page rather than a caption. */
.ihead{ display:flex; align-items:flex-start; justify-content:space-between; gap:28px;
  flex-wrap:wrap; width:100% }
.iread{ display:flex; flex-direction:column; align-items:flex-end; text-align:right;
  flex:none; padding-left:24px; border-left:1px solid var(--line) }
@media (max-width:720px){
  .iread{ align-items:flex-start; text-align:left; padding:12px 0 0; border-left:0;
    border-top:1px solid var(--line); width:100% }
}

/* Page tabs (Conversation intelligence, Leaderboard): a pill each, the active one in the brand
   colour. Shared because four pages carry them — it lived in two page <style> blocks, and the third
   and fourth page got no styling at all. */
.itab{ display:inline-block; padding:7px 15px; border-radius:6px; font-size:13.5px;
  font-weight:600; font-family:"Archivo",sans-serif; color:var(--ink-soft);
  border:1px solid var(--line-2); background:var(--paper); transition:.14s }
.itab:hover{ border-color:var(--line-2); background:var(--bg-2) }
.itab.on{ background:var(--red-tint); border-color:var(--red-soft); color:var(--red-deep) }

/* The track picker: one closed control for five mutually exclusive options. */
/* A segmented control: one control, N mutually-exclusive states, each carrying its count where the
   count is itself the finding (Strategy's and Campaigns' queues, the Leaderboard's Region/Branch).
   It lives HERE and not in a page's <style> block because four pages use it — the lesson of .itab,
   which was defined in two page blocks and therefore rendered unstyled on the third. */
.seg{ display:flex; flex-wrap:wrap }
.seg > a{ font-family:"Martian Mono",monospace; font-stretch:75%; font-size:12px; padding:7px 14px;
      color:var(--muted); border:1px solid var(--line); background:var(--bg-2);
      white-space:nowrap }
.seg > a:first-child{ border-radius:6px 0 0 6px }
.seg > a:last-child{ border-radius:0 6px 6px 0 }
.seg > a + a{ border-left:0 }
.seg > a:hover{ color:var(--ink); background:var(--paper) }
.seg > a.on{ color:#fff; background:var(--red); border-color:var(--red) }
.seg .c{ margin-left:7px; opacity:.72 }

/* The one-line lede a board carries under its headline: short enough to stay on one line at console
   width, and still allowed to wrap on a phone rather than pushing the page sideways. */
.lede{ font-family:"Archivo",sans-serif; font-size:17px; line-height:1.45;
      color:var(--ink); margin:0 }
.lede b{ font-family:"Archivo",sans-serif; font-weight:600; color:var(--ink);
      font-variant-numeric:tabular-nums }

/* The meaning of the selected segment, spelled out beneath it rather than hidden in a tooltip. */
.qmean{ font-size:12.5px; color:var(--muted); margin:10px 0 }

.trackpick{ font-family:"Martian Mono",monospace; font-stretch:75%; font-size:12px; color:var(--ink);
  background:var(--paper); border:1px solid var(--line-2); border-radius:6px;
  padding:7px 10px; min-height:34px }
.trackpick:hover{ border-color:var(--red) }

/* ============================================================================
   Waiting: the navigation rail, and the skeleton vocabulary.

   Two scales of ONE idea — a crimson segment travelling through a hairline. The rail runs across the
   top of the window while the next document is on its way; a skeleton runs through the shape of the
   content it stands in for. Neither claims progress: the server has not said how far along it is,
   and a percentage we invented is the sort of number this console exists to remove.
   ============================================================================ */
/* The rail itself is always in the DOM (one 2px line, no layout cost) and only moves when the body
   carries data-navigating — set by static/nav.js 140ms after a click, so a fast page never flashes. */
.navrail{ position:fixed; top:0; left:0; right:0; height:4px; z-index:60; pointer-events:none;
  background:transparent; overflow:hidden; opacity:0; transition:opacity .12s ease }
.navrail > i{ position:absolute; inset:0 auto 0 0; width:34%; border-radius:3px;
  background:linear-gradient(90deg, transparent, var(--red-2) 38%, var(--red) 70%, transparent);
  box-shadow:0 0 20px 3px rgba(202,37,43,.6);
  transform:translateX(-120%) }
body[data-navigating] .navrail{ opacity:1 }
/* A crimson glow inside the window's own edge, so the signal is not only a line at the top of a
   screen the reader may not be looking at. Shadow only — it never takes a pointer event and it
   never costs a layout. */
.navveil{ position:fixed; inset:0; z-index:55; pointer-events:none; opacity:0;
  box-shadow:inset 0 0 0 1px rgba(202,37,43,.26), inset 0 0 70px -14px rgba(202,37,43,.42);
  transition:opacity .25s ease }
body[data-navigating] .navveil{ opacity:1 }
/* Exponential ease-out into the sweep and a brief hold at the far end: an instrument settling, not
   a marquee. The loop is the message — it says "still working", not "60% done". */
body[data-navigating] .navrail > i{ animation:railsweep 1.15s cubic-bezier(.16,.84,.26,1) infinite }
@keyframes railsweep{
  0%{ transform:translateX(-120%) } 72%{ transform:translateX(420%) } 100%{ transform:translateX(420%) }
}
/* The outgoing page recedes while it waits: what is on screen describes the page you just left, so
   it should stop looking like an answer. The CONTENT recedes, not the furniture — the bar, the brand
   and the account stay crisp, and neither sticky container is given a filter (a filter makes a
   containing block, which would break the sticky topbar and sidebar). */
body[data-navigating] .pagebody,
body[data-navigating] .sidebar nav{ opacity:.38; filter:blur(1.4px);
  transition:opacity .3s ease, filter .3s ease }

/* ---- Skeletons -----------------------------------------------------------------------------
   A skeleton stands in for content that has not arrived: the same block, the same height, none of
   the numbers. It must never be mistaken for a value, so it carries no text and no digits. */
.sk{ position:relative; overflow:hidden; border-radius:6px; background:#ece9e3 }
.sk::after{ content:""; position:absolute; inset:0;
  background:linear-gradient(90deg, transparent, rgba(255,255,255,.72) 48%, transparent);
  transform:translateX(-100%); animation:skshimmer 1.5s cubic-bezier(.3,.7,.3,1) infinite }
@keyframes skshimmer{ to{ transform:translateX(100%) } }
.sk-line{ height:11px; margin:9px 0 }
.sk-line.lede{ height:15px }
.sk-head{ height:22px; width:42%; margin:0 0 14px; border-radius:6px }
.sk-chip{ display:inline-block; height:24px; width:84px; border-radius:6px; margin:0 6px 6px 0 }
.sk-row{ height:44px; margin:0 0 8px; border-radius:6px }
.sk-figure{ height:30px; width:92px; border-radius:6px }
/* A chart's placeholder: the plot's own box, with a baseline so it reads as an axis rather than a
   blank card. charts.js inserts one per canvas and removes it the moment the chart is drawn. */
.sk-chart{ position:absolute; inset:0; border-radius:6px; background:#f1eee9; overflow:hidden }
.sk-chart::before{ content:""; position:absolute; left:0; right:0; bottom:0; height:1px;
  background:var(--line-2) }
.sk-chart::after{ content:""; position:absolute; inset:0;
  background:linear-gradient(90deg, transparent, rgba(255,255,255,.7) 48%, transparent);
  transform:translateX(-100%); animation:skshimmer 1.5s cubic-bezier(.3,.7,.3,1) infinite }

/* A block whose contents describe the previous question until the answer arrives. */
[data-waiting]{ opacity:.45; transition:opacity .2s ease }

/* Motion is the signal here, so when it is unwelcome the signal becomes a steady state: the rail
   sits still and lit, the skeletons stay as plain blocks. Nothing disappears. */
@media (prefers-reduced-motion:reduce){
  body[data-navigating] .navrail > i{ animation:none; transform:none; width:100% }
  body[data-navigating] .pagebody,
  body[data-navigating] .sidebar nav{ filter:none; transition:none }
  .sk::after, .sk-chart::after{ animation:none; opacity:0 }
}

/* Page-number pager, for lists computed in Python (keyset nav is _cursor_nav.html's job). */
.pager{ display:flex; align-items:center; justify-content:center; gap:14px }
.pg{ font-family:"Martian Mono",monospace; font-stretch:75%; font-size:11.5px; padding:7px 13px; border-radius:6px;
  color:var(--ink-soft); border:1px solid var(--line-2); background:var(--paper) }
.pg:hover{ border-color:var(--red); color:var(--red-deep) }
.pg.off{ color:var(--faint); background:var(--bg-2); border-color:var(--line) }

/* ---- The calendar period filter (Hiring, Conversation intelligence) -------------------------
   Five fixed periods as one segmented control. Shared because two pages now carry it and a second
   copy would drift: the labels ARE the contract ("Last month · Sep 2026"). */
.filterbar{ display:flex; align-items:center; gap:12px; flex-wrap:wrap }
/* Not .kicker: 10px mono at .22em tracking is a data label, and this is a sentence introducing a
   control. The UI face at a readable size reads as an instruction instead. */
.fb-label{ font-family:"Archivo",sans-serif; font-size:13px; font-weight:500;
  color:var(--muted) }
.fb{ font-family:"Martian Mono",monospace; font-stretch:75%; font-size:11.5px; padding:7px 13px;
  color:var(--muted); border:1px solid var(--line); background:var(--bg-2);
  display:flex; align-items:baseline; gap:7px }
.fb:first-child{ border-radius:6px 0 0 6px }
.fb:last-child{ border-radius:0 6px 6px 0 }
.fb + .fb{ border-left:0 }
.fb:hover{ color:var(--ink); background:var(--paper) }
.fb.on{ color:#fff; background:var(--red); border-color:var(--red) }
.fb-l{ font-size:11px; opacity:.75; letter-spacing:.04em }

/* ---- Home: the four track cards ------------------------------------------------------------- */
/* Four tracks, two by two — a fixed 2x2 so the four choices read as one block of four rather than
   reflowing into a 3+1 row at some window widths. One column once two no longer fit. */
.trackgrid{ display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:18px; }
@media (max-width:900px){ .trackgrid{ grid-template-columns:minmax(0,1fr) } }
.trackcard{ display:block; background:var(--paper); border:1px solid var(--line);
  border-radius:12px; padding:23px 25px 20px;
  /* Elevation declared once: a hairline at rest, the shadow only as the lift on hover. */
  transition:transform .22s cubic-bezier(.16,.84,.26,1), box-shadow .22s, border-color .22s;
  animation:cardrise .6s cubic-bezier(.16,.84,.26,1) both;
  animation-delay:calc(var(--i, 0) * 60ms); }
@keyframes cardrise{ from{ opacity:.55; transform:translateY(9px) } }
.trackcard:hover{ transform:translateY(-3px); border-color:var(--line-2);
  box-shadow:0 2px 4px rgba(32,24,18,.04), 0 18px 34px -22px rgba(40,24,14,.34); }
.trackcard-quiet{ background:#fbfaf7 }
.trackcard-quiet .tname{ color:var(--ink-soft) }
.tstate{ display:inline-flex; align-items:center; gap:6px; white-space:nowrap;
  font-family:"Martian Mono",monospace; font-stretch:75%; font-size:10.5px; letter-spacing:.06em;
  border-radius:6px; padding:3px 9px 3px 7px; }
.tstate i{ height:6px; width:6px; border-radius:50%; flex:none }
/* Each state differs in lightness as well as hue, and always carries its word. */
.tstate-jade{ color:#0f6b3f; background:#e8f3ec } .tstate-jade i{ background:var(--green) }
.tstate-blue{ color:#1655bd; background:var(--blue-soft) } .tstate-blue i{ background:var(--blue) }
.tstate-amber{ color:var(--amber-deep); background:var(--amber-tint) }
.tstate-amber i{ background:var(--amber) }
.hair{ height:1px; background:var(--line); margin:15px 0 13px; }
.trows{ display:flex; flex-direction:column; gap:7px; font-size:13px; color:var(--ink-soft); }
.pagelist{ font-family:"Martian Mono",monospace; font-stretch:75%; font-size:10px; letter-spacing:.14em;
  text-transform:uppercase; color:var(--label); line-height:1.5; }
.tgo{ height:31px; width:31px; flex:none; border-radius:50%; border:1px solid var(--line-2);
  display:grid; place-items:center; color:var(--red-deep);
  transition:background .18s, color .18s, border-color .18s, transform .18s; }
.tgo svg{ width:15px; height:15px }
.trackcard:hover .tgo{ background:var(--red); border-color:var(--red); color:#fff;
  transform:translateX(2px); }
@media (prefers-reduced-motion:reduce){
  .trackcard{ animation:none } .livepill .pulse{ animation:none }
  .trackcard:hover{ transform:none } .trackcard:hover .tgo{ transform:none }
}

/* status stamps ------------------------------------------------------------ */
.stamp{ display:inline-flex; align-items:center; gap:.4em; white-space:nowrap;
  font:700 10.5px/1 "Archivo",sans-serif; font-variation-settings:"wdth" 75; letter-spacing:.09em; text-transform:uppercase;
  padding:.42em .6em .38em; border-radius:var(--s-r1); border:1.5px solid currentColor; color:var(--ink-soft); background:transparent; }
.stamp b{ color:inherit; font-weight:800 }
/* Amber is caution and crimson is alarm. They used to share one rule here, so a paused drive
   stamped like a dead fleet. Each now takes its own suite ink. */
.stamp.red, .stamp-bad{ color:var(--s-alarm); background:var(--s-alarm-tint) }
.stamp.amber, .stamp-warn{ color:var(--s-warn); background:var(--s-warn-tint) }
.stamp.jade, .stamp-good{ color:var(--s-ok); background:var(--s-ok-tint) }
.stamp.blue{ color:var(--s-info); background:var(--s-info-tint) }

/* surfaces ----------------------------------------------------------------- */
.panel{ background:var(--paper); border:1px solid var(--line); border-radius:12px; box-shadow:var(--shadow-sm); }
.rule{ height:1px; background:var(--line) }
.dossier{ position:relative; background:var(--paper); border:1px solid var(--line); border-radius:12px; padding:16px;
  transition:.22s cubic-bezier(.2,.7,.2,1); box-shadow:var(--shadow-sm); }
.dossier::before{ content:""; position:absolute; left:0; top:14px; bottom:14px; width:3px; border-radius:3px;
  background:linear-gradient(var(--red),var(--red) 60%, transparent); }
.dossier:hover{ transform:translateY(-3px); border-color:var(--red-soft); box-shadow:var(--shadow); }
.idx{ font-family:"Archivo",sans-serif; font-size:13px; color:var(--faint) }

.stat{ border:1px solid var(--line); border-radius:6px; padding:12px 14px; background:var(--bg-2) }
/* Big metric numbers: clean grotesque with tabular figures — easy to read at a glance. */
.stat .v{ font-family:"Archivo", sans-serif; font-weight:700; font-size:26px; line-height:1;
  color:var(--ink); font-feature-settings:"tnum"; letter-spacing:-.01em }
.stat .l{ font-family:"Martian Mono",monospace; font-stretch:75%; font-size:9px; letter-spacing:.18em; text-transform:uppercase; color:var(--faint); margin-top:6px }

/* buttons ------------------------------------------------------------------ */
.btn-ember{ font-family:"Martian Mono",monospace; font-stretch:75%; font-size:11px; letter-spacing:.06em; padding:8px 14px; border-radius:6px;
  background:linear-gradient(180deg,#e23b40,var(--red)); color:#fff; font-weight:600; border:none; cursor:pointer;
  box-shadow:0 8px 18px -10px var(--red); transition:.16s }
.btn-ember:hover{ transform:translateY(-1px) scale(1.02); box-shadow:0 12px 24px -10px var(--red) }
.btn-ghost{ font-family:"Martian Mono",monospace; font-stretch:75%; font-size:11px; padding:7px 12px; border-radius:6px; border:1px solid var(--line-2); color:var(--muted); background:var(--paper); cursor:pointer }
.btn-ghost:hover{ color:var(--red); border-color:var(--red) }
/* Neutral default button. Pages built later used a bare `.btn` that was never defined,
   so those controls rendered as unstyled browser buttons. */
.btn{ font-family:"Martian Mono",monospace; font-stretch:75%; font-size:11px; padding:7px 12px; border-radius:6px;
  border:1px solid var(--line-2); color:var(--ink-soft); background:var(--paper); cursor:pointer; transition:.16s }
.btn:hover{ border-color:var(--red-soft); color:var(--red) }
/* Destructive action (global stop, permanent campaign stop) — reads as a warning at rest,
   not only on hover, because these are the two clicks you cannot take back. */
.btn-danger{ border-color:var(--red-soft); color:var(--red-deep); background:var(--red-tint) }
.btn-danger:hover{ background:var(--red); color:#fff; border-color:var(--red) }
/* Selectable filter chip (cohort dimensions on Configure, wave-size presets). `.chip` was
   used by the templates but never defined, so every one of those controls rendered as a
   default browser button — which is why the filter row looked unfinished. */
.chip{ font-family:"Martian Mono",monospace; font-stretch:75%; font-size:10.5px; letter-spacing:.04em;
  padding:5px 10px; border-radius:6px; border:1px solid var(--line-2);
  color:var(--muted); background:var(--paper); cursor:pointer; transition:.14s; user-select:none }
.chip:hover{ border-color:var(--red-soft); color:var(--red) }
.chip.active{ border-color:var(--red); color:var(--red); background:var(--red-tint); font-weight:600 }

/* Icon-only control (the ⏸ ▶ ■ row) — a tap target, not a link. */
.btn-icon{ border:1px solid transparent; border-radius:6px; padding:4px 8px; color:var(--muted);
  background:transparent; cursor:pointer; transition:.14s; font-size:13px; line-height:1 }
.btn-icon:hover{ color:var(--red); border-color:var(--red-soft); background:var(--red-tint) }

.live-dot{ display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--green);
  box-shadow:0 0 0 0 rgba(23,138,82,.55); animation:pulse 1.8s infinite }
@keyframes pulse{ 0%{box-shadow:0 0 0 0 rgba(23,138,82,.45)} 70%{box-shadow:0 0 0 7px rgba(23,138,82,0)} 100%{box-shadow:0 0 0 0 rgba(23,138,82,0)} }

.bar{ width:100%; border-radius:3px 3px 0 0; transform-origin:bottom; animation:grow .8s cubic-bezier(.2,.8,.2,1) both; }
@keyframes grow{ from{transform:scaleY(.02)} to{transform:scaleY(1)} }

/* tables ------------------------------------------------------------------- */
table{ width:100%; border-collapse:collapse }
thead th{ font-family:"Martian Mono",monospace; font-stretch:75%; font-size:9.5px; letter-spacing:.16em; text-transform:uppercase; color:var(--faint); text-align:left; padding:10px 12px; }
tbody td{ padding:10px 12px; border-top:1px solid var(--line) }
tbody tr:hover{ background:var(--red-tint) }

/* orchestrated entrance ---------------------------------------------------- */
.reveal{ animation:rise .7s cubic-bezier(.2,.75,.2,1) both; animation-delay:calc(var(--i,0)*55ms + 70ms) }
@keyframes rise{ from{opacity:0; transform:translateY(13px)} to{opacity:1; transform:none} }
.fade{ animation:fade .8s ease both }

@keyframes fade{ from{opacity:0} to{opacity:1} }
@media (prefers-reduced-motion:reduce){ .reveal,.fade,.bar,.live-dot{ animation:none !important } }

/* browser surfaces ---------------------------------------------------------- */

::-webkit-scrollbar{ width:10px; height:10px }
::-webkit-scrollbar-thumb{ background:#d8d4cc; border-radius:6px; border:2px solid var(--bg) }
input[type=range]{ accent-color:var(--red) }
select,input{ font-family:"Martian Mono",monospace; font-stretch:75%; color:var(--ink) }
