/* ============================================================================
   oneshot.css: the Resolens design system, INSTRUMENT direction (2026-09-30)

   The product is drawn as a piece of hardware: a dotted-grid CHASSIS, flat PANELS
   bolted onto it (3px corners, one 14px chamfer top-right), a label TAB on a panel's
   top-left edge, dark READOUT screens with dot-matrix numerals for counts and money,
   round LEDs for state, and KEYS with 3px of travel. One signal colour (orange) marks
   the thing to press and the live figure; green/red LEDs carry pass/fail only.

   Faces: Silkscreen (pixel: page titles, section heads, brand), Doto (dot-matrix:
   readout figures >= 24px only), JetBrains Mono (labels, data, keys), Inter (reading).

   Theming contract (three states), unchanged:
   - bare :root          = the COMPLETE light palette
   - @media dark, guarded :root:not([data-theme="light"])  = token overrides only
   - :root[data-theme="dark"]                              = the same overrides
   No colour exists only inside a dark block. body paints an explicit token bg.

   GRID + SCALE. Spacing is the 4px grid (--s1..--s8); panels pad 22/26 desk, 16 phone,
   and stack 12px apart (--s3). Type: pixel titles clamp(28,5vw,48); pixel section
   heads 18-22; readout figures 24-54 (Doto 900); labels/tabs mono 650 9.5-11 caps
   tracked .12-.16em; reading text Inter 13-16.

   COMPONENT INDEX (all class names stable; new ones are additive)
     chassis ........ body, main, header.site (segmented nav switch), footer.site
     .card / .panel . the panel. Variants: .hero .flush .inset .quiet .ops, a.card
     .tab ........... ink label plate (+ .ix index in signal). Pinned on a panel's edge
                      automatically when it is the panel's first child, and any
                      `.card > h2:first-child` becomes a numbered tab (page counter)
     .led ........... round indicator: (unlit) .ok .warn .amber .live(blinks) .big
     .status ........ an LED + one word in ink (never a coloured pill): .ok .warn .live .dim
     .readout ....... dark screen, <b> figure + <span> legend. b.ink b.ok b.warn,
                      .zero / b.zero = dim (a reading of 0 is never orange); .sm
     .readouts ...... a row of readout windows (auto-fit grid)
     .gauge ......... 20-cell segmented bar, --v 0..1, --gc lit colour
     .meter ......... the analog dial on a readout screen (certificate)
     .spec .serial .. mono hardware labelling lines
     .switch ........ segmented selector (LED per position); a[aria-current] is lit
     keys ........... .btn (ink) .ghost (paper) .runbtn (money, signal) .seam (not yet);
                      one voice: mono caps 11.5px on 3px of travel
     .tabmeta ....... mono meta on a panel's top edge, opposite its tab
     .pagehead ...... pixel title + sub + 2px rule; .objhead for a data object
     .sechead ....... mono label + dotted rule to the edge (+ .n count, .act)
     .stat/.statrow . figure on paper (non-screen) for secondary numbers
     .kv ............ label / value line with a dashed rule
     .callout ....... note with a 4px bar (.warn .link .ok)
     .ledger/.tape .. the wallet tape: perforated roll, one printed line per entry
     .tbl table.ops . data tables (ink 2px head rule); .tbl-scroll keeps page from scrolling
     .emptystate .skel .rise .chip dialog #toast
   ========================================================================== */

/* ---------------------------------------------------------------- tokens -- */
:root{
  /* chassis, panels, wells */
  --paper:#E4E3DD; --card:#F7F6F2; --well:#ECEBE5;
  --ink:#161614; --ink2:#44443C; --ink3:#595951;
  --line:#CBCAC2; --line-soft:#E1E0D9;
  --dot:rgba(22,22,20,.13);
  /* keys */
  --btn:#161614; --btn-hover:#000000; --btn-ink:#F7F6F2; --key-edge:#000000;
  --key2:#F7F6F2; --key2-edge:#B9B8B0;
  /* the ONE signal colour: fills (with ink on it) and, a step darker, text */
  --sig:#FF5B1F; --on-sig:#161614; --sig-edge:#B8360A;
  --link:#9A2E05; --link-soft:#FBE3D8;
  --sig-lg:#C2410C;   /* signal as LARGE display text (>=24px) on paper: 3:1+ */
  /* semantic: pass / fail; never chrome */
  --ok:#136A42; --ok-soft:#DCEFE3;
  --warn:#B0261D; --warn-soft:#F8DFDB;
  --acc:var(--link); --acc-soft:var(--link-soft); --on-acc:#FFFFFF;
  /* LEDs (fills only; the word beside an LED is always ink) */
  --led-ok:#1ECB6B; --led-warn:#FF3B2F; --led-live:#FF5B1F; --led-amber:#FFB020;
  --led-off:#B4B3AB;
  /* the readout screen: dark in both themes */
  --scr:#151513; --scr-ink:#F2F1EB; --scr-dim:#A3A298; --scr-sig:#FF7A3D;
  --scr-ok:#57E394; --scr-warn:#FF7B6E; --scr-line:rgba(255,255,255,.08);
  /* character hexes unchanged (character-owned) */
  --scout:#96601E;   --scout-soft:#F4E9D8;
  --pulse:#B5455A;   --pulse-soft:#F5E3E7;
  --deepen:#33619E;  --deepen-soft:#E7EDF6;
  --verify:#0A7A64;  --verify-soft:#E3F1EC;
  --connect:#7A5AA0; --connect-soft:#EEE8F5;   /* key 'connect', displayed as Reveal */
  --resolve:#237373; --resolve-soft:#E2F1F1;
  --watch:#76807A;   --watch-soft:#EFF1ED;
  --dark:#151513; --on-dark:#E8E9E3;       /* the always-dark surfaces: log, toast */
  --log-st:#FF9A66;
  --shadow-1:none;
  --shadow-2:0 10px 30px rgba(0,0,0,.16);
  --shadow-3:0 18px 50px rgba(0,0,0,.28);
  --shadow-hover:none;
  --display:'Silkscreen',ui-monospace,monospace;
  --dots:'Doto','JetBrains Mono',ui-monospace,monospace;
  --sans:'Inter',-apple-system,'Segoe UI',system-ui,sans-serif;
  --mono:'JetBrains Mono',ui-monospace,'SF Mono',Menlo,monospace;
  /* shape */
  --r-tag:2px; --r-chip:3px; --r-input:3px; --r-card:3px; --r-hero:3px; --r-key:4px;
  --cut:14px; --cut-s:7px;
  --chamfer:polygon(0 0,calc(100% - var(--cut)) 0,100% var(--cut),100% 100%,0 100%);
  --w-read:760px; --w-page:980px; --w-wide:1120px;
  --s1:4px; --s2:8px; --s3:12px; --s4:16px; --s5:24px; --s6:32px; --s7:48px; --s8:64px;
  --ease:cubic-bezier(.2,.7,.2,1); --t-fast:.12s; --t:.2s;
  --ring:0 0 0 3px color-mix(in srgb,var(--sig) 45%,transparent);
  --header-h:60px;
  --stamp-blend:multiply;
  --tab-ix:#FF7A3D;   /* the index on an ink tab (tab is dark in light mode) */
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --paper:#0E0E0D; --card:#1A1A18; --well:#131312;
    --ink:#EEEDE7; --ink2:#B6B5AD; --ink3:#908F87;
    --line:#383733; --line-soft:#282825;
    --dot:rgba(255,255,255,.075);
    --btn:#EEEDE7; --btn-hover:#FFFFFF; --btn-ink:#121211; --key-edge:#77766F;
    --key2:#24241F; --key2-edge:#050505;
    --sig:#FF6A2B; --on-sig:#121211; --sig-edge:#9C300A;
    --link:#FF9160; --link-soft:#3A1E10; --sig-lg:#FF6A2B;
    --ok:#5BDB94; --ok-soft:#10301F;
    --warn:#FF8175; --warn-soft:#3B1613;
    --on-acc:#121211;
    --led-off:#4A4944;
    --scr:#070707; --scr-line:rgba(255,255,255,.07);
    --scout:#CD9A55;   --scout-soft:#3A2C16;
    --pulse:#D98A97;   --pulse-soft:#3B1B22;
    --deepen:#82A6D9;  --deepen-soft:#1B2A40;
    --verify:#41A98D;  --verify-soft:#12382B;
    --connect:#A98FD0; --connect-soft:#2C2140;
    --resolve:#5AB5B5; --resolve-soft:#123434;
    --watch:#8C958B;   --watch-soft:#242B24;
    --shadow-2:0 10px 30px rgba(0,0,0,.55);
    --shadow-3:0 18px 50px rgba(0,0,0,.7);
    --stamp-blend:normal;
    --tab-ix:#A8330A;
  }
}
:root[data-theme="dark"]{
  --paper:#0E0E0D; --card:#1A1A18; --well:#131312;
  --ink:#EEEDE7; --ink2:#B6B5AD; --ink3:#908F87;
  --line:#383733; --line-soft:#282825;
  --dot:rgba(255,255,255,.075);
  --btn:#EEEDE7; --btn-hover:#FFFFFF; --btn-ink:#121211; --key-edge:#77766F;
  --key2:#24241F; --key2-edge:#050505;
  --sig:#FF6A2B; --on-sig:#121211; --sig-edge:#9C300A;
  --link:#FF9160; --link-soft:#3A1E10; --sig-lg:#FF6A2B;
  --ok:#5BDB94; --ok-soft:#10301F;
  --warn:#FF8175; --warn-soft:#3B1613;
  --on-acc:#121211;
  --led-off:#4A4944;
  --scr:#070707; --scr-line:rgba(255,255,255,.07);
  --scout:#CD9A55;   --scout-soft:#3A2C16;
  --pulse:#D98A97;   --pulse-soft:#3B1B22;
  --deepen:#82A6D9;  --deepen-soft:#1B2A40;
  --verify:#41A98D;  --verify-soft:#12382B;
  --connect:#A98FD0; --connect-soft:#2C2140;
  --resolve:#5AB5B5; --resolve-soft:#123434;
  --watch:#8C958B;   --watch-soft:#242B24;
  --shadow-2:0 10px 30px rgba(0,0,0,.55);
  --shadow-3:0 18px 50px rgba(0,0,0,.7);
  --stamp-blend:normal;
  --tab-ix:#A8330A;
}

/* ------------------------------------------------------------------ base -- */
*,*::before,*::after{box-sizing:border-box}
html,body{overflow-x:clip}   /* the whoosh flies characters 120vw offscreen */
/* the chassis: a 16px dot grid on the paper token, painted on body */
body{margin:0;color:var(--ink);font:15px/1.6 var(--sans);
  background-color:var(--paper);
  background-image:radial-gradient(circle at 1px 1px,var(--dot) 1px,transparent 1.4px);
  background-size:16px 16px;
  min-height:100vh;display:flex;flex-direction:column}
::selection{background:var(--sig);color:var(--on-sig)}
a{color:var(--link);text-underline-offset:3px;text-decoration-thickness:1px}
code,kbd{font-family:var(--mono);font-size:.93em}
[id]{scroll-margin-top:calc(var(--header-h) + 16px)}
:focus-visible{outline:2px solid var(--sig);outline-offset:2px}
h1{font:400 clamp(28px,5vw,48px)/1.1 var(--display);letter-spacing:.01em;
   margin:8px 0 6px;text-wrap:balance}
.pagehead h1,#empty h1{text-transform:uppercase}
h2{font:650 10.5px/1.4 var(--mono);letter-spacing:.12em;text-transform:uppercase;
   color:var(--ink3);margin:28px 0 8px}
h3{font:650 13.5px/1.4 var(--sans);margin:14px 0 6px}
.eyebrow{font:650 10px/1 var(--mono);letter-spacing:.16em;text-transform:uppercase;color:var(--ink3)}

/* ---------------------------------------------------------- site chrome -- */
/* The header MARKUP is pinned to the byte (tests/auth/test_account_page.py): every
   bit of the faceplate is CSS plus the body[data-section] attribute. The bar is a
   panel strip; the nav is a segmented hardware switch, one LED per position. */
header.site{position:sticky;top:0;z-index:50;min-height:var(--header-h);
  display:flex;align-items:center;flex-wrap:wrap;gap:8px 14px;padding:10px 24px;
  background:var(--card);border-bottom:2px solid var(--ink)}
header.site .brand{font:400 18px/1 var(--display);letter-spacing:.04em;text-transform:uppercase;
  display:flex;align-items:center;gap:10px}
header.site .brand a{color:inherit;text-decoration:none;display:inline-block;padding:4px 0}
/* the power LED in front of the name */
header.site .brand::before{content:"";width:10px;height:10px;border-radius:50%;flex:none;
  background:var(--led-live);box-shadow:0 0 0 2px color-mix(in srgb,var(--led-live) 25%,transparent),
    0 0 10px color-mix(in srgb,var(--led-live) 70%,transparent)}
header.site .brand span{color:var(--ink3)}
/* the model plate */
header.site .brand::after{content:"RL\2011 01";font:650 9px/1 var(--mono);letter-spacing:.14em;
  color:var(--ink3);border:1px solid var(--line);padding:4px 5px;border-radius:2px}
header.site nav{margin-left:auto;display:flex;gap:0;padding:3px;border-radius:var(--r-key);
  background:var(--well);box-shadow:inset 0 0 0 1px var(--line)}
header.site nav a{position:relative;display:inline-flex;align-items:center;gap:8px;
  font:650 10.5px/1 var(--mono);letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink2);text-decoration:none;padding:9px 12px;
  border-radius:3px;white-space:nowrap;
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease)}
header.site nav a::before{content:"";width:6px;height:6px;border-radius:50%;flex:none;
  background:var(--led-off);transition:background var(--t) var(--ease),box-shadow var(--t) var(--ease)}
header.site nav a:hover{color:var(--ink);background:color-mix(in srgb,var(--card) 60%,transparent)}
body[data-section="console"] header.site nav a[href="/"],
body[data-section="runs"] header.site nav a[href="/runs"],
body[data-section="verify"] header.site nav a[href="/verify"],
body[data-section="account"] header.site nav a[href="/account"],
body[data-section="welcome"] header.site nav a[href="/welcome"]{color:var(--ink);background:var(--card);
  box-shadow:0 1px 0 var(--key2-edge),inset 0 0 0 1px var(--line)}
body[data-section="console"] header.site nav a[href="/"]::before,
body[data-section="runs"] header.site nav a[href="/runs"]::before,
body[data-section="verify"] header.site nav a[href="/verify"]::before,
body[data-section="account"] header.site nav a[href="/account"]::before,
body[data-section="welcome"] header.site nav a[href="/welcome"]::before{background:var(--led-live);
  box-shadow:0 0 8px color-mix(in srgb,var(--led-live) 80%,transparent)}
header.site .tag{margin-left:auto;min-width:0;overflow:hidden;text-overflow:ellipsis;
  font:600 9.5px/1 var(--mono);letter-spacing:.1em;text-transform:uppercase;
  color:var(--ink3);text-align:right;white-space:nowrap}
@media(max-width:640px){
  header.site{padding:8px 16px;gap:6px 8px}
  header.site .brand{order:0;font-size:15px}
  header.site .brand::after{display:none}
  header.site .walletchip{order:1;margin-left:auto}
  header.site nav{order:2;flex:1 0 100%;overflow-x:auto;scrollbar-width:none}
  header.site nav::-webkit-scrollbar{display:none}
  header.site nav a{padding:8px 9px;gap:6px;flex:1 0 auto;justify-content:center}
  /* flag-off chrome (no chip): the switch stays on the brand row */
  header.site:not(:has(.walletchip)) nav{flex:0 1 auto;order:1;margin-left:auto}
  body:has(header.site .walletchip){--header-h:100px}
}
@media(max-width:380px){
  header.site .brand{font-size:13px;gap:6px}
  header.site .brand a{gap:6px}
  header.site nav a{padding:8px 6px;letter-spacing:.06em;gap:5px}
  header.site nav a::before{width:5px;height:5px}
}
main{max-width:var(--w-wide);width:100%;flex:1 0 auto;margin:0 auto;padding:28px 28px 80px}
@media(max-width:640px){ main{padding:20px 16px 60px} }
body #consoleroot.mocking #pillrow{top:var(--header-h)}

/* the footer: a serial plate on the chassis */
footer.site{max-width:none;width:100%;margin:56px 0 0;padding:18px 28px 28px;text-align:center;
  border-top:1px solid var(--line);background:var(--card);
  font:400 10.5px/1.6 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--ink3)}
footer.site .signout{display:inline}
footer.site .signout button{background:none;border:none;box-shadow:none;padding:4px 2px;color:var(--ink3);
  font:600 10.5px/1.6 var(--mono);letter-spacing:.08em;text-transform:uppercase;text-decoration:underline;
  text-underline-offset:2px;cursor:pointer;min-height:0}
footer.site .signout button:hover{background:none;color:var(--ink)}
footer.site .legal{display:flex;justify-content:center;flex-wrap:wrap;gap:4px 20px;margin-bottom:6px}
footer.site .legal a{color:var(--ink2);text-decoration:none;padding:4px 2px;
  font:600 10.5px/1.6 var(--mono);letter-spacing:.08em;
  transition:color var(--t-fast) var(--ease)}
footer.site .legal a:hover{color:var(--ink);text-decoration:underline;text-underline-offset:3px}
@media(min-width:900px){
  footer.site{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;
    gap:8px 24px;padding:16px max(28px,calc((100vw - var(--w-wide)) / 2 + 28px));text-align:left}
  footer.site .legal{justify-content:flex-start;margin:0 0 0 -2px}
}
.grid{display:grid;grid-template-columns:1fr 1fr;gap:14px}
@media(max-width:820px){ .grid{grid-template-columns:1fr} }

/* --------------------------------------------------------- panels & chips -- */
/* .card IS the panel: flat, borderless on the chassis, square with one chamfer */
.card,.panel{position:relative;background:var(--card);border:0;border-radius:var(--r-card);
  padding:20px 22px;margin:12px 0;clip-path:var(--chamfer);
  box-shadow:inset 0 0 0 1px var(--line-soft)}
.chip{display:inline-flex;align-items:center;height:20px;vertical-align:middle;
  font:650 10px/1 var(--mono);letter-spacing:.06em;text-transform:uppercase;padding:4px 7px;
  border-radius:var(--r-chip);background:var(--link-soft);color:var(--link);white-space:nowrap}
.chip.ink{background:var(--ink);color:var(--paper)}
.chip.ok{background:var(--ok-soft);color:var(--ok)}
.chip.warn{background:var(--warn-soft);color:var(--warn)}
.chip.warn{height:auto;min-height:20px;max-width:100%;white-space:normal;
  overflow-wrap:anywhere;line-height:12px;text-transform:none;letter-spacing:0}
.chip.dim{background:var(--well);color:var(--ink2);box-shadow:inset 0 0 0 1px var(--line)}
.walletchip{font-variant-numeric:tabular-nums;text-decoration:none}
/* the header balance: a small readout window */
header.site .walletchip{height:30px;padding:0 10px;font:650 12px/1 var(--mono);margin-left:6px;
  background:var(--scr);color:var(--scr-sig);border-radius:3px;letter-spacing:.04em;
  box-shadow:inset 0 0 0 1px var(--scr-line)}
header.site .walletchip.dim{color:var(--scr-dim);background:var(--scr)}
header.site .walletchip.warn{color:var(--scr-warn);background:var(--scr)}
header.site .walletchip:hover{box-shadow:inset 0 0 0 1px var(--scr-sig)}

/* ------------------------------------------------ the instrument set -- */
/* .tab: the label that sits ON a panel's top edge (ink plate, chamfered end).
   Inside a padded .card it is pulled to the edge with the card's own padding. */
.tab{display:inline-flex;align-items:center;gap:8px;height:24px;padding:0 14px 0 10px;
  background:var(--ink);color:var(--card);font:650 10px/1 var(--mono);letter-spacing:.14em;
  text-transform:uppercase;white-space:nowrap;
  clip-path:polygon(0 0,100% 0,100% calc(100% - var(--cut-s)),calc(100% - var(--cut-s)) 100%,0 100%)}
.tab .ix{color:var(--tab-ix)}
/* .led: a round indicator. Colours: .ok .warn .live .amber, default unlit */
.led{display:inline-block;flex:none;width:8px;height:8px;border-radius:50%;background:var(--led-off);
  box-shadow:inset 0 -1px 1px rgba(0,0,0,.25);vertical-align:middle}
.led.ok{background:var(--led-ok);box-shadow:0 0 8px color-mix(in srgb,var(--led-ok) 70%,transparent)}
.led.warn{background:var(--led-warn);box-shadow:0 0 8px color-mix(in srgb,var(--led-warn) 70%,transparent)}
.led.amber{background:var(--led-amber);box-shadow:0 0 8px color-mix(in srgb,var(--led-amber) 70%,transparent)}
.led.live{background:var(--led-live);box-shadow:0 0 8px color-mix(in srgb,var(--led-live) 80%,transparent);
  animation:ledblink 1.2s steps(2,end) infinite}
/* .readout: the dark screen. b = the figure (dot-matrix), span = the legend */
.readout{position:relative;background:var(--scr);color:var(--scr-ink);border-radius:3px;
  padding:14px 16px 12px;min-width:0;
  background-image:repeating-linear-gradient(0deg,var(--scr-line) 0 1px,transparent 1px 3px);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.05),inset 0 10px 30px rgba(0,0,0,.45)}
.readout b{display:block;font:900 clamp(30px,4.2vw,44px)/1 var(--dots);letter-spacing:.02em;
  color:var(--scr-sig);font-variant-numeric:tabular-nums;white-space:nowrap;
  text-shadow:0 0 14px color-mix(in srgb,var(--scr-sig) 45%,transparent)}
.readout b.ink{color:var(--scr-ink);text-shadow:0 0 12px rgba(255,255,255,.18)}
.readout b.ok{color:var(--scr-ok);text-shadow:0 0 14px color-mix(in srgb,var(--scr-ok) 40%,transparent)}
.readout b.warn{color:var(--scr-warn);text-shadow:0 0 14px color-mix(in srgb,var(--scr-warn) 40%,transparent)}
.readout span{display:flex;align-items:center;gap:7px;margin-top:9px;font:650 9.5px/1.3 var(--mono);
  letter-spacing:.14em;text-transform:uppercase;color:var(--scr-dim)}
/* .gauge: a segmented bar, 20 cells, lit to --v (0..1); --gc sets the lit colour */
.gauge{--v:0;--gc:var(--sig);position:relative;height:18px;background:var(--line-soft);
  -webkit-mask-image:repeating-linear-gradient(90deg,#000 0 calc(5% - 3px),transparent calc(5% - 3px) 5%);
  mask-image:repeating-linear-gradient(90deg,#000 0 calc(5% - 3px),transparent calc(5% - 3px) 5%)}
.gauge::after{content:"";position:absolute;inset:0 auto 0 0;width:calc(var(--v) * 100%);background:var(--gc)}
/* .spec: a mono key/value line with an LED, for the instrument's spec blocks */
.spec{display:flex;align-items:center;gap:8px;font:650 10px/1.5 var(--mono);letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink2)}

/* A panel whose first child is an h2 wears that h2 as its TAB: pinned to the top-left
   edge, ink plate, a running section number from the page's counter. */
body{counter-reset:panel}
.card:has(> h2:first-child){padding-top:54px}
.card > h2:first-child{counter-increment:panel;position:absolute;top:0;left:0;margin:0;display:inline-flex;
  align-items:center;gap:8px;height:24px;padding:0 14px 0 10px;background:var(--ink);color:var(--card);
  font:650 10px/1 var(--mono);letter-spacing:.14em;
  clip-path:polygon(0 0,100% 0,100% calc(100% - 7px),calc(100% - 7px) 100%,0 100%)}
.card > h2:first-child::before{content:counter(panel,decimal-leading-zero);color:var(--tab-ix)}
.card > h2:first-child::after{display:none}
/* the same pinning for an explicit .tab (any label, not only an h2): the first child of
   a panel rides its top-left edge, and the panel makes room under it */
:is(.card,.panel):has(> .tab:first-child){padding-top:50px}
:is(.card,.panel) > .tab:first-child{position:absolute;top:0;left:0;margin:0}
/* a tab's right-hand companion: a mono meta line on the same edge (count, id, date) */
.tabmeta{position:absolute;top:0;right:26px;height:24px;display:flex;align-items:center;gap:8px;
  font:650 10px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--ink3);
  font-variant-numeric:tabular-nums}
@media(max-width:640px){ :is(.card,.panel):has(> .tab:first-child){padding-top:44px}
  .card:has(> h2:first-child){padding-top:46px} .tabmeta{right:18px} }

/* .readouts: a row of readout windows. .readout.sm drops the figure to the 24px floor */
.readouts{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:8px}
.readout.sm b{font-size:clamp(24px,3vw,30px)}
.readout.word b{font-family:var(--display);font-weight:400;font-size:clamp(20px,2.4vw,26px);
  letter-spacing:.02em;text-transform:uppercase}
.readout .led{margin-right:2px}
/* .led.big: a panel lamp */
.led.big{width:14px;height:14px}
/* .switch: a segmented hardware selector, one LED per position; the current one is lit */
.switch{display:inline-flex;flex-wrap:wrap;gap:0;padding:3px;border-radius:var(--r-key);
  background:var(--well);box-shadow:inset 0 0 0 1px var(--line);max-width:100%}
.switch > a,.switch > button{position:relative;display:inline-flex;align-items:center;gap:8px;
  font:650 10.5px/1 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--ink2);
  text-decoration:none;padding:9px 12px;border:0;border-radius:3px;background:transparent;box-shadow:none;
  white-space:nowrap;transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease)}
.switch > a::before,.switch > button::before{content:"";width:6px;height:6px;border-radius:50%;flex:none;
  background:var(--led-off)}
.switch > a:hover{color:var(--ink);background:color-mix(in srgb,var(--card) 60%,transparent)}
.switch > [aria-current],.switch > [aria-pressed="true"]{color:var(--ink);background:var(--card);
  box-shadow:0 1px 0 var(--key2-edge),inset 0 0 0 1px var(--line)}
.switch > [aria-current]::before,.switch > [aria-pressed="true"]::before{background:var(--led-live);
  box-shadow:0 0 8px color-mix(in srgb,var(--led-live) 80%,transparent)}

/* ------------------------------------------------ v2 shared components -- */
/* 1. .pagehead: section pages. Pixel title on the chassis, a rule under it */
.pagehead{margin:6px 0 30px;padding-bottom:18px;border-bottom:2px solid var(--ink)}
.pagehead .eyebrow{display:block;margin-bottom:10px}
.pagehead h1{margin:0 0 10px}
.pagehead .sub{font-size:15.5px;line-height:1.6;color:var(--ink2);max-width:60ch;margin:0}
.pagehead-row{display:flex;align-items:flex-end;justify-content:space-between;gap:16px;flex-wrap:wrap}

/* 2. .objhead: a data object */
.objhead{margin:6px 0 24px}
.objhead .eyebrow{display:block}
.objtitle{font:650 clamp(22px,3vw,30px)/1.2 var(--sans);letter-spacing:-.015em;
  margin:6px 0 8px;text-wrap:balance;overflow-wrap:break-word}
.objmeta{display:flex;flex-wrap:wrap;gap:6px 10px;align-items:center;
  font:400 11.5px/1.5 var(--mono);color:var(--ink3);font-variant-numeric:tabular-nums}
.objmeta .sep::before{content:"·"}

/* 3. .sechead: a label with a rule to the edge */
.sechead{display:flex;align-items:center;gap:12px;margin:36px 0 12px}
.sechead h2,.sechead .lbl{margin:0}
.sechead .lbl{font:650 10.5px/1.4 var(--mono);letter-spacing:.12em;text-transform:uppercase;color:var(--ink2)}
.sechead .n{font:650 10.5px/1.4 var(--mono);color:var(--ink);font-variant-numeric:tabular-nums;
  background:var(--card);padding:2px 6px;border-radius:2px;box-shadow:inset 0 0 0 1px var(--line)}
.sechead::after{content:"";flex:1;height:2px;background:repeating-linear-gradient(90deg,var(--line) 0 2px,transparent 2px 5px);order:1}
.sechead .act{order:2;margin-left:0}

/* 4. .stat / .statrow: the figure treatment, dot-matrix for the figure */
.statrow{display:flex;flex-wrap:wrap;gap:20px 36px;align-items:flex-end}
.stat{min-width:0}
.stat b{display:block;font:900 32px/1 var(--dots);font-variant-numeric:tabular-nums;
  letter-spacing:.01em;color:var(--ink)}
.stat span{display:block;margin-top:8px;font:650 10px/1.3 var(--mono);letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink3)}
.stat.xl b{font-size:clamp(38px,6vw,54px)}
.stat.lg b{font-size:40px}
.stat.sm b{font:650 20px/1.1 var(--mono)}
.stat.ok b{color:var(--ok)}
.stat.warn b{color:var(--warn)}
.stat.link b{color:var(--link)}
.statrow.ruled>.stat+.stat{padding-left:36px;border-left:1px solid var(--line)}
@media(max-width:520px){ .statrow.ruled>.stat+.stat{padding-left:0;border-left:none} }

/* 5. .status: an LED and its word. No fill; the LED carries the colour */
.status{display:inline-flex;align-items:center;gap:7px;height:22px;padding:0 8px 0 7px;
  border-radius:var(--r-chip);font:650 10px/1 var(--mono);letter-spacing:.12em;
  text-transform:uppercase;background:var(--well);color:var(--ink);white-space:nowrap;
  vertical-align:middle;box-shadow:inset 0 0 0 1px var(--line)}
.status::before{content:"";flex:none;width:7px;height:7px;border-radius:50%;background:var(--led-off)}
.status.live::before{background:var(--led-live);box-shadow:0 0 7px var(--led-live);
  animation:ledblink 1.2s steps(2,end) infinite}
.status.ok::before{background:var(--led-ok);box-shadow:0 0 7px color-mix(in srgb,var(--led-ok) 80%,transparent)}
.status.warn::before{background:var(--led-warn);box-shadow:0 0 7px color-mix(in srgb,var(--led-warn) 80%,transparent)}
.status.live,.status.ok,.status.warn{background:var(--well);color:var(--ink)}
.status.dim{background:transparent;color:var(--ink2)}
.status.plain{background:none;padding:0;box-shadow:none}
.chip.warn.status{text-transform:uppercase;letter-spacing:.12em;line-height:1;height:22px;white-space:nowrap}

/* 6. .emptystate */
.emptystate{display:flex;flex-direction:column;align-items:center;text-align:center;gap:10px;
  padding:44px 24px;border:2px dashed var(--line);border-radius:var(--r-card);
  background:color-mix(in srgb,var(--card) 70%,transparent)}
.emptystate .art{width:80px;height:80px}
.emptystate .art svg{width:100%;height:100%;display:block;overflow:visible}
.emptystate h3{font:600 17px/1.4 var(--sans);margin:4px 0 0}
.emptystate p{max-width:44ch;color:var(--ink2);font-size:14px;margin:0}
.emptystate .acts{margin-top:8px;display:flex;gap:10px;flex-wrap:wrap;justify-content:center}

/* 7. panel variants */
.card.hero{padding:28px 30px}
.card.flush{padding:0;overflow:hidden}
.card.inset{background:var(--well)}
.card.quiet{background:transparent;clip-path:none;box-shadow:inset 0 0 0 2px var(--line);border-radius:var(--r-card)}
a.card,.card.link{display:block;color:inherit;text-decoration:none;
  transition:box-shadow var(--t) var(--ease),transform var(--t) var(--ease)}
a.card:hover,.card.link:hover{box-shadow:inset 0 0 0 2px var(--ink);transform:translateY(-1px)}
@media(max-width:640px){
  .card{padding:16px}
  .card.hero{padding:20px}
  .card.flush{padding:0}
}

/* 10. .tbl */
.tbl th{position:sticky;top:0;background:var(--card);z-index:1}
.tbl td,.tbl th{padding:11px 14px}
.tbl tbody tr{transition:background var(--t-fast) var(--ease)}
.tbl tbody tr:hover{background:var(--well)}
.tbl td.mono{font-family:var(--mono);font-size:12.5px;font-variant-numeric:tabular-nums}
.tbl .nowrap{white-space:nowrap}
.tbl-scroll.fade{-webkit-mask-image:linear-gradient(90deg,#000 calc(100% - 28px),transparent);
  mask-image:linear-gradient(90deg,#000 calc(100% - 28px),transparent)}

/* 12-14. skeleton, entrance, severity tag */
.skel{background:linear-gradient(90deg,var(--line-soft) 0,
    color-mix(in srgb,var(--line-soft) 40%,var(--card)) 50%,var(--line-soft) 100%) 0 0/200% 100%;
  animation:skel 1.4s linear infinite;border-radius:2px}
.rise{animation:pop var(--t) var(--ease) both}

/* 17. .callout: a note with a thick left bar */
.callout{border:0;border-left:4px solid var(--ink3);border-radius:0 var(--r-card) var(--r-card) 0;
  background:var(--card);padding:14px 18px;box-shadow:inset 0 0 0 1px var(--line-soft)}
.callout.warn{border-left-color:var(--led-warn)}
.callout.link{border-left-color:var(--sig)}
.callout.ok{border-left-color:var(--led-ok)}

/* ------------------------------------------------------ keys & inputs -- */
/* Every button is a KEY: square-ish, with a 3px edge under it that it travels into
   when pressed. The primary key is ink; .runbtn (the money key) is signal orange. */
button,.btn{display:inline-block;font:650 13px/1 var(--sans);letter-spacing:.01em;padding:11px 18px;
  border-radius:var(--r-key);cursor:pointer;border:1px solid var(--btn);
  background:var(--btn);color:var(--btn-ink);text-decoration:none;text-align:center;
  box-shadow:0 3px 0 var(--key-edge);position:relative;top:0;
  transition:background var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease),
    color var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease),transform var(--t-fast) var(--ease)}
button:active:not(:disabled),.btn:active{transform:translateY(2px);box-shadow:0 1px 0 var(--key-edge)}
.btn.sm{padding:7px 12px;font-size:12px}
.btn.lg{padding:14px 24px;font-size:15px}
.btn .arr{display:inline-block;transition:transform var(--t-fast) var(--ease)}
.btn:hover .arr{transform:translateX(2px)}
button:hover,.btn:hover{background:var(--btn-hover);border-color:var(--btn-hover)}
.runbtn{background:var(--sig);color:var(--on-sig);border:1px solid var(--sig-edge);border-radius:var(--r-key);
  padding:11px 22px;font:700 13.5px var(--sans);cursor:pointer;box-shadow:0 3px 0 var(--sig-edge)}
.runbtn:hover{background:color-mix(in srgb,var(--sig) 88%,#fff);border-color:var(--sig-edge)}
.runbtn:active:not(:disabled){box-shadow:0 1px 0 var(--sig-edge)}
.ghost,button.ghost,.btn.ghost{background:var(--key2);
  border:1px solid var(--line);box-shadow:0 3px 0 var(--key2-edge);
  color:var(--ink);border-radius:var(--r-key);padding:9px 16px;font:650 12px/1 var(--sans);cursor:pointer}
.ghost:active:not(:disabled),button.ghost:active:not(:disabled),.btn.ghost:active{box-shadow:0 1px 0 var(--key2-edge)}
.ghost:hover,button.ghost:hover,.btn.ghost:hover{border-color:var(--ink);color:var(--ink);filter:none;
  background:var(--key2)}
.ghost:disabled,button.ghost:disabled,.btn.ghost[aria-disabled="true"]{border-style:dashed;background:transparent;box-shadow:none}
button:disabled,.btn:disabled,.btn[aria-disabled="true"],.runbtn:disabled{
  opacity:.5;cursor:not-allowed;filter:none}
.backbtn{margin-top:20px}

input,select,textarea{font:14px var(--sans);padding:9px 11px;border:1px solid var(--line);
  border-radius:var(--r-input);background:var(--well);color:var(--ink);
  box-shadow:inset 0 2px 0 rgba(0,0,0,.04);
  transition:border-color var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease)}
:where(input:not([type="checkbox"],[type="radio"],[type="range"],[type="file"],[type="hidden"],[type="color"]),
  select,textarea){min-height:40px}
:where(.composer,.budgetlbl) :is(input,select,textarea){min-height:0}
input:hover:not(:focus):not(:disabled):not([type="range"],[type="checkbox"],[type="radio"],[type="file"]),
select:hover:not(:focus):not(:disabled),textarea:hover:not(:focus):not(:disabled){
  border-color:var(--ink3)}
input:focus-visible,select:focus-visible,textarea:focus-visible{outline:none;
  border-color:var(--ink);box-shadow:var(--ring)}
select{-webkit-appearance:none;appearance:none;padding-right:30px;cursor:pointer;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%238B8D85' stroke-width='1.6' stroke-linecap='square'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 10px center;background-size:10px 6px}
select[multiple],select[size]:not([size="1"]){background-image:none;padding-right:11px}
input::placeholder,textarea::placeholder{color:var(--ink3)}
input[type="number"]{font-family:var(--mono);font-variant-numeric:tabular-nums}
/* the dials: a notched track (tick marks), filled in signal up to --fill, and a
   square fader cap with a centre line: a hardware slider, not a web range */
input[type="range"]{padding:0;border:none;background:none;box-shadow:none;accent-color:var(--sig);height:26px;
  -webkit-appearance:none;appearance:none;background:transparent;cursor:pointer}
input[type="range"]::-webkit-slider-runnable-track{height:6px;border-radius:1px;
  background:linear-gradient(var(--sig),var(--sig)) 0/var(--fill,0%) 100% no-repeat,
    repeating-linear-gradient(90deg,var(--line) 0 2px,var(--line-soft) 2px 8px)}
input[type="range"]::-moz-range-track{height:6px;border-radius:1px;
  background:linear-gradient(var(--sig),var(--sig)) 0/var(--fill,0%) 100% no-repeat,
    repeating-linear-gradient(90deg,var(--line) 0 2px,var(--line-soft) 2px 8px)}
input[type="range"]::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;
  width:14px;height:24px;margin-top:-9px;border-radius:2px;
  background:linear-gradient(90deg,transparent 6px,var(--sig) 6px 8px,transparent 8px),var(--btn);
  border:0;box-shadow:0 2px 0 var(--key-edge);
  transition:transform var(--t-fast) var(--ease),box-shadow var(--t-fast) var(--ease)}
input[type="range"]::-moz-range-thumb{width:14px;height:24px;border-radius:2px;
  background:linear-gradient(90deg,transparent 6px,var(--sig) 6px 8px,transparent 8px),var(--btn);
  border:0;box-shadow:0 2px 0 var(--key-edge);box-sizing:border-box}
input[type="range"]:hover::-webkit-slider-thumb{transform:translateY(-1px)}
input[type="range"]:focus-visible{outline:none}
input[type="range"]:focus-visible::-webkit-slider-thumb{box-shadow:0 2px 0 var(--key-edge),var(--ring)}
input[type="range"]:focus-visible::-moz-range-thumb{box-shadow:0 2px 0 var(--key-edge),var(--ring)}
input[type="range"]:disabled{cursor:not-allowed;opacity:.5}
input[type="file"]{font:13px var(--sans);color:var(--ink2);padding:2px;border:none;background:none;box-shadow:none;border-radius:3px}
input[type="file"]::file-selector-button{font:650 12px/1 var(--sans);padding:9px 14px;
  margin-right:12px;border-radius:var(--r-key);border:1px solid var(--line);
  background:var(--key2);color:var(--ink);cursor:pointer;box-shadow:0 2px 0 var(--key2-edge);
  transition:background var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease)}
input[type="file"]::file-selector-button:hover{border-color:var(--ink)}
textarea{resize:none;line-height:1.5}

details{font-size:12.5px;color:var(--ink2)}
summary{cursor:pointer;color:var(--ink2);font:650 10.5px/1.4 var(--mono);
  letter-spacing:.1em;text-transform:uppercase;width:fit-content}
summary:hover{color:var(--ink)}
details[open]>summary{margin-bottom:6px}

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

.jobpill{border:1px solid var(--line);border-radius:var(--r-key);padding:5px 12px;background:var(--card);
  box-shadow:0 2px 0 var(--key2-edge);
  display:none;align-items:center;gap:7px;cursor:pointer;font:600 11px var(--mono);color:var(--ink)}
/* .jobpill is a real <button>: outrank the generic button:hover ink fill (0,1,1)
   so hovering the pill never inverts it to an illegible ink blob */
.jobpill:hover{background:var(--card);border-color:var(--ink)}
.jobpill.on{display:inline-flex}
.jobpill .dotp{width:7px;height:7px;border-radius:50%;background:var(--led-live);box-shadow:0 0 7px var(--led-live);
  animation:blink 1.2s ease-in-out infinite}
.jobpill.done .dotp{background:var(--led-ok);box-shadow:0 0 7px var(--led-ok);animation:none}

/* ---------------------------------------------------------- chat thread -- */
/* Normal state grows naturally — no max-height cap, no overflow clip: a long
   thread must page-scroll and the sticky composer needs the viewport as its
   scroll container. The cap + clip exist only for the .shrunk collapse. */
#chatzone,.chatzone{flex:1;display:flex;flex-direction:column;justify-content:center;
  transition:flex .55s ease, opacity .4s ease, max-height .55s ease}
#chatzone.shrunk,.chatzone.shrunk{flex:0;max-height:0;opacity:0;pointer-events:none;
  overflow:hidden}
.thread{display:flex;flex-direction:column;gap:10px;padding:6px 0 14px}
.msg{font-size:14.5px;line-height:1.6;animation:pop .25s ease both;max-width:640px}
/* the ask bubble: a printed ticket, not a chat bubble */
.me{background:var(--card);border:0;border-radius:var(--r-card);
  box-shadow:inset 0 0 0 1px var(--line),3px 3px 0 var(--ink);padding:10px 14px;align-self:flex-end}
.bot{padding:2px}

/* the composer: a recessed input well with a key on the end */
.composer{display:flex;gap:8px;align-items:center;background:var(--card);
  border:0;border-radius:var(--r-card);padding:10px 10px 10px 16px;
  box-shadow:inset 0 0 0 2px var(--ink);
  transition:border-color var(--t) var(--ease),box-shadow var(--t) var(--ease)}
.composer:focus-within{box-shadow:inset 0 0 0 2px var(--ink),var(--ring)}
.composer input,.composer textarea{flex:1;border:none;outline:none;font:16px/1.5 var(--sans);
  background:none;color:var(--ink);padding:0;margin:0;border-radius:0}
.composer textarea{max-height:120px;overflow-y:auto}
.composer button{flex:none;width:36px;height:36px;padding:0;border-radius:var(--r-key);
  background:var(--sig);color:var(--on-sig);border:1px solid var(--sig-edge);box-shadow:0 3px 0 var(--sig-edge);
  font-size:15px;font-weight:700;cursor:pointer}
.composer button:hover{background:color-mix(in srgb,var(--sig) 88%,#fff);border-color:var(--sig-edge)}
.composer select{flex:none;font:600 11px var(--mono);color:var(--ink3);
  border:none;background:none;padding:4px 2px;cursor:pointer}

/* the clarify beat — questions render as italic .clarify lines under the
   customer_line (contract); the plan and free quote still follow */
.clarify{font-style:italic;font-size:13.5px;color:var(--ink2);margin-top:6px}
.whyq{font-size:11px;color:var(--ink3);margin-top:3px}

/* job cards in thread */
.jobcard{border:0;background:var(--card);border-radius:var(--r-card);clip-path:var(--chamfer);
  padding:14px 16px;max-width:640px;display:flex;gap:12px;align-items:center;
  box-shadow:inset 0 0 0 1px var(--line-soft)}
.jobcard svg{width:38px;height:38px;flex:none}
.jobcard .jt{font-size:13.5px;font-weight:600}
.jobcard .js{font-size:11.5px;color:var(--ink3)}

/* -------------------------------------------------- the seven characters -- */
/* the aperture apothem: registered so the diaphragm physically opens and
   closes between states (animatable length; unregistered browsers degrade
   to discrete steps, never a broken pose) */
@property --ap { syntax:"<length>"; inherits:true; initial-value:6px; }

.castwrap{padding:14px 0 4px}
.castlabel{text-align:center;font:400 10px/1.4 var(--mono);letter-spacing:.02em;
  color:var(--ink3);padding-bottom:14px;transition:opacity .4s}
/* the lineup is ONE line at full width: seven cells + six gaps must clear the
   832px content column (7×108 + 6×10 = 816). Six at 122/14 filled it exactly,
   so Pulse joining means the cell tightens — it still wraps gracefully below. */
.cast{display:flex;gap:10px;justify-content:center;flex-wrap:wrap;position:relative}
.who{display:flex;flex-direction:column;align-items:center;gap:7px;width:108px;cursor:pointer;
  transition:transform .75s cubic-bezier(.3,.9,.35,1.15), opacity .5s ease, filter .5s ease}
.who svg{width:84px;height:84px;display:block;overflow:visible}
/* scaled states (perk/pickpop) act INSIDE the svg viewport — overflow:visible
   above plus this headroom keep Scout's dish and pop-overshoot from clipping */
.castwrap,.cast{overflow:visible}
.castwrap{padding-top:18px}
.who .nm{font:650 10.5px/1 var(--mono);letter-spacing:.06em;text-transform:uppercase;
  text-align:center}   /* gated suffix wraps the label — wrapped lines must stay centered */
.who .rl{font-size:10.5px;color:var(--ink3);text-align:center;line-height:1.35}
/* gated: only the SVG dims — the honest text label stays fully legible
   (name renders in var(--ink2) via characters.js; suffix uses AA-passing ink3) */
.who.gated svg{opacity:.45}
.who.gated .nm::after{content:" · not for sale";color:var(--ink3);
  text-transform:none;letter-spacing:0}
/* ---- the v2.3 aperture system (cast lab, style locked) ----
   One registered CSS length (--ap, the diaphragm apothem: 0 = sealed, bigger
   = wider open) drives all seven .blade elements; every state is just a
   different opening. Motion is focus behavior — rack-focus on select,
   focus-hunt while working — NEVER a spin. Character art uses its own fixed
   hexes (mascots keep their colors in dark mode); --rest-ap comes inline per
   .who from characters.js (Scout 10 · Pulse 8.5 · Reveal 8 · Deepen 7 ·
   Resolve 6 · Verify 5.5 · Watch capped at 0). */
.who{--ap:var(--rest-ap,6px)}
svg.chr{--ap:var(--rest-ap,6px)}   /* standalone art (job cards, hero, seal) rests at its own aperture */
.who svg.chr{--ap:inherit}         /* in the row, the animated .who wrapper drives the blades */
.chr [data-part]{transform-box:fill-box}
/* Resolve's identity cue must survive small renders: at 62px (row) and 38px
   (job cards) the lab's 1-unit crosshair strokes render ~0.5px/0.3px and
   vanish, leaving Resolve and Verify near-twins. Boost only in these small
   contexts — standalone full-size art stays exactly at cast-lab spec. */
.who .chr .xh,.jobcard .chr .xh{stroke-width:2;opacity:.6}
.chr .root{transform-origin:50% 90%}
.chr .pupil,.chr .ring,.chr .badge,.chr .ping,.chr .shadow{transform-origin:center}
.chr .scan,.chr .ping{opacity:0}
.chr .badge{transform:scale(0)}
.chr .blade{transform:translateX(var(--ap))}

/* idle: bob + aperture blink at each character's own rest opening */
.cast.idle .who{animation:apblink 4.8s linear infinite}
.cast.idle .who[data-k="scout"]{animation-duration:5.7s}
.cast.idle .who .root{animation:bob 3.4s ease-in-out infinite}
.cast.idle .who .shadow{animation:shpulse 3.4s ease-in-out infinite}
.cast.idle .who:nth-child(2),.cast.idle .who:nth-child(2) .root,
.cast.idle .who:nth-child(2) .shadow{animation-delay:.4s}
.cast.idle .who:nth-child(3),.cast.idle .who:nth-child(3) .root,
.cast.idle .who:nth-child(3) .shadow{animation-delay:.8s}
.cast.idle .who:nth-child(4),.cast.idle .who:nth-child(4) .root,
.cast.idle .who:nth-child(4) .shadow{animation-delay:1.2s}
.cast.idle .who:nth-child(5),.cast.idle .who:nth-child(5) .root,
.cast.idle .who:nth-child(5) .shadow{animation-delay:1.6s}
.cast.idle .who:nth-child(6),.cast.idle .who:nth-child(6) .root,
.cast.idle .who:nth-child(6) .shadow{animation-delay:2s}
.cast.idle .who:nth-child(7),.cast.idle .who:nth-child(7) .root,
.cast.idle .who:nth-child(7) .shadow{animation-delay:2.4s}

/* hover (idle only): perk up, aperture opens with a little overshoot */
.cast.idle .who:hover:not(.capped){--ap:calc(var(--rest-ap) + 3.5px);
  animation:hoverap .35s ease-out both}
.cast.idle .who:hover:not(.capped) .root{animation:perk .28s ease-out forwards}
.cast.idle .who:hover:not(.capped) .pupil{transform:scale(1.1);transition:transform .2s ease}

/* selected: squash & overshoot; the grip RACKS FOCUS — one twist, a
   correction back, settle; aperture does an open / stop-down / open flourish */
.who.pick{--ap:11px;animation:selap .85s cubic-bezier(.3,.9,.4,1) both}
.who.pick .root{animation:pickpop .6s cubic-bezier(.3,1.4,.4,1) forwards}
.who.pick .ring{animation:focusrack .9s cubic-bezier(.3,.7,.3,1) both}

/* working: the grip HUNTS FOCUS — ±5° oscillation, never a spin; aperture
   breathes deeper, scan beam sweeps, pupil saccades, ping radiates */
.who.working{animation:apbreathe 1.6s ease-in-out infinite}
.who.working .root{animation:workbob 1.2s ease-in-out infinite}
.who.working .ring{animation:focushunt 1.4s ease-in-out infinite alternate}
.who.working .pupil{animation:saccade 2.8s ease-in-out infinite}
.who.working .scan{opacity:.8;animation:scanmove 1.6s ease-in-out infinite alternate}
.who.working .ping{animation:pingout 1.8s ease-out infinite}

/* success: bounce, aperture fully open, badge pops (hook for future wiring) */
.who.success{--ap:12px;animation:sucap .8s cubic-bezier(.3,1.2,.4,1) both}
.who.success .root{animation:cheer .7s cubic-bezier(.3,1.3,.4,1) forwards}
.who.success .ring{animation:focusrack .7s cubic-bezier(.3,.7,.3,1) both}
.who.success .pupil{transform:scale(1.12)}
.who.success .badge{animation:badgein .45s .25s cubic-bezier(.3,1.5,.4,1) forwards}

/* refuse (Verify's alone): head shake, aperture stops down to a glare slit */
.who.refuse{--ap:1.8px;animation:refap .5s ease both}
.who.refuse .root{animation:headshake .55s ease-in-out forwards}
.who.refuse .pupil{transform:scale(.8);transition:transform .3s ease .1s}

/* capped (gated): dormant, not asleep — dim + desaturate, bob but no blink */
.who.capped{cursor:default}
.who.capped svg{filter:saturate(.55)}
.cast.idle .who.capped{animation:none}

/* job cards keep their gentle pulse (a scale, not a spin) */
.jobcard.running svg{animation:workpulse 1.1s ease-in-out infinite}
/* the whoosh: unpicked fly off alternating sides, picked sweep to center */
.cast.choosing .who{cursor:default}
.cast.choosing .who.out{opacity:0;pointer-events:none}
.cast.choosing .who.out.l{transform:translateX(-120vw) rotate(-9deg)}
.cast.choosing .who.out.r{transform:translateX(120vw) rotate(9deg)}
.cast.choosing .who.pick{transform:scale(1.28) translateY(-4px)}

/* hover cards: characters.js owns .oneshot-hovercard and injects its own
   token-based styles — no duplicate definition here */

/* -------------------------------------- stage: assignment + the free quote -- */
#stage,.stage{max-width:660px;margin:0 auto;width:100%}
.stagelabel{text-align:center;font:650 10.5px/1 var(--mono);letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink3);padding:20px 0 6px;animation:pop .3s ease both}
.plan{background:var(--card);border:0;border-radius:var(--r-card);
  padding:18px 20px;margin-top:14px;animation:pop .35s ease both;box-shadow:inset 0 0 0 1px var(--line-soft)}
.plan .alabel,.alabel{font:650 11px/1 var(--mono);letter-spacing:.07em;text-transform:uppercase}
.plan .areason,.areason{font-size:13px;color:var(--ink2);margin-top:5px;max-width:520px}
.plan .layered,.layered{font-size:10.5px;color:var(--ink3);margin-top:6px}
.dials{margin:13px 0 3px;border-top:1px solid var(--line-soft);padding-top:9px}
.sev{font:600 10px/1 var(--mono);white-space:nowrap}
.sev.must{color:var(--link)}
.sev.nice{color:var(--scout)}
.sev.info{color:var(--ink3)}
.qrow{display:flex;gap:10px;margin-top:11px}
/* quote cells: the BIG figure treatment — mono 600 figure beside a 10px label,
   the 1:3+ Titan ratio */
.qcell{border:0;border-radius:var(--r-card);padding:10px 14px;flex:1}
.qcell b{font:900 34px/1.05 var(--dots);font-variant-numeric:tabular-nums;
  letter-spacing:-.01em;display:block}
.qcell span{font-size:10px;color:var(--ink3);display:block;margin-top:3px}
.planacts{display:flex;gap:10px;align-items:center;margin-top:14px;flex-wrap:wrap}
.freefine{font-size:10.5px;color:var(--ink3);margin-left:auto}

/* ------------------------------------------------------- working & story -- */
.workmsg{text-align:center;padding:18px 0 6px;animation:pop .35s ease both}
.workmsg .wt{font-size:15.5px;font-weight:600}
.workmsg .ws{font-size:12.5px;color:var(--ink2);margin-top:4px}
.narr{font:12px/1.8 var(--mono);color:var(--ink2);border-left:2px solid var(--line);
  padding:2px 0 2px 12px;margin:16px auto 0;max-width:520px;text-align:left}

/* ------------------------------------------------------------ certificate -- */
.cert{border:0;background:var(--card);border-radius:var(--r-card);
  padding:18px 20px;max-width:640px;animation:pop .3s ease both;box-shadow:inset 0 0 0 1px var(--line-soft)}
.cert .ch{font:650 10px/1 var(--mono);letter-spacing:.08em;text-transform:uppercase;color:var(--ink3)}
/* the "what arrived" headline number: same 1:3+ figure-to-label scale */
.cert .big{font:900 34px/1.1 var(--dots);font-variant-numeric:tabular-nums;
  letter-spacing:-.01em;margin:8px 0 2px}
.cert .sub{font-size:12.5px;color:var(--ink2)}
.chips{display:flex;gap:8px;flex-wrap:wrap;margin-top:11px}
.chips a{font-size:12px;text-decoration:none;color:var(--ink);background:var(--key2);
  border:1px solid var(--line);border-radius:var(--r-key);padding:6px 12px;cursor:pointer;
  box-shadow:0 2px 0 var(--key2-edge);
  transition:border-color var(--t-fast) var(--ease),color var(--t-fast) var(--ease),
    background var(--t-fast) var(--ease)}
.chips a:focus-visible{outline:2px solid var(--btn);outline-offset:2px}
.chips a:hover{border-color:var(--ink);color:var(--ink)}
.chips a.off{opacity:.55;pointer-events:none;border-style:dashed;background:transparent}
.finep{font-size:10.5px;color:var(--ink3);margin-top:8px}

/* --------------------------------------------- tables, kv, operator log -- */
.tbl-scroll{overflow-x:auto}
table{border-collapse:collapse;width:100%;font-size:13px}
th{font:650 10px/1.4 var(--mono);text-transform:uppercase;letter-spacing:.12em;
  color:var(--ink3);text-align:left;padding:6px 10px 6px 0;border-bottom:2px solid var(--ink)}
td{padding:7px 10px 7px 0;border-bottom:1px solid var(--line-soft);vertical-align:top}
.num{text-align:right;font-family:var(--mono);font-variant-numeric:tabular-nums}
.kv{display:flex;justify-content:space-between;align-items:baseline;gap:10px 16px;
  padding:9px 0;font-size:13.5px;border-bottom:1px dashed var(--line)}
.kv:last-child{border-bottom:none}
.kv>span:first-child{color:var(--ink2)}
.kv b{font-family:var(--mono);font-weight:600;text-align:right;font-variant-numeric:tabular-nums}
.kv .prose{font:500 13.5px/1.5 var(--sans);text-align:right;max-width:60%}
.kv.stack{flex-direction:column;align-items:stretch;gap:4px}
.kv.stack b,.kv.stack .prose{text-align:left;max-width:none}
@media(max-width:520px){
  .kv{flex-direction:column;align-items:stretch;gap:3px}
  .kv b,.kv .prose{text-align:left;max-width:none}
}
pre.log{background:var(--scr);color:var(--scr-ink);font:12px/1.55 var(--mono);
  box-shadow:inset 0 0 0 1px var(--scr-line);border-radius:var(--r-card);padding:14px 16px;max-height:420px;overflow:auto;
  white-space:pre-wrap;overflow-wrap:anywhere}
pre.log .st{color:var(--log-st)}

/* ---- table.ops — the /internal density exception ----------------------------
   Operator density is not customer air. Every CUSTOMER surface in this app uses the
   card-row pattern (a.runrow) and there is no <table> on any of them; /internal is the
   deliberate exception, because an operator comparing twelve tenants needs rows that
   line up, not twelve floating cards. ONE style, here, rather than per-page CSS in six
   internal templates — the same reason every other component in this file is shared.
   Radius 12 lives on the wrapping .card (the anti-pill map), and the card scrolls
   horizontally so a wide table never makes the PAGE scroll sideways. */
/* ---- the ledger row — the CUSTOMER wallet pattern ---------------------------
   Card-rows, not a table: /account and /account/wallet are customer surfaces and get the
   house air, exactly as /runs does (a.runrow). Shared here rather than in either template
   because templates/_wallet_entries.html is ONE row definition included by both pages,
   and a style that lived in one of them would make that only half true. */
/* INSTRUMENT: the ledger is a TAPE. One perforated roll (sprocket holes down both
   edges), one printed line per entry, a dashed tear line between them. The markup is
   the same card-row list; only the paper changed. */
.ledger,.tape{position:relative;display:flex;flex-direction:column;gap:0;
  padding:6px 34px;background-color:var(--card);border-radius:var(--r-card);
  background-image:radial-gradient(circle at 13px 50%,var(--paper) 3.5px,transparent 4.2px),
    radial-gradient(circle at calc(100% - 13px) 50%,var(--paper) 3.5px,transparent 4.2px);
  background-size:100% 18px;background-repeat:repeat-y;
  box-shadow:inset 0 0 0 1px var(--line-soft)}
.ledger::before,.ledger::after{content:"";position:absolute;top:0;bottom:0;width:1px;
  background:repeating-linear-gradient(180deg,var(--line) 0 3px,transparent 3px 6px)}
.ledger::before{left:26px}
.ledger::after{right:26px}
.ledgerrow{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:16px;
  padding:12px 4px;margin:0;border-bottom:1px dashed var(--line);color:inherit;text-decoration:none;
  transition:background var(--t-fast) var(--ease)}
.ledgerrow:last-child{border-bottom:none}
a.ledgerrow:hover{background:var(--well)}
a.ledgerrow:hover b{text-decoration:underline;text-underline-offset:3px}
.ledgerrow b{display:block;font:650 11.5px/1.4 var(--mono);letter-spacing:.1em;text-transform:uppercase;color:var(--ink)}
.ledgerrow .lsub{display:block;font:400 11px/1.5 var(--mono);color:var(--ink3);margin-top:2px;
  font-variant-numeric:tabular-nums;overflow:hidden;text-overflow:ellipsis}
/* the amount is a FIGURE and reads as one: mono, tabular, never coloured green. --ok is
   semantic-pass only, and money arriving is not a pass state. */
.ledgerrow .lamt{font:650 15px/1.2 var(--mono);font-variant-numeric:tabular-nums;
  color:var(--ink);white-space:nowrap}
.ledgerrow .lamt.neg{color:var(--ink2)}
@media(max-width:640px){
  .ledger,.tape{padding:4px 26px}
  .ledger::before{left:20px} .ledger::after{right:20px}
  .ledger,.tape{background-image:radial-gradient(circle at 10px 50%,var(--paper) 3px,transparent 3.7px),
    radial-gradient(circle at calc(100% - 10px) 50%,var(--paper) 3px,transparent 3.7px)}
}

.card.ops{overflow-x:auto;padding:14px 16px}
table.ops{font-size:12.5px}
table.ops th{white-space:nowrap;padding:6px 14px 6px 0}
table.ops td{padding:7px 14px 7px 0;vertical-align:middle}
table.ops tr:last-child td{border-bottom:none}
table.ops td.num,table.ops th.num{text-align:right;font-family:var(--mono);
  font-variant-numeric:tabular-nums}
table.ops td a{text-decoration:none}
table.ops td a:hover{text-decoration:underline}
table.ops .muted{color:var(--ink3)}
/* a disabled control: the ghost variant plus the dashed border the design spec names for
   things that are deliberately not available yet (UI_DESIGN_SPEC.md, geometry). Radius 6,
   like every other button. */
.btn.seam,button.seam{border-style:dashed;background:transparent;
  border-color:color-mix(in srgb,var(--ink) 25%,transparent);color:var(--ink3);
  border-width:1px;border-radius:var(--r-key);box-shadow:none;font:600 12px/1 var(--sans);padding:9px 16px;
  cursor:not-allowed}

/* ------------------------------------------------------- dialog & toast -- */
dialog{border:0;border-radius:var(--r-card);background:var(--card);color:var(--ink);
  padding:26px 26px 20px;width:min(92vw,360px);box-shadow:inset 0 0 0 2px var(--ink),var(--shadow-3)}
dialog::backdrop{background:rgba(12,13,11,.45)}
#toast,.toast{position:fixed;left:50%;bottom:26px;transform:translateX(-50%) translateY(80px);
  background:var(--scr);color:var(--scr-ink);border-radius:var(--r-card);padding:11px 18px;
  font:600 12.5px/1.5 var(--mono);box-shadow:inset 0 0 0 1px var(--scr-line),var(--shadow-2);z-index:60;max-width:90vw;
  visibility:hidden;transition:transform .45s ease,visibility 0s .45s}
#toast.on,.toast.on{transform:translateX(-50%) translateY(0);visibility:visible;
  transition:transform .45s ease}


/* the characters' hover card (characters.js injects its base; this re-cuts it) */
body .oneshot-hovercard{border-radius:var(--r-card);border:0;
  box-shadow:inset 0 0 0 2px var(--ink),6px 6px 0 color-mix(in srgb,var(--ink) 16%,transparent)}
body .oneshot-hovercard .hn{font:400 13px/1.2 var(--display)}

/* ------------------------------------------------ instrument, round 2 -- */
/* ONE KEY VOICE: every key (ink, ghost, money) speaks mono caps on the same 3px travel. */
:is(.btn,.ghost,button.ghost,.runbtn){font-family:var(--mono);font-weight:700;font-size:11.5px;
  letter-spacing:.1em;text-transform:uppercase;line-height:1.1}
:is(.btn,.ghost,button.ghost,.runbtn):focus-visible{outline:2px solid var(--sig);outline-offset:3px}
/* a readout that reads zero or nothing is DIM: orange means money moved or attention */
.readout b.zero,.readout.zero b,.fig.zero b{color:var(--scr-dim) !important;text-shadow:none !important}
/* the serial line a module carries on its foot (hardware labelling, decoration) */
.serial{font:600 9px/1.3 var(--mono);letter-spacing:.16em;text-transform:uppercase;color:var(--ink3)}
/* .dial: the analog meter (certificate: true rate vs bar). SVG drawn by the template:
   an arc track, a red zone below the bar, a green zone above it, a tick comb, the needle. */
.meter{display:grid;grid-template-columns:minmax(180px,260px) minmax(0,1fr);gap:18px 26px;align-items:center;
  background:var(--scr);color:var(--scr-ink);border-radius:3px;padding:18px 22px 16px;
  background-image:repeating-linear-gradient(0deg,var(--scr-line) 0 1px,transparent 1px 3px);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.05),inset 0 10px 30px rgba(0,0,0,.45)}
.meter svg{display:block;width:100%;height:auto;overflow:visible}
.meter .trk{fill:none;stroke:rgba(255,255,255,.1);stroke-width:14}
.meter .zbad{fill:none;stroke:color-mix(in srgb,var(--led-warn) 55%,transparent);stroke-width:14}
.meter .zgood{fill:none;stroke:color-mix(in srgb,var(--led-ok) 55%,transparent);stroke-width:14}
.meter .comb{fill:none;stroke:rgba(255,255,255,.55);stroke-width:22;stroke-dasharray:.35 9.65}
.meter .barmk{stroke:var(--scr-ink);stroke-width:2.5}
.meter .ndl{stroke:var(--scr-sig);stroke-width:3.5;stroke-linecap:round;
  filter:drop-shadow(0 0 4px color-mix(in srgb,var(--scr-sig) 70%,transparent))}
.meter.pass .ndl{stroke:var(--scr-ok);filter:drop-shadow(0 0 4px color-mix(in srgb,var(--scr-ok) 70%,transparent))}
.meter .hub{fill:var(--scr-ink)}
.meter .scl{font:600 9px var(--mono);fill:var(--scr-dim);letter-spacing:.06em}
.meter .mread{display:grid;gap:12px;min-width:0}
.meter .mread b{display:block;font:900 clamp(30px,4vw,44px)/1 var(--dots);color:var(--scr-sig);
  text-shadow:0 0 14px color-mix(in srgb,var(--scr-sig) 45%,transparent);white-space:nowrap}
.meter.pass .mread b{color:var(--scr-ok);text-shadow:0 0 14px color-mix(in srgb,var(--scr-ok) 40%,transparent)}
.meter .mread b.ink{color:var(--scr-ink);text-shadow:none;font-size:clamp(24px,3vw,32px)}
.meter .mread span{display:block;margin-top:7px;font:650 9.5px/1.3 var(--mono);letter-spacing:.14em;
  text-transform:uppercase;color:var(--scr-dim)}
.meter .mverdict{display:flex;align-items:center;gap:9px;font:700 12px/1.3 var(--mono);letter-spacing:.12em;
  text-transform:uppercase;color:var(--scr-ink)}
@media (max-width:560px){ .meter{grid-template-columns:minmax(0,1fr);padding:14px 14px 12px} }

@keyframes ledblink{50%{opacity:.25;box-shadow:none}}
@media (prefers-reduced-motion: reduce){
  .led.live,.status.live::before{animation:none}
}

/* --------------------------------------------------------------- motion -- */
@keyframes pop{from{opacity:0;transform:translateY(7px)}to{opacity:1;transform:none}}
@keyframes blink{50%{opacity:.3}}
@keyframes pxblink{50%{opacity:.25}}
@keyframes skel{to{background-position:-200% 0}}
@keyframes workpulse{0%,100%{transform:scale(1)}50%{transform:scale(1.06)}}

/* ---- cast v2.3 keyframes (ported from the cast lab, verbatim) ---- */
@keyframes bob{0%,100%{transform:translateY(0)}50%{transform:translateY(-3px)}}
@keyframes shpulse{0%,100%{transform:scaleX(1)}50%{transform:scaleX(.94)}}
@keyframes apblink{0%,10%{--ap:var(--rest-ap)}32%{--ap:calc(var(--rest-ap) + .7px)}
  58%{--ap:calc(var(--rest-ap) - .5px)}88%{--ap:var(--rest-ap)}93%{--ap:0px}
  98%,100%{--ap:var(--rest-ap)}}
@keyframes perk{0%{transform:scale(1)}60%{transform:scale(1.07)}100%{transform:scale(1.05)}}
@keyframes hoverap{0%{--ap:var(--rest-ap)}55%{--ap:calc(var(--rest-ap) + 4.5px)}
  100%{--ap:calc(var(--rest-ap) + 3.5px)}}
@keyframes pickpop{0%{transform:scale(1)}35%{transform:scale(1.16,.9)}60%{transform:scale(.95,1.08)}100%{transform:scale(1.07)}}
@keyframes focusrack{0%{transform:rotate(0)}30%{transform:rotate(16deg)}
  55%{transform:rotate(-9deg)}78%{transform:rotate(4deg)}100%{transform:rotate(0)}}
@keyframes selap{0%{--ap:var(--rest-ap)}25%{--ap:13px}50%{--ap:7px}
  80%{--ap:11.6px}100%{--ap:11px}}
@keyframes apbreathe{0%,100%{--ap:calc(var(--rest-ap) - 2.2px)}50%{--ap:calc(var(--rest-ap) + 2.2px)}}
@keyframes focushunt{0%{transform:rotate(-5deg)}100%{transform:rotate(5deg)}}
@keyframes scanmove{0%{transform:translateX(-22px)}100%{transform:translateX(22px)}}
@keyframes saccade{0%,22%{transform:translateX(0)}28%,46%{transform:translateX(-2.5px)}
  54%,72%{transform:translateX(2.5px)}80%,100%{transform:translateX(0)}}
@keyframes workbob{0%,100%{transform:scale(1.04) translateY(0)}50%{transform:scale(1.04) translateY(-2px)}}
@keyframes pingout{0%{opacity:.7;transform:scale(.4)}100%{opacity:0;transform:scale(1.6)}}
@keyframes cheer{0%{transform:scale(1)}30%{transform:scale(1.1) translateY(-6px)}
  55%{transform:scale(.97) translateY(0)}100%{transform:scale(1.03)}}
@keyframes badgein{0%{transform:scale(0)}70%{transform:scale(1.25)}100%{transform:scale(1)}}
@keyframes sucap{0%{--ap:var(--rest-ap)}40%{--ap:13px}70%{--ap:10.5px}100%{--ap:12px}}
@keyframes headshake{0%,100%{transform:translateX(0)}18%{transform:translateX(-5px)}
  40%{transform:translateX(4px)}62%{transform:translateX(-3px)}82%{transform:translateX(2px)}}
@keyframes refap{0%{--ap:var(--rest-ap)}40%{--ap:1.1px}70%{--ap:2.8px}100%{--ap:1.8px}}
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
}
