/* ============================================================================
   AI CHAUFFEUR — SHARED TOKENS + FONT LOCK          RUN 9 · "SIGNAL CUT v1.5"
   ----------------------------------------------------------------------------
   THIS IS THE CHAUFFEUR COPY. It lives under chauffeur/ and is served only to
   aichauffeur.ai, which is a separate Vercel project rooted at /chauffeur/. The
   AVA parent keeps its own copy of this filename at the repo root and RUN 9 did
   not touch it. The two files share a name and nothing else — do not sync them.

   Linked in every chauffeur page <head> BEFORE that page's own styles, so every
   page consumes the same tokens and the same keyboard-focus rule. It sets NO
   base/body styles, so linking it onto a page can never cause a regression.

   The palette law lives in the SIGNAL v1.1 TOKEN BLOCK below, which is
   byte-identical here, in assets/aic.css and in the embedded <style> in
   index.html. Read it there; it is not restated here, because a restated law is
   a law with two versions.

   WHAT USED TO BE HERE: the RUN 3 SEMANTIC LAW block, written when the accent
   was cyan and money was gold. Both of those colours are retired on this brand
   and neither hex appears in this file any more, so the block was describing a
   site that no longer exists. Comments ship; a stale one is worse than none.
   ============================================================================ */

/* ============================================================================
   SELF-HOSTED MONO. `--mono` has named 'JetBrains Mono' sitewide since the
   first build, but the pages never LOADED it — the family silently fell through
   to ui-monospace, so the whole technical voice of the site (rail, chips,
   timestamps, eyebrows) rendered in whatever mono the OS happened to ship.

   RUN 8 SUPERSEDES THIS BLOCK. The mono face moved into the FONT LOCK block
   below, which also self-hosts Space Grotesk, gives both faces their declared
   unicode-range, and adds a metric-matched fallback for each. The note stays
   because it records why the mono was already local: measuring that run found
   exactly ONE external font file left per page, not two.
   ============================================================================ */

/* ══ RUN 8 · FONT LOCK — SELF-HOSTED FACES ═══════════════════════════════════
   CANONICAL BLOCK. Byte-identical in all three CSS homes on this site:
   assets/circulant.css (all 12 pages), assets/aic.css (the 11 pages that load
   it) and the embedded <style> in index.html (which loads no aic.css). RUN 7
   shipped a site with two heads because one rule landed in only one copy;
   `node tools/run8_gate.js` asserts these three copies match character for
   character. Change one, change all three.

   THE FILES ARE GOOGLE'S FILES. chauffeur/fonts/space-grotesk.woff2 and
   jetbrains-mono.woff2 are SHA-256 IDENTICAL to the files Google's font CDN
   served for this site's exact request — verified, not assumed. (The hostname is
   deliberately not written out anywhere on this site: the gate greps for it, and
   a comment that quotes the banned string makes every future audit lie. RUN 7
   learned that one the hard way.) Nothing about the
   rendered face changes; only where it is fetched from. That is why no line
   break on the site moves, and why that claim is a measurement rather than a
   hope: a subset that differed by one glyph would re-wrap every page.

   unicode-range is Google's own declared latin range, VERBATIM. It is what
   decides which family paints a character, so reproducing it exactly keeps
   '→' (U+2192) and '✓' (U+2713) — present in NO subset of either family —
   falling through to the system stack exactly as they already do. Widen it and
   those two glyphs start coming from the fallback face at a different width.

   The Fallback faces are metric-matched so the swap moves zero pixels:
     Space Grotesk  <- Arial        size-adjust 108.9963%  (worst weight error 0.25%)
     JetBrains Mono <- Courier New  size-adjust  99.9837%
   Arial is the reference the brief names and it is right for the sans. It is
   wrong for the mono: Arial's advances span 72% of an em while JetBrains Mono's
   are every one 0.600, so an Arial-backed mono fallback re-flows every label the
   moment the real face lands — the exact defect this run exists to remove.
   Courier New measures 0.6001 em, a 0.02% match, and is monospace like the face
   it stands in for.
   ═══════════════════════════════════════════════════════════════════════════ */
@font-face{
  font-family:'Space Grotesk';
  font-style:normal;
  font-weight:300 700;
  font-display:swap;
  src:url('/fonts/space-grotesk.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'Space Grotesk Fallback';
  font-style:normal;
  font-weight:300 700;
  src:local('Arial'),local('Helvetica Neue'),local('Liberation Sans');
  size-adjust:108.9963%;
  ascent-override:90.2783%;
  descent-override:26.7899%;
  line-gap-override:0%;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'JetBrains Mono';
  font-style:normal;
  font-weight:400 700;
  font-display:swap;
  src:url('/fonts/jetbrains-mono.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
@font-face{
  font-family:'JetBrains Mono Fallback';
  font-style:normal;
  font-weight:400 700;
  src:local('Courier New'),local('Liberation Mono'),local('Nimbus Mono PS');
  size-adjust:99.9837%;
  ascent-override:102.0166%;
  descent-override:30.0049%;
  line-gap-override:0%;
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
}
/* ══ END RUN 8 · FONT LOCK ══════════════════════════════════════════════════ */

/* ══ SIGNAL v1.1 · TOKEN BLOCK ═══════════════════════════════════════════════
   CANONICAL BLOCK. Byte-identical in all three CSS homes on this site:
   assets/circulant.css (all 12 pages), assets/aic.css (the 11 pages that load
   it) and the embedded <style> in index.html (which loads no aic.css).
   `node tools/aic_signal_gate.js` asserts the three copies match character for
   character. Change one, change all three.

   Every ratio below is MEASURED against the surface named, not eyeballed.

     --ink              16.74:1 on midnight  ·  15.70:1 on surface
     --signal-blue       5.13:1 on midnight  ·   4.81:1 on surface
     --sky               9.10:1 on midnight  ·   8.54:1 on surface
     --success-green    12.18:1 on midnight  ·  11.42:1 on surface
     --amber            10.76:1 on midnight  ·  10.09:1 on surface
     --miss-red          5.61:1 on midnight  ·   5.26:1 on surface
     --neutral           6.38:1 on midnight  ·   5.98:1 on surface
     --ink-soft         10.21:1 on midnight  ·   9.78:1 on surface
     --ink-mute          5.47:1 on midnight  ·   5.38:1 on surface
     #FFFFFF on an --action-blue fill        6.25:1
     --action-blue as a control on midnight  3.15:1  (non-text, needs 3)

   RUN 10 adds a THIRD elevation and an input ground. Measured on those:

     --ink              14.82:1 on surface-2 ·  16.18:1 on input-bg
     --ink-soft          9.42:1 on surface-2 ·   9.98:1 on input-bg
     --ink-mute          5.28:1 on surface-2 ·   5.47:1 on input-bg
     --signal-blue       4.54:1 on surface-2 ·   4.96:1 on input-bg
     --neutral           5.65:1 on surface-2 ·   6.16:1 on input-bg
     #FFFFFF on --action-blue-hover          5.19:1
     --action-blue-hover as a control        3.79:1 on midnight

   CANVAS LAW. Page-depth treatment is allowed and REQUIRED: a wide horizon
   band of the blue at 3-5% alpha rising out of the lower third, a corner
   vignette around 6%, and a grid that is brighter at the top of the document
   than at the foot of it. That is a PAGE layer — painted once, below every
   section, naming no state. COMPONENT halos stay banned outright and § 4 GLOW
   LAW is unchanged: a card separates from the canvas with a hairline and a step
   of surface, never with light thrown outside its own box.

   THE GRID TOKENS CHANGED SHAPE, and the reason is a measurement rather than a
   preference. The line colour carried .05 alpha AND was multiplied by a zone
   opacity of .04, so a rendered page line was 0.002 alpha of blue over
   midnight: 61 x 0.002 + 7 x 0.998 = 7.1, which rounds to 7. Identical to the
   background, on every channel. Every page zone on this site was drawing a grid
   that could not produce one different pixel. The hue now lives at full
   strength in --grid-line and the ZONE sets the alpha, so the two numbers below
   are what actually paints. --grid-floor is the down-page multiplier: .05 at
   the top of the document, .05 x .40 = .02 at the bottom of it.

   ROLE, not decoration. A rule that wants a colour and cannot name the state it
   paints is decoration and does not ship.

     --signal-blue   live states, text links, focus rings, selected UI, console
                     activity, and at most ONE highlighted headline phrase per
                     section. It is a TEXT and LINE colour.
     --action-blue   filled CTA buttons only, always with white lettering. It is
                     a FILL colour and never sets type.
     --sky           secondary highlight and eyebrow accent.
     --success-green renders ONLY beside a label naming the action that
                     succeeded. Label text and colour change on the same frame.
                     A flow that merely ended is not a success.
     --amber         ringing · pending · the cost of the miss.
     --miss-red      failure only. Never "attention".
     --neutral       inactive · not-yet · n/a.

   --signal-blue is deliberately never used as a fill under small white type:
   white on it lands under the body floor. Filled controls take --action-blue,
   which measures 6.25:1 with white.

   On a light or print surface the blue is --action-blue. The lighter blue
   measures 3.61:1 on paper and is large-text only there.

   The artwork under /assets/brand/ is EXEMPT and keeps its own values. Those
   are supplied production files; a recolour run does not repaint a logo.
   ══════════════════════════════════════════════════════════════════════════ */
:root{
  /* ---- surfaces ---------------------------------------------------------- */
  --midnight:#070B14;
  --surface:#0D1420;
  --surface-2:#111A2A;
  --input-bg:#0A101C;
  --line:#1B2536;
  --line-hot:rgba(61,123,255,.42);

  /* ---- type -------------------------------------------------------------- */
  --ink:#E8EDF5;
  --ink-soft:rgba(232,237,245,.78);
  --ink-mute:rgba(232,237,245,.55);

  /* ---- the three blues --------------------------------------------------- */
  --signal-blue:#3D7BFF;
  --action-blue:#1E56D6;
  --action-blue-hover:#2A63E8;
  --sky:#7FB2FF;

  /* ---- semantic ---------------------------------------------------------- */
  --success-green:#2EE6A8;
  --amber:#FFB020;
  --miss-red:#FF3B4E;
  --neutral:#8A93A6;

  /* ---- state by role ----------------------------------------------------- */
  --state-ringing:var(--amber);
  --state-listening:var(--signal-blue);
  --state-captured:var(--success-green);
  --state-idle:var(--neutral);
  --state-fail:var(--miss-red);

  /* ---- grid · § B. The HUE is one value; the ZONE sets the alpha. -------- */
  --grid-line:#3D7BFF;
  --grid-cell:64px;
  --grid-page:.05;
  --grid-console:.08;
  --grid-floor:.40;

  /* ---- elevation · § C. ONE shadow, no colour in it, one per raised panel.  */
  --raise:0 8px 24px rgba(0,0,0,.45);

  /* ---- families ---------------------------------------------------------- */
  --sans:'Space Grotesk','Space Grotesk Fallback',sans-serif;
  --mono:'JetBrains Mono','JetBrains Mono Fallback',monospace;

  /* ---- back-compat aliases ----------------------------------------------- */
  /* Every name below predates Signal and is still referenced by shipped rules.
     They are ALIASES, not second definitions: the value lives once, above. */
  --void:var(--midnight);
  --void-2:var(--surface);
  --void-raise:var(--surface);
  --void-card:rgba(13,20,32,.62);
  --canvas:var(--midnight);
  --panel:var(--surface);
  --text:var(--ink);
  --matter:var(--ink);
  --dim:var(--ink-soft);
  --body-dim:var(--ink-soft);
  --ink-dim:var(--neutral);
  --booked-green:var(--success-green);
  --booked:var(--success-green);
  --green:var(--success-green);
  --alarm:var(--miss-red);
  --red:var(--miss-red);
  --danger:var(--miss-red);
  --cyan:var(--signal-blue);
  --cyan-bright:var(--sky);
  --cyan-active:var(--sky);
  --cyan-dim:rgba(61,123,255,.18);
  --line-strong:var(--line-hot);

  /* ---- panel recipe ------------------------------------------------------ */
  /* Flat. The hairline separates the panel from the void (panel-on-void is
     1.07:1 and invisible without it); the shadow is the only elevation cue and
     it carries no hue. */
  --gx-fill:#0D1420;
  --gx-solid:#0D1420;
  --gx-line:var(--line);
  --gx-line-hot:var(--line-hot);
  --gx-line-mid:#243044;
  --gx-blur:0px;
  --gx-edge:none;

  /* ---- light + print ----------------------------------------------------- */
  --paper:#F7F8FA;
  --paper-ink:#14161C;
  --blue-on-paper:var(--action-blue);
}
/* ══ END SIGNAL v1.1 · TOKEN BLOCK ═════════════════════════════════════════ */

/* ---- Flat panel utility (opt-in) --------------------------------------- */
.glass-x{
  background: var(--surface);
  border: 1px solid var(--line);
  box-shadow: var(--raise);
}

/* ══ § A2 · CANVAS LAW — THE PAGE LAYER ══════════════════════════════════════
   ONE COPY, ON PURPOSE. This file is loaded by all twelve pages and by nothing
   else, so a page-level layer declared here cannot drift the way a rule
   duplicated into aic.css and the homepage's embedded <style> can — which is
   exactly the defect § 1 of DESIGN-SYSTEM.md exists to describe. Nothing else
   on this site declares body::before. The two ambient washes that used to live
   there were deleted in RUN 9 and are NOT being restored: those were cyan, they
   were the page's only light source, and they made every surface read as lit
   from somewhere off-canvas.

   This is not those. Two gradients, one fixed layer, zero images, zero blur():

     1  HORIZON   the blue at .045, rising out of the lower third. The page
                  reads as a room with a floor rather than a sheet of paint.
     2  VIGNETTE  black at .06, corners only. It is what lets a panel with a
                  hairline read as sitting ON something instead of being cut
                  out of it — which is the acceptance bar for this run.

   position:fixed, so it costs one composited layer and nothing at all on
   scroll. pointer-events:none, z-index:0; .wrap and section both hold z-index:1
   so no content is ever painted through it. NOTHING HERE ANIMATES, so there is
   no motion for prefers-reduced-motion to switch off — the whole layer is
   static by construction, which is also why it is free.

   body{position:relative} is here because § B's grid moves from fixed to
   absolute in this run so its depth fade can map to the DOCUMENT rather than to
   the viewport. body is the containing block that makes that work. It changes
   nothing else: every absolutely positioned rule on this site already sits
   inside a positioned .wrap, section, .console or card, and position:fixed
   elements are unaffected by it.
   ══════════════════════════════════════════════════════════════════════════ */
body{position:relative}
body::before{content:'';position:fixed;inset:0;pointer-events:none;z-index:0;
  background:
    radial-gradient(120% 48% at 50% 100%,rgba(61,123,255,.045),rgba(61,123,255,0) 68%),
    radial-gradient(118% 80% at 50% 44%,rgba(0,0,0,0) 54%,rgba(0,0,0,.06) 100%)}

/* ══ RUN 11 · § 1 · THE ANCHOR GUTTER ════════════════════════════════════════
   ONE COPY, ON PURPOSE — the same argument as the canvas layer above. This file
   is loaded by all twelve pages and by nothing else, so the offset that clears
   the fixed header cannot drift between the three CSS homes the way a rule
   duplicated into aic.css and the homepage's embedded <style> can.

   THE DEFECT. nav.top is position:fixed, so it is out of flow and the scroll
   container knows nothing about it. Every anchored section on this site landed
   its own top edge at scroll offset 0 — under the bar. Measured at 390 before
   this run, across all ten homepage section anchors: nav bottom 61px, section
   kicker top 56px. The eyebrow rendered five pixels INSIDE the header on every
   one of them, at 390 and at 430. GOOGLE LEAD PROTECTION and Operator-built are
   simply the two a reader is most likely to reach from a deep link.

   TWO PROPERTIES, TWO JOBS, AND THEY ADD. Measured rather than assumed: at 390,
   scroll-padding-top 61 alone settles the target at 61, scroll-margin-top 16
   alone settles it at 16, and the pair settles it at 77. Splitting the offset
   is deliberate.

     scroll-padding-top   clears the CHROME. It lives on the scroll container,
                          so it covers every target on the page including ones
                          no rule below names, and it applies to a link jump, a
                          focus jump and scrollIntoView() alike.
     scroll-margin-top    is the 16px GUTTER, and it belongs to the target, so a
                          target that should sit flush can opt out without
                          anyone touching the chrome clearance.

   --nav-h is the bar's REAL height and tools/aic-run11-gate.mjs asserts it
   against getBoundingClientRect() at all six viewports. A constant that
   describes the header is worthless the first time the header changes and
   nobody re-measures; this one fails loudly instead of re-clipping in silence.
   8+44+8+1 = 61 below the desktop breakpoint, 14+44+14+1 = 73 above it.

   .cb-form used to carry a private scroll-margin-top of 76px in TWO files for
   the same reason. Both are deleted: an equal-specificity rule in a later
   stylesheet would have beaten this one, and the total would have been 137px.
   ══════════════════════════════════════════════════════════════════════════ */
:root{--nav-h:61px}
@media (min-width:1024px){:root{--nav-h:73px}}
html{scroll-padding-top:var(--nav-h)}
section[id],main[id],.cb-form[id]{scroll-margin-top:16px}

/* ══ RUN 9 · WHAT THIS FILE NO LONGER CARRIES ════════════════════════════════
   The legacy AVA-parent palette, the frosted-glass card recipe, the coloured
   outer-glow utilities, the pill button pair and the pulsing status dot were
   all deleted here rather than recoloured. Every one of them was referenced by
   nothing in chauffeur/*.html — verified by grep across all twelve pages before
   the cut — and between them they declared two colours § 3 bans outright plus
   an elevation ladder § C removes. Recolouring dead rules would have carried
   both problems forward under new hex values. This is the CHAUFFEUR copy of
   this file; the AVA parent keeps its own at the repo root, untouched.
   ══════════════════════════════════════════════════════════════════════════ */

/* ---- Global keyboard focus (a11y) ------------------------------------- */
/* Matches the proven rule in styles.css; extends it to standalone pages   */
/* that do not link styles.css. Only visible on keyboard focus.            */
*:focus-visible {
  outline: 2px solid var(--signal-blue);
  outline-offset: 2px;
}

/* ---- Motion safety ---------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}
