/* ═══════════════════════════════════════════════════════════════════════════
   BITZFIELD — THE ONE DESIGN FILE
   assets/bitzfield-theme.css · created 2026-08-08 (Ives)

   Andrew's ruling (Brain/memory.md, 2026-08-08 20:04, verbatim): "Everything
   should get the same OS look using the one design file that can be swapped
   if I wanted to."

   This file IS that one design file. Every design decision in the OS — the
   colors, the type, the corner rounding, the shadows, the glass, the motion,
   the spacing, the touch sizes — is a named value in this file and nowhere
   else. Swap this file, and the whole OS changes its look. Nothing else needs
   to be touched.

   HOW IT IS WIRED
   ---------------
   · Every OS page loads this file FIRST:  <link rel="stylesheet" href="/assets/bitzfield-theme.css">
   · assets/shell.css and assets/bitzy-ui.css are CONSUMERS now — they import
     this file at their top and paint components from these values. They no
     longer define any value of their own.
   · The written law for how these values are used is DESIGN.md (rendering)
     and Brain/design-standards.md (Andrew's rulings). This file is the values.

   PLAIN-ENGLISH MAP (what lives where in this file)
   -------------------------------------------------
     §1  The typefaces (the document font files)
     §2  Paper — the light document world (portal tools, marketing, printouts)
     §3  Paper, after dark — the same document world in dark mode
     §4  The shell — the dark-glass OS world (Dash, Jobs, Map, Office…)
     §5  The money voice — how every dollar figure is sized and weighted
     §6  Motion & material — how things move, and what the glass is made of
     §7  The glass dial — how see-through the OS is (one control)
     §8  On-black readability + the blue-primary word color
     §9  The official size ramps — the approved steps builders snap to
     §10 Paper in print — the printed-document law (pt ramp, money voice,
         rules, margins, per-entity ink)
   ═══════════════════════════════════════════════════════════════════════════ */

/* ═══ §1 · THE TYPEFACES ════════════════════════════════════════════════════
   Libertinus Sans is THE face (an open-source Optima) — Andrew, 2026-08-13:
   "My font is libertinus". Self-hosted, renders offline, nothing fetched from
   the internet. It is the document voice, the body voice AND the dense-data
   voice: --font-display, --font-body and --font-ui all name it (§2). The OS
   shell's chrome voice (Avenir Next, §4) is the one remaining system face —
   a system stack with no files to load. */
@font-face{font-family:'Libertinus Sans';font-style:normal;font-weight:400;font-display:swap;src:url('/assets/fonts/libertinus-sans-400.woff2') format('woff2');}
@font-face{font-family:'Libertinus Sans';font-style:normal;font-weight:700;font-display:swap;src:url('/assets/fonts/libertinus-sans-700.woff2') format('woff2');}
@font-face{font-family:'Libertinus Sans';font-style:italic;font-weight:400;font-display:swap;src:url('/assets/fonts/libertinus-sans-400-italic.woff2') format('woff2');}

/* ═══ §2 · PAPER — the light document world ═════════════════════════════════
   Used by the portal document tools, the marketing site, and anything that
   reads as a sheet of paper rather than OS glass. Brand is isolated to
   --brand and --accent: override those two and every paper surface re-skins. */
:root {
  /* ---- BRAND (white-label anchors — override these two to re-skin) ---- */
  --brand:        #283977;   /* Bonin blue — deep, saturated royal-navy, the identity */
  --accent:       #c9a766;   /* Gold — confident second, used with intent */

  /* ---- ON-BRAND tokens (text/glass sitting ON the navy topbar). Defaults
     are the exact literals the topbar always used. ---- */
  --on-brand-fg:           #fff;                    /* topbar/brand text + icons */
  --on-brand-fg-dim:       rgba(255,255,255,.72);   /* secondary on-brand text */
  --on-brand-glass:        rgba(255,255,255,.12);   /* glass button bg on the brand */
  --on-brand-glass-hover:  rgba(255,255,255,.2);
  --on-brand-glass-brd:    rgba(255,255,255,.22);
  --on-brand-glass-brd-hover: rgba(255,255,255,.35);
  --scrim:                 rgba(0,0,0,.5);          /* modal/overlay backdrop */
  /* ink ON a gold fill — rank C buttons, gold badges, ::selection. Near-black in
     BOTH modes (8.62:1 on --accent-400); white on gold never clears AA. Named
     here 2026-09-09 (Ives, Wave B) so bitzy-ui stops carrying the literal. */
  --on-accent-fg:          #1d1604;

  /* ---- Brand blue scale (deeper, saturated royal-navy) ---- */
  --brand-50:   #eef1fa;
  --brand-100:  #dce2f4;
  --brand-200:  #b6c1e6;
  --brand-300:  #8896d2;
  --brand-400:  #3c4fae;   /* lighter brand — richer */
  --brand-500:  #364aa0;   /* interactive blue (hover/links/focus) — deeper, premium */
  --brand-600:  #283977;   /* = --brand, deep royal-navy */
  --brand-700:  #1d2c5d;   /* deeper, cleaner shadow */
  --brand-800:  #142043;
  --brand-900:  #0d1631;
  --brand-ink:  #131d39;   /* navy-charcoal text */

  /* ---- Gold accent scale (use sparingly: CTA, underline marks, ticks, dividers) ---- */
  --accent-300: #e3cd98;
  --accent-400: #D4AF5A;   /* bright gold */
  --accent-500: #c9a766;   /* = --accent */
  --accent-600: #B8892E;   /* deep gold — RULES and FILLS on light paper ONLY:
                              2.9:1 on ivory, so never small text there (light
                              paper says its words in --brand-500; dark says
                              them in --accent-400). ONE GOLD (D6, Andrew
                              2026-09-09): this is the GCE brand gold of the
                              printed cards (§5 ruling 2026-09-07); the old
                              #B8922A near-twin (ΔE 6.8) is retired. */
  --accent-700: #9a7a22;

  /* ---- Semantic ---- */
  --ok:   #2f8f5b;
  --warn: #c08a2d;
  --bad:  #c0492f;
  --ok-bg:   #e7f3ec;
  --warn-bg: #f6edd9;
  --bad-bg:  #f6e4df;
  /* ---- State-category map: color = state, not positivity. Green is reserved
     for terminal success — pending/awaiting-you states use amber or
     interactive blue so nothing unfinished reads "done". ---- */
  --state-pending: var(--warn);      /* awaiting input / needs review */
  --state-ready:   var(--brand-500); /* ready for you to act */
  --state-done:    var(--ok);        /* filed / sent / complete */

  /* ---- LIGHT surfaces (default paper theme) ---- */
  --bg:          #fbfaf7;   /* ivory page */
  --bg-sunken:   #f3f1ea;   /* recessed wells / table stripes */
  --surface:     #ffffff;   /* card surface */
  --surface-2:   #f7f5ef;   /* secondary surface */
  --surface-glass: rgba(255,255,255,.66);
  --text:        #16203a;   /* deep navy-charcoal */
  --text-muted:  #5b6478;
  --text-faint:  #8b93a4;
  --border:      #e7e3d8;   /* warm hairline */
  --border-strong:#d6d1c3;
  --ring:        rgba(58,74,140,.35);   /* focus ring (brand-500) */
  /* THE LINK INK — a token, so `a{color:var(--link)}` stays at specificity
     (0,0,1) and every component that colours its own anchor still wins. Themed
     with a rule instead, its system-dark twin `:root:not([data-theme="light"]) a`
     scores (0,2,1) and silently repaints button labels (measured 2026-09-09:
     the homepage's gold CTA read its label in --brand-300, 1.37:1). Light paper
     says its links in the brand blue — 7.61:1 on ivory; gold words there are
     2.9:1 and are never used for text (§5). */
  --link:        var(--brand-500);
  --link-hover:  var(--brand-600);
  /* THE IDENTITY NAVY, PER WORLD — document headings, section rules, the header
     company line: the blue that says "Bonin" and stays readable on whichever
     paper it lands on. It exists because pages kept writing their dark identity
     ink as `[data-theme="dark"] h2{…}` and never the `@media (prefers-color-
     scheme: dark)` twin, so a visitor whose PHONE is dark but who never tapped
     the toggle — the ordinary case — got --brand-600 on the dark card: MEASURED
     1.60:1 on /terms/ section headings, 1.41:1 on the version bar, 1.93:1 on the
     contents links (2026-09-09). A token has all three worlds declared in one
     place, here, and no page can forget one of them. */
  --brand-title: var(--brand-600);

  /* ---- THE REST OF THE PER-WORLD INKS (added 2026-09-09, Wave B re-probe).
     Same law as --link / --brand-title above, and the sweep that finished it:
     every remaining `[data-theme="dark"] .component{…}` paint in bitzy-ui.css
     became one of these. Two of them were shipping BROKEN in system dark
     (measured): the four homepage eyebrows fell back to --brand-500 on #080b16
     at 2.47:1, and ten icon tiles (.card-tool .tool__icon ×6, .contact-line .ci
     ×4) rendered near-WHITE — background --brand-50 #eef1fa on the dark page —
     because their dark paint was pin-only. A token cannot forget a world.
     AND THE FIFTH SURFACE, PAPER: §11 below resets a token for print, but it
     CANNOT reach a selector — a reader who had pinned dark and printed got
     every `[data-theme="dark"]` paint on the white sheet (the /terms/ caps
     sub-line in --accent-400: 2.0:1 on paper). Tokens fix print for free. ---- */
  --brand-wash:      var(--brand-50);      /* soft brand tile ground — icon tiles, .badge--brand */
  --brand-wash-line: var(--brand-200);     /* its hairline */
  --gold-line:       var(--accent-500);    /* gold drawn as INK — rules, underline marks, chip hairlines */
  --accent-swap:     var(--brand-500);     /* the world's INTERACTIVE accent: blue on paper, gold after dark */
  --accent-swap-fg:  var(--on-brand-fg);   /* ink ON a filled --accent-swap surface */
  --accent-swap-strong: var(--brand-600);  /* the world's DISPLAY accent — eyebrows, chrome icons */
  /* GCE's ink, per world (the sister-company card, §0.11 "an entity speaks its
     own colour"): on light paper the deep gold rules and the AA text-gold says
     the words; after dark the brand gold does both. */
  --gce-rule:        var(--paper-ink-gce-deep);
  --gce-text:        var(--paper-ink-gce-text-gold);

  /* ---- Soft layered shadows (light) ---- */
  --shadow-sm: 0 1px 2px rgba(22,32,58,.05), 0 1px 1px rgba(22,32,58,.04);
  --shadow:    0 2px 4px rgba(22,32,58,.05), 0 6px 16px rgba(22,32,58,.07);
  --shadow-md: 0 4px 8px rgba(22,32,58,.06), 0 14px 32px rgba(22,32,58,.10);
  --shadow-lg: 0 10px 24px rgba(22,32,58,.08), 0 30px 60px rgba(22,32,58,.14);
  --shadow-accent: 0 8px 22px rgba(201,167,102,.32);

  /* gold hairline for the signature .card hover — a LINE, never a light source
     (the zero-offset gold halo is banned: design-standards §7) */
  --card-gold-ring:  color-mix(in srgb, var(--accent-500) 72%, var(--border));
  /* theme-aware REST border for .card — LIGHT = BLUE-forward (a brand-blue
     hairline at rest; gold answers on hover) */
  --card-ring: color-mix(in srgb, var(--brand-400) 38%, var(--border));

  /* ---- Premium gradients (blue stays primary, gold the confident second) ---- */
  --grad-brand:      linear-gradient(150deg, var(--brand-400) 0%, var(--brand-600) 60%, var(--brand-700) 100%);
  --grad-brand-deep: linear-gradient(160deg, var(--brand-600) 0%, var(--brand-800) 70%, var(--brand-900) 100%);
  --grad-gold:       linear-gradient(150deg, var(--accent-400), var(--accent-600));
  /* faint top-edge highlight so cards read as layered */
  --edge-hi:         inset 0 1px 0 rgba(255,255,255,.6);
  /* FLAT GROUND: the page stands on its solid --bg; gold appears as drawn
     rules (.rule-gold), not as atmosphere. */
  --bg-grad: none;

  /* ---- Typography (paper voices) ----
     ONE FACE. Andrew, 2026-08-13: "My font is libertinus." Display, body and
     the dense-data voice are all Libertinus Sans — self-hosted above (§ @font-face),
     nothing fetched from a CDN. --font-ui survives as a SEMANTIC token (hundreds
     of call sites mean "this is dense data"), but the face no longer differs:
     what separates a data cell from a paragraph here is tabular figures, size and
     weight, not a second typeface. Libertinus Sans ships tabular digits by
     default — measured identical set widths for 1111111111 / 0000000000 in
     Chromium 151 and WebKit 26.5 — so money columns stay aligned without tnum. */
  --font-display: 'Libertinus Sans', 'Optima', 'Optima nova', 'Segoe UI', 'Helvetica Neue', sans-serif;
  --font-body:    'Libertinus Sans', 'Optima', 'Optima nova', 'Segoe UI', 'Helvetica Neue', sans-serif;
  --font-ui:      'Libertinus Sans', 'Optima', 'Optima nova', 'Segoe UI', 'Helvetica Neue', sans-serif; /* dense data */

  /* Fluid type scale (paper) */
  --fs-eyebrow: .8125rem;
  --fs-body:    1.0625rem;
  --fs-lg:      1.25rem;
  --fs-h3:      clamp(1.35rem, 1.1rem + 1.1vw, 1.75rem);
  --fs-h2:      clamp(1.9rem, 1.4rem + 2.2vw, 2.85rem);
  --fs-h1:      clamp(2.6rem, 1.8rem + 3.6vw, 4.25rem);
  --fs-display: clamp(3.2rem, 2rem + 5vw, 5.5rem);

  /* ---- 4px spacing scale (both worlds) ---- */
  --sp-1: 4px;  --sp-2: 8px;  --sp-3: 12px; --sp-4: 16px;
  --sp-5: 20px; --sp-6: 24px; --sp-8: 32px; --sp-10: 40px;
  --sp-12: 48px; --sp-16: 64px; --sp-20: 80px; --sp-24: 96px;

  /* ---- Radii (paper squircles) ---- */
  --r-sm:   12px;
  --r-card: 20px;
  --r-lg:   28px;
  --r-pill: 999px;

  /* ---- Motion (both worlds' base clocks + eases) ---- */
  --ease:        cubic-bezier(.22,.61,.36,1);
  --ease-out:    cubic-bezier(.16,1,.3,1);
  --t-fast:   150ms;
  --t-base:   200ms;
  --t-slow:   250ms;

  /* ---- Layout ---- */
  --container: 1200px;
  --nav-h: 68px;

  color-scheme: light;
}

/* Narrow-screen display ramp — the ≤430px scale-down of --fs-display/--fs-h1/
   --fs-h2. Lives HERE (not in a consumer file) so a swapped theme brings its
   own narrow ramp instead of being clamped by bitzy-ui — moved from
   bitzy-ui.css 2026-08-08 (one-design-file ruling: consumers define no
   design value of their own). */
@media (max-width: 430px){
  :root {
    --fs-display: clamp(2.3rem, 1.5rem + 6vw, 3rem);
    --fs-h1:      clamp(1.95rem, 1.5rem + 4vw, 2.45rem);
    --fs-h2:      clamp(1.55rem, 1.25rem + 3.4vw, 1.95rem);
  }
}

/* ═══ §3 · PAPER, AFTER DARK ════════════════════════════════════════════════
   The document world's dark mode: rich near-black with a blue undertone,
   layered surfaces, gold brought in generously so it reads designed, not
   inverted. Applies when a page is pinned dark ([data-theme="dark"]) or when
   the device prefers dark and the page has not pinned light. */
[data-theme="dark"] {
  /* deep, blue-undertoned near-black base */
  --bg:          #080b16;
  --bg-sunken:   #05070f;
  --surface:     #131a2e;   /* elevated, slightly higher-contrast */
  --surface-2:   #1b2440;
  --surface-glass: rgba(17,23,42,.62);
  --text:        #eef1f8;
  --text-muted:  #a3acc6;
  --text-faint:  #717b98;
  --border:      #283457;
  --border-strong:#3a486a;
  --ring:        rgba(120,140,220,.55);
  /* dark paper's link ink: --brand-500 measures 2.18:1 on --surface here, so the
     readable blue after dark is 300 (6.86:1 on --bg); gold answers on hover */
  --link:        var(--brand-300);
  --link-hover:  var(--accent-400);
  --brand-title: var(--brand-300);   /* 6.04:1 on --surface, 5.35:1 on --surface-2 */
  /* the per-world inks, dark cut (keep in step with §2 and the twin below) */
  --brand-wash:      var(--surface-2);
  --brand-wash-line: var(--border-strong);
  --gold-line:       var(--accent-400);
  --accent-swap:     var(--accent-400);
  --accent-swap-fg:  var(--on-accent-fg);
  --accent-swap-strong: var(--accent-400);
  --gce-rule:        var(--paper-ink-gce);
  --gce-text:        var(--paper-ink-gce);   /* 8.3:1 on --surface */

  --brand-ink:  #eef1f8;

  /* black-alpha shadow set for dark, with a warm-gold lift on elevation */
  --shadow-sm: 0 1px 2px rgba(0,0,0,.45);
  --shadow:    0 2px 6px rgba(0,0,0,.5), 0 10px 24px rgba(0,0,0,.45);
  --shadow-md: 0 6px 16px rgba(0,0,0,.55), 0 20px 44px rgba(0,0,0,.5);
  --shadow-lg: 0 14px 30px rgba(0,0,0,.6), 0 40px 80px rgba(0,0,0,.62);
  --shadow-accent: 0 10px 30px rgba(212,175,90,.34);

  /* gold hairline for the signature .card hover */
  --card-gold-ring:  color-mix(in srgb, var(--accent-400) 70%, var(--border-strong));
  /* theme-aware REST border for .card — DARK = GOLD-forward (gold trim at rest
     on the blue-toned card surface; the hairline still answers on hover) */
  --card-ring: color-mix(in srgb, var(--accent-400) 44%, var(--border-strong));

  /* gold-leaning gradients read premium on dark; blue is richer royal */
  --grad-brand:      linear-gradient(150deg, #3b4ea8 0%, #283977 60%, #1d2c5d 100%);
  --grad-brand-deep: linear-gradient(160deg, #283977 0%, #142043 70%, #0d1631 100%);
  --edge-hi:         inset 0 1px 0 rgba(150,170,225,.16);

  /* flat ground — the page stands on --bg */
  --bg-grad: none;

  --ok-bg:   #11271d;
  --warn-bg: #2a2210;
  --bad-bg:  #2a1411;

  color-scheme: dark;
}

/* System preference — only when the user has NOT pinned light */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg:          #080b16;
    --bg-sunken:   #05070f;
    --surface:     #131a2e;
    --surface-2:   #1b2440;
    --surface-glass: rgba(17,23,42,.62);
    --text:        #eef1f8;
    --text-muted:  #a3acc6;
    --text-faint:  #717b98;
    --border:      #283457;
    --border-strong:#3a486a;
    --ring:        rgba(120,140,220,.55);
    --link:        var(--brand-300);   /* keep in step with pinned dark above */
    --link-hover:  var(--accent-400);
    --brand-title: var(--brand-300);
    --brand-wash:      var(--surface-2);
    --brand-wash-line: var(--border-strong);
    --gold-line:       var(--accent-400);
    --accent-swap:     var(--accent-400);
    --accent-swap-fg:  var(--on-accent-fg);
    --accent-swap-strong: var(--accent-400);
    --gce-rule:        var(--paper-ink-gce);
    --gce-text:        var(--paper-ink-gce);
    --brand-ink:  #eef1f8;
    --shadow-sm: 0 1px 2px rgba(0,0,0,.45);
    --shadow:    0 2px 6px rgba(0,0,0,.5), 0 10px 24px rgba(0,0,0,.45);
    --shadow-md: 0 6px 16px rgba(0,0,0,.55), 0 20px 44px rgba(0,0,0,.5);
    --shadow-lg: 0 14px 30px rgba(0,0,0,.6), 0 40px 80px rgba(0,0,0,.62);
    --shadow-accent: 0 10px 30px rgba(212,175,90,.3);
    --edge-hi:    inset 0 1px 0 rgba(150,170,225,.16);
    --bg-grad: none;   /* flat ground — matches pinned dark */
    --ok-bg:#11271d; --warn-bg:#2a2210; --bad-bg:#2a1411;
    /* gold ring + gold rest-trim so system-dark matches pinned dark */
    --card-gold-ring:  color-mix(in srgb, var(--accent-400) 70%, var(--border-strong));
    --card-ring: color-mix(in srgb, var(--accent-400) 44%, var(--border-strong));
    color-scheme: dark;
  }
}

/* ═══ §4 · THE SHELL — the dark-glass OS world ══════════════════════════════
   Dash, Jobs, Map, Office, the tools' shared chrome. TRUE-DARK void ground
   (Andrew: real near-black, NOT navy/violet). The ambient canvas paints the
   living field over this; the body ground is only the pre-paint fallback, so
   it too must read genuinely dark. */
:root{
  --sh-ground:#05070C;
  --sh-panel:#121826;
  --sh-panel2:#0F141F;
  --sh-ink:#E9ECF3;
  --sh-muted:#8B94A8;
  --sh-faint:#5C6478;
  --sh-line:#222B3D;
  --sh-gold:#D9B45E;
  /* ── Starfield FIELD tokens — read by assets/ambient-field.js for the WebGL
     card-lens field. Kept SEPARATE from --sh-ground so a brand ground override
     can re-tint the glass without ever pulling the deep-space void off
     true-black. --sh-gold is the accretion homage (brand-driven); --sh-cool is
     the secondary blue rim. */
  --sh-void:#05070C;      /* true near-black space — the deep field */
  --sh-voidtop:#0A0E1A;   /* a breath of cool depth toward the top */
  --sh-star:#E3E9F6;      /* cool starlight */
  --sh-cool:#5E82D8;      /* cool blue — secondary homage (rim + distant stars) */
  --sh-ok:var(--ok,#2f8f5b);
  --sh-warn:var(--warn,#c08a2d);
  --sh-bad:var(--bad,#c0492f);
  --sh-amber:#E0A83C;
  --sh-green:#4CAF7D;
  --sh-red:#E06050;
  --sh-caps:'Avenir Next','Avenir','Futura','Century Gothic','Trebuchet MS',system-ui,sans-serif;
  --sh-cap-min:10.5px;   /* the caps-label FLOOR — NO caps label below this,
                            ever: sub-9-point micro-caps are retired as sci-fi
                            costume, unreadable in a truck. */
  --sh-mono:ui-monospace,'SF Mono',Menlo,Consolas,monospace;
  /* ── §DISPLAY — the Statement voice: huge, thin, confident. ONE register for
     the front door and true-empty states: a plain-English sentence set large
     and light, no glow (light lives in the field, never on the type). Avenir
     Next w200 resolves to UltraLight on every Apple device this OS runs on;
     the stack is system-resident — nothing fetched. Earned placement only:
     true-empty states ("You're clear.") — never headings, never chrome.
     (The sign-in "This is private." headline was struck by Andrew 2026-08-09
     as too large for the door; the register itself stays.) */
  --sh-display:var(--sh-caps);
  --sh-display-w:200;
  --sh-fast:var(--t-fast,150ms);
  --sh-base:var(--t-base,200ms);
  /* ── §FIT — the six rail names on ONE line at phone width. One token pair
     drives the fit (measured at 390px: the row occupies 374px — 16px to
     spare); at 320px the same rules simply wrap to two lines. The rail has NO
     width breakpoint. */
  --sh-rail-gap:0px;     /* between rail items — the padding does the spacing */
  --sh-rail-pad:6px;     /* each side of a name */
  /* Apple soft-glass radii — panels round, small glass rounds less */
  --sh-radius:17px;      /* .sh-panel — Big Sur / visionOS card radius */
  --sh-radius-sm:13px;   /* .sh-tile · roster cards */
  --sh-radius-xs:9px;    /* money-rail nodes · held items · small glass */
  --sh-bracket:9px;      /* framing-square WHISPER (never a hard HUD bracket) */
  /* ── §LAYERS — the shell's THREE stack levels, named once. The rail IS a
     stacking context (sticky + backdrop-filter): this is the level that trap
     sits at. Full story: shell.css §LAYERS. */
  --sh-z-rail:90;        /* OS chrome: over page content + page sticky headers
                            (pages use 5-60), under page modals/toasts (100+) */
  --sh-z-gate:200;       /* the sign-in gate covers the chrome it gates */
}

/* ═══ §5 · THE MONEY VOICE (§NUMERAL) ═══════════════════════════════════════
   Every dollar figure in the OS rides this scale — four sizes, tabular digits
   (set house-wide on body.sh), one weight band. Weight 300 is permitted at
   the HERO size ONLY; rows and cards stay inside 500-700 and default to
   --sh-num-w. Entity tint rides ON these tokens unchanged — the voice sets
   size+weight+digits, never colour.
   SCOPED TO THE SHELL (body.sh) ON PURPOSE: the money voice belongs to OS
   surfaces. Paper pages that never load the shell (the marketing site's stat
   cards) keep their own document scale — bitzy-ui's .card-stat falls back to
   it exactly as before. Do not lift these to :root without re-checking that
   fallback. */
body.sh{
  --sh-num-hero:30px;    /* the Dash hero tile value — the ONE place 300 may go */
  --sh-num-hero-w:300;
  --sh-num-lg:21px;      /* card-level figure (hero job unbilled, drawer totals) */
  --sh-num-md:15px;      /* row / tile-secondary figure */
  --sh-num-sm:12.5px;    /* meta money (deltas, captions beside a figure) */
  --sh-num-w:600;        /* the rows-and-cards weight default (500-700 band) */
}

/* ═══ §6 · MOTION & MATERIAL ════════════════════════════════════════════════
   Motion law: entry animations + data-change flashes ONLY. Nothing loops
   idle. Motion decelerates and stops — no overshoot, no bounce, no elastic
   (design-standards §7: any bezier control point above 1 is a defect). */
:root{
  /* SOFT-CLOSE (Andrew's ruling 2026-08-08: "make it stop cleanly"). This
     replaced a gentle overshoot — the control travelled past its resting
     place and settled back; on a cabinet that's a slam. The soft-close
     decelerates hard out of the gate and arrives at rest with no rebound. */
  --sh-spring:cubic-bezier(.16,.84,.28,1);          /* soft-close — decelerate, no overshoot */
  /* ── §ONE GLASS — the merged material, three depth tiers. ONE substance:
     every glass surface reads a tier token for its backdrop recipe and
     --sh-glass-base (§7, the glass dial) for its fill, so the material is
     provably identical everywhere and the dial still flips atomically. */
  --glass-t1:blur(18px) saturate(130%);                    /* T1 · chrome — the rail slab */
  --glass-t2:blur(26px) saturate(135%) brightness(1.04);   /* T2 · cards/panels/tiles — the keeper */
  --glass-t3:blur(26px) saturate(135%) brightness(1.04);   /* T3 · overlays — tools panel, floating glass */
  --glass-edge:var(--sh-line);                             /* crisp near-black edge — the ONE hairline, Hairline Navy #222B3D (§281). Was a raw #262E44: an unregistered near-twin that made panel edges and cell edges differ by ΔE 3.15 on the same screen, which is exactly what this block promises never happens. */
  --glass-sheen:linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,0) 42%);  /* whisper top-sheen — no white wash */
  /* multi-layer, low-opacity, large-blur elevation → panels genuinely FLOAT.
     Three stacked layers (contact · mid · ambient) is the macOS/visionOS
     recipe. All shadows are neutral black and offset — a coloured, un-offset,
     blurred shadow is a glow, and glows are banned (design-standards §7). */
  --sh-elev-1:0 1px 1px rgba(0,0,0,.18), 0 6px 16px -4px rgba(0,0,0,.32), 0 16px 40px -12px rgba(0,0,0,.46);
  --sh-elev-2:0 1px 2px rgba(0,0,0,.22), 0 10px 26px -6px rgba(0,0,0,.42), 0 32px 66px -14px rgba(0,0,0,.6);
  --sh-hair:inset 0 1px 0 rgba(255,255,255,.11), inset 0 0 0 1px rgba(255,255,255,.03);
  --sh-glass-brd:1px solid color-mix(in srgb, var(--sh-ink) 11%, transparent);  /* light Apple edge (portal pages consume it) */
}

/* ═══ §7 · THE GLASS DIAL ═══════════════════════════════════════════════════
   How much of the field shows through the glass — ONE control for every glass
   surface. RULED STATE: SEE-THROUGH (Andrew 2026-07-25: "Keep old glass for
   now. Bug only happens when using full screen screenshot on iOS. Rare to use
   it. Keep fix and mostly solid option noted for future.")
   So: LIGHT CARDS IN A FULL-PAGE iOS SCREENSHOT ARE A DECISION, NOT A BUG.
   Do not "fix" it again without a new ruling from Andrew.

   TO RE-ARM: change --sh-glass-base below. Nothing else. All three presets
   were MEASURED with Server/scripts/qa/glass-probe.py --based, not estimated:
     transparent          → SEE-THROUGH (the ruling; 12 of 17 surfaces borrow
                            their fill, so a full-page iOS capture can read
                            light below the fold)
     rgba(7,10,18,.90)    → PARTIAL — the "mostly solid" middle Andrew noted
                            for the future. Keeps live drift AND photographs
                            dark. NOTE: .85 is NOT enough — measured, it still
                            borrowed on 11 of 17 surfaces. .90 is the first
                            value that holds.
     #070A12              → SOLID: 17/17 identical with and without a
                            backdrop, no field diffusion at all
   (The html:not([data-skin]) prefix is an inert specificity idiom from the
   retired skin era — the attribute is never set, so it is always true. It is
   kept because removing it changes cascade weight; that cleanup is its own
   probed pass. Do not add the prefix to new rules.) */
html:not([data-skin]) body.sh{
  --sh-glass-base:transparent;          /* ← THE DIAL (see the three presets above) */
  /* the card tint Andrew tuned. Plain rgba, never color-mix-with-transparent:
     older WebKit drops that as invalid and collapses the surface to its flat
     fallback (the bitzy-dock.js lesson). These are the exact same colours the
     old color-mix values resolved to — #0B1120@56% and #05070E@62%. */
  --sh-glass-top:rgba(11,17,32,.56);
  --sh-glass-bot:rgba(5,7,14,.62);
}

/* ═══ §8 · ON-BLACK READABILITY + BLUE-PRIMARY ══════════════════════════════
   Blue is where you are; gold is what you do. The main WORDS of the shell
   (page titles, active nav, panel captions, the monogram) speak Bonin blue —
   a bright, readable on-black tint of the brand navy — and gold holds the
   action grammar. The foreground greys are lifted above the base pair so
   labels and metadata read cleanly on the deep-black ground. */
html:not([data-skin]) body.sh{
  /* brighter foreground greys — higher-contrast, still calm */
  --sh-muted:#AEB7CC;
  --sh-faint:#828CA6;
  /* bright Bonin-blue for on-black WORDS (lightened --brand, logo homage) */
  --sh-blue:#8098E6;
}

/* ═══ §9 · THE OFFICIAL RAMPS — steps builders snap to ══════════════════════
   THE TUNE-UP RAMP (Andrew approved, 2026-08-08): the values that kept
   recurring across surfaces as in-betweens are now OFFICIAL steps. True
   one-offs stay one-off — a builder snaps new work to the nearest step
   instead of minting another in-between.

   TYPE SIZE STEPS (shell px ramp, smallest to largest):
     10.5 (--sh-cap-min) · 11 (label) · 12 (meta-mono) · 12.5 (--sh-num-sm) ·
     13 (--fs-caption) · 14 (--fs-body-sm) · 15 (body) · 16 (--fs-body-touch) ·
     21 (title / --sh-num-lg) · 30 (--sh-num-hero) · Statement clamp below.
   NOT steps (do not copy into new work; snap instead): 9.5px, 10px (legacy
     chip caps), 11.5px, 12.5px outside the money voice, 7-8px glyph sizing
     (CSS-drawn shapes only — no word may ever render at glyph size).

   RADIUS STEPS: 3 (--r-tick) · 4 (chip) · 6 (--r-control) · 8 (--r-control-lg) ·
     9 (--sh-radius-xs) · 12 (--r-sm paper) · 13 (--sh-radius-sm) ·
     16 (--r-glass-mid) · 17 (--sh-radius) · 20 (--r-card) · 28 (--r-lg) ·
     999 (pill) · 50% (dot).
   NOT steps: 1px, 2px, 7px, 10px — existing one-offs; snap new work. */
:root{
  /* the three type sizes that recurred their way into the ramp */
  --fs-caption:13px;      /* dense row / caption text */
  --fs-body-sm:14px;      /* secondary body — between caption and body */
  --fs-body-touch:16px;   /* coarse-pointer body + the form-input floor:
                             below 16px, iOS Safari zooms the page on focus */
  /* the four radii that recurred their way into the ramp */
  --r-tick:3px;           /* tiny marks — focus-ring corners, bracket tips */
  --r-control:6px;        /* small controls — the rail mark tile, rail item tops */
  --r-control-lg:8px;     /* small buttons — hamburger, compact controls */
  --r-glass-mid:16px;     /* mid glass — between tile (13) and panel (17) */
  /* the Statement register (the shell's display voice) as swappable values */
  --fs-statement:clamp(28px, 5vw, 40px);
  /* touch + input floors, documented as values so the law is swappable too */
  --touch-floor:44px;     /* minimum coarse-pointer target, both axes */
  --input-text-floor:16px;/* minimum form-input text size on coarse pointers */
}

/* ═══ §10 · PAPER IN PRINT — the printed-document law ═══════════════════════
   Added 2026-08-08 (Ives), from two rulings the same evening:
   · 21:09 (Andrew, verbatim): "Make sure printed bonin docs are os style too"
     — every generated printed document carries the OS design language IN
     PRINT TERMS: the one money voice (tabular numerals), the type discipline,
     the restraint, the layout quality — expressed in each ENTITY'S brand on
     white. The dark starfield and the OS chrome NEVER go to paper.
   · 21:14 (Andrew, verbatim): "Bonin doesnt have to be hard ruled to gold.
     Just good use of the logos blue" — Bonin paper is anchored to the LOGO'S
     BLUE (hierarchy, rules, headers — restraint, not decoration); gold on
     Bonin paper only where the logo lockup itself carries it. Gold is GCE's
     voice. BCI speaks its own navy.

   THIS BLOCK IS TOKENS AND LAW ONLY — a §PAPER counterpart of the screen
   sections, IN this file on purpose: the one-design-file ruling (2026-08-08
   20:04) makes THIS file the swappable unit, and a sibling import would split
   that unit in two and open the exact screen/paper drift seam this section
   closes. Nothing visual changed when this landed; generators adopt these
   tokens in their own probed passes.

   IRON LAWS this section renders but does not own (homes cited):
   · 12pt body / 10pt legal floors, spacing-before-shrinking, no shrink-to-fit
     — Brain/design-standards.md §1 (the rulings home; it wins).
   · One entity per page, never conflated; license/company facts per
     Skills/user/{bonin,bci,gce}-company-info.md.
   · BitzField never appears on client paper. Personal ("billed as me") paper
     carries NO company mark.
   · Checks: MICR E13B stays embedded, the security banner NEVER prints
     (.claude/agents/blake.md) — untouchable, not restyled by this section.
   · B&W-LASER TRUTH: every document must print TRUE on a black-and-white
     laser. Hierarchy is carried by case, tracking, weight and size — the
     entity ink is IDENTITY, never the only thing separating two ranks.

   THE TYPE RAMP, IN POINTS (named against the shipping reference sheet —
   Server/os-shell.js renderInvoiceHtml(), the registry's governed OS invoice
   paper; design-standards §2):
     10pt legal (allowlist only) · 12pt body/labels · 13pt strong ·
     15pt doc title · 18.5pt letterhead · 24pt money hero.

   CONSUMERS — where a doc generator reads these values:
   · HTML/print generators (Server/os-shell.js paper, portal tools' print CSS,
     terms print): read the CSS custom properties below, or carry the same
     literal values with a comment citing §10.
   · jsPDF generators (portal/tools/{invoice,waiver,warranty}/app.js, aia.js,
     root app.js) cannot read CSS: portal/tools/waiver/brands.js is the JS
     MIRROR of the three entity inks (colorHex/docInk) and MUST equal the
     hexes below — a diff between brands.js and §10 is drift, fix at §10's
     value or bring a new ruling. */
:root{
  /* ---- The pt ramp (floors are LAW: design-standards §1) ---- */
  --paper-pt-legal:10pt;       /* legal-footnote allowlist ONLY — named list per generator */
  --paper-pt-body:12pt;        /* the body floor — nothing a person READS below this */
  --paper-pt-strong:13pt;      /* emphasized values, signature names */
  --paper-pt-title:15pt;       /* the document title + party names — caps, .24em */
  --paper-pt-letterhead:18.5pt;/* the company letterhead name */
  --paper-pt-hero:24pt;        /* the ONE hero figure per document (amount due) */
  --paper-lh:1.36;             /* body leading (the measured no-shrink fit) */
  --paper-lh-tight:1.2;        /* caps labels / letterhead lines */
  /* ---- The caps voice on paper (same signature as the shell, pt-tuned) ---- */
  --paper-track-label:.11em;   /* 12pt/700 caps labels */
  --paper-track-title:.24em;   /* the 15pt document title */
  /* ---- The money voice in print: ONE voice, tabular digits, right-aligned
     columns, a figure never larger than its rank (hero > strong > body). Use:
     font-variant-numeric: var(--paper-num-variant); plus
     font-feature-settings:"tnum" 1 for older engines. ---- */
  --paper-num-font:'Helvetica Neue',Helvetica,Arial,sans-serif;
  --paper-num-variant:tabular-nums;
  /* ---- Rule weights (print hairlines that hold on a 600dpi laser) ---- */
  --paper-rule-hair:.75pt;     /* the working hairline — table rows, dividers (≈1px@96) */
  --paper-rule-band:1.5pt;     /* section rules, band edges — the strong rank */
  /* ---- The sheet (letter; the shipping margins of the governed invoice).
     Content box 7.2in — WIDER CONTENT = the shrink-to-fit floor violation
     (design-standards §1): fix the geometry, never let the engine scale. ---- */
  --paper-margin-top:.6in;
  --paper-margin-x:.65in;
  --paper-margin-bottom:.95in; /* deep on purpose — the running-footer band */
  /* ---- Body ink on paper (convergence target; adopting it in a generator is
     its own probed pass — os-shell carries #1E1E1E, GCE docInk #1D2333 today) */
  --paper-ink-body:#16203a;
  /* ---- PER-ENTITY INK (21:14). One entity per page — these never mix. ----
     BONIN — the logo's blue. MEASURED from Skills/assets/bonin-logo.datauri
       (2026-08-08, Ives): dominant sampled bucket #4454A4, median #4754A2.
       The token is #4050A0 — the already-shipping print cut of that same blue
       (waiver/brands.js docInk + entity-bonin), kept so the system carries ONE
       Bonin blue, not two a few points apart. */
  --paper-ink-bonin:#4050A0;
  /*   BCI — its own navy. MEASURED from bci-logo-simple.datauri: median
       #001446 — the logo navy is near-black, and an accent ink that matches
       the body ink marks nothing; the shipping readable cut holds. */
  --paper-ink-bci:#2C3E6B;
  /*   GCE — gold, RULES/BANDS/HEADER MARKS ONLY, never running-text ink
       (design-standards §2 registry: "GCE gold = rules/bands only"). MEASURED
       from gce-logo-color.datauri: face gold #ECC46C, deep-stroke median
       #D5A65B — confirming the shipping brand gold within a point. */
  --paper-ink-gce:#D4AF5A;
  --paper-ink-gce-deep:#B8892E;/* fine rules / small marks that must hold on white (= --accent-600;
                                  the ONE GCE gold — D6 2026-09-09, #B8922A retired. Small TEXT in
                                  GCE gold on light paper uses the derived text-gold #8B6723,
                                  design-standards §5) */
  --paper-ink-gce-text:#1D2333;/* GCE running-text ink — near-black (brands.js docInk) */
  --paper-ink-gce-text-gold:#8B6723;/* small WORDS that must read as GCE gold on light paper —
                                  the AA-derived text-gold (design-standards §5, 2026-09-07:
                                  the brand hue/saturation with lightness 45%→34%; 4.54:1 on
                                  GCE paper, 5.12:1 on white). TEXT ONLY — never a fill, never
                                  a brand substitute. Carried by the /c/ GCE cards (THEMES
                                  accent_text) and the homepage's sister-company button. */
}

/* ═══ §11 · PAPER IN PRINT — THE LIGHT PALETTE ALWAYS WINS ON PAPER ══════════
   Added 2026-09-09 (Ives, Wave B) after a MEASURED defect on /terms/ — the
   governed print page (design-standards §2): a reader who had PINNED dark
   ([data-theme="dark"]) and printed got --text #eef1f8 on the forced-white
   sheet (1.04:1 — invisible) and a #131a2e card fill (a page of toner). Print
   engines force prefers-color-scheme to light but cannot undo an author pin.
   §10's law is that the dark world NEVER goes to paper, so on paper the §2
   light values win regardless of the pin — declared here, LAST in the file,
   at the pin's own specificity (0,2,0), so no screen rule can out-rank it.
   These are the §2 values verbatim (keep them in step; CSS has no "revert to
   :root" for a custom property, which is the only reason they appear twice).
   Light-pinned print is byte-identical before and after this block. */
@media print {
  :root, :root[data-theme="dark"], :root:not([data-theme="light"]) {
    --bg:#fbfaf7; --bg-sunken:#f3f1ea; --surface:#ffffff; --surface-2:#f7f5ef;
    --surface-glass:rgba(255,255,255,.66);
    --text:#16203a; --text-muted:#5b6478; --text-faint:#8b93a4;
    --border:#e7e3d8; --border-strong:#d6d1c3; --ring:rgba(58,74,140,.35);
    --link:var(--brand-500); --link-hover:var(--brand-600); --brand-title:var(--brand-600);
    --brand-wash:var(--brand-50); --brand-wash-line:var(--brand-200);
    --gold-line:var(--accent-500); --accent-swap:var(--brand-500);
    --accent-swap-fg:var(--on-brand-fg); --accent-swap-strong:var(--brand-600);
    --gce-rule:var(--paper-ink-gce-deep); --gce-text:var(--paper-ink-gce-text-gold);
    --brand-ink:#131d39;
    --ok-bg:#e7f3ec; --warn-bg:#f6edd9; --bad-bg:#f6e4df;
    --card-gold-ring:color-mix(in srgb, var(--accent-500) 72%, var(--border));
    --card-ring:color-mix(in srgb, var(--brand-400) 38%, var(--border));
    --edge-hi:inset 0 1px 0 rgba(255,255,255,.6);
    color-scheme:light;
  }
}

/* END bitzfield-theme.css — THE ONE DESIGN FILE. Components live in
   assets/shell.css (OS chrome) and assets/bitzy-ui.css (paper components);
   they consume these values and define none of their own. */
