/* QuantSuite — shared design system ("Thirty-Seven Tabs" restyle, 2026-08).
   Link this on every page:
   <link rel="stylesheet" href="assets/quantsuite.css">  (adjust path for subdirs)
   One near-black terminal theme, painted explicitly — no light mode and no CDN
   of any kind. ONE web-font binary ships, bundled beside this file (the display
   face; see the @font-face below) — everything else is a system stack. Every
   class below is stable vocabulary for page agents; each carries a one-line
   purpose comment.
   EDITING HAZARD: a CSS comment ends at the FIRST star-slash sequence — comments
   do not nest and have no escape — so never write a glob such as
   star-star-slash inside one; the parser would silently eat the next rule.
   Pinned by tests/unit/test_css_comments_are_closed_where_intended.py.

   2026-09-04 PIXEL-DISPLAY RESTYLE. Same components, same markup, retuned
   surface: near-black ground, warm off-white ink, a pixel display face for
   headings and headline numerals, pill chrome, a bright rule over metric
   tiles, and a fixed grain-plus-vignette layer. Nothing external is fetched —
   the site's CSP is script-src/style-src 'self' plus inline, so a font CDN or
   an icon CDN would be blocked silently and ship a page whose type never
   loads. The display face is therefore BUNDLED (see the @font-face below) and
   every icon on this site is already inline SVG. */

/* THE DISPLAY FACE — bundled, never fetched.
   assets/fonts/GeistPixel-Circle.woff2 (28 KB), path relative to THIS file.
   The weight RANGE is declared deliberately: the face ships one weight, and
   without a declared range a `font-weight:700` heading gets FAUX-BOLD — the
   browser smearing a pixel grid sideways, which is exactly the artefact a
   pixel face must never show. Declaring 400-700 tells the browser the face
   covers those weights, so it draws the real design at every one of them.
   Verified in-browser before adoption: digits, upper, lower, ASCII
   punctuation and the typographic marks this site actually sets (em dash,
   en dash, middot, ellipsis, curly quotes, arrows, plus-minus, times) are ALL
   present — a missing glyph would fall back per-CHARACTER and shatter a
   headline mid-word. */
@font-face{
  font-family:"Geist Pixel Circle";
  src:url("fonts/GeistPixel-Circle.woff2") format("woff2");
  font-weight:400 700;
  font-style:normal;
  font-display:swap;
}

:root{
  /* Ground + surfaces. The canvas lost its blue cast in the 2026-09 restyle:
     #050505 is a NEUTRAL near-black, which is what lets the warm ink below
     read as warm rather than as a screen with the white balance wrong. */
  --bg:#050505;            /* page ground — neutral near-black, painted explicitly */
  --band:#0a0a0a;          /* the alternating raised band (.band-alt, .strip, .mstrip) */
  --panel:#0a0a0a;         /* raised solid surface: window-chrome bars, nav sheet */
  --card:#0b0b0b;          /* solid card surface */
  --glass:rgba(255,255,255,.04);   /* glassy card fill (white/4) */
  --border:rgba(255,255,255,.10);  /* hairline ring on surfaces */
  --border2:rgba(255,255,255,.20); /* stronger ring: inputs, ghost buttons, pills */
  /* --rule — the BRIGHT hairline, used only where a rule is the design rather
     than the edge of a box: above a metric tile, under a section band. Kept a
     separate token on purpose — promoting every card ring to this weight turns
     the page into a wireframe. */
  --rule:rgba(255,255,255,.36);
  --line:var(--border);            /* canonical alias used by newer markup */

  /* Ink: a warm off-white at three confidence levels, solid rather than
     white-alpha. Alpha ink takes the hue of whatever is under it, so on a
     neutral ground it can only ever be neutral grey; stating the warm value
     is what gives long-form prose its paper cast. */
  --text:#f2efe9;          /* primary ink — warm off-white */
  --dim:#b5b1a9;           /* secondary ink — running prose */
  --muted:#8b8781;         /* tertiary ink — labels, captions */

  /* The one brand accent (emerald-400) + its hover step. */
  --accent:#34d399;        /* emerald — brand, verified, CTA */
  --accent-2:#6ee7b7;      /* emerald hover step */
  --accent-dim:#10b981;    /* deep emerald — gradient tail */
  --on-accent:#051109;     /* ink on an emerald fill (reads as black) */
  --grad:linear-gradient(135deg,var(--accent-dim) 0%,var(--accent) 100%);

  /* Tone palette — the four chip colours + P&L semantics. Emerald = brand or
     verified, gold/amber = caveat or illustrative, sky = neutral info,
     violet = AI/model, rose = loss or refusal. */
  --gain:#34d399;          /* a number that went up */
  --loss:#fb7185;          /* a number that went down (rose-400) */
  --gold:#fcd34d;          /* caveat / illustrative (amber-300) */
  --sky:#7dd3fc;           /* neutral info tone (sky-300) */
  --vio:#c4b5fd;           /* AI / model tone (violet-300) */

  /* Legacy aliases — ~20 pages were written against colour-literal names.
     They reference the canonical tokens, so retuning happens in one place. */
  --cyan:var(--accent); --violet:var(--vio);
  --green:var(--gain); --red:var(--loss); --amber:var(--gold);

  --radius:10px;           /* default card radius */
  --radius-sm:6px;         /* small tags that stay rectangular */
  /* --pill — the chrome radius. Nav, buttons, eyebrows and tone chips are
     fully round; cards and panels are not. That split is the restyle's one
     structural rule: CHROME is round, CONTENT is squared. */
  --pill:999px;
  --maxw:1400px;           /* content measure — generous terminal gutters */
  /* --page-inset — the gutter, as a clamp rather than a fixed 24px, so the
     column breathes on a wide monitor and tightens on a phone. */
  --page-inset:clamp(18px,1.55vw,28px);

  /* Native form controls follow the declared scheme, not the painted colours —
     without this, selects/scrollbars/autofill render light-mode chrome. */
  color-scheme:dark;

  /* Typeface roles, declared once.
     BODY + MONO are stacks, never fetched: Inter and JetBrains Mono lead as
     the DESIGN TARGET and degrade to the system faces on a machine without
     them. Fetching Inter from a font CDN would be blocked by this site's CSP
     and would fail SILENTLY, so the stack is the design, not a fallback.
     DISPLAY is the one bundled binary (the @font-face at the top of this
     file) — headings, the wordmark, and headline numerals. It ends in
     var(--font-body) so a browser that cannot load woff2 still gets a
     coherent page rather than Times. */
  --font-body:Inter,"Segoe UI",system-ui,-apple-system,sans-serif;
  --font-display:"Geist Pixel Circle",var(--font-body);
  --font-mono:"JetBrains Mono","Cascadia Code",Consolas,"SF Mono",ui-monospace,"Roboto Mono",monospace;
}

/* ── Reset + ground ─────────────────────────────────────────────────────── */
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
/* body paints the ground explicitly — dark-first single-theme is deliberate */
body{background:var(--bg);color:var(--text);font-family:var(--font-body);line-height:1.6;-webkit-font-smoothing:antialiased;overflow-x:hidden}
a{color:inherit;text-decoration:none}
/* .wrap — the page column: max-w 1400px on a clamped gutter */
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 var(--page-inset)}
/* .mono / .num — every number that must sit in columns: mono + tabular */
.mono{font-family:var(--font-mono);font-variant-numeric:tabular-nums}
.num{font-family:var(--font-mono);font-variant-numeric:tabular-nums}
/* THE BACKDROP, in TWO fixed layers under everything. They are split by BLEND
   MODE, not by taste, and that split is load-bearing:

     ::before blends NORMALLY  — emerald glow, blueprint grid, edge vignette.
     ::after  blends SOFT-LIGHT — grain and pixel field only.

   The first draft put all six gradients on one soft-light element, and the
   vignette stopped working: soft-light over a near-black ground LIGHTENS, so
   the layer whose whole job is to darken the top and bottom edges was
   brightening them instead, hazing the mid-tones and pulling body copy toward
   the background. A darkening layer has to blend normally. Keep them apart.

   Both sit at z-index:-1, and ::after paints later, so the film lands over the
   grid — the intended order. pointer-events:none on both, or the page stops
   taking clicks. */
body::before{content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;background:
  radial-gradient(900px 520px at 78% -8%,rgba(52,211,153,.07),transparent 60%),
  linear-gradient(rgba(255,255,255,.035) 1px,transparent 1px),
  linear-gradient(90deg,rgba(255,255,255,.035) 1px,transparent 1px),
  linear-gradient(180deg,rgba(0,0,0,.5) 0%,transparent 10%,transparent 76%,rgba(0,0,0,.55) 100%);
  background-size:auto,48px 48px,48px 48px,auto;}

/* Grain + pixel field. The grain is an inline SVG feTurbulence — no request,
   no binary, and `data:` is the one non-self source this site's CSP admits for
   images. It breaks up the flat black that makes a dark page read as a
   switched-off monitor. The pixel field is a 3px/5px scanline beat, the same
   texture as the display face, so the ground and the type argue for the same
   thing. Kept faint on purpose: this sits over EVERY page including six
   thousand words of legal copy, and texture that you notice while reading is
   texture set too high. */
body::after{content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;
  background-image:
    url("data:image/svg+xml,%3Csvg viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='.9'/%3E%3C/svg%3E"),
    repeating-linear-gradient(0deg,transparent 0 2px,rgba(255,255,255,.02) 2px 3px),
    repeating-linear-gradient(90deg,transparent 0 4px,rgba(0,0,0,.045) 4px 5px);
  background-size:180px 180px,auto,auto;
  opacity:.3;mix-blend-mode:soft-light}

/* ── Ticker marquee (thin ribbon above the nav) ─────────────────────────── */
/* .ticker — the thin top ribbon; black ground, hairline bottom border */
.ticker{display:flex;align-items:center;height:28px;overflow:hidden;background:#030303;border-bottom:1px solid var(--border)}
/* .ticker-tag — the ribbon's label chip. THE CHIP MUST NEVER OVERSTATE THE
   NUMBERS BESIDE IT, so its state is set by the server's freshness verdict, not
   by the page:
     .is-live    emerald — every quote is minutes old (server-decided)
     (no class)  amber   — real quotes, but older; the stamp leads the ribbon
     .is-off     muted   — no quotes at all; the ribbon carries a reason
     .is-wait    muted   — first fetch in flight
   Amber is this site's "caveat" colour everywhere else, which is why DELAYED
   inherits the bare-class default rather than getting a colour of its own. */
.ticker-tag{display:flex;align-items:center;gap:6px;flex:none;height:100%;padding:0 12px;border-right:1px solid var(--border);
  font-family:var(--font-mono);font-size:10px;font-weight:700;letter-spacing:.18em;text-transform:uppercase;color:var(--gold)}
.ticker-tag i{width:6px;height:6px;border-radius:50%;background:var(--gold);display:block}
.ticker-tag.is-live{color:var(--gain)}
.ticker-tag.is-live i{background:var(--gain)}
.ticker-tag.is-off,.ticker-tag.is-wait{color:var(--muted)}
.ticker-tag.is-off i,.ticker-tag.is-wait i{background:var(--muted)}
/* .ticker-view — clips the moving track */
.ticker-view{position:relative;flex:1;overflow:hidden}
/* .ticker-track — the marquee itself; markup carries the item list TWICE (two
   .tkset halves of equal width) so the -50% translate loops seamlessly */
.ticker-track{display:flex;white-space:nowrap;width:max-content;
  font-family:var(--font-mono);font-variant-numeric:tabular-nums;font-size:11px;
  animation:qs-marquee 60s linear infinite}
/* .is-static — ONE item and no second half (the loading line, or the sentence
   the ribbon shows when it has no quotes). A -50% translate over a track with
   nothing to loop just walks the message off the left edge, so the marquee is
   switched off rather than scrolling a status line out of view. */
.ticker-track.is-static{animation:none}
/* .tkset — one copy of the item list; padding-left doubles as the item gap so
   both halves measure identically and the loop point is invisible */
.tkset{display:inline-flex;flex:none;gap:32px;padding-left:32px}
/* .tk — one ticker item: symbol · price · signed change */
.tk{display:inline-flex;align-items:center;gap:6px;color:var(--text)}
.tk .s{color:var(--muted)}          /* symbol, tertiary ink */
.tk .up{color:var(--gain)}          /* positive change */
.tk .dn{color:var(--loss)}          /* negative change */
@keyframes qs-marquee{0%{transform:translateX(0)}100%{transform:translateX(-50%)}}
@media (prefers-reduced-motion:reduce){.ticker-track{animation:none}}

/* ── Nav (multi-page, sticky + blurred) ─────────────────────────────────── */
nav{position:sticky;top:0;z-index:50;backdrop-filter:blur(12px);background:rgba(5,5,5,.82);border-bottom:1px solid var(--border)}
nav .wrap{display:flex;align-items:center;justify-content:space-between;height:58px}
/* .brand — lockup: emerald mark + wordmark in the display face; identical on
   every page. Weight 500, not 700: the bundled face declares its weight range
   so nothing is synthesised, and a pixel grid at 700 reads as noise. */
.brand{display:flex;align-items:center;gap:10px;font-family:var(--font-display);font-weight:500;letter-spacing:-.005em;font-size:16.5px}
.brand .dot{width:12px;height:12px;border-radius:3px;background:var(--grad);box-shadow:0 0 14px rgba(52,211,153,.6)}
.brand b{color:var(--accent)}
/* .navlinks — desktop destination list (hidden below 900px, .navmenu takes
   over). Restyled 2026-09 into the pack's pill rail: one rounded container,
   pill links inside it, the current page filled rather than merely coloured.
   Markup is unchanged — this is the same flex row it always was. */
.navlinks{display:flex;gap:2px;align-items:center;padding:3px;border:1px solid var(--border2);
  border-radius:var(--pill);background:rgba(255,255,255,.03);backdrop-filter:blur(12px)}
.navlinks a{display:grid;place-items:center;min-height:30px;padding:0 12px;border-radius:var(--pill);
  color:var(--dim);font-size:12.5px;font-weight:500;transition:color .15s,background .15s}
.navlinks a:hover{color:var(--text);background:rgba(255,255,255,.08)}
.navlinks a[aria-current]{color:var(--accent);background:rgba(52,211,153,.10)}

/* ── Mobile nav — <details> disclosure, no JS, keyboard-operable ────────── */
/* .navmenu — hamburger disclosure shown below 900px beside the brand + CTA */
.navmenu{display:none;position:relative;margin-left:auto;margin-right:10px}
/* A circle, not a rounded square: this is the last piece of nav chrome, and
   the restyle's rule is that chrome is round. It sits beside a pill CTA. */
.navmenu>summary{list-style:none;cursor:pointer;display:grid;place-items:center;
  width:38px;height:38px;border:1px solid var(--border2);border-radius:50%;color:var(--text)}
.navmenu>summary::-webkit-details-marker{display:none}
.navmenu>summary:hover{border-color:var(--accent);color:var(--accent)}
.navmenu[open]>summary{border-color:var(--accent);color:var(--accent)}
/* MEASURED, Edge/Chromium 151: display:none here is load-bearing — a closed
   <details> does not hide an absolutely positioned descendant whose containing
   block is the <details> itself, so visibility must key off [open]. */
.navmenu .sheet{display:none;position:absolute;right:0;top:46px;min-width:200px;z-index:60;
  background:var(--panel);border:1px solid var(--border);border-radius:10px;padding:6px;
  box-shadow:0 18px 46px rgba(0,0,0,.55);gap:2px}
.navmenu[open] .sheet{display:grid}
.navmenu .sheet a{display:block;padding:9px 12px;border-radius:7px;font-size:14px;color:var(--dim)}
.navmenu .sheet a:hover{background:var(--glass);color:var(--text)}
.navmenu .sheet a[aria-current]{color:var(--accent)}

/* keyboard focus ring — :focus-visible only, so mouse clicks stay quiet.
   3px of offset (was 2px): pill chrome needs the ring clear of the curve. */
:focus-visible{outline:2px solid var(--accent);outline-offset:3px}

/* ── Buttons ────────────────────────────────────────────────────────────── */
/* .btn — base button/link: compact, semibold, and PILL since the 2026-09
   restyle, so every control on the page belongs to the same rounded family as
   the nav rail. */
.btn{display:inline-flex;align-items:center;gap:8px;border:none;cursor:pointer;font-weight:600;font-size:13.5px;padding:10px 18px;border-radius:var(--pill);transition:box-shadow .2s,background .2s,border-color .2s,color .2s;font-family:inherit;white-space:nowrap}
/* .btn-primary — emerald fill, black ink; the one loud action per view */
.btn-primary{background:var(--accent);color:var(--on-accent);box-shadow:0 4px 16px rgba(52,211,153,.22)}
.btn-primary:hover{background:var(--accent-2);box-shadow:0 6px 22px rgba(52,211,153,.34)}
/* .btn-ghost — hairline ring, transparent fill; the quiet sibling */
.btn-ghost{background:rgba(255,255,255,.03);color:var(--text);border:1px solid var(--border2)}
.btn-ghost:hover{border-color:var(--accent);color:var(--accent)}
/* .btn-lg — hero-scale variant */
.btn-lg{padding:14px 28px;font-size:15px}

/* ── Sections / headings / labels ───────────────────────────────────────── */
section{padding:72px 0}
.center{text-align:center}
/* .band — full-bleed section separated by hairlines (reference border-b idiom) */
.band{border-top:1px solid var(--border);border-bottom:1px solid var(--border)}
/* .band-alt — same, one step raised for alternating rhythm */
.band-alt{border-top:1px solid var(--border);border-bottom:1px solid var(--border);background:var(--band)}
/* .kicker — the section eyebrow: mono, uppercase, tracked wide, emerald */
.kicker{color:var(--accent);font-weight:600;letter-spacing:.22em;text-transform:uppercase;font-size:11px;font-family:var(--font-mono)}
/* .microlabel — the smaller neutral micro-label (stat keys, table heads) */
.microlabel{font-family:var(--font-mono);font-size:10px;font-weight:500;letter-spacing:.18em;text-transform:uppercase;color:var(--muted)}
/* Display headings — the bundled pixel face, set the way that face wants to be
   set: weight 500, tight tracking, leading pulled under 1. h3 is DELIBERATELY
   left on the body face: at 18px a pixel grid stops being a display effect and
   starts being a legibility tax, and h3 is the size where card titles and
   clause headings live. Same split the source pack makes — it uses its pixel
   face for the wordmark, the hero line and the metric numerals, never for
   anything you have to read a paragraph of. */
h1{font-size:clamp(34px,4.6vw,60px);line-height:.96;font-weight:500;letter-spacing:-.045em;font-family:var(--font-display)}
h2{font-size:clamp(25px,3vw,40px);line-height:1.02;font-weight:500;letter-spacing:-.035em;margin:10px 0 14px;font-family:var(--font-display)}
h3{font-size:18px;font-weight:600;margin:22px 0 8px;font-family:var(--font-body);letter-spacing:-.01em}
/* .dim inside a heading — the greyed second half of a headline (white/40) */
h1 .dim,h2 .dim{color:var(--muted)}
h1 .g,h2 .g{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
h1 .k,h2 .k{color:var(--accent)}
/* .lead — the standfirst under a heading; secondary ink, bounded measure */
.lead{color:var(--dim);font-size:15.5px;line-height:1.65;max-width:680px}
.lead.center{margin:0 auto}
/* .eyebrow — bordered chip variant of the kicker (legacy pages). Pill + blur
   since the 2026-09 restyle: this is chrome, and chrome is round. */
.eyebrow{display:inline-flex;align-items:center;gap:8px;font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--accent);border:1px solid rgba(52,211,153,.2);background:rgba(52,211,153,.08);padding:6px 14px;border-radius:var(--pill);margin-bottom:18px;font-family:var(--font-mono);backdrop-filter:blur(10px)}
/* .mtag — tiny mono tag over a card (legacy pages) */
.mtag{display:inline-block;font-family:var(--font-mono);font-size:11px;color:var(--accent);letter-spacing:.04em;border:1px solid rgba(52,211,153,.2);background:rgba(52,211,153,.06);padding:2px 9px;border-radius:var(--pill);margin-bottom:12px}

/* ── Tone chips — emerald/amber/sky/violet on /10 fills with /20 rings ──── */
/* .tone — base chip: mono micro-type on a translucent fill with a ring */
.tone{display:inline-flex;align-items:center;gap:6px;padding:3px 10px;border-radius:var(--pill);
  font-family:var(--font-mono);font-size:10px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  box-shadow:inset 0 0 0 1px}
.tone i{width:5px;height:5px;border-radius:50%;background:currentColor;display:block;flex:none}
.tone-emerald{color:var(--accent);background:rgba(52,211,153,.10);box-shadow:inset 0 0 0 1px rgba(52,211,153,.22)}  /* brand / verified */
.tone-amber{color:var(--gold);background:rgba(252,211,77,.10);box-shadow:inset 0 0 0 1px rgba(252,211,77,.22)}      /* caveat / illustrative */
.tone-sky{color:var(--sky);background:rgba(125,211,252,.10);box-shadow:inset 0 0 0 1px rgba(125,211,252,.22)}       /* neutral info */
.tone-violet{color:var(--vio);background:rgba(196,181,253,.10);box-shadow:inset 0 0 0 1px rgba(196,181,253,.22)}    /* AI / model */
.tone-rose{color:var(--loss);background:rgba(251,113,133,.10);box-shadow:inset 0 0 0 1px rgba(251,113,133,.22)}     /* loss / refusal */
.tone-mute{color:var(--dim);background:rgba(255,255,255,.05);box-shadow:inset 0 0 0 1px rgba(255,255,255,.10)}      /* system / neutral */

/* ── Stat tiles — the metric strip ──────────────────────────────────────── */
/* .statgrid — a row of .stat tiles */
.statgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:24px}
/* .stat — one tile: micro key, big display value, small caption.
   RESTYLED 2026-09: the rule moved from the LEFT edge to the TOP and got the
   bright --rule weight. Same element, same three children, same grid — but a
   rule over a number reads as a measurement on a page, where a rule beside it
   reads as a list item. This is the source pack's metric strip.
   NOT reordered with `order`, though the pack puts its numeral first: these
   tiles read key -> value -> caption in the DOM, and flipping them visually
   would hand a screen-reader user a different sentence from the one on the
   screen. The rule carries the look; the reading order stays honest. */
.stat{border-top:1px solid var(--rule);padding-top:12px;display:flex;flex-direction:column;gap:4px}
.stat .k{font-family:var(--font-mono);font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--muted)}
/* The headline numeral takes the display face. It keeps tabular-nums so a
   column of them still lines up — the face is proportional, and without this
   a changing figure would shuffle sideways. */
.stat .v{font-family:var(--font-display);font-variant-numeric:tabular-nums;font-size:clamp(24px,3vw,38px);font-weight:500;line-height:1;letter-spacing:-.04em;color:var(--text)}
.stat .v.accent{color:var(--accent)}
.stat .d{font-size:12px;color:var(--muted);line-height:1.4}

/* ── Cards ──────────────────────────────────────────────────────────────── */
.grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:32px}
/* .card — solid card surface with hairline ring. The 2026-09 restyle adds the
   pack's two-part depth: a 1px inset highlight along the TOP edge (so the card
   catches light like a physical panel) over a wide, very soft drop shadow.
   Both are in one box-shadow; the hover rules further down restate the inset
   so the highlight does not blink out when the card lifts. */
.card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:22px;transition:border-color .2s;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.045),0 14px 46px rgba(0,0,0,.32)}
.card:hover{border-color:var(--border2)}
/* .glasscard — glassy variant: white/4 fill, white/10 ring */
.glasscard{background:var(--glass);border:1px solid rgba(255,255,255,.10);border-radius:var(--radius);padding:22px;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05),0 14px 46px rgba(0,0,0,.28);backdrop-filter:blur(14px)}
.card .ic{width:44px;height:44px;border-radius:12px;display:flex;align-items:center;justify-content:center;font-size:22px;background:rgba(52,211,153,.10);border:1px solid rgba(52,211,153,.22);margin-bottom:14px}
/* Icon chips are bespoke inline SVG — stroke-based, currentColor, 24x24
   viewBox — defined per page as a hidden <symbol> sprite and placed with
   <use href="#i-name">. Emoji are banned as iconography; the set is
   demonstrated on styleguide.html. */
.ic{color:var(--accent)}
.ic svg{width:22px;height:22px;display:block}
.card h3{margin-top:0;font-size:17px}
.card p{color:var(--dim);font-size:14px}
/* .chip — the 40px icon chip used beside prose (pillars, diff cards) */
.chip{width:40px;height:40px;border-radius:10px;display:grid;place-items:center;flex:none;color:var(--accent);
  background:rgba(52,211,153,.10);box-shadow:inset 0 0 0 1px rgba(52,211,153,.25)}
.chip svg{width:20px;height:20px}

/* ── Terminal window frame — chrome bar + three dots over a capture ─────── */
/* .termframe — the framed "app window" that holds a real screenshot */
.termframe{border-radius:var(--radius);border:1px solid rgba(255,255,255,.10);overflow:hidden;position:relative;background:var(--panel);
  box-shadow:0 60px 120px -40px rgba(0,0,0,.9)}
/* .termbar — the window-chrome strip: dots, mono title, provenance tag */
.termbar{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:9px 14px;background:var(--panel);border-bottom:1px solid var(--border)}
/* .termdots — the three faux window dots */
.termdots{display:flex;gap:6px}
.termdots i{width:10px;height:10px;border-radius:50%;background:rgba(255,255,255,.12);display:block}
/* .termtitle — mono path/caption in the chrome bar */
.termtitle{color:var(--muted);font-size:11.5px;font-family:var(--font-mono)}
/* .termtag — emerald provenance chip in the chrome bar ("Real capture") */
.termtag{color:var(--accent);font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;font-family:var(--font-mono);
  border:1px solid rgba(52,211,153,.35);background:rgba(52,211,153,.08);padding:3px 11px;border-radius:var(--pill);white-space:nowrap}
.termframe img{display:block;width:100%;height:auto}

/* ── Family / module cards (the 66-screens grid) ────────────────────────── */
/* .famgrid — the module-card lattice */
.famgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-top:36px}
/* .famcard — one module: tone chip + zero-padded count + mono tab list */
.famcard{position:relative;overflow:hidden;border:1px solid var(--border);border-radius:var(--radius);background:var(--card);padding:18px;transition:border-color .2s;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.04),0 12px 38px rgba(0,0,0,.28)}
.famcard:hover{border-color:var(--border2)}
.famcard .hd{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:14px}
.famcard .count{font-family:var(--font-mono);font-variant-numeric:tabular-nums;font-size:11px;color:var(--muted)}
.famcard ul{list-style:none;display:grid;gap:6px;font-family:var(--font-mono);font-size:11.5px;color:#cfcbc4}
.famcard li{display:flex;align-items:baseline;gap:8px;line-height:1.35}
.famcard li::before{content:"\203A";color:rgba(255,255,255,.25);flex:none}

/* ── Checklist — emerald check rows ─────────────────────────────────────── */
/* .checklist — feature/benefit rows with the drawn check chip */
.checklist{list-style:none;display:grid;gap:12px;margin-top:22px}
.checklist li{display:flex;gap:12px;align-items:flex-start;font-size:14px;color:var(--text);line-height:1.5}
.checklist li .ic{color:var(--accent);flex:none;margin-top:1px}
.checklist li .ic svg{width:18px;height:18px;display:block}

/* ── FAQ — <details> rows ───────────────────────────────────────────────── */
/* .faqlist — column of .faq-item disclosures */
.faqlist{max-width:820px;margin-top:28px;border-top:1px solid var(--border)}
details.faq-item{border-bottom:1px solid var(--border)}
details.faq-item summary{list-style:none;cursor:pointer;padding:18px 4px;display:flex;justify-content:space-between;
  align-items:center;gap:16px;font-weight:500;font-size:15.5px;color:var(--text)}
details.faq-item summary::-webkit-details-marker{display:none}
.faq-item summary .plus{color:var(--muted);font-family:var(--font-mono);font-size:19px;line-height:1;flex:none;transition:transform .2s,color .2s}
details[open].faq-item summary .plus{transform:rotate(45deg);color:var(--accent)}
.faq-item .a{padding:0 4px 18px;color:var(--dim);font-size:14px;line-height:1.65;max-width:760px}

/* ── Pricing cards ──────────────────────────────────────────────────────── */
/* .pricegrid — the two-plan lattice */
.pricegrid{display:grid;grid-template-columns:1fr 1fr;gap:18px;max-width:860px;margin:34px auto 0}
/* .pcard — one plan card; .best gets the emerald treatment */
.pcard{position:relative;border:1px solid var(--border);border-radius:var(--radius);background:var(--card);padding:28px;display:flex;flex-direction:column;text-align:left;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05),0 16px 50px rgba(0,0,0,.34)}
.pcard.best{border-color:rgba(52,211,153,.40);background:linear-gradient(180deg,rgba(52,211,153,.06),var(--card) 55%)}
/* .badge-best — the "BEST VALUE" flag riding the featured card */
.badge-best{position:absolute;top:-11px;left:22px;background:var(--accent);color:var(--on-accent);font-family:var(--font-mono);
  font-size:10px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;padding:4px 12px;border-radius:var(--pill)}
.pcard .plan{font-family:var(--font-mono);text-transform:uppercase;letter-spacing:.14em;font-size:11.5px;color:var(--muted)}
/* The price in the display face. TYPE ONLY — the figures themselves are
   contract terms and are set in the page markup, never here.
   TRACKING IS DELIBERATELY LOOSER THAN THE HEADINGS' -.045em. At 46px that
   pulls each glyph 2px left, which was enough to slide the "$" INTO the first
   digit — measured on this page, "$50" rendered as an overlap. A headline can
   afford tight tracking; a price is a contract term and has to be unambiguous
   at a glance. The <small> markers ($ and .99) are also reset to zero tracking
   and back onto the body face: they are 16px, well under the size where a
   pixel grid is a display effect rather than a legibility tax. */
.pcard .amt{font-family:var(--font-display);font-size:46px;font-weight:500;letter-spacing:-.02em;line-height:1;margin:12px 0 4px;font-variant-numeric:tabular-nums}
.pcard .amt small{font-size:16px;color:var(--muted);font-weight:500;letter-spacing:normal;font-family:var(--font-body)}
.pcard .per{color:var(--muted);font-size:13px}
.pcard .checklist{margin:20px 0 22px;flex:1}
.pcard .btn{width:100%;justify-content:center}
.pcard .fineprint{color:var(--muted);font-size:11.5px;text-align:center;margin-top:12px}

/* ── CTA band ───────────────────────────────────────────────────────────── */
/* .cta-band — the closing full-width invitation card */
.cta-band{border:1px solid var(--border);border-radius:14px;text-align:center;padding:64px 32px;
  background:linear-gradient(180deg,rgba(52,211,153,.05),transparent)}
.cta-band .spark{color:var(--accent);margin-bottom:14px}
.cta-band .spark svg{width:32px;height:32px}
.cta-band .lead{margin-left:auto;margin-right:auto}
.cta-band .cta-row{justify-content:center;margin-top:24px}
/* .cta-row — a wrapping row of buttons */
.cta-row{display:flex;gap:12px;flex-wrap:wrap;align-items:center;margin-top:26px}
/* .cta-note — the small reassurance line under a CTA */
.cta-note{color:var(--muted);font-size:12.5px;margin-top:14px}
.cta-note b{color:var(--text);font-weight:600}
/* .morelink — arrow link whose gap widens on hover (two flex spans required) */
.morelink{display:inline-flex;align-items:center;gap:7px;margin-top:26px;color:var(--accent);font-family:var(--font-mono);font-size:12.5px;font-weight:600;
  transition:gap .18s ease,color .15s}
.morelink:hover{gap:11px;color:var(--accent-2)}

/* ── Callout ────────────────────────────────────────────────────────────── */
/* .callout — emerald left-rule aside; .warn flips it to the amber caveat */
.callout{background:linear-gradient(180deg,rgba(52,211,153,.07),transparent);border:1px solid var(--border);border-left:3px solid var(--accent);border-radius:var(--radius);padding:18px 20px;margin:20px 0;color:var(--dim);font-size:14px}
.callout.warn{border-left-color:var(--gold);background:linear-gradient(180deg,rgba(252,211,77,.06),transparent)}
.callout b{color:var(--text)}

/* ── Prose / legal / docs pages ─────────────────────────────────────────── */
/* .doc — bounded prose column for legal + documentation pages */
.doc{max-width:840px;margin:0 auto;padding:56px 24px 40px}
.doc .updated{color:var(--muted);font-size:13px;margin:6px 0 26px}
.doc h2{font-size:22px;margin:34px 0 10px;padding-top:6px}
.doc h3{font-size:17px;margin:20px 0 6px}
.doc p,.doc li{color:var(--dim);font-size:15px;margin:10px 0}
.doc strong{color:var(--text)}
.doc ul,.doc ol{margin:10px 0 10px 22px}
.doc a{color:var(--accent)}
.doc a:hover{text-decoration:underline}
.doc .toc{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:16px 20px;margin:22px 0}
.doc .toc a{display:block;color:var(--dim);font-size:14px;padding:3px 0}
.doc .toc a:hover{color:var(--accent)}
/* .placeholder — amber dashed "worked example / unverified" inline chip */
.placeholder{color:var(--gold);background:rgba(252,211,77,.08);border:1px dashed rgba(252,211,77,.40);border-radius:var(--radius-sm);padding:1px 7px;font-size:13px}

/* ── Tables — mono numerals so figures compare down a column ────────────── */
.tablewrap{overflow-x:auto;margin-top:28px;border:1px solid var(--border);border-radius:var(--radius)}
table{width:100%;border-collapse:collapse;min-width:640px;font-variant-numeric:tabular-nums}
th,td{padding:13px 16px;text-align:left;border-bottom:1px solid var(--border);font-size:13.5px}
thead th{background:rgba(255,255,255,.02);color:var(--muted);font-weight:500;font-size:10.5px;text-transform:uppercase;letter-spacing:.14em;font-family:var(--font-mono)}
tbody td:first-child{color:var(--dim)}
/* .yes / .no — our green check vs the muted dash in comparison grids */
.yes{color:var(--gain);font-weight:700}.no{color:var(--muted)}
/* .unv — an "unverified" competitor claim; amber, honest about sourcing */
.unv{color:var(--gold);font-size:12px}

/* ── Strip + pillars (edge-to-edge honesty band) ────────────────────────── */
/* .strip — full-bleed hairline band on a raised ground */
.strip{border-top:1px solid var(--border);border-bottom:1px solid var(--border);background:var(--band);margin-top:52px}
/* .pillars — three icon+prose columns inside a .strip */
.pillars{display:grid;grid-template-columns:repeat(3,1fr);gap:26px;padding:32px 24px}
.pillar{display:flex;gap:14px;align-items:flex-start}
.pillar p{font-size:13.5px;color:var(--dim);line-height:1.6}
.pillar p b{color:var(--text);font-weight:600;display:block;margin-bottom:3px}

/* legacy metric strip (docs.html). Given the same bright top rule as .stat in
   the 2026-09 restyle: it is the four-up fact row that actually ships on a
   page, so it is where the metric-strip idiom has to read. Rule, label, then
   the line under it. */
.mstrip{border-top:1px solid var(--border);border-bottom:1px solid var(--border);background:var(--band)}
.mstrip .wrap{display:grid;grid-template-columns:repeat(4,1fr);gap:22px;padding:22px var(--page-inset) 24px}
.mstrip .cell{font-family:var(--font-mono);font-variant-numeric:tabular-nums;font-size:12.5px;color:var(--dim);line-height:1.6;
  border-top:1px solid var(--rule);padding-top:12px}
.mstrip .cell b{color:var(--text);display:block;font-size:13px;margin-bottom:2px}
@media(max-width:900px){.mstrip .wrap{grid-template-columns:1fr 1fr}}
@media(max-width:560px){.mstrip .wrap{grid-template-columns:1fr}}

/* ── Mega footer ────────────────────────────────────────────────────────── */
footer{border-top:1px solid var(--border);padding:52px 0 34px;margin-top:40px;color:var(--muted);font-size:13.5px;background:var(--bg)}
footer .cols{display:grid;grid-template-columns:1.6fr 1fr 1fr 1fr;gap:28px;margin-bottom:30px}
footer h4{color:var(--muted);font-size:10.5px;text-transform:uppercase;letter-spacing:.18em;margin-bottom:12px;font-family:var(--font-mono);font-weight:500}
footer a{display:block;color:var(--dim);padding:4px 0;font-size:13.5px}
footer a:hover{color:var(--accent)}
/* .disc — the legal disclosure line; its copy is contract language, keep it */
footer .disc{border-top:1px solid var(--border);padding-top:18px;color:var(--muted);font-size:11.5px;line-height:1.6;max-width:900px;font-family:var(--font-mono)}

/* ── Responsive ─────────────────────────────────────────────────────────── */
/* .navlinks{display:none} is only safe because .navmenu{display:block} sits
   beside it — the two must stay together or the destination list vanishes. */
@media(max-width:1100px){.famgrid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:900px){.navlinks{display:none}.navmenu{display:block}.grid{grid-template-columns:1fr 1fr}footer .cols{grid-template-columns:1fr 1fr}
  .statgrid{grid-template-columns:1fr 1fr;gap:18px}.pillars{grid-template-columns:1fr}}
@media(max-width:640px){.famgrid{grid-template-columns:1fr}.pricegrid{grid-template-columns:1fr}}
@media(max-width:560px){.grid,footer .cols{grid-template-columns:1fr}
  /* MEASURED at 375px: brand + hamburger + CTA hold one line only with the
     wrap padding and CTA trimmed. */
  nav .wrap{padding:0 14px}
  .navmenu{margin-right:8px}
  nav .wrap>.btn{padding:9px 13px;font-size:13px}}

/* SELF-HOSTED DISPLAY FACE — ACTIVATED 2026-09-04.
   This block used to hold a commented-out TEMPLATE, with a note that which
   face (if any) replaces the system stack was the owner's call, made by eye.
   That call has been made: the live @font-face sits at the TOP of this file
   (Geist Pixel Circle, bundled at assets/fonts/), and --font-display in :root
   points at it. The procedure the template described still holds if the face
   is ever swapped — drop the new file beside the old one, repoint the token,
   and every heading follows without a single page being edited.
   Two things that have to stay true of any replacement:
     * it is BUNDLED, never fetched. The site's CSP is style-src 'self' plus
       inline, so a font-CDN link is blocked SILENTLY — the page renders in the
       fallback and nothing anywhere reports it.
     * its glyph coverage is CHECKED first. A missing glyph falls back
       per-character, so one absent en dash shatters a headline mid-word.
   EDITING HAZARD: a comment ends at the FIRST star-slash sequence — CSS
   comments do not nest and have no escape — so never write a glob like
   star-star-slash in here; it terminates the comment mid-sentence and the
   parser silently eats the next rule. See
   tests/unit/test_css_comments_are_closed_where_intended.py. */

/* =====================================================================
   Legal / policy pages (terms, eula, privacy, disclaimer) — 2026-08
   restyle. Hero band + sticky mono TOC rail + glass section cards.
   Everything is scoped under .legaldoc (or ld- prefixed) so docs.html's
   plain .doc column and the legacy .toc rules are untouched. The visible
   text of these pages is contract copy under lawyer review: these rules
   are skin only and must never inject content (no CSS-generated text). */
.legaldoc{padding-bottom:44px}
/* .ld-hero — full-bleed header band: eyebrow, title, date chip, intro */
.ld-hero{border-bottom:1px solid var(--border);background:radial-gradient(900px 340px at 15% -55%,rgba(52,211,153,.09),transparent 60%),var(--band);padding:60px 0 40px}
.ld-hero .wrap,.ld-body{max-width:1140px}
.ld-hero h1{font-size:clamp(30px,4vw,44px);margin:0 0 16px}
/* .ld-date — mono micro-chip carrying the effective-date line */
.ld-date{display:inline-flex;align-items:center;gap:8px;font-family:var(--font-mono);font-size:11px;font-weight:500;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);border:1px solid var(--border);background:var(--glass);padding:6px 14px;border-radius:var(--pill)}
.ld-date i{width:5px;height:5px;border-radius:50%;background:var(--accent);display:block;flex:none}
/* .ld-intro — the preamble prose (and callouts) that live in the hero */
.ld-intro{max-width:880px}
.ld-intro p{color:var(--dim);font-size:15px;line-height:1.75;margin:16px 0 0}
.ld-intro strong{color:var(--text)}
.ld-intro a{color:var(--accent)}
.ld-intro a:hover{text-decoration:underline}
.ld-hero .callout{margin:18px 0 0;max-width:880px;font-size:14.5px;line-height:1.7}
/* .ld-body — sticky TOC rail on the left, section cards on the right */
.ld-body{margin:0 auto;padding:36px 24px 0;display:grid;grid-template-columns:272px minmax(0,1fr);gap:32px;align-items:start}
.ld-rail{position:sticky;top:74px}
/* .ld-toc — glass contents card: mono numbered links, emerald top rule */
.ld-toc{background:var(--glass);border:1px solid var(--border);border-top:2px solid rgba(52,211,153,.35);border-radius:var(--radius);padding:14px 16px}
.ld-toc a{display:block;font-family:var(--font-mono);font-size:12.5px;line-height:1.5;color:var(--dim);padding:5px 0;break-inside:avoid}
.ld-toc a:hover{color:var(--accent)}
/* .ld-card — one numbered clause per glass card */
.ld-card{background:var(--glass);border:1px solid var(--border);border-radius:var(--radius);padding:24px 26px;margin:0 0 16px}
.ld-card h2{font-size:19px;line-height:1.3;letter-spacing:-.01em;margin:0 0 4px;scroll-margin-top:76px}
.ld-card .secno{font-family:var(--font-mono);font-size:.74em;color:var(--accent);margin-right:4px}
.ld-card p,.ld-card li{color:var(--dim);font-size:14.5px;line-height:1.7;margin:10px 0}
.ld-card>p:last-child,.ld-card>ul:last-child{margin-bottom:0}
.ld-card strong{color:var(--text)}
.ld-card ul{margin:10px 0 10px 22px}
.ld-card a{color:var(--accent)}
.ld-card a:hover{text-decoration:underline}
@media(max-width:960px){
  .ld-body{grid-template-columns:1fr;gap:22px}
  .ld-rail{position:static}
  .ld-toc{columns:2;column-gap:26px}
  .ld-card{padding:20px 18px}}
@media(max-width:560px){.ld-toc{columns:1}}

/* =====================================================================
   Motion + hover polish — 2026-08 homepage pass, shared so every page's
   cards behave alike. Purely additive: these later rules at equal
   specificity deliberately win the cascade over the base card rules above.
   EDITING HAZARD (same as the header): never write a star-star-slash glob
   inside a comment — the comment ends at the first star-slash sequence and
   the next rule is silently eaten. */

/* Cards lift with a soft emerald edge glow on hover; :focus-within gives a
   keyboard user the same affordance on cards that contain a focusable
   control (the pricing buttons). 180ms, matching the site's .2s idiom.
   Each hover shadow RESTATES the resting inset top-highlight as its first
   layer. box-shadow replaces wholesale rather than merging, so omitting it
   would make the card's lit top edge blink off at the moment it lifts —
   exactly backwards. */
.card,.famcard,.pcard{transition:border-color .18s ease,transform .18s ease,box-shadow .18s ease}
.card:hover,.card:focus-within,
.famcard:hover,.famcard:focus-within{
  transform:translateY(-2px);border-color:rgba(52,211,153,.30);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06),0 10px 30px rgba(0,0,0,.45),0 0 0 1px rgba(52,211,153,.10),0 0 24px rgba(52,211,153,.08)}
.pcard:hover,.pcard:focus-within{
  transform:translateY(-4px);border-color:rgba(52,211,153,.45);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.07),0 14px 38px rgba(0,0,0,.5),0 0 0 1px rgba(52,211,153,.14),0 0 30px rgba(52,211,153,.10)}

/* The marquee pauses while the pointer is over it, so a quote you want to read
   holds still. Pausing changes nothing about the numbers: each carries the time
   it was quoted, and the chip's LIVE/DELAYED state comes from the server. */
.ticker:hover .ticker-track{animation-play-state:paused}

/* Reduced motion — EVERY animation and transition site-wide collapses to a
   settled, static state: the marquee freezes (see also the ticker's own
   reduce rule above), hover lifts become instant, the cursor blink stops,
   and the homepage's entrance/reveal/counter layer never arms because its
   inline JS checks this same media query before adding html.anim. */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    transition-delay:0ms !important}
}
