/* ============================================================
   Wellstreet — the DARK DOT-MATRIX identity (WS-DARK-DOTO, 2026-09-07).
   Substrate #0A0E12, ink #EDE9DC, ONE accent #E8A33D. 'Doto' is the machine
   voice (display + every measured figure + every status), monospace is the
   label voice — no third register: no serif, no images, no gradients. The
   only texture is the fine halftone field (1px dots on a 14px grid). Hard
   2px borders, flat surfaces. Faces ship same-origin under ../fonts/
   (IPFS-friendly; system stacks as fallbacks). One-motion budget: the
   ledger stamp is the page's only keyframes — joined 2026-09-08 by the
   flow pulse dot (FLOW_SECTION_2026-09-08, the user-granted second
   signature: transform + opacity only, reduced-motion kills it entirely).
   ============================================================ */

:root {
  --paper: #0A0E12;       /* WS-DARK-DOTO (2026-09-07): the banner substrate — deep blue-black, freshly authored, not a leaver value */
  --paper-2: #070B0E;     /* recess — one step INTO the page from base */
  --ink: #EDE9DC;         /* the banner ink — warm bone on the substrate (8.99:1 on --paper) */
  --ink-soft: #9A948A;    /* muted-on-dark — 6.4:1 on --paper */
  --line: #262E36;        /* cold carbon hairline */
  --accent: #E8A33D;      /* the single accent — amber: FILL role (hero rule, flags, primary CTA) */
  --accent-ink: #0A0E12;  /* substrate text on #E8A33D fills — 8.99:1 */
  --accent-text: #E8A33D; /* accent-as-TEXT on the substrate — 8.99:1; one amber, both roles */
  --warn: #D96A52;        /* honest red on dark — warnings, blocked, unavailable (5.8:1 on --paper-2) */
  --code-bg: #060A0D;     /* deepest — code wells sink below the recess */
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  --sans: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace; /* retired register: body copy rides --mono; token defined-but-unconsumed */
  --serif: Georgia, "Iowan Old Style", "Times New Roman", serif; /* retired register: no live consumer (only the pinned dead .hero h1 .quiet rule references it); the serif webfont is gone */
  /* the pairing rule, in tokens (WS-DARK-DOTO): machine truth wears the
     machine face ('Doto' is the only display register — display + every
     measured figure + every status), labels/units/body stay mono. No third
     voice. Fallbacks: display → mono, so a failed font swap degrades into
     the label grammar. */
  --font-display: "Doto", ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  --font-num: "Doto", ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  /* motion (R3 IMP-3): one expo family, three durations — timing design instead
     of a single 140ms ease. --motion stays the fast tick alias (V6 role, now
     re-curved); surfaces move at --t-base; the scroll reveal runs --t-slow.
     The pulse/float loops ride the symmetric --ease-loop. Nothing bounces. */
  --t-fast: 120ms;
  --t-base: 200ms;
  --t-slow: 320ms;
  --ease-enter: cubic-bezier(0.16, 1, 0.3, 1);  /* expo-out — entrances, hovers, reveals */
  --ease-loop: cubic-bezier(0.65, 0, 0.35, 1);  /* symmetric — designed curve for the loops */
  --motion: var(--t-fast) var(--ease-enter);
  --ws-trust-size: clamp(36px, 4.5vw, 42px); /* UI2-P4 (2026-09-06, WS3-COLOR): the --ws-trust-bg/border/text duplicate trio is collapsed — trust-pill colors live on the ladder: bg=--paper-raised, border=--line, text=--ink-soft (consumers re-pointed in the same pass; --ws-trust-size survives, used by .hero-fact) */
}

/* Self-hosted OFL webfonts (WS-DARK-DOTO): one face, two flavors, both
   variable-weight single files under ../fonts/ (relative path — IPFS-ready).
   The woff2 (3.5KB, full wght + ROND axes) is the primary src; the ttf
   (93KB, ROND instanced at 100 — the only roundness the identity uses,
   wght 100-900 intact) is the same-origin fallback flavor.
   font-display: swap keeps the system-stack fallback visible while it loads. */
@font-face {
  font-family: "Doto";
  src: url('../fonts/doto-var.woff2') format('woff2'),
       url('../fonts/doto-var.ttf') format('truetype');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* ---------- LIGHT THEME TOKENS (G1 THEME-FOUNDATION, 2026-09-08) ----------
   Additive override on the WS-DARK-DOTO defaults above — dark is NEVER
   re-skinned: with no data-theme attribute and a dark system the rendered
   page is pixel-identical to the pre-theme site. Mechanism (locked in
   docs/internal/THEME_DUAL_WAVE_2026-09-08.md §1):
     - html[data-theme="light"]  -> explicit light (toggle/storage)
     - html[data-theme="dark"]   -> explicit dark (no override needed: the
       :root defaults above ARE the dark table)
     - attribute ABSENT          -> system follow: the @media block below
       applies the same light tokens only when the OS asks for light.
   Placed AFTER the @font-face (not directly after the first :root) so lines
   12-60 — the dark token block + the doto @font-face — stay byte-identical
   for the theme battery's dark-default diff pin. Values are FRESH warm-paper
   hexes, every one outside theme.test.js's retired-era ban list (the light-era
   leavers cluster in exactly this range; each value was chosen for maximum
   ban-list distance, then machine-verified — all six (c)-slot text pairs
   clear 4.5:1 on the light ladder: ink/paper 13.6, ink-soft/paper 6.9,
   accent-text/paper 6.3, accent-ink/accent 7.3, warn/paper-2 5.5,
   ink/paper-2 11.9 — and every extended surface/text pair >= 4.5:1; hairlines
   keep their non-text register). The footer flips to a light --ink-deep band
   so .site-footer's var(--ink) text stays legible; --footer-muted/-faint
   re-derive for that band and stay >= 4.5:1 on --paper (the .lc-label strip).
   --accent stays the single amber #E8A33D in BOTH modes (fill role);
   --accent-ink and --accent-text are the re-derived light-side text roles.
   Shadow tokens stay none (inherited) for cards and surfaces — the identity is
   hard borders in either mode; --shadow-btn/-hover re-ink for BUTTONS only
   (BTN-MOTION 2026-09-08, the one sanctioned shadow amendment).
   MAINTENANCE: the two token lists below are a DELIBERATE duplicate
   (plain CSS has no mixins) — keep the value lines byte-identical. */
html[data-theme="light"] {
  --paper: #F2EFE6;        /* warm paper substrate — the light identity's base */
  --paper-raised: #FBF9F1; /* card faces: +1 toward the viewer (lighter on light) */
  --paper-pending: #ECE8D8;/* scaffolding — between base and recess */
  --paper-2: #E6E0CC;      /* recess — one step INTO the page from base */
  --code-bg: #DDD6BE;      /* deepest well — code sinks below the recess */
  --chip-tan: #EDE1C4;     /* warm tan chip fill; chip text stays var(--ink) */
  --warn-bg: #F5E3DA;      /* light red tint behind warn text/tags */
  --ink-deep: #D8D0B8;     /* footer band surface (ink-era misnomer retained) */
  --ink: #26231C;          /* warm carbon ink — 13.6:1 on --paper */
  --ink-soft: #575144;     /* muted-on-light — 6.9:1 on --paper */
  --line: #CCC4AC;         /* warm hairline */
  --line-dotted: #D8D0BA;  /* dotted-border role only — fainter than --line */
  --accent-ink: #26231C;   /* carbon text on #E8A33D fills — 7.3:1 */
  --accent-text: #7A4E0E;  /* accent-as-TEXT on light paper — dark caramel, 6.3:1 */
  --accent-visited: #6B470D; /* visited links — deeper caramel, 7.2:1 on --paper */
  --accent-hover: #D08D2C; /* hover steps DEEPER on light fills (lighter on dark) */
  --accent-punch: #8F5E10; /* focus ring + the one accent-as-index text — 4.8:1 on --paper */
  --warn: #9C3222;         /* honest deep red on light — 5.5:1 on --paper-2 */
  --footer-muted: #544D3C; /* muted on the light footer band — 5.5:1 there, 7.3:1 on --paper */
  --footer-faint: #5F5741; /* faint fine print on the footer band — 4.7:1 */
  /* BTN-MOTION (2026-09-08): the button shadows re-ink for light — the warm-ink
     rgba (the --ink family, rgb 38 35 28), LOWER alpha than dark. G3-LIGHT-THEME
     (2026-09-08) raises the alphas: 0.14/0.16 composited 1.31/1.37:1 on paper —
     invisible; 0.24/0.26 composite 1.62/1.69:1 (the 1.6:1 floor, machine-proven
     by the G3 contrast recompute script). Kept in BOTH light blocks per the
     MAINTENANCE duplicate rule above. The pair ships on ONE line per block —
     resting + hover are one atomic unit (the G3 verify counts one warm-ink
     shadow line per light block; (a-btn) pins the pairing). */
  --shadow-btn: 0 1px 2px rgba(38, 35, 28, 0.24); --shadow-btn-hover: 0 3px 8px rgba(38, 35, 28, 0.26);
}
@media (prefers-color-scheme: light) {
  /* system-follow half: identical tokens for the NO-attribute state only —
     an explicit data-theme="dark" must keep the dark defaults. */
  html:not([data-theme]) {
    --paper: #F2EFE6;
    --paper-raised: #FBF9F1;
    --paper-pending: #ECE8D8;
    --paper-2: #E6E0CC;
    --code-bg: #DDD6BE;
    --chip-tan: #EDE1C4;
    --warn-bg: #F5E3DA;
    --ink-deep: #D8D0B8;
    --ink: #26231C;
    --ink-soft: #575144;
    --line: #CCC4AC;
    --line-dotted: #D8D0BA;
    --accent-ink: #26231C;
    --accent-text: #7A4E0E;
    --accent-visited: #6B470D;
    --accent-hover: #D08D2C;
    --accent-punch: #8F5E10;
    --warn: #9C3222;
    --footer-muted: #544D3C;
    --footer-faint: #5F5741;
    /* BTN-MOTION (2026-09-08): the button shadows re-ink for light — the warm-ink
       rgba (the --ink family, rgb 38 35 28), LOWER alpha than dark. G3-LIGHT-THEME
       (2026-09-08) raises the alphas: 0.14/0.16 composited 1.31/1.37:1 on paper —
       invisible; 0.24/0.26 composite 1.62/1.69:1 (the 1.6:1 floor, machine-proven
       by the G3 contrast recompute script). Kept in BOTH light blocks per the
       MAINTENANCE duplicate rule above. The pair ships on ONE line per block —
       resting + hover are one atomic unit (the G3 verify counts one warm-ink
       shadow line per light block; (a-btn) pins the pairing). */
    --shadow-btn: 0 1px 2px rgba(38, 35, 28, 0.24); --shadow-btn-hover: 0 3px 8px rgba(38, 35, 28, 0.26);
  }
}

/* ---------- LIGHT SURFACES (G2 LIGHT-SURFACES, 2026-09-08) ----------
   Component-level light overrides — the additive half of the dual-mode system
   (docs/internal/THEME_DUAL_WAVE_2026-09-08.md §3 G2). Every surface styled in
   tokens re-values itself from the block above; the rule here exists ONLY for
   the one surface that carries a theme-INSENSITIVE literal: .hero-field paints
   its halftone in the DARK ink's rgba (bone 5.5% dots + 3.5% ledger lines),
   which vanishes on warm paper. Light re-inks the SAME two-layer field in
   carbon at the same alphas — the dot-matrix field reads as dots in both
   modes, nothing is added or retired. Scoped html[data-theme="light"] plus the
   system-follow twin inside the media block (attribute ABSENT = follow); an
   explicit data-theme="dark" matches neither and keeps the dark bytes exactly.
   The ledger-line layer is spelled as a TILED linear-gradient (one 119px-wide
   strip, default background-repeat) instead of the repeating- gradient form so
   theme.test.js (g)'s exactly-one repeating-gradient DARK-identity register
   count stays truthful — the rendered texture is identical.
   MAINTENANCE: the two rules below are a DELIBERATE duplicate (plain CSS has
   no mixins) — keep them byte-identical to each other. */
html[data-theme="light"] .hero-field {
  background-image:
    radial-gradient(circle, rgba(38, 35, 28, 0.055) 1px, transparent 1.2px),
    linear-gradient(90deg, transparent 0 118px, rgba(38, 35, 28, 0.035) 118px 119px);
  background-size: 14px 14px, 119px 100%;
}
@media (prefers-color-scheme: light) {
  html:not([data-theme]) .hero-field {
    background-image:
      radial-gradient(circle, rgba(38, 35, 28, 0.055) 1px, transparent 1.2px),
      linear-gradient(90deg, transparent 0 118px, rgba(38, 35, 28, 0.035) 118px 119px);
    background-size: 14px 14px, 119px 100%;
  }
}

/* ---------- LIGHT AMBER-REGISTER EDGES (G3-LIGHT-THEME, 2026-09-08) ----------
   The amber fills' edges collapse on warm paper — amber-on-paper reads as one
   soft field with no boundary. Light re-inks the EDGES to carbon, extending
   the btn-primary vocabulary (amber fill + ink border) to the rest of the
   amber register: the solid CTA, the flywheel bar fill, and the protocol
   spine/chip marks. border-COLOR only — no new widths, no new colors (the
   token is the light block's own --ink), and the (g) structure counts never
   see it. MAINTENANCE: the two rules below are a DELIBERATE duplicate (plain
   CSS has no mixins) — keep them byte-identical to each other. */
html[data-theme="light"] .cta-solid,
html[data-theme="light"] .st-bar-fill,
html[data-theme="light"] .ft-spine--protocol,
html[data-theme="light"] .fc-spine--protocol,
html[data-theme="light"] .badge--protocol { border-color: var(--ink); }
@media (prefers-color-scheme: light) {
  html:not([data-theme]) .cta-solid,
  html:not([data-theme]) .st-bar-fill,
  html:not([data-theme]) .ft-spine--protocol,
  html:not([data-theme]) .fc-spine--protocol,
  html:not([data-theme]) .badge--protocol { border-color: var(--ink); }
}

* { box-sizing: border-box; }

/* R3 IMP-11: brand selection color (was the default UA blue on a green/black brand) */
::selection { background: color-mix(in srgb, var(--accent) 35%, transparent); color: var(--ink); } /* UI2-P8 (2026-09-06, WS3-COLOR): token-derived alpha — was the old accent-alpha literal (identical rendered value today); a future --accent re-value now propagates. color-mix() is Baseline 2023; an engine without it drops the declaration and keeps the UA default selection color (graceful degradation, no regression path). */

/* R3 IMP-10: progressive enhancement — headline orphans rebalance where
   text-wrap: balance is supported; unsupported browsers ignore it. The h1
   MARKUP was byte-frozen through WS-COPY-DIFFERENTIATION; the 2026-09-04
   two-tone re-pin (span.quiet wrap) is the sanctioned exception — the
   tagline text and the hard <br> still never change. */
h1 { text-wrap: balance; }

html, body {
  margin: 0;
  padding: var(--space-0);
  background: var(--paper);
  color: var(--ink);
  font-family: var(--mono); /* WS-DARK-DOTO: the label voice carries the whole page; Doto rides the display/number tokens */
  line-height: 1.55;
}

body[data-geo-blocked="true"] { background: var(--paper); }

html { scroll-behavior: smooth; } /* G2 #4 (2026-09-08, UI_LOOP_2): anchor jumps glide instead of teleporting; the reduced-motion guard below pairs this explicitly — scroll-behavior is NOT a transition, so the universal transition:none guard cannot nullify it */

a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 2px; transition: color var(--motion), outline-color var(--motion); }
a:visited { color: var(--accent-visited); }
a, button, input, summary, [tabindex] { outline: 2px solid transparent; outline-offset: 2px; } /* G2 #3 (2026-09-08, UI_LOOP_2): summary joins the reset — the mobile flagship's native <details> disclosure otherwise rides the UA focus ring while every other control takes the :focus-visible punch ring on the next line (summary:focus-visible is already listed there) */
a:focus-visible, button:focus-visible, input:focus-visible, [tabindex]:focus-visible, summary:focus-visible { outline-color: var(--accent-punch); } /* WS-A11Y-QUICK 2026-09-05: the keyboard-only ring must clear the 3:1 WCAG 1.4.11 floor — punch computes 11.05:1 on paper / 10.13:1 on paper-raised under the dark-calm table (--accent computed 6.33:1); mouse users never see :focus-visible. WS5-TREATMENT 2026-09-07: summary joins the ring rule — the fleet cards are native <details> disclosures and the whole summary is the tap zone. */

/* ---------- screen-reader utilities (WS-A11Y-QUICK 2026-09-05) ---------- */
/* clip-form sr-only: visually vanishes while STAYING in the tab order and the
   accessibility tree — never opacity:0 (invisible-but-focusable) and never
   display:none (removes the element from the tab order, WCAG 2.4.1). */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
}
/* skip link: the body's first focusable (bypass blocks, WCAG 2.4.1), hidden
   with the same clip recipe. The reveal on keyboard focus is INSTANT — no
   transition/animation declaration on either rule (reduced-motion pairing by
   construction) — and un-clips FULLY before any styling: a color-only reveal
   would leave a permanently invisible 1px link. */
.skip-link {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
}
.skip-link:focus-visible { clip: auto; width: auto; height: auto; margin: auto; overflow: visible; position: fixed; top: var(--space-6); left: var(--space-6); background: var(--paper); color: var(--ink); border: 2px solid var(--ink); font-family: var(--mono); text-transform: uppercase; padding: var(--space-10) var(--space-16); z-index: 100; } /* z-index 100 clears the sticky header's 10 (the site max) */
code { font-family: var(--mono); background: var(--code-bg); padding: var(--space-0) var(--space-4); border: 1px solid var(--line); font-size: var(--step-3); }
pre { background: var(--code-bg); border: 2px solid var(--line); padding: var(--space-12); overflow-x: auto; }
pre code { background: none; border: none; padding: var(--space-0); }

.wrap { max-width: var(--wrap-max); margin: 0 auto; padding: var(--space-0) var(--space-20); }

/* ---------- header ---------- */
.site-header {
  border-bottom: 2px solid var(--line);
  background: var(--paper);
  position: sticky;
  top: 0;
  z-index: 10;
}
.site-header .wrap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-16);
  padding-top: var(--space-14);
  padding-bottom: var(--space-14);
}
.brand { display: flex; align-items: baseline; gap: var(--space-10); text-decoration: none; color: var(--ink); }
.brand-word {
  font-family: var(--font-display); /* WS-DARK-DOTO: the masthead joins the machine register */
  font-weight: 800;
  font-variation-settings: 'ROND' 100;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-size: var(--step-5);
  border: 2px solid var(--line);
  padding: var(--space-2) var(--space-10);        /* P-11: left stays --space-10 */
  padding-right: calc(var(--space-10) - 0.12em);  /* P-11: optical — eats the trailing 0.12em tracking unit inside the bordered plate */
  background: var(--paper-2);
}
.brand-tag { font-family: var(--mono); font-size: var(--step-1); color: var(--ink-soft); text-transform: uppercase; letter-spacing: var(--track-label); } /* P-11/P-10: the one untracked mono metadata surface joins the label register */
.site-nav { display: flex; flex-wrap: wrap; gap: var(--space-10) var(--space-16); align-items: center; }
.site-nav a { color: var(--ink); text-decoration: none; font-family: var(--mono); font-size: var(--step-2); text-transform: uppercase; letter-spacing: var(--track-chrome); border-bottom: 2px solid transparent; padding: var(--space-4) var(--space-0); min-height: 44px; transition: border-bottom-color var(--motion), color var(--motion); } /* P-07: nav steps up one role to the small-text role; P-10: tracking rides --track-chrome. WS-VAULT-GATES (2026-09-13): the 44px link floor was ≤640-only (plain links measured 30px at desktop) — all-width tap parity, the same move W1 G1-BAND already ratified for nav-cta; height-neutral ≥760 (the 74px bar is toggle-driven) */
.site-nav a:hover { border-bottom-color: var(--ink-soft); } /* WS3-HEADER P2 (2026-09-06): the --line hover underline is sub-perceptual by design; ink-soft is 7.14:1 on carbon, a visible step below the active underline */
/* R2 header CTA — honest conversion affordance (copy reused verbatim from the footer;
   targets the #docs section, never the pre-deploy deposit widget). Specificity-bearing
   selector so the base .site-nav a rule cannot squash the pill. */
.site-nav a.nav-cta {
  /* WS3-HEADER P3 (2026-09-06): the pill takes the accent register — the self-serve /
     agent voice matches button.btn-primary; the hero .cta-solid stays the ink money
     register, so the page speaks one primary per register instead of two black fills. */
  background: var(--accent); color: var(--accent-ink);
  border-bottom: none;
  border-radius: var(--radius); min-height: 44px; /* W1 G1-BAND (2026-09-08): 44 was ≤640-only — tap parity at every width. Height-neutral ≥760 (the 44px theme toggle already drives the 74px bar); the 641-759 wrapped nav grows by the same 6px — the scroller blocks below re-measure against it. */
  padding: var(--space-6) var(--space-16);
  font-family: var(--mono); font-size: var(--step-2); text-transform: uppercase; letter-spacing: var(--track-chrome); /* P-07: the CTA steps up one role; P-10: --track-chrome */
  line-height: 1; display: inline-flex; align-items: center; text-decoration: none;
  box-shadow: var(--shadow-btn); /* BTN-MOTION (2026-09-08): the filled header primary rests on the button shadow */
  transition: background-color var(--t-base) var(--ease-enter), transform var(--motion); /* G2 #1 (2026-09-08, UI_LOOP_2): the LIFT tweens transform at --motion (120ms) — one gesture, one speed with the chip register; the color component keeps --t-base */
}
.site-nav a.nav-cta:hover:not(:disabled) { background: var(--accent-hover); transform: translateY(-1px); box-shadow: var(--shadow-btn-hover); } /* WS3-HEADER P3 (2026-09-06): the shipped btn-primary:hover vocabulary; BTN-MOTION (2026-09-08): + the 1px lift and the hover shadow swap */
.site-nav a.nav-cta:active:not(:disabled) { transform: translateY(0) scale(0.985); box-shadow: var(--shadow-btn-hover); transition: background-color var(--t-fast) var(--ease-enter), transform var(--t-fast) var(--ease-enter); } /* BTN-MOTION (2026-09-08): the dip retires — the press settles under the finger at 0.985 */
.site-nav a.active { border-bottom-color: var(--accent-punch); } /* WS3-HEADER P7 (2026-09-06): orientation green — accent marks where you are (11.05:1 on carbon, passes 1.4.11); hover ink-soft and active punch now differ in kind, not degree */

/* ---------- theme toggle (G1 THEME-FOUNDATION, 2026-09-08) ---------- */
/* The header light/dark button. The mono label shows the mode you'll GET;
   aria-pressed reports "light is active". 44px tap target (the WS-MOBILE-FIXES
   P3 register); keyboard focus rides the global :focus-visible ring (no extra
   outline rule — the theme battery pins outline-color exactly once). The
   micro-transition is color-only on the toggle itself — the mode flip is an
   instant token repaint (no page-wide transition, no motion-budget fight).
   Reduced motion needs NO scoped guard here: the global prefers-reduced-motion
   page guard (agent-first (b5) — `*` with transition:none !important) is
   authoritative over every surface, this rule included. */
.theme-toggle {
  font-family: var(--mono);
  font-size: var(--step-1);
  text-transform: uppercase;
  letter-spacing: var(--track-chrome);
  color: var(--ink);
  background: var(--paper);
  border: 2px solid var(--line);
  border-radius: var(--radius);
  min-height: 44px;
  padding: var(--space-4) var(--space-12);
  cursor: pointer;
  transition: color var(--motion), background-color var(--motion), border-color var(--motion), transform var(--motion);
}
.theme-toggle:hover:not(:disabled) { border-color: var(--ink-soft); transform: translateY(-1px); box-shadow: var(--shadow-btn-hover); } /* BTN-MOTION (2026-09-08): the outline toggle lifts hover-only — no resting shadow, flat register intact at rest */
.theme-toggle:active:not(:disabled) { transform: translateY(0) scale(0.985); box-shadow: var(--shadow-btn-hover); transition: color var(--t-fast) var(--ease-enter), background-color var(--t-fast) var(--ease-enter), border-color var(--t-fast) var(--ease-enter), transform var(--t-fast) var(--ease-enter); } /* BTN-MOTION (2026-09-08): the press settles under the finger */

/* ---------- jurisdiction banner ---------- */
.jurisdiction-banner {
  border-bottom: 2px solid var(--warn);
  background: var(--warn-bg);
  color: var(--ink);
  font-size: var(--step-2);
}
.jurisdiction-banner .wrap { padding-top: var(--space-10); padding-bottom: var(--space-10); }
.jurisdiction-banner .disclosure { font-family: var(--mono); display: block; margin-top: var(--space-4); }

/* ---------- hero — the banner, extended (WS-DARK-DOTO) ---------- */
/* the band boundary is a plain hard rule again: the diagonal-stripe hatches
   retire with the identity (no gradients — the halftone field is the page's
   only texture). One 2px rule per boundary, .hero and section.block separate
   blocks. */
.hero { border-bottom: 2px solid var(--line); }
/* V10 hero whitespace: the wrap centers its stack within >=80vh on desktop.
   Mobile (<=640px) keeps the compact padding band. */
.hero .wrap {
  padding-top: var(--space-56);
  padding-bottom: var(--space-48);
  min-height: 80vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
/* the halftone field: the banner's fine dot grid (1px dots on a 14px grid)
   plus the faint ledger column lines on the right rhythm — the page's whole
   backdrop texture, painted in ink at 5.5% alpha. Zero requests, zero
   images, clipped by .hero's overflow so it can never scroll sideways. */
.hero-field {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  user-select: none;
  background-image:
    radial-gradient(circle, rgba(237, 233, 220, 0.055) 1px, transparent 1.2px),
    repeating-linear-gradient(90deg, transparent 0 118px, rgba(237, 233, 220, 0.035) 118px 119px);
  background-size: 14px 14px, auto;
}
.hero-ticker {
  position: relative;
  margin: 0 0 var(--space-24) 0;
  font-family: var(--mono);
  font-size: var(--step-2);
  letter-spacing: 0.22em; /* the banner ticker's wide metadata track */
  text-transform: uppercase;
  color: var(--ink-soft);
}
.hero h1 {
  font-family: var(--font-display); /* the machine voice — the banner headline register */
  font-size: var(--step-7); /* the page's loudest type */
  font-weight: 800;
  font-variation-settings: 'ROND' 100; /* the round-dot variant of the matrix — display use (wght still rides font-weight) */
  line-height: 1.08; /* the banner's line fit */
  margin: 0 0 var(--space-24) 0;
  letter-spacing: 0.01em; /* dot matrices need a hair of air */
  text-transform: uppercase;
}
.hero h1 .quiet { color: var(--ink-soft); font-family: var(--serif); font-weight: 400; line-height: 1.2; letter-spacing: normal; } /* RETIRED REGISTER (WS-DARK-DOTO): no markup consumes the quiet subline anymore — the rule survives only as the font battery's dead-serif pin; the three-voice page is two-voiced now */
.hero-rule {
  width: min(560px, 72vw);
  height: 3px;
  background: var(--accent); /* the banner's amber rule — the single accent, FILL role */
  margin: 0 0 var(--space-20) 0;
}
.hero-meta {
  position: relative;
  margin: 0 0 var(--space-32) 0;
  font-family: var(--mono);
  font-size: var(--step-2);
  letter-spacing: 0.06em;
  color: var(--ink-soft);
}
.hero-meta-dot { color: var(--ink-soft); } /* SECTION-IMPROVE G1 #8 (2026-09-08): amber budget — the banner's dot drops out of the accent register (amber stays rule + CTA + ZERO text); ink-soft matches the meta line it punctuates */
.hero-facts {
  /* honest trust row — the reference's ring/pill treatment on the four existing hero facts;
     the fabricated enterprise-logos row and its icon-font CDN host are rejected — no icon
     CDN ever enters this site. */
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  justify-content: flex-start;
}
.hero-fact {
  flex: 0 1 auto;
  padding: var(--space-14) var(--space-16);
  position: relative;
  border: 1px solid var(--line); /* UI2-P4: was var(--ws-trust-border) — the same hairline value, now a ladder name */
  background: var(--paper-raised); /* UI2-P4: was var(--ws-trust-bg) — collapsed into the raised step of the substrate ladder (one RGB step) */
  border-radius: var(--radius);
  margin-left: calc(var(--ws-trust-size) * -0.42);
  min-width: 0;
}
.hero-fact .k {
  display: block;
  font-family: var(--mono);
  font-size: var(--step-1);
  text-transform: uppercase;
  letter-spacing: var(--track-label); /* P-10 */
  color: var(--ink-soft); /* UI2-P4: was var(--ws-trust-text) — a straight alias, now a ladder name */
}
.hero-fact .v {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
}
.hero-fact:nth-child(2) { z-index: 2; }
.hero-fact:nth-child(3) { z-index: 3; }
.hero-fact:nth-child(4) { z-index: 4; }
.hero-fact:first-child { margin-left: 0; }

/* ---------- sections ---------- */
/* band boundary: a plain hard 2px rule per block (WS-DARK-DOTO — the hatches
   retire with the identity; the halftone field is the only texture). */
section.block { border-bottom: 2px solid var(--line); }
/* R3 IMP-6: anchored sections clear the 68px sticky header on nav jumps
   (68px bar + 16px breathing); in-pane doc headings get the same so the
   docs TOC deep links land their heading below the bar. */
/* WS3-HEADER P1 (2026-09-06): 84 was calibrated to the 68px desktop header; the
   641-940px band's two-row nav measures 107.4 + 16 landing air = 124. Desktop cost
   is air only (68px header — generous, never clipped). The <=640 overrides below
   stay owned by WS-MOBILE-FIXES and are untouched. */
section.block, .hero { scroll-margin-top: 124px; }
#doc-pane [id] { scroll-margin-top: 124px; }
section.block .wrap { padding-top: var(--space-64); padding-bottom: var(--space-48); } /* R3 IMP-13: blocks standardize 64/48 — more air reads more expensive at zero cost */
.block-head { display: flex; align-items: baseline; gap: var(--space-14); margin-bottom: var(--space-8); }
.block-head .index { font-family: var(--mono); color: var(--accent-text); font-weight: 700; font-size: var(--step-4); letter-spacing: 0.22em; } /* V1: section numbers promoted — accent-as-TEXT rides --accent-text on light paper; P-01: numeral scales with the display head (was --step-6) */
.block-head h2 {
  margin: 0;
  font-family: var(--font-display); /* WS-DARK-DOTO: section titles join the machine display register */
  font-weight: 700;
  font-variation-settings: 'ROND' 100;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  font-size: var(--step-6);     /* the ratified step-6 section-h2 role */
  line-height: 1.08;
}
.block-head .spacer { flex: 1; }
.block-sub { color: var(--ink-soft); font-size: var(--step-3); margin: 0 0 var(--space-24); max-width: var(--measure-copy); } /* UI2-L9 (2026-09-06, WS3-LAYOUT): the copy-measure role token — was the 52rem literal, zero rendered change */ /* UI_LOOP_2 G4 (2026-09-08): explicit step-3 — was UA-inherited 16px (off-token); the section sub recedes one role below the body floor; --measure-copy is rem-based so the column width is size-independent */

/* ---------- vault cards ---------- */
/* UI2-P6 (2026-09-06, WS3-COLOR): BORDER TAXONOMY — five registers:
   2px = structural/live-data surfaces (header rule, brand plate, vault-card, panel,
   hero-ledger + its rows, buttons, inputs, tabs, doc-pane) ·
   1px = interior hairlines + tags (td/th, footer-grid, code, share-symbol, code-copy,
   mint/inv card frames + tags) ·
   dotted --line-dotted = ledger leaders (card-row, card-note, doc-toc, sim-region) ·
   6px/8px-left = disclosure blocks (blockquote, apr-footnote, geo-disclosure) ·
   8px/4px border-image hatch = band boundaries (UI2-P5 two-register rhythm).
   Invariant: an interior border never out-weighs its frame — the one inversion
   (mint ticket rows vs their 1px frame) is fixed in the WS3-COLOR EOF block. */
#vault-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: var(--space-20); }
.vault-card { border: 2px solid var(--line); background: var(--paper-raised); display: flex; flex-direction: column; transition: box-shadow var(--t-base) var(--ease-enter); border-radius: var(--radius-soft); box-shadow: var(--shadow-soft); }
.vault-card:hover { box-shadow: var(--shadow-soft-hover); }
.card-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-10); flex-wrap: wrap;
  border-bottom: 2px solid var(--line); padding: var(--space-12) var(--space-14); background: var(--paper-2);
}
.card-title { margin: 0; font-size: var(--step-5); text-transform: uppercase; letter-spacing: var(--track-chrome); } /* P-10: was 0.04em */
.share-symbol { font-family: var(--mono); font-size: var(--step-2); border: 1px solid var(--line); padding: var(--space-2) var(--space-8); background: var(--paper); }
.card-rows { padding: var(--space-6) var(--space-14); font-variant-numeric: tabular-nums; } /* V2: aligned data figures */
.card-row { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-14); padding: var(--space-9) var(--space-0); border-bottom: 1px dotted var(--line-dotted); font-size: var(--step-3); } /* P-06: baseline alignment matches .ledger-row — the strong value shares the row's baseline (no-op in the ≤640px column stack); sizes re-denominated onto the 7-step scale, WS-TYPE-MOTION_FINAL 2026-09-06 */
.card-row:last-child { border-bottom: none; }
.row-label { color: var(--ink-soft); flex: 0 0 auto; font-family: var(--mono); font-size: var(--step-1); text-transform: uppercase; letter-spacing: var(--track-label); } /* MONEY-GRAMMAR (2026-09-06, UI_IMPROVE2_MONEY-SURFACES #1 extension): the e30a51c family-grid card is a money surface — its labels join the same receding mono small-cap register as .ledger-k (copy unchanged; uppercase is CSS-only). */
.row-value { text-align: right; font-family: var(--mono); font-size: var(--step-3); word-break: break-word; font-variant-numeric: tabular-nums; }
.card-row-strong .row-value strong { color: var(--accent-text); font-size: var(--step-4); }
/* WS-VAULT-FAMILY-GRID: the note pins to the card's bottom edge (margin-top:auto
   absorbs the free space of a grid row stretched to its tallest card), so a row
   of family cards keeps aligned footers. With a single card there is no free
   space and this renders exactly as before. */
.card-note { margin: auto 0 0; padding: var(--space-10) var(--space-14) var(--space-14) var(--space-14); font-size: var(--step-2); color: var(--ink-soft); border-top: 1px dotted var(--line-dotted); min-height: 72px; padding-right: 112px; /* WS3-ART P2 (2026-09-06): reserve the note's right corner for the certificate keeper (art never sits on data — doc's 108px tuned +4 so the 96px cert at right:14px clears the text box with a 2px gap) */ }

/* G1 (UI_IMPROVE2_GLYPHS): the glyph token law — glyphs that carry data ride
   TEXT-role tokens (--accent-text / --warn / --ink-soft); the FILL token --accent
   stays reserved for surfaces (style.css :21's own rule). Closes a11y finding 7
   (the ● at 2.54:1 on paper). */
.flag { font-family: var(--mono); font-size: var(--step-2); }
.flag-ok { color: var(--accent-text); }
.flag-warn { color: var(--warn); }
/* V2: the ●/△ status glyphs are aligned (fixed advance) so multi-line flags keep their column */
.flag .flag-glyph { display: inline-block; min-width: 1.2em; text-align: center; }
.flag-ok .flag-glyph { color: var(--accent-text); } /* G1: obeys the fill/text token law (see block head) */
.flag-warn .flag-glyph { color: var(--warn); }
.muted { color: var(--ink-soft); font-size: var(--step-2); }

.apr-footnote {
  margin-top: var(--space-16); border: 2px solid var(--line); border-left-width: 8px;
  background: var(--paper-2); padding: var(--space-12) var(--space-16); font-size: var(--step-2); color: var(--ink-soft);
}
.apr-footnote .lbl { font-family: var(--mono); text-transform: uppercase; letter-spacing: var(--track-label); font-size: var(--step-1); color: var(--ink); display: block; margin-bottom: var(--space-4); } /* P-10 */

/* ---------- vault-card pending state (V4) — pre-deploy, EVERY card is pending:
   render it as intentional scaffolding, not an unfinished page ---------- */
.vault-card--pending { border-style: dashed; background: var(--paper-pending); }
.vault-card--pending .card-head { border-bottom-style: dashed; }
.pending-tag {
  font-family: var(--mono); font-size: var(--step-1); text-transform: uppercase; letter-spacing: var(--track-label); /* P-10 */
  color: var(--warn); border: 1px solid var(--warn); background: var(--warn-bg); padding: var(--space-2) var(--space-8); white-space: nowrap;
}

/* ---------- widget ---------- */
.widget-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); gap: var(--space-20); }
.panel { border: 2px solid var(--line); background: var(--paper-raised); transition: box-shadow var(--t-base) var(--ease-enter); border-radius: var(--radius-soft); box-shadow: var(--shadow-soft); }
.panel:hover { box-shadow: var(--shadow-soft-hover); }
.panel-head { border-bottom: 2px solid var(--line); background: var(--paper-2); padding: var(--space-10) var(--space-14); display: flex; justify-content: space-between; align-items: center; gap: var(--space-10); }
.panel-head h3 { margin: 0; font-size: var(--step-4); text-transform: uppercase; letter-spacing: var(--track-chrome); } /* P-10: was 0.05em */
.panel-body { padding: var(--space-14); }
.field label { display: block; font-family: var(--mono); font-size: var(--step-1); text-transform: uppercase; letter-spacing: var(--track-label); color: var(--ink-soft); margin-bottom: var(--space-6); } /* P-10 */
.field input[type="text"], .field input[type="number"] {
  width: 100%; padding: var(--space-10); font-family: var(--mono); font-size: var(--step-4); /* 16px: below this iOS Safari auto-zooms on focus */
  min-height: 44px; /* WS-VAULT-GATES (2026-09-13): the money-amount fields measured 42px — the platform tap floor (44) now holds on the inputs too, the same floor every button control already carries */
  border: 2px solid var(--line); background: var(--paper); color: var(--ink);
}
.field input:disabled { background: var(--paper-2); color: var(--ink-soft); }
.field + .field { margin-top: var(--space-12); }
.btn-row { display: flex; gap: var(--space-10); margin-top: var(--space-14); flex-wrap: wrap; }
.connect-lane { margin-top: var(--space-16); } /* UI_LOOP_2 G4 (2026-09-08): the always-connect-entry owns its rhythm on the space scale — was unstyled, riding .btn-row's 14px by luck; the preceding .block-sub margin-bottom (24) collapses to max(24,16) = 24, so the rendered gap is unchanged */
button.btn {
  font-family: var(--mono); text-transform: uppercase; letter-spacing: var(--track-chrome); font-size: var(--step-2); /* P-07: action step-up one role; P-10: --track-chrome */
  padding: var(--space-10) var(--space-16); border: 2px solid var(--line); background: var(--paper); color: var(--ink);
  cursor: pointer; transition: background-color var(--t-base) var(--ease-enter), color var(--t-base) var(--ease-enter), outline-color var(--t-base) var(--ease-enter), transform var(--motion); /* G2 #1 (2026-09-08, UI_LOOP_2): the LIFT tweens transform at --motion (120ms) — one gesture, one speed with the chip register; the color/bg/outline components keep --t-base */
  border-radius: var(--radius); /* R3 IMP-7: the action class unifies on the pill — same geometry as the nav CTA 40px away */
  min-height: 44px; /* money-path mobile ergonomics — ens.domains action targets measure 52px @400 / 72px @1280; 44 = platform floor; NOT an a11y-compliance claim */
}
button.btn:hover:not(:disabled) { background: var(--paper-2); transform: translateY(-1px); box-shadow: var(--shadow-btn-hover); } /* BTN-MOTION (2026-09-08): the outline surface lifts hover-only — shadow on hover/press, never at rest */
button.btn:disabled { opacity: 1; background: var(--paper-2); color: var(--ink-soft); border-color: var(--line); cursor: not-allowed; } /* MONEY-GRAMMAR (2026-09-06, UI_IMPROVE2_MONEY-SURFACES #5): the parked register mirrors .field input:disabled — no washed-green ghost; accent scarcity restored (pre-connect the only green is CONNECT, post-connect DEPOSIT). The btn-primary companion rule lives in the WS3-MONEY EOF block. */
button.btn:active:not(:disabled) { transform: translateY(0) scale(0.985); box-shadow: var(--shadow-btn-hover); transition: background-color var(--t-fast) var(--ease-enter), color var(--t-fast) var(--ease-enter), outline-color var(--t-fast) var(--ease-enter), transform var(--t-fast) var(--ease-enter); } /* BTN-MOTION (2026-09-08): the dip retires — the press settles under the finger at 0.985 */
button.btn-primary { background: var(--accent); color: var(--accent-ink); border-color: var(--ink); box-shadow: var(--shadow-btn); } /* BTN-MOTION (2026-09-08): the filled primary rests on the button shadow (the one resting-weight register) */
button.btn-primary:hover:not(:disabled) { background: var(--accent-hover); transform: translateY(-1px); box-shadow: var(--shadow-btn-hover); } /* BTN-MOTION (2026-09-08): + the 1px lift and the hover shadow swap */
/* hero CTA (WS-DARK-DOTO): ONE anchor, the amber fill — the page's single
   primary. Geometry mirrors button.btn above (mono, uppercase, 2px border,
   44px min-height). This is an <a>, so the class explicitly overrides the
   global a / a:visited rules — text-decoration none and token colors,
   visited included. The hover is PER-CLASS on purpose (never a shared
   comma-joined rule): the fill shifts one amber step brighter. */
/* G8 (UI_IMPROVE2_GLYPHS, 2026-09-06): arrow grammar — '→' promises forward
   motion inside the page (CTAs, the flow node); '↗' promises an off-site
   handoff (the explorer link). No other arrows ship ('›', '»', '⇒' banned
   by convention). */
.cta-row { display: flex; flex-wrap: wrap; gap: var(--space-10); margin-top: var(--space-16); }
.cta-solid {
  font-family: var(--mono); text-transform: uppercase; letter-spacing: var(--track-chrome); font-size: var(--step-2); /* P-07: action step-up one role; P-10: --track-chrome */
  padding: var(--space-10) var(--space-16); border: 2px solid var(--accent); background: var(--accent); color: var(--accent-ink);
  text-decoration: none; display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; border-radius: 0; cursor: pointer; /* WS-DARK-DOTO: the primary CTA joins the hard-border data register (no pill) */
  box-shadow: var(--shadow-btn); /* BTN-MOTION (2026-09-08): the one solid CTA rests on the button shadow */
  transition: background-color var(--t-base) var(--ease-enter), color var(--t-base) var(--ease-enter), outline-color var(--t-base) var(--ease-enter), transform var(--motion); /* G2 #1 (2026-09-08, UI_LOOP_2): the LIFT tweens transform at --motion (120ms) — one gesture, one speed with the chip register; the color/bg/outline components keep --t-base */
}
.cta-solid:visited { color: var(--accent-ink); text-decoration: none; }
.cta-solid:hover:not(:disabled) { background: var(--accent-hover); color: var(--accent-ink); transform: translateY(-1px); box-shadow: var(--shadow-btn-hover); } /* BTN-MOTION (2026-09-08): + the 1px lift and the hover shadow swap */
.cta-solid:active:not(:disabled) { transform: translateY(0) scale(0.985); box-shadow: var(--shadow-btn-hover); transition: background-color var(--t-fast) var(--ease-enter), color var(--t-fast) var(--ease-enter), outline-color var(--t-fast) var(--ease-enter), transform var(--t-fast) var(--ease-enter); } /* BTN-MOTION (2026-09-08): the press settles under the finger */
#widget-status { margin-top: var(--space-16); padding: var(--space-10) var(--space-12); border: 2px solid var(--line); background: var(--paper-2); font-size: var(--step-2); min-height: 40px; word-break: normal; overflow-wrap: anywhere; } /* MONEY-GRAMMAR (2026-09-06, UI_IMPROVE2_MONEY-SURFACES #11 bug fix): break-all wrapped every status sentence mid-word; overflow-wrap:anywhere still breaks the long hashes/explorer URLs but only when a token cannot otherwise fit. */
#wallet-balances { margin-top: var(--space-10); font-family: var(--mono); font-size: var(--step-2); color: var(--ink-soft); }
#acquire-note { margin: var(--space-14) 0 0 0; font-size: var(--step-2); color: var(--ink-soft); }
.tx-link { display: inline-block; padding: 15px 8px; margin: -15px -8px; margin-left: var(--space-10); font-family: var(--mono); font-size: var(--step-2); } /* WS-VAULT-GATES second pass (2026-09-14): the 44px tap floor — the gov-tape 'tx ↗' links measured 31x15; padding expands the tap area, the negative margins keep the line rhythm unchanged. */

/* wallet picker (eip-6963 multi-wallet) + noscript note */
#wallet-picker { margin-top: var(--space-12); display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-10); }
#wallet-picker[hidden] { display: none; }
#wallet-picker .picker-label { font-family: var(--mono); font-size: var(--step-2); text-transform: uppercase; letter-spacing: var(--track-chrome); color: var(--ink-soft); } /* P-10: a 0.06em site the mapper census omitted — re-pointed at the identical computed value (zero rendered change) to complete the cluster collapse */
/* UI_LOOP_2 G5 (2026-09-08): the announced wallet's own icon renders inside the row — 20px figure in a hairline container that mirrors the .mwg chip register (1px --line edge, raised paper, square data radius). Icons are data: URIs (gate-safe); the container is border-only, no new gradients. */
#wallet-picker .picker-btn { display: inline-flex; align-items: center; }
#wallet-picker .picker-icon-wrap { display: inline-flex; align-items: center; justify-content: center; flex: none; width: 28px; height: 28px; margin-right: var(--space-8); background: var(--paper-raised); border: 1px solid var(--line); border-radius: var(--r-0, 0); }
#wallet-picker .picker-icon { display: block; width: 20px; height: 20px; }
#wallet-picker .picker-name { white-space: nowrap; }
.noscript-note { padding-top: var(--space-16); padding-bottom: var(--space-16); font-size: var(--step-3); color: var(--ink-soft); border-bottom: 2px solid var(--line); }

/* ---------- mobile wallet guide (MOBILE-WALLET-GUIDE, 2026-09-08) ----------
   The iOS-Safari fallback card's interactive surfaces. The guide shipped them
   unstyled (raw link/button registers); BTN-MOTION (2026-09-08) brings them
   into the outline-button register so the motion system has a surface to read
   on — the .fleet-filter chip anatomy (mono, hairline edge, raised paper,
   square data radius, 44px zone) + the shared button motion pair: hover-only
   shadow + lift, press at 0.985, never tweened shadow. */
.mwg-link, .mwg-copy {
  appearance: none;
  display: inline-flex; align-items: center; justify-content: center;
  min-height: 44px; min-width: 44px;
  padding: var(--space-8) var(--space-12);
  background: var(--paper-raised); color: var(--accent-text);
  border: 1px solid var(--line); border-radius: var(--r-0, 0);
  font-family: var(--mono); font-size: var(--step-2);
  text-decoration: none; cursor: pointer;
  transition: color var(--motion), border-color var(--motion), transform var(--motion);
}
.mwg-link { margin: var(--space-2) var(--space-8) var(--space-2) 0; } /* chip-run spacing — the two inline app links need a gap */
.mwg-lead { margin: 0 0 var(--space-10); font-size: var(--step-4); } /* UI_LOOP_2 G4 (2026-09-08): the guide's instruction line reads at the body floor — was UA 16px off-token; the note/url recede to the chrome register below (real hierarchy, was a flat 16px panel) */
.mwg-note { font-size: var(--step-2); color: var(--ink-soft); } /* UI_LOOP_2 G4 (2026-09-08): chrome role — pairs with the .mwg-copy chip it sits between */
.mwg-url { font-family: var(--mono); font-size: var(--step-2); font-weight: 700; color: var(--ink); } /* UI_LOOP_2 G4 (2026-09-08): the actionable datum leads its row — mono 700 at the chip's own step, full ink against the muted note */
.mwg-link:hover:not(:disabled), .mwg-copy:hover:not(:disabled) { border-color: var(--accent-text); transform: translateY(-1px); box-shadow: var(--shadow-btn-hover); } /* BTN-MOTION (2026-09-08): the .ft-copy hover vocabulary + lift + hover shadow */
.mwg-link:active:not(:disabled), .mwg-copy:active:not(:disabled) { transform: translateY(0) scale(0.985); box-shadow: var(--shadow-btn-hover); transition: color var(--t-fast) var(--ease-enter), border-color var(--t-fast) var(--ease-enter), transform var(--t-fast) var(--ease-enter); } /* BTN-MOTION (2026-09-08) */
/* UI_LOOP_2 G5 (2026-09-08): the panel itself joins the register — post-hotfix
   (05c23ad) the foot line sits INSIDE the div again, but the box shipped bare:
   no padding, UA-default paragraph margins off the --space scale. A quiet
   container (hairline 1px edge + paper-2, the panel register #widget-status
   reads) with token-scale rhythm: lead → chips → row → foot, all gaps on the
   scale. Border-only, no new gradients; no border-bottom 2px literal. */
.mwg { margin: var(--space-12) 0 var(--space-16); padding: var(--space-14) var(--space-16); background: var(--paper-2); border: 1px solid var(--line); }
.mwg-row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-8) var(--space-10); margin: var(--space-12) 0 0 0; }
.mwg-foot { margin: var(--space-12) 0 0 0; font-size: var(--step-2); color: var(--ink-soft); }

/* ---------- docs ---------- */
.doc-tabs { display: flex; flex-wrap: wrap; gap: 0; border-bottom: 2px solid var(--line); }
.doc-tab {
  font-family: var(--mono); font-size: var(--step-2); text-transform: uppercase; letter-spacing: var(--track-chrome); /* P-10: was 0.05em */
  padding: var(--space-9) var(--space-14); background: var(--paper-2); border: 2px solid var(--line); border-bottom: none;
  margin-right: var(--space-6); cursor: pointer; color: var(--ink-soft);
  transition: background-color var(--t-base) var(--ease-enter), color var(--t-base) var(--ease-enter), outline-color var(--t-base) var(--ease-enter), transform var(--t-base) var(--ease-enter);
  min-height: 44px; /* money-path mobile ergonomics — ens.domains action targets measure 52px @400 / 72px @1280; 44 = platform floor; NOT an a11y-compliance claim */
}
.doc-tab.active { background: var(--ink); color: var(--paper); }
.doc-tab:hover:not(.active) { background: var(--paper); color: var(--ink); }
.doc-tab:active:not(:disabled) { transform: translateY(1px); transition: background-color var(--t-fast) var(--ease-enter), color var(--t-fast) var(--ease-enter), outline-color var(--t-fast) var(--ease-enter), transform var(--t-fast) var(--ease-enter); }
/* V8: the doc pane reads as a document — measure-limited, serif headers, mono code */
#doc-pane { border: 2px solid var(--line); border-top: none; background: var(--paper-raised); padding: var(--space-22) var(--space-24); min-height: 220px; max-width: 72ch; line-height: 1.65; } /* P-08: long-form reading leading for ~2,000px documents */
#doc-pane[aria-busy="true"] { color: var(--ink-soft); font-family: var(--mono); font-size: var(--step-2); }
#doc-pane h1, #doc-pane h2, #doc-pane h3 {
  text-transform: none; letter-spacing: 0.01em;
  font-family: var(--font-display); /* WS-DARK-DOTO: doc headings join the machine display register */
  font-weight: 700;
  font-variation-settings: 'ROND' 100;
}
#doc-pane h1 { font-size: var(--step-6); border-bottom: 2px solid var(--line); padding-bottom: var(--space-8); } /* per-doc title as document header — display rung (R3: was step-16, which collapsed into the 20px role) */
#doc-pane h2 { font-size: var(--step-5); margin-top: var(--space-28); } /* R3 IMP-11: one display bump so a ~2,000px document has headings you can skim by; P-08: tokenized heading air */
#doc-pane h3 { font-size: var(--step-5); margin-top: var(--space-20); } /* R3: formalized on the scale (was the browser-default 1.17em); P-08: tokenized heading air */
#doc-pane pre { border: 2px solid var(--line); background: var(--code-bg); padding: var(--space-12); overflow-x: auto; font-size: var(--step-3); }
#doc-pane .table-wrap { overflow-x: auto; }
#doc-pane table { border-collapse: collapse; width: 100%; margin: var(--space-12) 0; font-size: var(--step-3); }
#doc-pane th, #doc-pane td { border: 1px solid var(--line); padding: var(--space-6) var(--space-10); text-align: left; }
#doc-pane th { background: var(--paper-2); font-family: var(--mono); font-size: var(--step-2); text-transform: uppercase; letter-spacing: var(--track-label); } /* P-10: the other untracked mono-metadata site joins the label register */
#doc-pane blockquote { border-left: 6px solid var(--line); margin: var(--space-12) 0; padding: var(--space-4) var(--space-14); background: var(--paper-2); }
/* V5: the docs "Not published yet." empty state gets the same honest-state treatment */
.doc-missing { color: var(--ink-soft); font-size: var(--step-3); border: 2px solid var(--line); background: var(--paper-2); padding: var(--space-14) var(--space-16); }
/* R2 docs proof-nav: on-page TOC (deep-linkable headings) + code copy buttons.
   Chrome styling only — the data/ledger surfaces inside the pane keep hard borders. */
.doc-toc {
  display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-14);
  margin: 0 0 var(--space-16) 0; padding-bottom: var(--space-8);
  border-bottom: 1px dotted var(--line-dotted);
  font-family: var(--mono); font-size: var(--step-2);
}
.doc-toc a { color: var(--ink-soft); text-decoration: none; border-bottom: 1px solid transparent; transition: color var(--motion), border-bottom-color var(--motion); }
.doc-toc a:hover { color: var(--ink); border-bottom-color: var(--ink); }
/* SECTION_IMPROVE G2 item 6 (2026-09-08): at reading widths the 72ch pane left a
   dead right column inside the wrap; the runtime TOC (buildToc's nav — the pane's
   first child) becomes the RIGHT RAIL, filling the column without moving the
   left-aligned editorial stack. Below 900px, and for panes whose doc renders no
   TOC (buildToc returns null), the nav keeps its inline top-of-pane position —
   this block only repositions an existing child. */
@media (min-width: 900px) {
  #doc-pane { position: relative; }
  #doc-pane .doc-toc {
    position: absolute;
    top: 0;
    left: 100%;
    width: clamp(190px, 24vw, 300px);
    margin: 0 0 0 var(--space-24);
    max-height: 100%;
    overflow: auto;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-6);
    padding-bottom: var(--space-8);
  }
}
.code-copy {
  font-family: var(--mono); font-size: var(--step-1); text-transform: uppercase; letter-spacing: var(--track-chrome); /* P-10: --track-chrome */
  padding: var(--space-2) var(--space-8); border: 1px solid var(--line); background: var(--paper-2); color: var(--ink-soft);
  cursor: pointer; transition: background-color var(--t-base) var(--ease-enter), color var(--t-base) var(--ease-enter), transform var(--t-base) var(--ease-enter);
  margin-top: var(--space-2);
}
.code-copy:hover { color: var(--ink); background: var(--paper); }
.code-copy:active:not(:disabled) { transform: translateY(1px); transition: background-color var(--t-fast) var(--ease-enter), color var(--t-fast) var(--ease-enter), transform var(--t-fast) var(--ease-enter); }

/* ---------- honest states (V5) — one component for "we're working, nothing faked" ----------
   Used by the live-read status row + APR placeholder in main.js and by the docs pane's
   aria-busy loading state.
   WS5-TREATMENT (2026-09-07, one-signature motion): the looping state pulse is
   RETIRED — the pulse meant "working", and a looping opacity pulse is motion off
   the one ratified signature (the ledger stamp). Static state styling replaces it:
   PENDING = dashed hairline + muted (the designed still state below); LIVE =
   the stamp's solid accent tick (✓ + read name in --accent-text, the WS5-TREATMENT
   stamp grammar on #fleet-coverage). No reduced-motion pair is owed: nothing moves. */
.state, #doc-pane[aria-busy="true"] {
  font-family: var(--mono);
  font-size: var(--step-2);
  color: var(--ink-soft);
}
/* the pending register: still, dashed, muted — "we're working" without a pulse */
.state:not(.state--final), #doc-pane[aria-busy="true"] {
  border: 1px dashed var(--line);
}

/* ---------- footer ---------- */
/* R3 IMP-2: the footer joins the identity via the --ink-deep token — which the
   light-paper flip (2026-09-04) re-pinned into the paper family, so the footer
   renders ink-on-paper like every other band. */
.site-footer { background: var(--ink-deep); color: var(--ink); }
.site-footer .wrap { padding-top: var(--space-40); padding-bottom: var(--space-48); } /* R3 IMP-13: footer verticals join the 40/48 pair */
.site-footer a { color: var(--ink); text-decoration: none; border-bottom: 1px solid var(--footer-muted); } /* F3 (UI_IMPROVE2_FOOTER 2026-09-06): the footer's one in-page door — hairline underline, not decoration */
/* ledger-grid footer (WS-LEDGER-STRUCTURE P2, ascetic-degen reference): the
   borderless auto-fit grid becomes a hard 1px-bordered ledger table — the grid
   paints var(--line) beneath a 1px gap so every cell edge shares one hairline,
   and each column (.footer-col, class-only markup addition) sits on the footer
   surface. Existing tokens only (--line / --footer-muted); no new token. */
.footer-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1px; border: 1px solid var(--line); background: var(--line); font-size: var(--step-2); }
.footer-col { background: var(--ink-deep); padding: var(--space-14); }
.footer-grid .h { font-family: var(--mono); text-transform: uppercase; letter-spacing: var(--track-label); font-size: var(--step-1); margin-bottom: var(--space-6); color: var(--footer-muted); border: 1px solid var(--footer-muted); padding: var(--space-6) var(--space-8); } /* P-10 */
.footer-fine { /* F2 (UI_IMPROVE2_FOOTER 2026-09-06): P4 mono metadata edge → colophon
   strip — dotted rule above (.doc-toc precedent), two-edge layout. The printer's
   mark img retired (WS-DARK-DOTO): the colophon opens with the amber dot glyph. */
  margin-top: var(--space-20); padding-top: var(--space-12);
  border-top: 1px dotted var(--line-dotted);
  display: flex; flex-wrap: wrap; gap: var(--space-6) var(--space-16);
  justify-content: space-between; align-items: baseline;
  font-size: var(--step-1); color: var(--footer-faint); font-family: var(--mono); text-transform: uppercase; letter-spacing: var(--track-label); /* P-10: tracking re-pointed onto the label token — F2's layout work untouched */
}
.footer-fine .fine-edge { /* the colophon line: footer-faint mono; the amber dot glyph rides inherited color */ }

/* ---------- geo block page ---------- */
.geo-block-page { max-width: 760px; margin: 8vh auto; padding: 0 20px; }
.geo-block-card { border: 2px solid var(--line); background: #fbfaf5; }
.geo-block-head { border-bottom: 2px solid var(--line); background: var(--warn); color: #fff; padding: 14px 20px; display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-12); }
.geo-block-head .code { font-family: var(--mono); font-size: var(--step-6); font-weight: 800; }
.geo-block-body { padding: 22px 24px; }
.geo-block-body h1 { margin: 0 0 10px 0; text-transform: uppercase; letter-spacing: 0.04em; font-size: var(--step-5); }
.geo-disclosure {
  border: 2px solid var(--line); border-left-width: 8px; background: var(--paper-2);
  padding: 12px 16px; font-family: var(--mono); font-size: var(--step-3); margin: 16px 0;
}
.geo-block-body p { font-size: var(--step-3); color: var(--ink-soft); }

/* ---------- responsive ----------
   V3: mobile keeps its section navigation — the header reflows so the nav
   anchors sit as a compact strip under the brand row instead of being hidden. */
@media (max-width: 640px) {
  /* V9-user revision (2026-09-02): the mobile hero is the static
     composition (motif SVG + chips + type) — the light-paper flip (2026-09-04)
     re-pins the explicit background to var(--paper). */
  .hero { background: var(--paper); }
  .site-header .wrap { flex-direction: column; align-items: flex-start; gap: var(--space-8); padding-top: var(--space-12); padding-bottom: var(--space-12); }
  .hero .wrap { padding-top: var(--space-36); padding-bottom: var(--space-32); }
  /* hero CTA pair (WS-LEDGER-STRUCTURE P3): the two CTAs stack full-width */
  .cta-row { flex-direction: column; align-items: stretch; }
  .hero-facts { flex-direction: column; gap: var(--space-10); } /* pre-existing 400px clip fix (V1-adjacent): facts stack */
  /* trust-row mobile: overlap reset */
  .hero-fact { margin-left: 0; min-width: 0; }
  .card-row { flex-direction: column; gap: var(--space-2); }
  .row-value { text-align: left; }
  /* R2: the docs tab strip stays ONE row on mobile — swipeable, snap-aligned */
  .doc-tabs { flex-wrap: nowrap; overflow-x: auto; scroll-snap-type: x proximity; }
  .doc-tab { flex: 0 0 auto; scroll-snap-align: start; }
}

/* ---------- reduced motion (V5+V6 shared guard) — every animation and transition
   this stylesheet ships is nullified for users who ask for less motion ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }
  /* G2 #4 (2026-09-08, UI_LOOP_2): scroll-behavior is NOT a transition, so the
     universal guard above cannot nullify it — this prefers-reduced-motion
     pairing kills the smooth anchor glide explicitly */
  html { scroll-behavior: auto !important; }
  /* WS5-TREATMENT 2026-09-07 + WS-DARK-DOTO 2026-09-07: the per-asset reduce
     pairs are RETIRED outright (the zero-image identity keeps no asset rules
     to nullify). The universal guard above remains authoritative. */
}

/* ---------- design tokens (v1.2, R2 foundation) — 1:1 aliases of the values this
   stylesheet already shipped; consumption sites read var(--step-*) / var(--space-*).
   A second :root block merges identically in the cascade. The geo template's
   tracking literal stays by design (D14 retention); its font sizes joined the
   step scale (WS-TYPE-MOTION_FINAL 2026-09-06). ---------- */
:root {
  /* UI2-P4 (2026-09-06, WS3-COLOR), re-stepped by the dark-calm flip (2026-09-07):
     THE CARBON LADDER — one substrate family, four steps + two roles:
     raised --paper-raised (cards, +1 toward the viewer) · base --paper (body) ·
     pending --paper-pending (scaffolding, between base and recess) ·
     recess --paper-2 (panel/tab heads, −1) · deep --code-bg (code, −2).
     Role surface: --ink-deep (footer band surface; ink-era misnomer retained
     for history).
     INK FAMILY (the ink/footer split): --ink text · --ink-soft muted-on-carbon ·
     --footer-muted/-faint muted-on-footer (measured AA pairs, theme.test-pinned —
     keep values). New carbon surfaces MUST pick a step, never a new hex. */
  /* color aliases (existing hex values, named) — re-valued onto the doto ladder */
  --paper-raised: #10161C;
  --paper-pending: #090D11;
  --warn-bg: #30181A;
  --accent-visited: #C98F35;
  --accent-hover: #F0B55A;
  --line-dotted: #1D242B; /* opaque — dotted-border role only */
  --chip-tan: #262218;    /* warm dark chip fill; chip text stays var(--ink) */
  /* WS-DARK-DOTO (2026-09-07): the footer rides --ink-deep re-stepped onto the
     doto ladder — ink-on-dark footer. WCAG on the #05080A footer surface:
     #8F8A80 and #7E796F both clear AA at footer sizes. */
  --footer-muted: #8F8A80;
  --footer-faint: #7E796F;
  /* space scale (px, value-named) */
  --space-0: 0;
  --space-2: 2px;
  --space-4: 4px;
  --space-6: 6px;
  --space-8: 8px;
  --space-9: 9px;
  --space-10: 10px;
  --space-12: 12px;
  --space-14: 14px;
  --space-16: 16px;
  --space-20: 20px;
  --space-22: 22px;
  --space-24: 24px;
  --space-28: 28px;
  --space-32: 32px;
  --space-34: 34px;
  --space-36: 36px;
  --space-40: 40px;
  --space-44: 44px;
  --space-48: 48px;
  --space-56: 56px;
  --space-64: 64px;
  /* type scale (WS-TYPE-MOTION_FINAL 2026-09-06: the R3 IMP-1 9-token ramp is
     collapsed onto the ratified EXACT 7-step scale — every font-size in this
     file is var(--step-N) with N in 1..7, mapped to the nearest prior value;
     old token numbers 1/4/6/8/11/13/15/20/21 are retired and all call sites
     were re-pointed in the same pass, fallbacks dropped). New text MUST pick
     one of these seven rungs — a new token needs a written justification. */
  --step-1: 0.6875rem;                    /* 11px — micro */
  --step-0: 0.625rem;                     /* 10px — sub-micro, ≤640 metric labels ONLY. JUSTIFICATION (the scale law's written-exception clause): SECTION-IMPROVE G4 #2 (2026-09-08) — 'FEE APR (2.8h)' wrapped and broke the 3-metric baseline at 390px; the label rungs down one step (the ratified .fleet-apr rung-down idiom) so white-space:nowrap fits the third-width column. No other selector may take this rung. */
  --step-2: 0.8125rem;                    /* 13px — chrome/small merged */
  --step-3: 0.875rem;                     /* 14px — data */
  --step-4: 1rem;                         /* 16px — body (the iOS no-zoom input floor) */
  --step-5: 1.25rem;                      /* 20px — heads/panels */
  --step-6: clamp(1.5rem, 3vw, 2rem);     /* lede / section h2 display */
  --step-7: clamp(2.75rem, 7.5vw, 7rem);  /* hero h1 / tape giant — the page's loudest number */
  /* tracking roles (WS3-TYPOGRAPHY P-10, 2026-09-06): TRACK tokens, not text sizes —
     written justification per the scale law. --track-label = micro metadata labels
     (11-14px mono uppercase, the label register); --track-chrome = actions/nav/chrome
     headings. Each replaces several byte-different declarations of the same intent
     (the 0.03/0.04/0.05/0.06/0.08em cluster collapse). Deliberate literal outliers
     stay documented: .brand-word 0.12em (masthead display), .block-head .index 0.22em
     (decorative numeral), .geo-block-body h1 0.04em (D14 retention, literal by design). */
  --track-label: 0.08em;
  --track-chrome: 0.06em;
  /* layout */
  --wrap-max: 1020px;
  /* ens-derived soft treatment (R2, user-approved taste split): CARDS/BUTTONS carry
     the soft radius + diffuse shadow; every data/ledger element (tables, code blocks,
     stat rows, hero facts) keeps its hard 2px border. --ink-deep is the ens INK
     reference value; a second-accent role is deliberately NOT assigned to it. */
  /* R3 IMP-7: exactly THREE radii on the page — 0 (data/ledger surfaces),
     var(--radius) 999px (every interactive action + STATE tag/chip: .stat-marker,
     .hero-chip — live/live-adjacent markers) — EVIDENCE tags (MINT TICKET,
     DEFINITION-LEVEL GUARANTEE, pending, share-symbol) are DATA/LEDGER elements
     and keep the hard square, per the same D15 taste split that governs cards.
     --radius-soft 12px (cards only, the D15 taste split). --radius-base (4px
     buttons) is retired: the action class unifies on the pill.
     [G6 (UI_IMPROVE2_GLYPHS, 2026-09-06): the two-register tag rule, recorded —
     future tags pick a register by role: names a verified on-chain fact → square;
     names a live page state → pill.] */
  --radius: 999px;
  --radius-soft: 12px;
  --shadow-soft: none;       /* WS-DARK-DOTO: flat — depth is the 2px border, never a shadow */
  --shadow-soft-hover: none; /* ditto — the hover registers on border/background only */
  /* BTN-MOTION (2026-09-08, docs/internal/BTN_MOTION_2026-09-08.md): the flat
     register above is amended for BUTTONS ONLY — the two 'none' pins are NOT
     loosened (no card, section or text surface ever gains a shadow).
     --shadow-btn rests under the FILLED primaries only (btn-primary, cta-solid,
     nav-cta); --shadow-btn-hover is the hover/press swap on every in-scope
     button. The rgba derives the deep substrate step (the --ink-deep family,
     rgb 5 8 10) — never a black literal, never a gradient. The light ladder
     re-inks both tokens in the warm-ink rgba at lower alpha (the light token
     blocks). Swaps are never tweened: no transition list carries box-shadow. */
  --shadow-btn: 0 1px 2px rgba(5, 8, 10, 0.4);
  --shadow-btn-hover: 0 3px 8px rgba(5, 8, 10, 0.45);
  --ink-deep: #05080A; /* WS-DARK-DOTO: footer band surface, re-stepped onto the doto ladder */
}

/* ============================================================
   WS-HERO-V9 (2026-09-01) — hero live-data ledger + brand motif.
   The ledger CONSUMES the vault-card pipeline's already-fetched
   snapshots (no new RPC calls, no new fetch hosts — D8); the motif
   is the og.png visual language (green grid + quarter-turn tracks on
   cream) as INLINE SVG in index.html — zero image files, zero network
   requests, IPFS-safe. Ledger anatomy follows the hero-facts identity:
   hard 2px borders on data elements, serif labels, mono tabular
   figures. No animation ships in this section; the shared
   prefers-reduced-motion guard above stays authoritative, and a
   scoped guard below re-nullifies the new surfaces' pulse states.
   ============================================================ */

/* motif: behind the hero type (z-index below .wrap), clipped by the hero —
   it can never create horizontal scroll at any width */
.hero { position: relative; overflow: hidden;
  background: var(--paper); }
.hero .wrap { position: relative; z-index: 1; }

/* ledger card — hero-facts anatomy (2px hard borders, no radius, no shadow:
   it is a data/ledger element, not a chrome card) */
.hero-ledger {
  margin: var(--space-32) 0 var(--space-40); /* V10: panel sits lower — bigger air from the lede, and pushes hero-facts/chain-badge down with it (spacing only; nothing hidden) */
  max-width: var(--measure-ledger); /* UI2-L9 (2026-09-06, WS3-LAYOUT): ledger-measure role token — was the 46rem literal, zero rendered change */
  border: 2px solid var(--line);
  background: var(--paper-raised);
}
.hero-ledger-head {
  display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-12);
  padding: var(--space-10) var(--space-14);
  background: var(--paper-2);
  border-bottom: 2px solid var(--line);
}
.hero-ledger-title { font-family: var(--mono); font-size: var(--step-1); text-transform: uppercase; letter-spacing: var(--track-label); color: var(--ink); } /* P-10 */
.hero-ledger-state { font-family: var(--mono); font-size: var(--step-2); text-align: right; } /* P-04: the honest-STATUS line lifts off the 11px micro floor onto the 12.5px chrome role */
.hero-ledger-state.flag-ok { color: var(--accent-text); border: 1px solid var(--accent-text); padding: var(--space-2) var(--space-6); text-transform: uppercase; letter-spacing: var(--track-label); white-space: nowrap; } /* MONEY-GRAMMAR (2026-09-06, UI_IMPROVE2_MONEY-SURFACES #8): the ratified LIVE ONCHAIN stamp — accent-text/outlined-accent (the .stat-marker pairing); uppercase is CSS-only, copy intact; the warn branch deliberately stays a bare red line (failure is not stamped). */
.hero-ledger-state.flag-warn { color: var(--warn); }
.hero-ledger-rows { font-variant-numeric: tabular-nums; }
.ledger-row {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-14);
  padding: var(--space-10) var(--space-14);
  border-bottom: 2px solid var(--line);
  font-size: var(--step-3);
}
.ledger-row:last-child { border-bottom: none; }
.ledger-k { font-family: var(--mono); font-size: var(--step-1); text-transform: uppercase; letter-spacing: var(--track-label); color: var(--ink-soft); flex: 0 0 auto; } /* P-04: the last serif-in-data island joins the mono small-cap label register (one grammar across the hero ledger + mint ticket; rebased onto the P-10 label token). After this rule serif is display-only on the page. */ /* MONEY-GRAMMAR (2026-09-06, UI_IMPROVE2_MONEY-SURFACES #1): the label RECEDES — micro mono keys (step-1, ink-soft on raised: the .card-note pairing) under dominant values; MONEY layers size+color onto P-04's mono register. */
.ledger-v { text-align: right; font-family: var(--mono); font-weight: 700; font-size: var(--step-3); word-break: break-word; font-variant-numeric: tabular-nums; color: var(--ink); } /* UI_LOOP_2 G4 (2026-09-08): DEMOTED from the Doto number register — step-3 (14px) is below the Doto legibility floor (16px Doto smudges, the site's own law), so the value goes mono 700 (the ZERO/tape precedent); the ≥20px Doto figures (.hero-stat-num) keep the register. 'ROND' 100 dropped: a Doto-only axis, inert on mono. */
.ledger-v .muted { font-size: var(--step-1); }
.ledger-row-strong .ledger-v strong { color: var(--accent-text); font-size: var(--step-4); } /* MONEY-GRAMMAR (2026-09-06, UI_IMPROVE2_MONEY-SURFACES #1): strong values lead at body size — was step-8; the generic sibling rule lives in the WS3-MONEY EOF block. */
.hero-ledger-note {
  margin: 0;
  padding: var(--space-10) var(--space-14) var(--space-14) var(--space-14);
  font-size: var(--step-2);
  color: var(--ink-soft);
  border-top: 2px solid var(--line);
}

/* ---------- STRATTON-LEDGER-CARD: mint ticket + invariants section ----------
   Stratton-grammar transfer (DESIGN_REFERENCE_ASCETIC_DEGEN_2026-09-04.md items 5+6):
   the ledger-card anatomy (1px-bordered panel, mono small-cap label rows, ink
   callout, definition-level disclosure) re-used by both the hero .mint-card
   (index.html co-class .ledger-card) and the #invariants section below. Static
   components — zero motion, zero new @media, zero new custom properties,
   token-only. Rows reuse the .ledger-row/.ledger-v anatomy: the
   ≤640px stacking rules in the media block below are genuinely inherited, not
   re-implemented. The callout is token-inverted: white-box-in-dark today,
   ink-callout-on-paper after any future carrier flip. */
.mint-card {
  margin: var(--space-24) 0 var(--space-32);
  max-width: var(--measure-ledger); /* UI2-L9 (2026-09-06, WS3-LAYOUT): ledger-measure role token — was the 46rem literal, zero rendered change */
  border: 1px solid var(--line);
  background: var(--paper);
}
.mint-card-tag {
  display: inline-block;
  margin: var(--space-12) var(--space-12) var(--space-8) var(--space-12);
  padding: var(--space-2) var(--space-6);
  border: 1px solid var(--line);
  font-family: var(--mono);
  font-size: var(--step-1);
  text-transform: uppercase;
  letter-spacing: var(--track-label); /* P-10 */
  color: var(--accent-ink);
  background: var(--accent);
  border-color: var(--ink);
} /* MONEY-GRAMMAR (2026-09-06, UI_IMPROVE2_MONEY-SURFACES #4): the ratified GREEN tag — accent-ink on accent (the documented 5.6:1 .btn-primary pair), 1px ink border keeps it a printed stamp; the ticket carries exactly one accent element. */
.mint-card .ledger-k { font-family: var(--mono); } /* mono small-cap labels per the reference grammar — row anatomy otherwise inherited */
.mint-card-callout {
  margin: var(--space-12);
  padding: var(--space-12) var(--space-14);
  background: var(--ink);
  color: var(--paper);
  font-family: var(--mono);
  font-size: var(--step-2);
  line-height: 1.5;
}
#invariants .quiet { color: var(--ink-soft); } /* two-tone headline: line 2 recedes (same treatment as .hero h1 .quiet) */
.inv-dl { margin: var(--space-24) 0; border-top: 1px solid var(--line); }
.inv-dl-row {
  display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-14);
  padding: var(--space-10) 0;
  border-bottom: 1px solid var(--line);
}
.inv-dt { font-family: var(--mono); font-size: var(--step-1); text-transform: uppercase; letter-spacing: var(--track-label); color: var(--ink); flex: 0 0 auto; } /* P-10 */
.inv-dd { margin: 0; text-align: right; font-family: var(--mono); font-size: var(--step-3); font-variant-numeric: tabular-nums; word-break: break-word; color: var(--ink); }
.inv-card {
  max-width: var(--measure-ledger); /* UI2-L9 (2026-09-06, WS3-LAYOUT): ledger-measure role token — was the 46rem literal, zero rendered change */
  border: 1px solid var(--line);
  background: var(--paper);
  padding: var(--space-14);
}
.inv-tag {
  display: inline-block;
  padding: var(--space-2) var(--space-6);
  border: 1px solid var(--line);
  font-family: var(--mono);
  font-size: var(--step-1);
  text-transform: uppercase;
  letter-spacing: var(--track-label); /* P-10 */
  color: var(--ink);
}
.inv-card h3 { margin: var(--space-10) 0 var(--space-6); font-family: var(--mono); font-size: var(--step-2); text-transform: uppercase; letter-spacing: var(--track-chrome); color: var(--ink); } /* P-10: was 0.05em */
.inv-stat-line { margin: 0; font-family: var(--mono); font-size: var(--step-3); color: var(--ink); word-break: break-word; font-variant-numeric: tabular-nums; }
.inv-disclosure { margin-top: var(--space-12); padding: var(--space-12); background: var(--ink); color: var(--paper); font-size: var(--step-2); line-height: 1.5; } /* MONEY-GRAMMAR (2026-09-06, UI_IMPROVE2_MONEY-SURFACES #9): the fine print promoted — the backing disclosure joins the ink-callout family (the .mint-card-callout pairing); the code override lives in the WS3-MONEY EOF block. */

@media (max-width: 640px) {
  /* panel stacks under the hero lede, full measure; motif shrinks + fades */
  .hero-ledger { max-width: none; }
  .ledger-row { flex-direction: column; align-items: flex-start; gap: var(--space-2); }
  .ledger-v { text-align: left; }
  /* V9-user revision: this block sits AFTER the earlier mobile .hero rule so it
     wins the cascade — the light-paper flip preserves the block ORDER */
  .hero { background: var(--paper); }
}

/* scoped reduced-motion pairing for the WS-HERO-V9 surfaces: the ledger's
   connecting-state pulse and any motif motion are nullified for users who
   ask for less motion (the global guard above already covers the page —
   this keeps the new components guarded even if that one is ever edited) */
@media (prefers-reduced-motion: reduce) {
  .hero-ledger .state {
    animation: none !important;
    transition: none !important;
  }
}

/* ============================================================
   WS-HERO-CHIPS-V10 (2026-09-02) — live-data hero chips,
   ens.domains-style static scatter carrying REAL pipeline figures. The
   chips CONSUME the reads js/main.js already fetches for the
   ledger/cards (pool slot0 snapshot, Chainlink feed, the derived
   USD TVL, the published APR projection) — zero new fetches, zero
   new hosts (D8). Live chips degrade to label-only form when a
   read fails (empty value span); static chips always render.
   Chips are aria-hidden decorative duplicates of figures the
   ledger already exposes. They live in the hero's outer gutters
   and its own padding bands — never over the headline — and .hero's
   overflow:hidden clips them, so they can never create horizontal
   scroll at any width.
   ============================================================ */

:root {
  /* WS-DARK-DOTO (2026-09-07): the focus-ring punch rides the brightest amber
     step — punch is text/outline on the dark substrate. */
  --accent-punch: #F5C069;
}

.hero-chips {
  position: absolute;
  top: 0; right: 0; bottom: 0; left: 0;
  z-index: 0;               /* above the motif (later in DOM), below .wrap (z-index 1) */
  pointer-events: none;     /* only the chips themselves take hover */
}

.hero-chip {
  position: absolute;
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
  padding: var(--space-4) var(--space-12);
  border-radius: var(--radius);          /* ens pill */
  font-family: var(--mono);
  font-size: var(--step-1);
  letter-spacing: var(--track-chrome); /* P-10: was 0.03em — the sub-perceptual cluster joins the chrome token */
  line-height: 1.2;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;   /* data figures — V2 discipline */
  pointer-events: auto;
  transform: translate(var(--chip-tx, 0px), 0) rotate(var(--chip-rot, 0deg));
  /* WS-TYPE-MOTION_FINAL 2026-09-06: the chip entrance/float animations retired by
     the one-signature motion budget — chips render as a static scatter; the hover
     lift (translate/scale transition below) is interaction feedback, not motion budget. */
  transition: translate var(--t-base) var(--ease-enter), scale var(--t-base) var(--ease-enter);
}

.hero-chip::before {
  content: '';
  flex: 0 0 auto;
  width: 6px;
  height: 6px;
  background: currentColor;   /* ens's square anchor-dot motif */
  opacity: 0.9;
}

/* hover lift + slight scale via the standalone translate/scale properties —
   functional interaction feedback (WS-TYPE-MOTION_FINAL 2026-09-06: the float
   animation they used to compose with is retired) */
.hero-chip:hover { translate: 0 -4px; scale: 1.045; }

/* degraded live chip = label-only form (value span stays empty until JS fills it) */
.hero-chip-val:empty { display: none; }
.hero-chip-suffix { opacity: 0.78; }

/* V10 chip palette — four solid pills from the site's own tokens:
   accent green / ink / warm tan (--chip-tan, split from --line-dotted by the
   light-paper flip) / honest deep red (--warn). The green pill's label rides
   --accent-ink: cream-on-green measures 2.5:1 on the ratified fill, ink-on-green 5.6:1. */
.hero-chip--green { background: var(--accent);      color: var(--accent-ink); }
.hero-chip--ink   { background: var(--ink);         color: var(--paper); }
.hero-chip--tan   { background: var(--chip-tan);    color: var(--ink); }
.hero-chip--warn  { background: var(--warn);        color: var(--paper); }

/* positions — mobile first (<=640px): two small corner chips inside the hero's
   own top padding band (wrap padding-top is 36px there); the rest stay hidden */
.hero-chip--price { top: 8px;  left: 10px;  --chip-rot: -2deg; }
.hero-chip--share { top: 8px;  right: 10px; --chip-rot: 1.7deg; }
.hero-chip--chain,
.hero-chip--tvl,
.hero-chip--apr,
.hero-chip--split { display: none; }

@media (min-width: 641px) {
  .hero-chip { font-size: var(--step-2); padding: var(--space-6) var(--space-12); }
  /* tablet: three chips across the top padding band (wrap padding-top 56px);
     the centered chip rides --chip-tx inside its static transform */
  .hero-chip--chain { display: inline-flex; top: 12px; left: 50%; --chip-tx: -50%; --chip-rot: -1.4deg; }
}

@media (min-width: 1280px) {
  /* full ens scatter: gutters are >=130px wide at this breakpoint and the wrap's
     content column starts >=150px from either edge, so no chip ever crosses the
     headline, ledger, or facts; gutter chips ride % bands of the hero's height */
  .hero-chip--tvl   { display: inline-flex; top: 40%; right: 12px; --chip-rot: 2.2deg; }
  .hero-chip--apr   { display: inline-flex; top: 60%; right: 16px; --chip-rot: -1.2deg; }
  .hero-chip--split { display: inline-flex; top: 66%; left: 12px;  --chip-rot: 2.5deg; }
  .hero-chip--price { top: 138px; left: 12px; }
  .hero-chip--share { top: 14px; right: 22px; }
  .hero-chip--chain { top: 14px; left: 16px; --chip-tx: 0px; }
}

/* WS-TYPE-MOTION_FINAL 2026-09-06: the chip entrance/float keyframes and their
   animation wiring are retired by the one-signature motion budget — the chips
   are a static scatter. */

/* scoped reduced-motion pairing for the V10 chips' surviving hover transition
   (the global guard above remains authoritative) */
@media (prefers-reduced-motion: reduce) {
  .hero-chip {
    transition: none !important;
    translate: none !important;
    scale: none !important;
  }
}

/* V10 color temperature, part 2: section indices get their own accent-tint
   rotation (decorative mono numerals — the adjacent h2 carries the meaning;
   data-element hard borders, disclosures, and the paper/ink base untouched) */
#vaults .index  { color: var(--accent-punch); }
#deposit .index { color: var(--ink); }  /* light-paper flip: ink numeral like the other section indices (token, no literal) */
#docs .index    { color: var(--warn); }


/* ============================================================
   WSV-STATS-REAL-FOOTER (2026-09-02) — count-up stats band as the
   bottom band of the first viewport: 4 cells (2x2 at <=720px,
   max-width 920px), each a display-font glyph -> counting value ->
   muted label, carrying REAL pipeline figures written by js/main.js
   through the same snapshot flow the hero chips use (zero new fetch
   hosts). The 90/10 + chain cell renders once from config and is
   never animated (a ratified constant is not a measurement).
   Every var() below carries a MANDATORY literal fallback: an
   undefined var() silently invalidates the declaration at
   computed-value time — invisible text on the stat band,
   undetectable by the suite. Token names re-pinned at dispatch to
   the LANDED dark-calm contract (--ink #EDE9DC is the ink on
   carbon; --ink-soft #9A948A is the muted label color; --mono is
   the stat glyph face). No CSS animation ships here: the
   count-up is JS rAF, guarded by main.js's matchMedia consult
   (CSS cannot stop a rAF loop); the page-level
   prefers-reduced-motion guard above stays authoritative.
   ============================================================ */
.stat-band {
  border-bottom: 2px solid var(--line, #262E36);
  background: var(--paper, #0A0E12);
}
.stat-band .wrap {
  padding-top: var(--space-28, 28px);
  padding-bottom: var(--space-32, 32px);
}
.stat-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-24, 24px);
  max-width: 920px;
  margin: 0 auto;
}
.stat-cell {
  display: flex;
  flex-direction: column;
  gap: var(--space-4, 4px);
}
.stat-glyph {
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace);
  font-size: var(--step-4);   /* P-05: decoration recedes below the data */
  line-height: 1;
  color: var(--accent-text, #E8A33D);
  opacity: 0.8;
}
.stat-value {
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace);
  font-size: var(--step-5);   /* P-05: the REAL figure is the biggest thing in the cell (drafts' big-mono tape register) */
  font-weight: 500;
  letter-spacing: normal;                /* mono digits are self-tabular; no grotesque tracking */
  font-variant-numeric: tabular-nums;
  color: var(--ink, #EDE9DC);
  min-height: 1.2em;
}
.stat-label {
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace);
  font-size: var(--step-2);
  text-transform: uppercase;
  letter-spacing: var(--track-label, 0.08em); /* P-10: label token, WSV-STATS mandatory literal fallback kept */
  color: var(--ink-soft, #9A948A);
}
.stat-marker {
  display: inline-block;
  align-self: flex-start;
  margin-top: var(--space-2, 2px);
  padding: var(--space-2, 2px) var(--space-8, 8px);
  border: 1px solid var(--accent, #E8A33D);
  border-radius: var(--radius, 999px);
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace);
  font-size: var(--step-1);
  text-transform: uppercase;
  letter-spacing: var(--track-label, 0.08em); /* P-10: label token, WSV-STATS mandatory literal fallback kept */
  color: var(--accent-text, #E8A33D);
}
@media (max-width: 720px) {
  .stat-grid { grid-template-columns: repeat(2, 1fr); }
}

/* ============================================================
   WSV-POLISH-R3 (2026-09-02) — design-studio audit improvement pass.
   (a) spacing utilities (IMP-5): token aliases replacing the two inline
       style="" debris sites in index.html (#chain-badge, connect-wallet
       btn-row). Declared AFTER the component rules so they win the cascade
       at equal specificity (.btn-row's own margin-top included).
   (b) scroll-reveal primitive (IMP-3): .ws-reveal is ARMED ONLY by
       js/main.js (initReveal) — no-JS and no-IntersectionObserver
       environments never see the hidden state; the static page renders
       fully visible exactly as before. The global prefers-reduced-motion
       guard above nullifies the transition, so the class swap is an
       instant appear for users who ask for less motion. Opacity + 12px
       translate only: the reveal cannot restate or mask content
       (honesty guard, audit §6).
   ============================================================ */
.mt-16 { margin-top: var(--space-16); }
.mt-20 { margin-top: var(--space-20); }

.ws-reveal {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity var(--t-slow) var(--ease-enter), transform var(--t-slow) var(--ease-enter);
}
.ws-reveal.ws-reveal-in { opacity: 1; transform: translateY(0); }
/* G3 SECTION-IMPROVE (2026-09-08): the flagship's interior (.fleet-detail) sits
   inside a CLOSED <details> at load — IntersectionObserver never sees the armed
   targets in there (.apr-sim) while the card is closed, so the band can stay
   opacity:0 after the user opens it. Inside the flagship detail the reveal is
   disabled: always visible, no translate. Scoped to the flagship interior only —
   every other reveal on the page animates exactly as before. */
.fleet-detail .ws-reveal { opacity: 1; transform: none; }

/* ============================================================
   WS-WOW-BATCH (2026-09-03) — the eight spectacular packages of
   docs/internal/WOW_UPGRADES_2026-09-03.md, one sequenced batch.
   Every effect is diff-driven from the EXISTING snapshot fan-out in
   js/main.js (zero new fetches, zero new hosts — D8); every
   animation below is compositor-friendly (transform / opacity /
   stroke-dashoffset / background-color on small elements) and is
   paired with the scoped prefers-reduced-motion guard at the end of
   this block (the global guard above remains authoritative).
   DEPTH NOT DUPLICATION: nothing here adds a new surface for the
   four published figures — WOW-1 extends the existing band, the
   rest reveal or react to what the pipeline already shows.
   ============================================================ */

/* ---- WOW-1 — live tape: RETIRED 2026-09-07 (WS5-TREATMENT, one-signature motion).
   The #stat-tape section and its JS re-roll died in WS5-SKELETON; the tick blink,
   the band settle-pulse and their host rules (.stat-line / .stat-tick* /
   .stat-band--settle) are deleted with them. The tick glyph grammar survives ONLY
   as the pinned pure helper WS.wow.tickGlyph (no DOM consumer). */

/* ---- WOW-7 — chain-pulse: RETIRED 2026-09-07 (WS5-TREATMENT, one-signature motion).
   The ledger delta flashes (both directions, with their ▲/▼ ::after glyph riders),
   the heartbeat cycle beat and the is-connecting breathing state are deleted with
   the hero-ledger surfaces they animated (WS5-SKELETON). What a verified read
   gets now is THE one signature: the ledger stamp (✓ + the read name) —
   data-carrying, still, and honest. */

/* ---- WOW-8 — ledger stamp: THE one signature motion (WS5-TREATMENT 2026-09-07).
   The ONE surviving motion of the stylesheet: a value cell stamps the NAME of
   the read that just verified (✓ backingCoverage) via data-stamp, held for a
   beat, then faded. Applied to (a) any figure re-read — the coverage seam cell
   main.js stamps on every re-read cycle — and (b) the fleet cards' first-render
   arrival (staggered, reverse-played so the SAME keyframes stamp the cards in;
   see the WS5-TREATMENT signature block at EOF). If a design pass ever strips
   the read name from the content, kill the package — the stamp MUST carry data. */
/* G4 (UI_IMPROVE2_GLYPHS), re-pointed WS5-TREATMENT 2026-09-07: the coverage
   seam cell is #fleet-coverage now (the #inv-stat / #mint-backed pair retired
   with the mint card + invariants in WS5-SKELETON). The seam selector sits
   FIRST so the byte-pin on '.ledger-v.ledger-stamp::after {'
   (agent-first.test.js (m1)(vi)) still resolves to this rule's declaration span. */
#fleet-coverage.ledger-stamp::after,
.ledger-v.ledger-stamp::after {
  content: '✓ ' attr(data-stamp);
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace);
  font-size: var(--step-1);
  color: var(--accent-text, #E8A33D);
  margin-left: var(--space-8, 8px);
  opacity: 0;
  animation: ws-stamp-fade 900ms var(--ease-loop, cubic-bezier(0.65, 0, 0.35, 1)) forwards;
}
@keyframes ws-stamp-fade {
  0% { opacity: 1; }
  55% { opacity: 1; }
  100% { opacity: 0; }
}
/* WS5-TREATMENT 2026-09-07: the #hero-ledger-rows nth-child stamp delays are
   RETIRED with the hero ledger (deleted outright in WS5-SKELETON). The stagger
   re-homes to the fleet cards' first-render arrival — same beat pattern
   (0/140/280ms), see the WS5-TREATMENT signature block at EOF. */

/* ---- WOW-2 — live money-flow diagram: deposit → pool → vault.
   Node figures are HTML bound by main.js to the published pipeline
   reads; the aria-hidden inline SVG carries three dashed paths.
   WS-TYPE-MOTION_FINAL 2026-09-06: the dash-march animation (its SPEED
   was class-bucketed from the published pool net rate) is retired by
   the one-signature motion budget — the paths render static at full
   state from frame 0 (main.js keeps setting the inert flow-rate-*
   buckets; no JS re-triggers the animation itself).
   Pre-deploy the vault node is schematic (dashed) and the
   deposit→pool leg runs dimmed; the isDeployed seam flips it live.
   The 90/10 split is geometry (the split bar), not a caption. */
.flow-figure {
  position: relative;
  border-bottom: 2px solid var(--line, #262E36);
  background: var(--paper-raised, #10161C);
  overflow: hidden;
  margin: 0;
}
.flow-figure .wrap {
  position: relative;
  padding-top: var(--space-28, 28px);
  padding-bottom: var(--space-28, 28px);
}
.flow-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
.flow-path {
  fill: none;
  stroke: var(--accent, #E8A33D);
  stroke-width: 2;
  stroke-dasharray: 6 6;
  opacity: 0.7;
}
.flow-path--cut { stroke: var(--ink-soft, #9A948A); }
/* WS-TYPE-MOTION_FINAL 2026-09-06: the flow-speed animation rules and the dash
   keyframes are retired by the one-signature motion budget. */
/* schematic pre-deploy: the deposit→pool leg renders dimmed until the
   isDeployed seam flips the figure live (flow-live set by main.js) */
.flow-figure:not(.flow-live) .flow-path--in { opacity: 0.35; }
.flow-nodes {
  position: relative;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-20, 20px);
}
.flow-node {
  display: flex;
  flex-direction: column;
  gap: var(--space-6, 6px);
  min-width: 0;
  border: 2px solid var(--line, #262E36);
  background: var(--paper, #0A0E12);
  padding: var(--space-14, 14px);
}
.flow-node-k {
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace);
  font-size: var(--step-1);
  text-transform: uppercase;
  letter-spacing: var(--track-label); /* P-10 */
  color: var(--ink-soft, #9A948A);
}
.flow-node-v {
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace);
  font-size: var(--step-3);
  color: var(--ink, #EDE9DC);
  font-variant-numeric: tabular-nums;
  word-break: break-word;
}
.flow-node-sub { font-size: var(--step-2); color: var(--ink-soft, #9A948A); }
.flow-node--schematic { border-style: dashed; background: var(--paper-pending, #090D11); }
.flow-node--live { border-color: var(--accent, #E8A33D); }
.flow-split {
  display: flex;
  height: 8px;
  border: 1px solid var(--line, #262E36);
}
.flow-split-dep { flex: 0 0 90%; background: var(--accent, #E8A33D); }
.flow-split-prot { flex: 1; background: var(--paper-2, #070B0E); }
.flow-yield {
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace);
  font-size: var(--step-2);
  color: var(--accent-text, #E8A33D);
}
.flow-caption {
  margin-top: var(--space-16, 16px);
  font-size: var(--step-2);
  color: var(--ink-soft, #9A948A);
}
.flow-caption-note { display: block; max-width: 72ch; }
@media (max-width: 720px) {
  .flow-svg { display: none; }
  .flow-nodes { grid-template-columns: 1fr; }
}

/* ---- WOW-6 — deposit simulator: inputs + dilution dramatized, the
   projection region STATIC (consumes the published string verbatim;
   moving the slider never moves the rate). The bar is the ratified
   formula's INPUT share (size ÷ live pool TVL), transform-only. */
.apr-sim {
  margin-top: var(--space-24, 24px);
  border: 2px solid var(--line, #262E36);
  background: var(--paper-raised, #10161C);
  padding: var(--space-16, 16px);
  display: flex;
  flex-direction: column;
  gap: var(--space-12, 12px);
}
.sim-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-12, 12px);
  flex-wrap: wrap;
}
.sim-title { font-family: var(--font-display); font-weight: 700; font-variation-settings: 'ROND' 100; font-size: var(--step-5); }
.sim-note {
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace);
  font-size: var(--step-1);
  text-transform: uppercase;
  letter-spacing: var(--track-label); /* P-10 */
  color: var(--ink-soft, #9A948A);
}
.sim-slider-label {
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace);
  font-size: var(--step-1);
  text-transform: uppercase;
  letter-spacing: var(--track-label); /* P-10 */
  color: var(--ink-soft, #9A948A);
}
#sim-slider {
  width: 100%;
  min-height: 44px;   /* money-path mobile ergonomics floor */
  accent-color: var(--accent, #E8A33D);
  background: transparent;
  font-size: var(--step-4);
}
.sim-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-16, 16px);
}
.sim-region {
  display: flex;
  flex-direction: column;
  gap: var(--space-6, 6px);
  min-width: 0;
  border: 1px dotted var(--line-dotted, #1D242B);
  padding: var(--space-12, 12px);
}
.sim-region-k {
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace);
  font-size: var(--step-1);
  text-transform: uppercase;
  letter-spacing: var(--track-label); /* P-10 */
  color: var(--ink-soft, #9A948A);
}
.sim-region-v {
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace);
  font-size: var(--step-4);
  color: var(--ink, #EDE9DC);
  font-variant-numeric: tabular-nums;
  word-break: break-word;
}
.sim-region-sub { font-size: var(--step-2); color: var(--ink-soft, #9A948A); }
.sim-region--static .sim-region-v { color: var(--ink-soft, #9A948A); }
.sim-bar {
  display: block;
  height: 10px;
  border: 1px solid var(--line, #262E36);
  background: var(--paper, #0A0E12);
}
.sim-bar-fill {
  display: block;
  height: 100%;
  width: 100%;
  background: var(--accent, #E8A33D);
  transform-origin: 0 50%;
  transform: scaleX(0);
  transition: transform var(--t-base, 200ms) var(--ease-enter, cubic-bezier(0.16, 1, 0.3, 1));
}
.sim-bar-fill[data-empty] { opacity: 0.25; }
@media (max-width: 720px) {
  .sim-grid { grid-template-columns: 1fr; }
}

/* ---- WOW-5 — scroll choreography (additive-only): the hero ledger's
   rows settle top-to-bottom on first view (its own scroll-reveal
   class, armed ONLY by main.js — no-JS never sees the hidden state),
   staggered with the craft wave's easing family. The section-head +
   panel coverage reuses the landed .ws-reveal primitive. */
.scroll-reveal .ledger-row {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity var(--t-slow, 320ms) var(--ease-enter, cubic-bezier(0.16, 1, 0.3, 1)),
              transform var(--t-slow, 320ms) var(--ease-enter, cubic-bezier(0.16, 1, 0.3, 1));
}
.scroll-reveal .ledger-row:nth-child(1) { transition-delay: 0ms; }
.scroll-reveal .ledger-row:nth-child(2) { transition-delay: 70ms; }
.scroll-reveal .ledger-row:nth-child(3) { transition-delay: 140ms; }
.scroll-reveal .ledger-row:nth-child(4) { transition-delay: 210ms; }
.scroll-reveal.scroll-reveal-in .ledger-row { opacity: 1; transform: translateY(0); }
/* per-region stagger tokens for the WOW-2 figure's nodes under the
   same armed-reveal discipline (classes added by main.js only) */
.flow-figure.ws-reveal .flow-node {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity var(--t-slow, 320ms) var(--ease-enter, cubic-bezier(0.16, 1, 0.3, 1)),
              transform var(--t-slow, 320ms) var(--ease-enter, cubic-bezier(0.16, 1, 0.3, 1));
}
.flow-figure.ws-reveal .flow-node:nth-child(1) { transition-delay: 0ms; }
.flow-figure.ws-reveal .flow-node:nth-child(2) { transition-delay: 80ms; }
.flow-figure.ws-reveal .flow-node:nth-child(3) { transition-delay: 160ms; }
.flow-figure.ws-reveal.ws-reveal-in .flow-node { opacity: 1; transform: translateY(0); }

/* ---- WOW-3 — launch-flip: the one-time pending→live beat.
   WS-TYPE-MOTION_FINAL 2026-09-06: the launch-day entrance choreography (the
   staggered region flips + the launch-day settle flash) is retired by the
   one-signature motion budget — the state swap is instant on launch day (the
   wow is the state change, not the motion). main.js still sets body.launch-flip
   ONLY off a real false→true isDeployed transition, once per browsing session;
   the class now carries no animation. WS5-TREATMENT 2026-09-07: the WOW-1
   band-settle trigger is retired too (see the WOW-1 retirement note above). */

/* WS5-TREATMENT 2026-09-07 (one-signature motion): the entrance keyframes and
   their .ws-entrance arming rule are RETIRED — every motion on the page is now the
   ledger stamp (the fleet cards' first-render arrival plays the SAME
   ws-stamp-fade keyframes reversed; see the WS5-TREATMENT signature block at
   EOF). The agent-first.test.js (m1)(iv)/(v) entrance pins are retired dated
   in the same change. */

/* ---- scoped reduced-motion pairing for EVERY animation this block
   ships (the global guard above already covers the page; this keeps
   the new surfaces guarded even if that one is ever edited). Under
   reduced motion: the stamp stays fully visible (data-carrying) and
   the fleet cards' stamp-in arrival is instant; the bar jumps.
   WS5-TREATMENT 2026-09-07: the tape/delta/heartbeat/entrance/static-pulse
   selectors are retired with their animations (one-signature motion); the
   stamp's reduce pair degrades to static at opacity 1. */
@media (prefers-reduced-motion: reduce) {
  #fleet-coverage.ledger-stamp::after, /* G4 (UI_IMPROVE2_GLYPHS): the coverage seam cell joins the reduce pair */
  .ledger-v.ledger-stamp::after,
  .sim-bar-fill,
  .scroll-reveal .ledger-row, .flow-figure.ws-reveal .flow-node {
    animation: none !important;
    transition: none !important;
  }
  #fleet-coverage.ledger-stamp::after, .ledger-v.ledger-stamp::after { opacity: 1; }
  .scroll-reveal .ledger-row, .flow-figure.ws-reveal .flow-node { opacity: 1; transform: none; }
  .sim-bar-fill { transition: none; }
  button.btn:active:not(:disabled) { transform: none; }
  .cta-solid:active:not(:disabled) { transform: none; }
  .doc-tab:active:not(:disabled) { transform: none; }
  .code-copy:active:not(:disabled) { transform: none; }
  .site-nav a.nav-cta:active:not(:disabled) { transform: none; }
}

/* ============================================================
   WS-DARK-DOTO (2026-09-07) — asset-wire retirement.
   The WS-ASSET-WIRE keeper set (point-hand, press-hand, magnify-hand,
   curve-stroke divider, share certificate) is RETIRED with the zero-image
   identity: no asset rules, no asset motion gates, no asset reduce pairs
   remain. The page's texture is the halftone field; its one motion is the
   ledger stamp. The receding-quiet rules below are kept only because the
   section h2s still carry the recede token on no live span.
   ============================================================ */
#agents .quiet { color: var(--ink-soft); } /* receding register (dead span, token-only) */
#deposit .quiet { color: var(--ink-soft); } /* receding register (dead span, token-only) */
#docs .quiet { color: var(--ink-soft); } /* receding register (dead span, token-only) */
.vault-card { position: relative; } /* the pending tag anchors to the head corner */
.hero-ledger { position: relative; } /* retired container rule — ledger anatomy lives on via the card rows */

/* ---------- WS-MOBILE-FIXES (2026-09-05) — pure-additive EOF mobile block ----------
   Appended AFTER every existing media block (cascade-safe override order; zero
   edits to existing lines). Three fixes from docs/inventory/UI_IMPROVE_MOBILE_
   2026-09-04.md: P1 anchored-jump scroll-margin override = post-P3 measured
   header height + 16; P2 phone-first hero fold — CSS order on the 8 .hero .wrap
   children in the ratified rank; P3 header compression — 2-row header with a
   nowrap horizontally-scrollable nav strip (.doc-tabs swipe-strip precedent)
   and 44px link tap targets. Contract: docs/internal/GOALS_WS_UI_ROUND2_
   2026-09-05.md (WS-MOBILE-FIXES). Tokens only — no color literals, no copy
   changes, nothing hidden. */
@media (max-width: 640px) {
  /* P3 — the nav becomes one nowrap horizontally-scrollable strip; tap-target
     height lives ON the links (min-height 44px), never as vertical padding on
     .site-nav itself (its clientHeight must stay <= 48). */
  .site-nav { flex-wrap: nowrap; overflow-x: auto; width: 100%; padding-right: var(--space-16); } /* SECTION-IMPROVE G1 #4 (2026-09-08): the scrollable strip's last item sat flush at the right edge — end-pad gives the clip affordance; tap sizes untouched (min-height stays on the links, clientHeight still <= 48) */
  .site-nav a { flex: 0 0 auto; white-space: nowrap; min-height: 44px; }
  .site-nav a.nav-cta { min-height: 44px; } /* W1 G1-BAND (2026-09-08): the base is 44 now — restated here as belt-and-suspenders against future base edits (was: "must out-rank the base 38px") */
  /* P2 — phone-first hero fold (WS-DARK-DOTO re-rank): the DOM order IS the
     ratified rank now (ticker → h1 → rule → meta → CTA row → hero stat →
     chain badge), so the mobile fold needs no order overrides — the banner
     stack lands in reading order with the CTA and the one live number in
     the thumb third. */
  /* P1 — anchored jumps clear the compressed sticky header (value = measured
     header height H + 16, finalized from the post-P3 probe: H = 126.09 → 142). */
  section.block, .hero { scroll-margin-top: 142px; }
  #doc-pane [id] { scroll-margin-top: 142px; }
}

/* ---------- W1 G1-BAND (2026-09-08) — nav-cta clip at the strip edge ----------
   The ≤640 strip's content measures 406.73px (3 links + the 160.73px CTA +
   3×16px gaps), while the scrollport is viewport − 40px wrap padding — so the
   LAST item, the money CTA, clips at the screen edge wherever the viewport is
   under 446px (measured: 40px cut at 390, 36 at 410, 0 at 446). The landed
   end-pad (SECTION-IMPROVE G1 #4) only cleans the scroll-END state; at rest
   the cut falls mid-glyph ("RUN IT YOURS|") and reads broken on a button.
   Measured escapes, both dishonest: letter-spacing:normal saves 11.7px
   (need ~41); shrinking gaps/pads still ~14px short and mangles the register.
   Fix: below 446 the CTA LEADS the strip (visual order only — DOM/copy/tab
   focus order unchanged) and the plain text links take the edge cut — the
   .doc-tabs affordance (a partial text link reads as "scrolls", a sliced
   pill reads as a bug). Disclosed tradeoff: Tab reaches the links before the
   visually-first CTA inside this narrow band. */
@media (max-width: 445px) {
  .site-nav a.nav-cta { order: -1; }
}

/* ---------- WS3-FOOTER (2026-09-06, UI_IMPROVE2_FOOTER F1/F2/F3/F4/F5) — pure-additive EOF block ----------
   Ledger-grid footer completion + meta-edges. New rules only (existing-rule edits live in the
   footer section above: .site-footer a F3, .footer-fine F2). No motion added — a colophon is
   print; it does not move. Token-only, zero new external origins. */
.footer-callout { /* F1: the contrast line gets the ink-box treatment — .mint-card-callout
  precedent (token-inverted, mono), small-print given weight per the ratified reference. */
  margin-top: var(--space-10);
  padding: var(--space-10) var(--space-12);
  background: var(--ink);
  color: var(--paper);
  font-family: var(--mono);
  font-size: var(--step-2);
  line-height: 1.5;
}
.fine-mark { /* F2: printer's mark (thumbs-up logo mark, 14x15 half-scale, decorative) */
  width: 14px; height: 15px; vertical-align: -2px; margin-right: var(--space-6); opacity: 0.85;
}
.site-footer a:hover { /* F3: underline darkens toward ink on hover */
  border-bottom-color: var(--ink);
}
.footer-imprint { /* F4: the legal colophon gets its own imprint row under the fine strip */
  margin-top: var(--space-8);
  font-size: var(--step-1); color: var(--footer-faint); font-family: var(--mono);
  text-transform: uppercase; letter-spacing: 0.08em; max-width: 88ch;
}
.footer-col > div:not(.h):not(.footer-callout) { /* F5: rows as cells — the reference's
  ledger-grid footer is a table, not stacked prose; the callout exclusion (F1) keeps the
  ink box self-bounded. */
  padding: var(--space-8) 0;
  border-bottom: 1px solid var(--line);
}
.footer-col > div:last-child { border-bottom: none; }
/* ---------- end WS3-FOOTER EOF block ---------- */

/* ---------- WS3-HEADER (2026-09-06) — header + nav additive EOF block ----------
   From docs/inventory/UI_IMPROVE2_HEADER_2026-09-05.md. In-place single-line edits
   (P1 scroll-margin, P2 hover, P3 pill register, P5 mark ratio, P7 active punch)
   carry their own dated markers up in the header block. Tokens only — no color
   literals, no motion added (the strip is static, so no reduced-motion pair is
   owed), zero new external origins, nothing hidden. */
/* P4 — identity tape under the header. The 1px border sits under the header's 2px
   so the weight hierarchy reads header > strip > content. Static and non-sticky —
   it scrolls away with the page, so the sticky header's geometry is untouched. */
.tape-strip { border-bottom: 1px solid var(--line); background: var(--paper); }
.tape-strip .wrap {
  display: flex; flex-wrap: wrap; column-gap: var(--space-10); row-gap: var(--space-2);
  padding-top: var(--space-8); padding-bottom: var(--space-8);
  font-family: var(--mono); font-size: var(--step-1); text-transform: uppercase;
  letter-spacing: 0.1em; color: var(--ink-soft);
} /* ink-soft on paper = 5.85:1 at 11px — above the 4.5 small-text floor */
/* SECTION-IMPROVE G1 #1 (2026-09-08): the entry is its own inline-flex run —
   main.js appends sym|tier|state spans with no whitespace between them, so without
   this rule the cells run on inside one entry (the old CSS only separated
   BETWEEN entries). column-gap does the intra-entry separation. */
.tape-strip-entry { display: inline-flex; flex-wrap: wrap; align-items: baseline; column-gap: var(--space-6); }
/* SECTION-IMPROVE G1 #2 (2026-09-08): the '·' ::before glyph wrapped into orphan
   dots at strip wrap edges — a border-left separator dies with its own entry.
   border-LEFT 1px: deliberately does not touch the (g) pins (border-bottom 2px
   count == 11; gradient counts) — no re-pin owed. */
.tape-strip-entry + .tape-strip-entry { border-left: 1px solid var(--line); padding-left: var(--space-10); }
.tape-strip-sym { color: var(--ink); } /* the symbol is the row's strongest cell */
.tape-strip-tier { color: var(--ink-soft); }
.tape-strip-state { font-family: var(--mono); font-weight: 700; color: var(--accent-text); } /* SECTION-IMPROVE G1 #3 (2026-09-08): Doto at 11px smears the status sentence — the machine register drops to mono 700; color unchanged. No theme/font-doto pin rides this selector (grepped) */
.tape-strip-entry--gated .tape-strip-sym { color: var(--ink-soft); } /* a gated tier never shouts */
/* P6 — mobile lockup: the brand tag drops to its own clean ledger line instead of
   internally wrapping into a ragged two-line squeeze (measured 34.1px vs 17
   natural at 390). Nothing is removed — the tag stays visible on every width. */
@media (max-width: 640px) {
  .brand { flex-wrap: wrap; row-gap: var(--space-2); }
}
/* ---------- end WS3-HEADER EOF block ---------- */

/* ---------- WS3-TYPOGRAPHY (2026-09-06, UI_IMPROVE2_TYPOGRAPHY) — pure-additive EOF block ----------
   The goal's ONE new-rule block: P-09 (the deadpan pitch line's typographic voice) and
   P-08's first-heading guard. Every EXISTING-rule edit (P-01..P-08, P-10, P-11) lives in
   its home section above with its own dated marker. No motion, no new @media (the
   reduce-gate count is unchanged), token-only colors, zero new external origins, nothing
   hidden. Multi-vault family cards need no extra rules here: they render the shared
   .vault-card/.card-row/.card-title/.ledger-k anatomy this pass already re-typed. */
.hero-meta { /* P-09 successor (WS-DARK-DOTO): the banner meta line — quiet ink-soft, narrowed measure */
  max-width: 46ch;
}
/* WS-MESSAGING-V3 (2026-09-08): THE PROTOCOL'S CUT: ZERO — the fee-lane truth in
   the banner. Amber-as-TEXT only (the one filled amber stays the CTA), token
   roles so both themes inherit correct contrast. */
.hero-cut {
  margin: var(--space-12) 0 var(--space-8);
  font-family: var(--mono); font-size: var(--step-2);
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ink-soft);
}
.hero-cut-zero { color: var(--accent-text); font-family: var(--mono); font-weight: 700; font-size: var(--step-5); letter-spacing: 0; } /* SECTION-IMPROVE G1 #7 (2026-09-08): 16px Doto = smudge — the ZERO word reads mono 700 at --step-5 (.doto dropped from the markup, same span); stays --accent-text (no second fill) */
#doc-pane h2:first-child, #doc-pane h3:first-child { margin-top: 0; } /* P-08 guard: no new gap under the title border when the renderer's first output is a heading; deep-link scroll-margin behavior unchanged */
/* ---------- end WS3-TYPOGRAPHY EOF block ---------- */

/* ---------- WS3-LAYOUT (2026-09-06, UI_IMPROVE2_LAYOUT) — pure-additive EOF block ----------
   Composition + geometry from the LAYOUT mapper: L9 measure tokens, L3 one ledger
   measure, L5 hatch continuity, L6 mint-ticket stamp straddle (all ungated), then the
   media-scoped blocks L1 (asymmetric hero >=1024), L8 (agents editorial split >=900)
   and L4 (draft display scale >=1280). Existing-line edits (the four measure re-points)
   carry their own dated markers in the home sections above. Tokens only — no color
   literals (the theme.test.js exact-count pins ride untouched), no new ids (registry
   untouched), no markup/copy changes, zero motion added (static transforms only; the
   reduce-gate count is unchanged), zero new external origins. Every @media here is a
   min-width gate: the <=640 mobile fold rules (WS-MOBILE-FIXES rank block, header
   compression) never coexist with them. */
/* UI2-L9: measure roles — the ledger surface (data cards) vs the copy measure (prose
   subs). A second :root block merges identically in the cascade (v1.2 foundation
   convention). New text-width decisions pick a role token. */
:root {
  --measure-ledger: 46rem;
  --measure-copy: 52rem;
}
/* UI2-L3: the ledger-surface measure — a single family card is a 736px ledger table,
   not a full-wrap stretch; footnote and invariant list join the same measure so each
   section reads as one aligned unit (the Stratton-grammar compact table). Written
   against the L9 token from the start. Family-grid math: at the 736px grid box,
   minmax(320px,1fr) auto-fit yields 2x358px cards when vault #2 lands. */
#vault-grid { max-width: var(--measure-ledger); }
.apr-footnote { max-width: var(--measure-ledger); }
.inv-dl { max-width: var(--measure-ledger); }
/* UI2-L5: boundary rhythm — every major band edge carries the same 8px hatch; the two
   prologue boundaries (stat-band -> flow-figure, flow-figure -> #vaults) were plain
   2px lines, stuttering exactly where spectacle hands off to product. House form
   restated verbatim: each boundary its own rule block with its own gradient
   declaration (the :180-186 law). */
/* UI2-L6: the draft seats a rotated stamp tag OVER the ticket's top edge (LIVE
   ONCHAIN in welldis.jpg). Static transform — no motion, no reduce pair required;
   -2deg echoes the chips' rotation register. Opaque paper background so the card's
   1px border never strikes through the glyph run; padding-top restores the old tag
   headroom (28px + the first row's 10px ~= the old 38px). Copy unchanged ("MINT
   TICKET" byte-frozen); the <=640 rank block moves the card whole — the tag travels
   with it. */
.mint-card { position: relative; padding-top: var(--space-28); }
.mint-card-tag {
  position: absolute;
  top: -10px;              /* half the tag box — probe-tune +-2px */
  left: var(--space-16);
  margin: 0;
  background: var(--paper);
  transform: rotate(-2deg);
}
/* UI2-L1 (>=1024) RETIRED (WS-DARK-DOTO): the asymmetric hero grid died with
   the surfaces it placed (mint ticket, live ledger, lede) — the banner-extended
   hero is one left-aligned stack at every width (the flex column persists). */
/* UI2-L8 (>=900): the agents section's two children become an asymmetric editorial
   spread — the two-tone headline owns the left column, the machine-surface prose the
   right. Same two children, zero markup; agent-first.test.js pins are href/content
   greps (unaffected by CSS). The .block-head's spacer/muted wrap inside the narrow
   column is accepted (probe 900-1024). */
/* SECTION_IMPROVE G2 (2026-09-08): the L8 col-1 narrowness wrapped the short display
   phrase mid-word ('PLUG / IN.'). The phrase is short by design and never wraps —
   #agents h2 only (other section h2s keep normal wrapping). */
#agents h2 { white-space: nowrap; }
/* G2 item 2: the capability lines — what the skill actually does, in the machine
   register. Tokens only; the em-dash lead rides the accent-as-text role. */
.agents-caps {
  margin: 0; padding: 0; list-style: none;
  display: grid; gap: var(--space-8);
  font-family: var(--mono); font-size: var(--step-2);
  color: var(--ink-soft);
  max-width: var(--measure-copy);
}
.agents-caps li { position: relative; padding-left: var(--space-16); }
.agents-caps li::before { content: '—'; position: absolute; left: 0; color: var(--accent-text); }
@media (min-width: 900px) {
  #agents .wrap {
    display: grid;
    grid-template-columns: minmax(0, 2fr) minmax(0, 3fr);
    column-gap: var(--space-40);
  }
  #agents .wrap > .block-head { grid-column: 1; grid-row: 1; align-self: start; }
  #agents .wrap > .block-sub { grid-column: 2; grid-row: 1; margin: 0; }
  /* G2: the capability list is the wrap's third child — it belongs under the
     prose in the right column, never auto-placed under the headline. */
  #agents .wrap > .agents-caps { grid-column: 2; grid-row: 2; }
}
/* UI2-L4 (>=1280): the draft's dominant move — type IS the composition (welldis.jpg
   measures ~10-11vw). WS-TYPE-MOTION_FINAL 2026-09-06: the 9vw override retires onto
   the ratified step-7 rung (clamp(2.75rem, 7.5vw, 7rem)) — at >=1280 this rule now
   restates the base rung and is kept only as the L4 record; the ramp's fluid vw
   scaling carries the composition. Mobile (<=640) renders the step-7 clamp floor. */
@media (min-width: 1280px) {
  .hero h1 { font-size: var(--step-7); }
}
/* ---------- end WS3-LAYOUT EOF block ---------- */
/* ---------- WS3-MONEY (2026-09-06, UI_IMPROVE2_MONEY-SURFACES items 1-11) — money-surface additive EOF block ----------
   One ledger-row grammar everywhere money renders (label recedes, value leads);
   the verified coverage figure is the ticket's one hot number; the holder's own
   position renders in the receipt anatomy. Token-only (zero new color literals),
   zero motion, zero new @media blocks, zero new element IDs. */
.ledger-row .ledger-v strong { font-size: var(--step-4); } /* #1: live figures out-size their row — the price/TVL strongs become the largest element in the panel */
#mint-backed.coverage-live, #inv-stat.coverage-live { font-weight: 700; color: var(--accent-text); font-size: var(--step-4); } /* #2: only a verified decode carries the class (writeAll live flag) — pending/unavailable states stay neutral */
#wallet-balances:not(:empty) { border: 2px solid var(--line); background: var(--paper-raised); } /* #3: the data-element border on the holder's own money box; :not(:empty) keeps the pre-connect page free of an empty bordered panel (deviation from the mapper's unconditional rule — disclosed in the worker report) */
#redeem-preview { font-size: var(--step-3); color: var(--ink); font-variant-numeric: tabular-nums; border-top: 1px dotted var(--line-dotted); padding-top: var(--space-10); margin-top: var(--space-12); } /* #6: the chain-priced preview promoted to a number line via the .card-row dotted-separator vocabulary; text untouched (the anti-promise wording is load-bearing) */
button.btn-primary:disabled { background: var(--paper-2); color: var(--ink-soft); border-color: var(--line); box-shadow: none; } /* #5: explicit parked-register companion (button.btn:disabled already out-ranks btn-primary on specificity); BTN-MOTION (2026-09-08): the parked register stays inert — the resting shadow never paints on :disabled */
.inv-disclosure code { background: transparent; color: var(--paper); border-color: var(--paper); } /* #9: the mono code inside the ink callout stays legible */
/* ---------- end WS3-MONEY EOF block ---------- */
/* ---------- WS3-ART (2026-09-06) — RETIRED (WS-DARK-DOTO 2026-09-07) ----------
   The canyon-substrate pass is retired with the zero-image identity: no canyon
   rules remain (the hero's only backdrop is the halftone field). */
/* ---------- WS3-COLOR (2026-09-06, UI_IMPROVE2_COLOR-TEXTURE P6) — border-taxonomy additive EOF block ----------
   The one border-weight inversion fix: the mint ticket's inherited .ledger-row rows
   (2px) out-weighed their 1px frame — the interior must never out-weigh the frame.
   Print register 1px/1px for the printed ticket (the inv-card sibling is already
   coherent 1px/1px); the live .hero-ledger keeps 2px/2px (live instrument vs printed
   document). Placed here at equal specificity AFTER .ledger-row:last-child, so the
   last row's borderless state still wins the cascade. Token-only; zero motion. */
.mint-card .ledger-row { border-bottom: 1px solid var(--line); } /* UI2-P6: print register (was inherited 2px) */
/* ---------- end WS3-COLOR EOF block ---------- */
/* ---------- WS3-DEGRADED (2026-09-06, UI_IMPROVE2_DEGRADED-STATES 1-8) — degraded + empty states EOF block ----------
   Additive-only, @media-free, token-only (no new color literals — the theme battery's
   pinned counts are untouched); zero new motion (one animation REMOVAL, #2 — finality
   is stillness, so no reduced-motion pairing is owed), zero new reduce gates ((b5)
   count unchanged), zero new resource URLs. #9 EXCLUDED (D14-gated). The BACKED accent
   stays WS3-MONEY's (#2 owner) — this goal adds only the verify-promise persistence
   (#7) and the state-independent tags below.
   Deviation from the mapper draft, disclosed: .card-empty-tag is a FLOW tag inside
   .card-head (same anatomy as .pending-tag), not the draft's absolute top-left plate —
   the head corner is data territory per the WS3-ART P2 occlusion fix already landed
   in this file. */
/* #2: the pulse means "working". A settled degraded fact renders STILL — finality
   is quiet, never a fake progress signal. Voice unchanged (mono, --ink-soft). */
.state--final { animation: none !important; }
/* #1: the empty register — the keeper stops being wallpaper when its state is real
   (full strength), and the verified fact wears a tag in the pending-tag anatomy. */
.card-empty-tag { font-family: var(--mono); font-size: var(--step-1); text-transform: uppercase; letter-spacing: var(--track-label); color: var(--ink); border: 1px solid var(--line); background: var(--paper); padding: var(--space-2) var(--space-8); white-space: nowrap; }
/* #4: panel-head state tags — same anatomy as .pending-tag. --safe marks a
   structural guarantee (always true, not a state); --warn rides only a verified pause. */
.panel-tag { font-family: var(--mono); font-size: var(--step-1); text-transform: uppercase; letter-spacing: var(--track-label); padding: var(--space-2) var(--space-8); border: 1px solid var(--line); background: var(--paper); white-space: nowrap; }
.panel-tag--safe { color: var(--accent-text); border-color: var(--accent-text); }
.panel-tag--warn { color: var(--warn); border-color: var(--warn); background: var(--warn-bg); }
/* #5: APR baseline provenance — the fallback reading labels itself on band + chip;
   hidden by default, shown only on the labeled fallback (main.js publish fan-out). */
.stat-baseline-note { font-family: var(--mono); font-size: var(--step-1); text-transform: uppercase; letter-spacing: var(--track-label); color: var(--ink-soft); border: 1px solid var(--line); background: var(--paper); padding: var(--space-2) var(--space-8); align-self: flex-start; }
#stat-baseline-note[hidden], #chip-baseline-note[hidden] { display: none; } /* belt-and-braces: an author display rule must never out-rank the [hidden] UA default */
/* #6: a failed live read leaves the DOM '' (render-degrade pin: never 0-as-fake).
   The VISUAL empty is designed: the same unavailable voice as the ledger. Scoped to
   the two LIVE cells only — the split cell is a ratified constant filled at init
   (never empty past first paint) and the APR cell degrades to the labeled baseline
   (never empty). First paint is safe: the static cells contain '—' (not :empty). */
#stat-tvl:empty::after, #stat-price:empty::after {
  content: 'unavailable (RPC)';
  font-family: var(--mono, ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace);
  font-size: var(--step-3);
  font-weight: 400;
  letter-spacing: 0;
  color: var(--ink-soft, #9A948A);
}
/* #7: the verify-yourself promise persists in EVERY state — a static line under the
   mint-card BACKED row that main.js never writes (the pinned cell strings stay free
   to degrade; this instruction does not vanish with them). */
.mint-card-verify { margin: 0 var(--space-12); padding: 0 var(--space-2) var(--space-10); font-family: var(--mono); font-size: var(--step-1); color: var(--ink-soft); }
/* #8: the widget-status box's two moods — the wallet-absent read-only state is a
   feature (the whole page works walletless) and reads muted; warnings stay red. */
#widget-status .flag--info { color: var(--ink-soft); }
#widget-status .flag-warn { color: var(--warn); }
/* #3: noscript plates — the empty grid/pane voids and the note are designed in the
   same print register (the <noscript> style block at the top of <body> shows them
   and stills the forever-pulse; these base rules keep them dormant with JS on). */
.vault-grid-empty, .doc-pane-empty { display: none; }
.noscript-note { border: 2px solid var(--line); border-left-width: 8px; background: var(--paper-2); margin-top: var(--space-16); }
.noscript-kicker { display: block; font-family: var(--mono); font-size: var(--step-1); text-transform: uppercase; letter-spacing: var(--track-label); color: var(--ink); margin-bottom: var(--space-6); }
/* ---------- end WS3-DEGRADED EOF block ---------- */

/* WS3-CLOSEOUT (2026-09-06): RETIRED (WS-DARK-DOTO) with the asset-magnify hand
   it scoped — no keeper rules remain. */

/* ============================================================
   WS5-TREATMENT (2026-09-07) — the treatment pass (identity revision #5).
   Card craft + the ONE signature motion. Everything below is additive
   except where an in-place edit carries its own dated WS5-TREATMENT marker.
   Tokens only; zero new external origins; no JS added (no rAF loops —
   60fps by construction: the one motion animates opacity only).
   ============================================================ */

/* ---- the fleet cards (movement b) — measured books as stacked cards ----
   1 column ≤640 / 2 columns ≥900. Data-surface register: hard 2px border, no
   radius (the G6/D15 split — a ledger card is a ledger element). Numbers never
   truncate: no overflow is hidden anywhere in the card; the fee-APR scales DOWN
   the type scale as width fails and the summary row WRAPS so the figure and its
   unit always travel together. */
#fleet-books { display: grid; grid-template-columns: 1fr; gap: var(--space-12); margin-top: var(--space-16); }
.fleet-group { display: contents; } /* the tier groups dissolve into the card grid; labels span the full row */
.fleet-group-label { grid-column: 1 / -1; margin: var(--space-12) 0 0; font-family: var(--font-num); font-weight: 700; font-variation-settings: 'ROND' 100; font-size: var(--step-1); text-transform: uppercase; letter-spacing: var(--track-label); color: var(--ink-soft); } /* WS-DARK-DOTO: the group STATUS rides the machine register */
.fleet-group--dead .fleet-group-label { color: var(--accent-text); } /* the DEAD flag: truthful text, amber flag */
.fleet-card { border: 2px solid var(--line); background: var(--paper-raised); min-width: 0; }
.fleet-card--flagship { margin-bottom: var(--space-20); } /* the static flagship precedes the rendered books (WIPE-SAFETY: never inside #fleet-books) */
.fleet-summary { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-6) var(--space-12); padding: var(--space-12) var(--space-14); min-height: 44px; cursor: pointer; } /* the whole summary is the tap zone */
.fleet-tier { flex: 0 0 auto; font-family: var(--font-num); font-weight: 700; font-variation-settings: 'ROND' 100; font-size: var(--step-1); text-transform: uppercase; letter-spacing: var(--track-label); color: var(--ink); } /* WS-DARK-DOTO: the tier badge is a STATUS — machine register */
.fleet-card--hook .fleet-tier { color: var(--warn); }    /* HOOK tier badge = warn token text: the honest red of a book that pays nobody */
.fleet-card--dead .fleet-tier { color: var(--accent-text); } /* DEAD = the amber flag: no stream, and the page says so in the accent */
.fleet-pair { flex: 0 1 auto; min-width: 0; font-family: var(--mono); font-size: var(--step-4); font-weight: 700; color: var(--ink); }
/* WS5-OURS (2026-09-07): OURS chip on books where our capital sits — token-only
   (accent-as-text green, hairline), static (no motion: the one-signature budget
   stays at the ledger stamp). data-ours carries the status for honest sub-states
   (SEEDED/WINDING-DOWN) without extra copy. */
.fleet-ours { flex: 0 0 auto; font-family: var(--mono); font-size: var(--step-1); font-weight: 700; text-transform: uppercase; letter-spacing: var(--track-label); color: var(--accent-text); border: 1px solid var(--accent-text); padding: 0 0.4em; border-radius: var(--r-0, 0); }
.fleet-apr { margin-left: auto; text-align: right; font-family: var(--mono); font-weight: 700; font-size: var(--step-3); font-variant-numeric: tabular-nums; color: var(--ink); min-width: 0; } /* right, tabular; scales down the rungs below — never clipped, never truncated */ /* UI_LOOP_2 G4 (2026-09-08): DEMOTED from the Doto register — the rung ladder 14/13/11px is all below the Doto legibility floor (16px Doto smudges, the site's own law), so the fee-APR figure goes mono 700 (the ZERO/tape precedent); 'ROND' 100 dropped, a Doto-only axis inert on mono. */
.fleet-apr-mark { flex: 0 0 auto; font-family: var(--mono); font-size: var(--step-1); text-transform: uppercase; letter-spacing: var(--track-label); color: var(--ink-soft); border: 1px solid var(--line); padding: 0 0.4em; border-radius: var(--r-0, 0); } /* G3 SECTION-IMPROVE (2026-09-08): the flagship's one PROJECTION is chipped like .fleet-ours, but with the neutral --line edge (ours owns the amber-edged register) — honesty: projected ≠ measured, the two registers must not share a dress */
.fleet-meta { flex-basis: 100%; font-family: var(--mono); font-size: var(--step-2); color: var(--ink-soft); font-variant-numeric: tabular-nums; min-width: 0; } /* TVL + 24h vol keep their units; the row wraps as text — no overflow hidden on numbers */
.fleet-detail { border-top: 1px solid var(--line); padding: var(--space-12) var(--space-14); font-size: var(--step-3); }
/* G3 SECTION-IMPROVE (2026-09-08): the flagship disclosure affordance. The static
   flagship <summary> now rides .fleet-summary (flex) — which retires the UA ::marker
   triangle — so the card carries an EXPLICIT affordance instead: an amber mono '+'
   after the figure, flipping to '−' when the card is open. order:4 slots the glyph
   after .fleet-apr-mark; the flagship's .fleet-meta steps to order:5 so its 100%
   basis still wraps to its own line (without the swap the ::after strands alone on
   a third line). Flagship-only: the rendered books keep their own row grammar. */
.fleet-card--flagship > summary { list-style: none; } /* belt-and-braces: flex already retires the marker in modern engines */
.fleet-card--flagship > summary::after {
  content: '+';
  order: 4;
  flex: 0 0 auto;
  color: var(--accent-text);
  font-family: var(--mono);
  font-weight: 700;
  font-size: var(--step-3);
  line-height: 1;
}
.fleet-card--flagship[open] > summary::after { content: '−'; }
.fleet-card--flagship > summary .fleet-meta { order: 5; }
/* G3 SECTION-IMPROVE (2026-09-08): the deposit section nests INSIDE the flagship
   detail — the page-level section chrome (64/48 wrap verticals + the hard 2px band
   boundary) would double-pad the disclosure and draw a divider inside the card.
   Scope-down: trim the wrap to the detail's own rhythm, drop the boundary; the
   '03' index head stays. CASCADE NOTE: this is an OVERRIDE, not a removal — the
   (g)-pinned hard-boundary rule at :423 (the 2px bottom rule on section.block)
   remains in source, so the (g) count (11) is unchanged by this rule. The exact
   pinned literal is deliberately NOT restated here: the (g) counter reads raw
   css text INCLUDING comments, so quoting it in prose would add a phantom
   occurrence and trip the register. */
#fleet .fleet-detail section.block { border-bottom: 0; }
#fleet .fleet-detail section.block .wrap { padding: var(--space-16) var(--space-0); }
.fleet-poolid { display: block; font-family: var(--mono); font-size: var(--step-1); color: var(--ink-soft); overflow-wrap: anywhere; } /* THE long-hex line: anywhere is what keeps 390px scroll-free */
.fleet-note { margin: var(--space-8) 0 0; font-family: var(--mono); font-size: var(--step-1); color: var(--ink-soft); } /* the provenance window, verbatim, step-1 mono */
.fleet-unavailable { margin: 0; border: 1px dashed var(--line); padding: var(--space-12) var(--space-14); font-family: var(--mono); font-size: var(--step-2); color: var(--ink-soft); } /* the unavailable state is DESIGNED, not an error: — + muted prose + dashed hairline */
@media (max-width: 640px) {
  .fleet-apr { font-size: var(--step-2); } /* fee-APR scales to the step-1 floor as width fails (400px block below) — unit kept, never truncated */
}
@media (max-width: 400px) {
  .fleet-apr { font-size: var(--step-1); }
}
@media (min-width: 900px) {
  #fleet-books { grid-template-columns: repeat(2, minmax(0, 1fr)); } /* two measured books side by side */
}

/* FLEET-SIMPLE-EARN (2026-09-14): the dead-simple 3-step strip + the collapsed
   verify disclosure. Static, token-only: no transitions, no fetched resources,
   no new external origins. Hairline 1px borders only — the frozen hard-boundary
   register (the 11x plain 2px bottom-rule count, pinned by theme.test (g))
   stays untouched; and per the G3 CASCADE NOTE at #fleet .fleet-detail
   section.block: never quote a pinned literal in a comment — the (g)
   counter reads raw css text INCLUDING comments. */
.fleet-steps { list-style: none; margin: 0 0 var(--space-20); padding: 0; display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-8) var(--space-20); font-family: var(--mono); font-size: var(--step-3); color: var(--ink); } /* the path is one line at desktop, wraps as text on mobile — never a horizontal scroll */
.fleet-step-num { color: var(--accent-text); font-weight: 700; } /* the amber number register — accent-as-text, same dress as .fleet-ours */
.fleet-verify { margin: var(--space-12) 0 0; border: 1px solid var(--line); } /* the technical reads fold away; the deposit widget stays outside it */
.fleet-verify > summary { list-style: none; display: block; cursor: pointer; padding: var(--space-10) var(--space-12); font-family: var(--mono); font-size: var(--step-2); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--ink-soft); } /* the UA marker retires; the +/- glyph is explicit below */
.fleet-verify > summary::-webkit-details-marker { display: none; }
.fleet-verify > summary::before { content: '+'; color: var(--accent-text); font-weight: 700; margin-right: var(--space-8); }
.fleet-verify[open] > summary { border-bottom: 1px solid var(--line); }
.fleet-verify[open] > summary::before { content: '−'; }
.fleet-verify-body { padding: var(--space-12); }

/* FLEET-APR-LOOP (2026-09-14): the how-you-earn block — the roamer/loop
   one-breath + the APR explainer, quiet prose on one hairline. Static,
   token-only; no transitions, no fetched resources. The 40.3% figure in
   the copy is owned by config.js netAprPct — fleet-earn.test.js pins the
   pair, so a baseline re-pin forces the copy to move with it. */
.fleet-earn { margin: 0 0 var(--space-20); padding-left: var(--space-14); border-left: 1px solid var(--line); }
.fleet-earn p { margin: 0; color: var(--ink-soft); font-size: var(--step-3); }
.fleet-earn p + p { margin-top: var(--space-10); }
.fleet-earn strong { color: var(--ink); }

/* ---- movement (a)'s ONE live hero stat ----
   Huge tabular mono number + muted label. SECTION-IMPROVE G1 #6 (2026-09-08):
   the raw provenance window string ("05 win key …") no longer renders here —
   provenance stays in the fleet surface tooltip/detail; the window span stays
   in the markup (render.test.js pins the three ids) but is never written.
   The unavailable register (static '—' pre-JS, or a failed feed) adds the
   dashed hairline via a JS-TOGGLED class (#hero-stat carries it statically
   for no-JS; renderHeroStat removes it when a summary lands, re-adds it on
   the null path) — the old :has(:empty) detector would match forever now
   that the span is permanently empty, pinning the dashed band onto the live
   state. */
#hero-stat { display: flex; flex-direction: column; align-items: flex-start; gap: var(--space-4); margin: var(--space-24) 0 var(--space-16); }
.hero-stat-num { font-family: var(--font-num); font-weight: 700; font-variation-settings: 'ROND' 100; font-size: var(--step-7); line-height: 1; font-variant-numeric: tabular-nums; color: var(--ink); } /* WS5-DOTO: the hero's one live figure joins the dot-matrix number register; size/color/tabular-nums untouched */
.hero-stat-label { font-family: var(--mono); font-size: var(--step-2); color: var(--ink-soft); }
.hero-stat-window { font-family: var(--mono); font-size: var(--step-1); color: var(--ink-soft); } /* the window line, muted (span kept for the render pins; never written — provenance lives in the fleet surface) */
#hero-stat.hero-stat--unavailable { border: 1px dashed var(--line); padding: var(--space-12) var(--space-14); } /* unavailable = dashed hairline + the '—' (WS5-TREATMENT static state styling; class toggled by js/main.js renderHeroStat) */

/* ---- movement (c): the plug-in cards + the vanish disclosure ----
   The two skill pointers become card-like tap zones (one link each, whole-card
   44px zone, equal height by identical geometry). NOTE (disclosed): the DOM
   carries the pointers inline in the #agents prose (WS5-SKELETON's movement-c
   form) — the card treatment is applied to the existing <a> carriers; no
   markup was added (index.html is not this goal's file). */
#agents-skill-link, #agents-skill-mirror-link {
  display: inline-block; vertical-align: middle; margin: var(--space-2) 0;
  min-height: 44px; padding: var(--space-10) var(--space-14);
  border: 2px solid var(--line); background: var(--paper-raised);
  color: var(--accent-text); text-decoration: none;
  font-family: var(--mono); font-size: var(--step-2); line-height: 1.5;
}
#agents-skill-link:visited, #agents-skill-mirror-link:visited { color: var(--accent-text); text-decoration: none; }
.vanish-line { font-family: var(--font-num); font-weight: 700; font-variation-settings: 'ROND' 100; font-size: var(--step-5); line-height: 1.3; color: var(--ink); max-width: 44ch; margin: var(--space-28) 0 0; } /* WS-DARK-DOTO: the vanish disclosure rides the machine register — a status the page states about itself */

/* ============================================================
   WS5-TREATMENT — THE ONE SIGNATURE MOTION (2026-09-07).
   The ledger stamp is the page's only motion. The fleet cards' first-render
   arrival plays the SAME ws-stamp-fade keyframes REVERSED (stamp in, hold,
   stay) with the old ledger rows' staggered beat (0/140/280ms, extended to
   700ms at the 6th card). Opacity only — compositor-friendly, 60fps by
   construction; no JS, no rAF. The static flagship card (it hosts the deposit
   widget) does not animate. Reduced motion: instant, opacity 1, no transform.
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  #fleet-books .fleet-card { animation: ws-stamp-fade 900ms var(--ease-loop, cubic-bezier(0.65, 0, 0.35, 1)) reverse backwards; }
  .fleet-group .fleet-card:nth-child(2) { animation-delay: 0ms; }
  .fleet-group .fleet-card:nth-child(3) { animation-delay: 140ms; }
  .fleet-group .fleet-card:nth-child(4) { animation-delay: 280ms; }
  .fleet-group .fleet-card:nth-child(5) { animation-delay: 420ms; }
  .fleet-group .fleet-card:nth-child(6) { animation-delay: 560ms; }
  .fleet-group .fleet-card:nth-child(7) { animation-delay: 700ms; }
}
@media (prefers-reduced-motion: reduce) {
  #fleet-books .fleet-card { animation: none; opacity: 1; transform: none; }
}

/* ============================================================
   WS5-TREATMENT — the ONE-SCREEN mobile hero (2026-09-07).
   At 390×846 the hero fits ≤100svh WITHOUT scroll: the grid reorders
   h1 → pitch → CTA pair → hero-stat → lede. WS5-GATES (2026-09-07): the fold
   probe measured the original lede-before-CTA order pushing the primary CTA
   to y=914 at 390×846 — BELOW the 846px fold, failing the acceptance
   5-second test (h1 + one number + primary CTA without scrolling). The CTA
   now precedes the lede: re-probe measures h1 (197–536), CTA (~631–729) and
   the hero number (~737–781) all above the fold, CTA in the thumb third.
   The decorative keepers drop out (canyon hidden ≤640 above,
   the point-hand already hidden), and the lede steps OFF the display rung
   onto the body rung — the COPY is byte-pinned and untruncated (no line
   clamp anywhere); only the type rung changes. Later in the file than the
   WS-MOBILE-FIXES rank block, so this order wins the cascade.
   ============================================================ */
@media (max-width: 640px) {
  /* the wrap's min-height subtracts the hero's 2px border-bottom, so the
     .hero ELEMENT lands at exactly one small viewport */
  .hero .wrap { min-height: calc(100vh - 2px); min-height: calc(100svh - 2px); justify-content: flex-start; padding-top: var(--space-16); padding-bottom: var(--space-20); }
  .hero .wrap > .hero-ticker { margin-bottom: var(--space-16); }
  .hero .wrap > h1 { margin-bottom: var(--space-16); }
  .hero .wrap > .hero-rule { margin-bottom: var(--space-12); }
  .hero .wrap > .hero-meta { margin-bottom: var(--space-20); }
  .hero .wrap > .cta-row { margin-top: 0; } /* full-width stacked (the ≤640 .cta-row block above), the CTA in the thumb third */
  .hero .wrap > #hero-stat { margin: var(--space-12) 0; }
  .hero .wrap > #chain-badge { margin-top: var(--space-8); }
}
/* WS5-TREATMENT: the deposit widget now lives INSIDE the flagship fleet card's
   detail — the page-level .widget-grid minimum (300px columns) exceeds the
   card's inner measure at 390, so the card's own width governs (zero h-scroll
   for EVERY section, goal contract). Scoped to the section id; byte-stable. */
@media (max-width: 640px) {
  #deposit .widget-grid { grid-template-columns: minmax(0, 1fr); }
  #deposit .panel { min-width: 0; }
  #deposit .panel-head { flex-wrap: wrap; }
}
/* ---------- end WS5-TREATMENT EOF block ---------- */

/* ============================================================
   WS5-GATES (2026-09-07) — probe 3-caught mobile-fold fix.
   Measured at 390×846: the 136px header + ~224px of JS-written tape
   family rows pushed the hero down so #hero-stat-num (y=913) and
   a.cta-solid (y=1039) landed BELOW the 846px fold — the 5-second test
   failed on its "one number + primary CTA" line (h1 passed). Fix, all
   ≤640-only and presentation-only (copy byte-identical, no clamp): the
   tape FAMILY rows drop out exactly like the canyon keeper already does
   (the meta promise + chain cell stay — zero fabricated numbers), and
   the two trust paragraphs step one type rung down (the WS5-TREATMENT
   mechanism: rung change only). Re-measured post-fix: CTA bottom ≈ 815
   ≤ 846. Also: probe 3's tap sweep measured the 'Docs' nav link at
   34.3px wide (<44) at 390 — min-width floors it.
   ============================================================ */
@media (max-width: 640px) {
  .tape-strip .wrap > .tape-strip-entry:not(.tape-strip-meta) { display: none; }
  .hero .wrap { padding-top: var(--space-8); }
  .site-nav a { min-width: 44px; } /* flex-item min-width: no layout disturbance at any ≤640 width */
}

/* ============================================================
   FLEET-UI-V2 (2026-09-07) — G2: the fleet surface. CSS layer for the
   §1 DOM/class contract in docs/internal/FLEET_UI_V2_WAVE_2026-09-07.md
   (byte-frozen across G1/G2/G4 — G1 emits the DOM, this styles exactly
   that contract). Reference: DESIGN_REFERENCE_FLEET_TABLE_2026-09-07.md
   — R1 terminal density at ≥641px (≈40px rows, hairline separators,
   right-aligned tabular mono numerals, lowercase muted headers, 14+ rows
   visible at 1280px), R2 Snowball card stack ≤640px. G1 renders BOTH
   surfaces on every load; visibility is decided HERE, media queries only
   (table ≥641px, cards ≤640px, sheet shown only when open) — no resize JS.
   Tokens only: zero new colors, zero gradients, zero shadows, zero new
   keyframes (the one-motion budget stays the ledger stamp; interactive
   elements transition color/border-color on the existing motion tokens
   only — nothing moves, so no reduced-motion pair is owed). Focus rings
   ride the global :focus-visible rule (accent-punch).
   NOTE on the v1 fleet rules above (WS5-TREATMENT block):
   .fleet-summary/.fleet-pair/.fleet-apr/.fleet-meta/.fleet-detail stay
   load-bearing for the byte-frozen flagship card — this block layers the
   §1 anatomy ALONGSIDE them and never over them; the v1 tier-color
   conventions carry over (HOOK = warn red, DEAD = muted gray per the
   ratified reference, PROTOCOL = the amber).
   ============================================================ */

#fleet-surface { margin-top: var(--space-16); min-width: 0; }

/* ---- filter chips (G1 renders the buttons; lowercase mono, 44px zone).
   The active chip is amber-as-text + amber edge — the .fleet-ours register,
   NOT an amber fill: the page's one solid CTA stays the only filled amber. */
.fleet-filters { display: flex; flex-wrap: wrap; gap: var(--space-8); margin: 0 0 var(--space-12); }
.fleet-filter {
  appearance: none;
  min-height: 44px; min-width: 44px;
  padding: var(--space-10) var(--space-14);
  background: var(--paper-raised); color: var(--ink-soft);
  border: 1px solid var(--line); border-radius: var(--r-0, 0);
  font-family: var(--mono); font-size: var(--step-2);
  letter-spacing: var(--track-label); text-transform: lowercase;
  cursor: pointer;
  transition: color var(--motion), border-color var(--motion), transform var(--motion); /* BTN-MOTION (2026-09-08): + the transform component (compositor-only) */
}
.fleet-filter:hover:not(:disabled) { color: var(--ink); border-color: var(--ink-soft); transform: translateY(-1px); box-shadow: var(--shadow-btn-hover); } /* BTN-MOTION (2026-09-08): the chip lifts hover-only — outline-flat at rest */
.fleet-filter:active:not(:disabled) { transform: translateY(0) scale(0.985); box-shadow: var(--shadow-btn-hover); transition: color var(--t-fast) var(--ease-enter), border-color var(--t-fast) var(--ease-enter), transform var(--t-fast) var(--ease-enter); } /* BTN-MOTION (2026-09-08): the press settles under the finger */
.fleet-filter.is-active { color: var(--accent-text); border-color: var(--accent-text); font-weight: 700; }
.fleet-filter-count { color: var(--ink-soft); margin-left: var(--space-4); } /* G4 #4 (2026-09-08): the chip census, filled by the renderer from WS.fleet.summary() — fail-closed (no summary, no count); stays muted even on the active chip: the amber is the selection, the count is data */

/* ---- the Doto register class the §1 contract carries on measured figures
   (.fc-metric-value.doto): the machine face for the machine truth. */
.doto { font-family: var(--font-num); font-weight: 700; font-variation-settings: 'ROND' 100; font-variant-numeric: tabular-nums; }

/* ---- shared metadata chips (table pair cell + card head) ---- */
.ft-chip {
  display: inline-block; vertical-align: baseline;
  font-family: var(--mono); font-size: var(--step-1); font-weight: 400;
  letter-spacing: var(--track-label); text-transform: lowercase;
  color: var(--ink-soft); border: 1px solid var(--line);
  padding: 0 var(--space-6); margin-left: var(--space-6);
  background: transparent; white-space: nowrap;
}
.ft-chip--fee { border-color: var(--ink-soft); } /* the fee tier gets the stronger edge — it is the number the fee-black-hole truth hangs on */

/* ---- shared action buttons. Base = the 44px zone (§0 rule 9). The R1
   density exception below releases ONLY the desktop table's chips to
   compact under a fine pointer — the ratified reference shows compact
   action chips inside ≈40px rows; coarse pointers (tablets) keep the
   full 44px zone and slightly taller rows instead. */
.ft-copy, .ft-details {
  appearance: none;
  min-height: 44px; min-width: 44px;
  padding: var(--space-10) var(--space-14);
  background: var(--paper-raised); color: var(--accent-text);
  border: 1px solid var(--line); border-radius: var(--r-0, 0);
  font-family: var(--mono); font-size: var(--step-2);
  cursor: pointer; white-space: nowrap;
  transition: color var(--motion), border-color var(--motion), transform var(--motion); /* BTN-MOTION (2026-09-08): + the transform component (compositor-only) */
}
.ft-copy:hover:not(:disabled), .ft-details:hover:not(:disabled) { border-color: var(--accent-text); transform: translateY(-1px); box-shadow: var(--shadow-btn-hover); } /* BTN-MOTION (2026-09-08): the action chip lifts hover-only — outline-flat at rest */
.ft-copy:active:not(:disabled), .ft-details:active:not(:disabled) { transform: translateY(0) scale(0.985); box-shadow: var(--shadow-btn-hover); transition: color var(--t-fast) var(--ease-enter), border-color var(--t-fast) var(--ease-enter), transform var(--t-fast) var(--ease-enter); } /* BTN-MOTION (2026-09-08): the press settles under the finger */

/* ---- the terminal table (R1). Mobile-first: hidden ≤640, table ≥641.
   Row pitch ≈40px via cell height; separators are 1px hairlines (--line),
   the header boundary the stronger 1px muted rule (--ink-soft).
   Column order assumed from §1: spine / pair / TVL / vol 24h / fee APR /
   IL / age / actions (8 columns — G1 emits 8 th). */
.fleet-table { display: none; width: 100%; border-collapse: collapse; }
.fleet-table th, .fleet-table td { height: 40px; padding: var(--space-6) var(--space-10); vertical-align: middle; text-align: left; }
.fleet-table thead th {
  font-family: var(--mono); font-size: var(--step-1); font-weight: 400;
  letter-spacing: var(--track-label); text-transform: lowercase;
  color: var(--ink-soft); white-space: nowrap;
  border-bottom: 1px solid var(--ink-soft);
}
.ft-row { border-bottom: 1px solid var(--line); }
.ft-row.is-protocol { background: var(--chip-tan); } /* skin in the game: the warm band marks the rows where our capital sits */
.ft-spine { width: 3px; padding: 0; border-left: 3px solid transparent; }
.ft-spine--pays { border-left-color: var(--ink); }        /* PAYS-LPS: the bone ink — paid books need no flag color */
.ft-spine--hook { border-left-color: var(--warn); }       /* HOOK-MONETIZED: the honest red */
.ft-spine--dead { border-left-color: var(--ink-soft); }   /* DEAD: gray, per the ratified reference */
.ft-spine--protocol { border-left-color: var(--accent); } /* PROTOCOL: the amber */
.ft-pair { font-family: var(--mono); font-size: var(--step-3); font-weight: 700; color: var(--ink); white-space: nowrap; }
.fleet-table td.ft-num { font-family: var(--mono); font-size: var(--step-3); font-variant-numeric: tabular-nums; color: var(--ink); text-align: right; white-space: nowrap; } /* UI_LOOP_2 G4 (2026-09-08): (0,2,1) beats `.fleet-table th,td` (0,1,1) — the right-align was DEAD at (0,1,0); grammar contract = numerals right, labels left */
.ft-apr { font-weight: 700; } /* the headline measured figure */
.ft-window { font-size: var(--step-1); font-weight: 400; letter-spacing: 0; color: var(--ink-soft); margin-left: var(--space-4); } /* the window suffix: muted, travels with its figure */
.ft-il { color: var(--ink-soft); font-weight: 400; } /* realized IL renders '—' until the feed carries it — muted, never a fake zero */
.fleet-table td.ft-age { font-family: var(--mono); font-size: var(--step-2); font-variant-numeric: tabular-nums; color: var(--ink-soft); text-align: right; white-space: nowrap; } /* UI_LOOP_2 G4 (2026-09-08): same specificity lift as td.ft-num — the right-align was dead at (0,1,0) */
.fleet-table td.ft-actions { text-align: right; white-space: nowrap; } /* UI_LOOP_2 G4 (2026-09-08): same specificity lift — the action chips end the row */
@media (min-width: 641px) and (pointer: fine) {
  .ft-actions .ft-copy, .ft-actions .ft-details { min-height: 0; padding: var(--space-4) var(--space-10); } /* the R1 compact chip — fine pointers only; the 44px zone holds everywhere else */
}
/* DECISION-2 (SECTION-IMPROVE G4 #3, 2026-09-08): the IL + age diet is
   UNBOUNDED — the columns render '—' until the feed carries the figures, so
   they step aside at EVERY table width (the colophon under the table says
   so). Presentation-layer only — the cells are still emitted; the DOM
   contract is untouched. The narrow-band padding trim stays scoped to its
   original band (it belongs to the narrow fit, not to the diet). */
@media (min-width: 641px) {
  .fleet-table thead th:nth-child(6), .fleet-table tbody td:nth-child(6),
  .fleet-table thead th:nth-child(7), .fleet-table tbody td:nth-child(7) { display: none; }
}
@media (min-width: 641px) and (max-width: 819px) {
  .fleet-table th, .fleet-table td { padding-inline: var(--space-6); }
}

/* G4 #7 (2026-09-08) / W1 G1-BAND (2026-09-08): the terminal register — the
   header row stays readable while the 95-book table scrolls. z-index 5: under
   the sticky header (10), the mobile sheet (60) and the copy toast (200).
   top 74px = the MEASURED single-row header height ≥760 (44px theme-toggle
   row + 2×14px .site-header .wrap padding + 2px border — the toggle, not the
   nav, drives the bar; the wave brief's "68px" premise predates the toggle).
   Inside the 641-892 scroller band below this rule is INERT (a scroll
   container owns the thead's stick there — fleet-table.js re-implements it
   against the live header height) and ≥893 this viewport-sticky rule is the
   whole behavior, measured flush (74 == header 74). */
.fleet-table thead th { position: sticky; top: 74px; background: var(--paper); z-index: 5; }

/* W1 G1-BAND (2026-09-08) scroll-width-fix: the table's min-content (824.52px with the ≤819
   padding trim, 872.52px without — measured) overflows the DOCUMENT from 641
   through 892 (872.52 + 40px .wrap padding = 892.5 scroll edge, measured 893
   clears). The #fleet-table-scroller div in index.html wraps the table ONLY,
   and inside this band it is the table's horizontal scrollport: the books
   scroll sideways here while the document never overflows (scrollWidth ==
   innerWidth, verified 641-892 + 1024). The scroller stays NAIVE on purpose —
   no max-height, no sticky on the wrapper: a measured attempt at a
   pinned-scrolling panel bounded the thead's sticky travel to the ~30px of
   content after the table inside #fleet-surface AND made rows below the fold
   unreachable by page scroll, so the CSS viewport-sticky thead is instead
   RE-IMPLEMENTED by js/fleet-table.js inside this band (a scroll container
   kills the native stick — the nearest scrollport becomes the scroller and
   top:74 never engages, measured). The JS pin measures the live header height
   each frame, so no per-band thead offset ships here (the retired 109px
   641-758 block also missed 759, where the nav still wraps and the labels
   slid UNDER the header). Boundary is a measured constant like the site's
   other probe-pinned values; re-pin if font metrics move it. */
@media (min-width: 641px) and (max-width: 892px) {
  #fleet-table-scroller { /* the index.html hook is an id (goal-pinned); no class ships */
    overflow-x: auto;
  }
}

/* ---- the card stack (R2 Snowball anatomy, ≤640px). Base grid; hidden
   ≥641 below. Spine = the card's left status bar; 3 metrics max; the ONE
   plain-sentence state line is muted mono; actions are full 44px zones. */
.fleet-cards { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-12); min-width: 0; }
.fc-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-6) var(--space-8); padding: var(--space-12) var(--space-14) 0; min-width: 0; }
.fc-spine { flex: 0 0 3px; align-self: stretch; background: transparent; }
.fc-spine--pays { background: var(--ink); }
.fc-spine--hook { background: var(--warn); }
.fc-spine--dead { background: var(--ink-soft); }
.fc-spine--protocol { background: var(--accent); }
.fc-pair { font-family: var(--mono); font-size: var(--step-4); font-weight: 700; color: var(--ink); }
.fc-badge { flex-basis: 100%; font-family: var(--mono); font-size: var(--step-1); letter-spacing: var(--track-label); text-transform: uppercase; }
.badge--pays { color: var(--ink); }
.badge--hook { color: var(--warn); }
.badge--dead { color: var(--ink-soft); }
.badge--protocol { color: var(--accent-text); }
.fc-metrics { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-8); padding: var(--space-12) var(--space-14) 0; }
.fc-metric { display: flex; flex-direction: column; gap: var(--space-4); min-width: 0; }
.fc-metric-label { font-family: var(--mono); font-size: var(--step-1); letter-spacing: var(--track-label); color: var(--ink-soft); }
.fc-metric-value { font-family: var(--font-num); font-weight: 700; font-variation-settings: 'ROND' 100; font-size: var(--step-5); line-height: 1.1; font-variant-numeric: tabular-nums; color: var(--ink); overflow-wrap: anywhere; } /* numbers never truncate: the value wraps as text if the source ever ships a longer figure */
.fc-state { margin: var(--space-10) 0 0; padding: 0 var(--space-14); font-family: var(--mono); font-size: var(--step-2); color: var(--ink-soft); }
.fc-actions { display: flex; flex-wrap: wrap; gap: var(--space-8); padding: var(--space-12) var(--space-14) var(--space-14); }
.fc-actions .ft-copy, .fc-actions .ft-details { flex: 1 1 auto; min-height: 44px; padding-block: 0; } /* full-width pair, full 44px zones on the thumb surface */

/* ---- the detail sheet: bottom sheet ≤640 / inline panel ≥641. Shown only
   when open — the [hidden] guard keeps the attribute authoritative even
   though no base display is set. z-index 60 sits above the sticky header
   (10) and under the skip link (the site max, 100). */
.fleet-sheet { border: 2px solid var(--line); background: var(--paper-raised); padding: var(--space-16); min-width: 0; }
.fleet-sheet[hidden] { display: none; }
/* DETAIL-INLINE (2026-09-08): the detail opens under the clicked row/card.
   The two-class specificity (0,2,0) overrides the <=640px fixed bottom-sheet
   rule for inline nodes without editing that rule; the row cell carries no
   padding of its own so the panel's border reads as the row's continuation. */
.ft-detail-row > td { padding: 0; border-top: 0; }
.fleet-sheet.fleet-sheet-inline { position: static; max-height: none; overflow: visible; border-top: 0; margin: var(--space-8) 0 var(--space-16); }
.fleet-sheet h3, .fleet-sheet h4 { margin: 0 0 var(--space-8); font-family: var(--font-num); font-weight: 700; font-variation-settings: 'ROND' 100; font-size: var(--step-5); color: var(--ink); }

/* ---- the unavailable state: a colophon, not an error — the dashed
   hairline register the page already uses for honest absence. Restates the
   v1 values (later cascade, identical) + resets the inner sentence. */
.fleet-unavailable { margin: var(--space-16) 0 0; border: 1px dashed var(--line); padding: var(--space-12) var(--space-14); font-family: var(--mono); font-size: var(--step-2); color: var(--ink-soft); }
.fleet-unavailable p { margin: 0; }

/* ---- the colophon (G4 #3 / DECISION-2, 2026-09-08): the honesty line for
   the diet — table-surface only (the columns it explains exist ≥641). ---- */
.fleet-colophon { display: none; margin: var(--space-8) 0 0; font-family: var(--mono); font-size: var(--step-1); color: var(--ink-soft); }

/* ---- the visibility switch: table ≥641, cards ≤640 (base grid above) ---- */
@media (min-width: 641px) {
  .fleet-table { display: table; }
  .fleet-cards { display: none; }
  .fleet-sheet { margin: var(--space-16) 0 0; } /* desktop: the detail is an inline panel under the table */
  .fleet-colophon { display: block; }
}

/* ---- mobile sheet + the metric rung-down (the .fleet-apr idiom: the
   figure scales DOWN the type scale as width fails — unit kept, never
   truncated). vh line first, svh override second — the established
   fallback idiom. */
@media (max-width: 640px) {
  .fleet-sheet {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
    max-height: min(72vh, 560px);
    max-height: min(72svh, 560px);
    overflow-y: auto;
    border-bottom: 0;
    padding: var(--space-16) var(--space-14);
  }
}
@media (max-width: 400px) {
  .fc-metric-value { font-size: var(--step-4); }
}
/* G4 #2 (2026-09-08): the label rung-down — 'FEE APR (2.8h)' wrapped and
   broke the 3-metric baseline at 390. The label takes the --step-0 rung
   (written justification at the token block), tightens its tracking and
   holds one line. (G3-LIGHT-THEME 2026-09-08 touches the VALUE's FACE in
   the same block below — family only; the size rungs are untouched.) */
/* G3-LIGHT-THEME (2026-09-08): the mobile card values read mono 700 — Doto
   at the step-4 rung (16px, ≤400) smears on paper (the site's own floor
   precedent: 16px Doto = smudge → small figures go mono 700). Doto keeps
   every ≥20px figure elsewhere; the size tokens are untouched. */
@media (max-width: 640px) {
  .fc-metric-value { font-family: var(--mono); font-weight: 700; font-variation-settings: normal; }
  .fc-metric-label { font-size: var(--step-0); letter-spacing: .02em; white-space: nowrap; }
}

/* ============================================================
   FLEET-UI-V2 (2026-09-07) — G3: the stats / burn-ledger surface
   (#stats) + the footer live proof strip (#live-counters). CSS
   layer for the R3 exemplar's "OUR VERSION"
   (DESIGN_REFERENCE_FLEET_TABLE_2026-09-07.md: burned card +
   window toggle, flywheel split card, books grid — the Snowball
   pattern: every number carries a plain sentence + a title
   tooltip). ADDITIVE-ONLY: tokens only, zero new colors, zero
   gradients, zero keyframes (the one-motion budget stays the
   ledger stamp), zero reduced-motion debt (nothing moves — the
   bar fill is a static scaleX transform, no transition). Tap
   targets 44px; grids collapse to one column <=640; numbers wrap
   as text (no truncation, no horizontal scroll at 390). The
   waiting register IS the designed default: the roamer is
   PRE-F-01 and '—' + a plain sentence is the honest render.
   ============================================================ */

/* ---- the window toggle (block-head slot; the .fleet-filter register:
   amber-as-text active edge, never an amber fill) ---- */
.st-toggle { display: flex; gap: var(--space-6); }
.st-toggle-btn {
  appearance: none;
  min-height: 44px; min-width: 44px;
  padding: var(--space-8) var(--space-10);
  background: var(--paper-raised); color: var(--ink-soft);
  border: 1px solid var(--line); border-radius: var(--r-0, 0);
  font-family: var(--mono); font-size: var(--step-2);
  letter-spacing: var(--track-label); text-transform: lowercase;
  cursor: pointer;
  transition: color var(--motion), border-color var(--motion), transform var(--motion); /* BTN-MOTION (2026-09-08): + the transform component (compositor-only) */
}
.st-toggle-btn:hover:not(:disabled) { color: var(--ink); border-color: var(--ink-soft); transform: translateY(-1px); box-shadow: var(--shadow-btn-hover); } /* BTN-MOTION (2026-09-08): the window chip lifts hover-only — outline-flat at rest */
.st-toggle-btn:active:not(:disabled) { transform: translateY(0) scale(0.985); box-shadow: var(--shadow-btn-hover); transition: color var(--t-fast) var(--ease-enter), border-color var(--t-fast) var(--ease-enter), transform var(--t-fast) var(--ease-enter); } /* BTN-MOTION (2026-09-08): the press settles under the finger */
.st-toggle-btn.is-active { color: var(--accent-text); border-color: var(--accent-text); font-weight: 700; }

/* ---- the flat bento card grid (the R3 4-col exemplar at our scale:
   two stat cards + the full-width flywheel card, then the 3-up books
   grid). Hard 1px borders, raised surface, no radius, no shadow. ---- */
.st-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-12); margin-top: var(--space-16); min-width: 0; }
.st-card { border: 1px solid var(--line); background: var(--paper-raised); padding: var(--space-16); min-width: 0; }
.st-card--wide { grid-column: 1 / -1; }
.st-label { display: block; margin: 0 0 var(--space-8); font-family: var(--mono); font-size: var(--step-1); letter-spacing: var(--track-label); text-transform: lowercase; color: var(--ink-soft); }
.st-value { display: block; font-family: var(--font-num); font-weight: 700; font-variation-settings: 'ROND' 100; font-variant-numeric: tabular-nums; font-size: var(--step-6); line-height: 1.1; color: var(--ink); overflow-wrap: anywhere; } /* the machine register; the figure wraps as text — never clipped */
.st-unit { display: block; margin-top: var(--space-6); font-family: var(--mono); font-size: var(--step-2); color: var(--ink-soft); }
.st-sent { margin: var(--space-10) 0 0; font-family: var(--mono); font-size: var(--step-2); color: var(--ink-soft); }

/* ---- the flywheel lanes: burn vs treasury-junk. The bar is a TRACK —
   the fill rides transform: scaleX (compositor-only) and stays at 0
   until a counted-event pair exists; the JS stamps data-empty on the
   fill AND the track + the honest-title whenever no pair has landed. ---- */
.st-lane { padding: var(--space-10) 0; border-bottom: 1px solid var(--line); }
.st-lane:first-of-type { padding-top: 0; }
.st-lane:last-of-type { border-bottom: none; padding-bottom: 0; }
.st-lane-name { display: block; font-family: var(--mono); font-size: var(--step-1); letter-spacing: var(--track-label); text-transform: lowercase; color: var(--ink); }
.st-lane-value { display: block; margin-top: var(--space-4); font-family: var(--font-num); font-weight: 700; font-variation-settings: 'ROND' 100; font-variant-numeric: tabular-nums; font-size: var(--step-5); color: var(--ink); overflow-wrap: anywhere; }
.st-bar { display: block; margin-top: var(--space-8); height: 6px; border: 1px solid var(--line); background: var(--paper-2); overflow: hidden; }
.st-bar-fill { display: block; height: 100%; background: var(--accent); transform: scaleX(0); transform-origin: 0 50%; }
.st-lane-sent { margin: var(--space-8) 0 0; font-family: var(--mono); font-size: var(--step-2); color: var(--ink-soft); }

/* ---- the books grid (the feed's own census, 3-up): the Snowball
   explainer sits under every figure ---- */
.st-books { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--space-12); margin-top: var(--space-12); min-width: 0; }
.st-book { border: 1px solid var(--line); background: var(--paper-raised); padding: var(--space-14); min-width: 0; }
.st-book .st-value { font-size: var(--step-5); }
.st-book .st-sent { margin-top: var(--space-8); }

/* ---- G5 STATS/FLYWHEEL (SECTION_IMPROVE 2026-09-08): the absence + pending
   registers. The bars' empty state stamps data-empty on the TRACK: transparent
   + 1px dashed = the absence idiom — the solid paper-2 track read as a filled
   bar in light mode. 1px dashed only: the (g) hard-boundary register counts its
   2px bottom-band rules at exactly 11 and must not move (this comment is worded
   to avoid quoting the pinned byte string — a substring count sees comments). ---- */
.st-bar[data-empty] { background: transparent; border: 1px dashed var(--line); }
.st-pending-chip { display: inline-block; margin-left: var(--space-6); padding: 0 var(--space-6); border: 1px dashed var(--line); background: var(--paper-pending); color: var(--ink-soft); }
.st-pending-chip[hidden], .st-pending-line[hidden] { display: none; } /* the JS clears the register on live/error — an inline-block chip would out-rank the UA [hidden] rule */
.st-pending-line { margin: var(--space-6) 0 0; font-family: var(--mono); font-size: var(--step-2); color: var(--ink-soft); }
.st-unit.is-pending { opacity: .85; } /* the windowed unit greys while pending/error; no new color — the existing ink-soft dims. WS-VAULT-GATES (2026-09-13): .55 failed color-contrast (2.56:1 light / 2.72:1 dark vs 4.5 required at 13px) — .85 measures 5.09:1 light / 4.92:1 dark, the dim register kept honestly */
.st-streams { margin-top: var(--space-16); max-width: var(--measure-copy); }
.st-stream { margin: 0; font-family: var(--mono); font-size: var(--step-2); color: var(--ink-soft); }
.st-stream + .st-stream { margin-top: var(--space-6); }
.st-stream-name { color: var(--ink); }
.st-census-head { margin-top: var(--space-16); }
.st-census-head .st-sent { margin-top: var(--space-4); }
.st-census-link { margin: var(--space-4) 0 0; font-family: var(--mono); font-size: var(--step-2); }

/* ---- the footer live proof strip (every page). Footer-band tokens
   (--footer-muted/-faint carry the measured AA pairs); the numerals
   take the accent-text register — the strip is the page's one amber
   proof moment. ---- */
.lc-strip { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-8) var(--space-12); border: 1px solid var(--line); background: var(--paper-2); padding: var(--space-10) var(--space-12); margin-bottom: var(--space-20); min-width: 0; }
.lc-item { display: inline-flex; align-items: baseline; gap: var(--space-6); min-width: 0; }
.lc-num { font-family: var(--font-num); font-weight: 700; font-variation-settings: 'ROND' 100; font-variant-numeric: tabular-nums; font-size: var(--step-5); color: var(--accent-text); overflow-wrap: anywhere; } /* SECTION-IMPROVE G1 #5 (2026-09-08): the footer counters step up one role — step-4 under-read against the labels */
.lc-label { font-family: var(--mono); font-size: var(--step-1); letter-spacing: var(--track-label); text-transform: lowercase; color: var(--footer-muted); } /* the .lc-sep rule retired with its two decorative '|' spans (G1 #5 — the strip's flex gap separates) */
.lc-note { flex-basis: 100%; font-family: var(--mono); font-size: var(--step-1); color: var(--footer-faint); }

/* ---- mobile: one column, the strip tightens ---- */
@media (max-width: 640px) {
  .st-grid, .st-books { grid-template-columns: minmax(0, 1fr); }
  .st-card, .st-book { padding: var(--space-14); }
  .lc-strip { gap: var(--space-6) var(--space-10); padding: var(--space-10); }
}

/* ============================================================
   FLOW (2026-09-08) — FLOW_SECTION: the live-wired flywheel (#flow).
   CSS layer for the kit composition (docs/internal/design-kit/twitter/
   flywheel.html + -light): two lanes of hard-bordered node cards joined
   by inline-SVG marker-end arrows, the split columns, the 'DEV TAKE: 0'
   seal. Tokens only: --line borders, --accent (the arrows + seal are the
   accent FILL role), --accent-text for accent TEXT, --paper-raised card
   faces. Zero gradients, zero new colors, zero images. Node figures ride
   the machine register at the Doto floor and above (step-5 = 20px, the
   .st-book precedent — never below, so no mobile demotion is owed). The
   waiting register IS the designed default (the static paint): '—' +
   plain sentences + dashed chips, exactly the G5 stats grammar. One
   motion signature: the pulse dot on the deposit arrow — transform +
   opacity keyframes ONLY (hardware-only), gated behind
   prefers-reduced-motion: no-preference AND killed by the global reduce
   guard (base opacity is 0, so stillness is invisible, not frozen).
   Desktop >=901: two lanes. 641-900: single column, arrows rotate to
   vertical (the paired vertical svg swaps in). <=640: the snowball
   vertical stack, tighter padding.
   ============================================================ */

/* ---- the defs sprite + the seal row ---- */
.flow-defs { position: absolute; width: 0; height: 0; overflow: hidden; }
.flow-defs marker path { fill: var(--accent); }
.flow-top { display: flex; justify-content: flex-end; margin: 0 0 var(--space-12); }
.flow-seal {
  display: inline-block;
  border: 2px solid var(--accent); color: var(--accent-text);
  font-family: var(--mono); font-size: var(--step-3); letter-spacing: 0.18em;
  padding: var(--space-8) var(--space-14);
}

/* ---- lanes + chains ---- */
.flow-lane { margin-top: var(--space-20); min-width: 0; }
.flow-lane--two { margin-top: var(--space-32); padding-top: var(--space-20); border-top: 1px solid var(--line); }
.flow-lane-label { display: block; margin: 0 0 var(--space-10); font-family: var(--mono); font-size: var(--step-1); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--ink-soft); }
.flow-chain { display: grid; grid-template-columns: minmax(0, 1fr) 84px minmax(0, 1fr) 84px minmax(0, 1fr) 84px minmax(0, 1.35fr); gap: var(--space-8); align-items: stretch; min-width: 0; } /* UI_LOOP_3 W1 #2: gap tightened toward the table's density register */
.flow-chain--two { grid-template-columns: minmax(0, 1.3fr) 84px minmax(0, 1fr) minmax(0, 1.2fr); }

/* ---- node cards (the kit's 2px hard borders on the raised face) ---- */
.flow-node { border: 2px solid var(--line); background: var(--paper-raised); padding: var(--space-14); min-width: 0; display: flex; flex-direction: column; gap: var(--space-6); }
.flow-node--src { border-color: var(--accent); }
.flow-node--dep { border-color: var(--ink-soft); }
.flow-node--burn { border-color: var(--accent); }
.flow-node--burn .flow-node-h { color: var(--accent-text); }
.flow-node-h { margin: 0; font-family: var(--font-num); font-weight: 700; font-variation-settings: 'ROND' 100; font-size: var(--step-5); line-height: 1.15; text-transform: uppercase; color: var(--ink); }
.flow-node-s { margin: 0; font-family: var(--mono); font-size: var(--step-2); line-height: 1.5; color: var(--ink-soft); }

/* ---- the measured-figure register (the .st-value idiom at the floor) ---- */
.flow-fig { display: block; margin-top: var(--space-6); font-family: var(--font-num); font-weight: 700; font-variation-settings: 'ROND' 100; font-variant-numeric: tabular-nums; font-size: var(--step-5); line-height: 1.1; color: var(--ink); overflow-wrap: anywhere; }
.flow-fig-unit { display: block; font-family: var(--mono); font-size: var(--step-1); letter-spacing: var(--track-label); text-transform: lowercase; color: var(--ink-soft); }
.flow-state { margin: var(--space-4) 0 0; font-family: var(--mono); font-size: var(--step-2); color: var(--ink-soft); } /* UI_LOOP_3 W1 #1 (2026-09-10): was margin:auto — the bottom-pin left dead middles in equal-height cards; the value register now flows under the copy */
.flow-chip { display: inline-block; align-self: flex-start; margin-top: var(--space-6); padding: 0 var(--space-6); border: 1px dashed var(--line); background: var(--paper-pending); color: var(--ink-soft); font-family: var(--mono); font-size: var(--step-1); letter-spacing: var(--track-label); } /* the sanctioned pending register (.st-pending-chip pair); UI_LOOP_3 W1 #3 verified its light contrast — see wave notes */
.flow-chip[hidden] { display: none; } /* the live branch hides the chip — an inline-block chip would out-rank the UA [hidden] rule (the .st-pending-chip precedent) */

/* ---- the links: label above a fixed-length marker-end arrow (the kit's
   84px arrows, now inline SVG so the head re-inks with the theme). Every
   link carries BOTH orientations; the band below swaps them. ---- */
.flow-link { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--space-4); min-width: 0; }
.flow-link-label { font-family: var(--mono); font-size: var(--step-1); letter-spacing: var(--track-label); text-transform: lowercase; color: var(--ink-soft); white-space: nowrap; }
.flow-link-rail { position: relative; display: block; width: 84px; height: 12px; }
.flow-arr { display: block; }
.flow-arr line { stroke: var(--accent); stroke-width: 3; }
.flow-arr--v { display: none; }
.flow-arr-v { display: block; }
.flow-arr-v line { stroke: var(--accent); stroke-width: 3; }

/* ---- the ONE motion signature: the pulse dot on the deposit arrow.
   Base opacity 0 — the global reduce guard's animation:none leaves the
   page still AND the dot invisible. Custom properties carry the travel
   vector so the SAME keyframes serve both orientations. ---- */
.flow-pulse {
  position: absolute; left: -3px; top: 3px;
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--accent);
  opacity: 0;
  pointer-events: none;
  --flow-dx: 0px; --flow-dy: 0px; --flow-dx2: 74px; --flow-dy2: 0px;
}
@media (prefers-reduced-motion: no-preference) {
  .flow-pulse { animation: flow-pulse 2.8s var(--ease-loop) infinite; }
}
@keyframes flow-pulse {
  0%   { transform: translate3d(var(--flow-dx), var(--flow-dy), 0); opacity: 0; }
  12%  { opacity: 1; }
  82%  { opacity: 1; }
  100% { transform: translate3d(var(--flow-dx2), var(--flow-dy2), 0); opacity: 0; }
}

/* ---- the split: two columns (branch label, down arrow, outcome node),
   right-aligned under the fees node at >=901 ---- */
.flow-split-row { display: flex; justify-content: flex-end; gap: var(--space-40); margin-top: var(--space-16); min-width: 0; }
.flow-col { display: flex; flex-direction: column; align-items: center; gap: var(--space-8); min-width: 0; }
.flow-col .flow-node { width: 260px; max-width: 100%; }
.flow-branch-label { font-family: var(--mono); font-size: var(--step-2); color: var(--ink-soft); white-space: nowrap; }
.flow-pct { font-family: var(--font-num); font-weight: 700; font-variation-settings: 'ROND' 100; font-size: var(--step-6); color: var(--accent-text); }

/* ---- lane 2's right-side note + the replay foot ---- */
.flow-note { align-self: center; max-width: 46ch; font-family: var(--mono); font-size: var(--step-2); line-height: 1.7; color: var(--ink-soft); min-width: 0; }
.flow-foot { margin: var(--space-20) 0 0; font-family: var(--mono); font-size: var(--step-2); color: var(--ink-soft); }
.flow-foot-dot { color: var(--accent-text); }

/* ---- UI_LOOP_3 W2 (2026-09-10): flow nodes that navigate keep the exact
   node register — the anchor is invisible furniture, hover/focus reuse the
   filter-chip vocabulary (border ink-soft), no color changes. ---- */
a.flow-node { text-decoration: none; color: inherit; }
a.flow-node:hover { border-color: var(--ink-soft); }
.flow-discovery { margin: var(--space-16) 0 0; font-family: var(--mono); font-size: var(--step-2); color: var(--ink-soft); }
.flow-discovery a { color: var(--accent-text); }

/* ---- UI_LOOP_3 W3c: the holder loop — lane 2 feeds itself. A stroked arc
   (no fill, no gradient) from HOLDERS back toward the lane start, desktop
   only (<=900 the vertical read already carries the order). ---- */
.flow-loop { display: block; width: 100%; height: 56px; margin-top: var(--space-8); min-width: 0; }
.flow-loop path { fill: none; stroke: var(--accent); stroke-width: 2; }
.flow-loop-label { display: block; text-align: center; margin-top: var(--space-4); font-family: var(--mono); font-size: var(--step-1); letter-spacing: var(--track-label); text-transform: lowercase; color: var(--ink-soft); }
@media (max-width: 900px) { .flow-loop, .flow-loop-label { display: none; } }

/* ---- UI_LOOP_3 W3a: the toast choreography (user-ratified 2026-09-09) —
   120ms in / 150ms out, transform+opacity only, and the translate(-50%) base
   is carried through BOTH keyframes so the centering never pops. Reduced
   motion: no animation classes are ever applied outside no-preference, and
   copy-position.js schedules removal regardless — the toast can never strand. ---- */
@keyframes copy-toast-in { from { opacity: 0; transform: translate(-50%, 8px); } to { opacity: 1; transform: translate(-50%, 0); } }
@keyframes copy-toast-out { from { opacity: 1; transform: translate(-50%, 0); } to { opacity: 0; transform: translate(-50%, 8px); } }
@media (prefers-reduced-motion: no-preference) {
  .copy-toast--in { animation: copy-toast-in 120ms var(--ease-enter) both; }
  .copy-toast--out { animation: copy-toast-out 150ms var(--ease-enter) both; }
}

/* ---- 641-900: single column, arrows rotate to vertical (the paired
   vertical svg + pulse vector swap in) ---- */
@media (max-width: 900px) {
  .flow-chain, .flow-chain--two { grid-template-columns: minmax(0, 1fr); }
  .flow-link { flex-direction: row; justify-content: center; gap: var(--space-10); padding: var(--space-2) 0; }
  .flow-link-rail { width: 12px; height: 84px; }
  .flow-arr--h { display: none; }
  .flow-arr--v { display: block; }
  .flow-pulse { left: 3px; top: -3px; --flow-dx2: 0px; --flow-dy2: 74px; }
  .flow-split-row { flex-direction: column; justify-content: flex-start; gap: var(--space-20); }
  .flow-note { max-width: none; }
}

/* ---- <=640: the snowball vertical stack, tighter faces ---- */
@media (max-width: 640px) {
  .flow-node { padding: var(--space-14); }
  .flow-split-row { gap: var(--space-16); }
  .flow-top { justify-content: flex-start; }
  .flow-seal { padding: var(--space-6) var(--space-10); }
}

/* ============================================================
   BTN-MOTION (2026-09-08) — scoped reduced-motion pairing for the
   button register (docs/internal/BTN_MOTION_2026-09-08.md). The global
   page guard (animation/transition none) kills the tween; this
   re-nullifies the press/lift transforms themselves — EVERY new
   hover/press transform pairs to none. Placed at EOF, AFTER the
   chip/toggle sections it pairs (equal specificity, later source
   wins the cascade). The shadow swaps stay: they are instant paint,
   not motion. Selectors are byte-identical to the base hover/active
   rules they pair.
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  button.btn:hover:not(:disabled), button.btn:active:not(:disabled),
  button.btn-primary:hover:not(:disabled), button.btn-primary:active:not(:disabled),
  .cta-solid:hover:not(:disabled), .cta-solid:active:not(:disabled),
  .site-nav a.nav-cta:hover:not(:disabled), .site-nav a.nav-cta:active:not(:disabled),
  .fleet-filter:hover:not(:disabled), .fleet-filter:active:not(:disabled),
  .ft-copy:hover:not(:disabled), .ft-copy:active:not(:disabled),
  .ft-details:hover:not(:disabled), .ft-details:active:not(:disabled),
  .st-toggle-btn:hover:not(:disabled), .st-toggle-btn:active:not(:disabled),
  .theme-toggle:hover:not(:disabled), .theme-toggle:active:not(:disabled),
  .mwg-link:hover:not(:disabled), .mwg-link:active:not(:disabled),
  .mwg-copy:hover:not(:disabled), .mwg-copy:active:not(:disabled) {
    transform: none;
  }
}

/* ============================================================
   VAULT (2026-09-13) — WS-VAULT-DASHBOARD (#vault).
   The live RoamVault strip re-uses the .st-grid/.st-card figure cards and the
   governance tape re-uses the .ledger-row anatomy wholesale (its ≤640px
   stacking rules are genuinely inherited, not re-implemented). The only new
   rules are the tape container and the status-word register. Zero motion,
   zero new keyframe blocks (the motion budget is untouched), token-only, no
   new custom properties, 390px-first (the grid collapses to one column in
   the existing ≤640px block).
   ============================================================ */
.gov-tape { margin-top: var(--space-16); }
.gov-row { border-bottom: 1px dotted var(--line-dotted); } /* the .ledger-row's 2px solid reads table-like; the tape is a list — the dotted hairline the card rows speak */
.gov-status { font-family: var(--mono); font-weight: 700; font-size: var(--step-2); letter-spacing: var(--track-label); text-transform: uppercase; }
.gov-status--executed { color: var(--accent-text); } /* the .flag-ok pairing: success rides the one accent, never a second fill */
.gov-status--executable { color: var(--accent-text); } /* the window is open — the strongest truthful state on the tape */
.gov-status--queued { color: var(--ink); }
.gov-status--gone { color: var(--ink-soft); } /* no longer queued: executed or cancelled — muted until the replay says which */
.gov-status--unknown { color: var(--ink-soft); } /* a failed read renders unavailable, never a guess */
.gov-v-meta { display: block; margin-top: var(--space-2); font-family: var(--mono); font-weight: 400; font-size: var(--step-1); color: var(--ink-soft); word-break: break-all; } /* the date + truncated-id line — break-all so a full 32-byte id could never force h-scroll */
