/* ── Qgentic site — "letterpress" design system, dark + light ──────────────
   Two themes, one voice. Dark ("midnight"): warm cream ink on a lacquer-dark
   oxblood desk — the charcoal carries the wax red's own hue, the way a night
   palette carries a cast rather than reading as colourless grey — with
   lacquer-red seals, ember glow and paper grain over an engineering dot-grid.
   Light ("daylight"): crisp white sheets on warm porcelain, deeper lacquer
   red, same glass letterhead. Terminals stay dark in both themes — they are
   the evidence exhibits. Theme selection: OS preference by default
   (prefers-color-scheme), manual override via [data-theme] set by the nav
   toggle and persisted in localStorage.
   Every asset is same-origin: fonts are self-hosted, subset woff2 (assets/fonts/). */

/* ── self-hosted type ─────────────────────────────────────────────────── */
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 400; font-display: swap;
  src: url(fonts/downloaded-font-1.woff2) format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 500; font-display: swap;
  src: url(fonts/downloaded-font-2.woff2) format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 600; font-display: swap;
  src: url(fonts/downloaded-font-3.woff2) format('woff2');
}
@font-face {
  font-family: 'Inter'; font-style: normal; font-weight: 700; font-display: swap;
  src: url(fonts/downloaded-font-4.woff2) format('woff2');
}
@font-face {
  font-family: 'Outfit'; font-style: normal; font-weight: 500; font-display: swap;
  src: url(fonts/downloaded-font-5.woff2) format('woff2');
}
@font-face {
  font-family: 'Outfit'; font-style: normal; font-weight: 600; font-display: swap;
  src: url(fonts/downloaded-font-6.woff2) format('woff2');
}
@font-face {
  font-family: 'Outfit'; font-style: normal; font-weight: 700; font-display: swap;
  src: url(fonts/downloaded-font-7.woff2) format('woff2');
}
@font-face {
  font-family: 'Outfit'; font-style: normal; font-weight: 800; font-display: swap;
  src: url(fonts/downloaded-font-8.woff2) format('woff2');
}

@font-face {
  font-family: "IBM Plex Mono"; font-style: normal; font-weight: 400; font-display: swap;
  src: url("fonts/ibm-plex-mono-latin-400-normal.woff2") format("woff2");
}
@font-face {
  font-family: "IBM Plex Mono"; font-style: normal; font-weight: 600; font-display: swap;
  src: url("fonts/ibm-plex-mono-latin-600-normal.woff2") format("woff2");
}

/* ── tokens: dark (default) ───────────────────────────────────────────── */
:root {
  color-scheme: dark;
  /* the night desk — oxblood, not grey: same lightness as before (every
     contrast pair re-measured), the hue borrowed from the wax seal */
  --bg: #110b0e;
  --bg2: #150e12;
  --panel: #1a1117;
  --panel-sheen: linear-gradient(180deg, rgba(244, 239, 226, 0.045), rgba(244, 239, 226, 0.012) 38%, transparent);
  /* the duet, inside the glass: wax breathes in from one corner, verdict
     from the other. Peaks are capped so --sub copy stays ≥4.5:1 even at the
     corner (measured 4.84:1 on the green corner — the harsher of the two). */
  --duet:
    radial-gradient(130% 90% at 0% 0%, rgba(226, 84, 62, 0.055), transparent 52%),
    radial-gradient(130% 95% at 100% 100%, rgba(87, 227, 137, 0.05), transparent 52%);
  --line: rgba(233, 227, 213, 0.13);
  --line-soft: rgba(233, 227, 213, 0.07);
  --chip-bg: rgba(233, 227, 213, 0.04);
  --list-bg: rgba(233, 227, 213, 0.025);
  /* warm ink */
  --text: #c9c3b4;
  --head: #f4efe2;
  --sub: #8e887a;
  --nav-link: #f8fafc;
  --head-grad: linear-gradient(135deg, #ffffff 0%, #dcd4c3 100%);
  --head-glow: 0 0 70px rgba(244, 239, 226, 0.18);
  --q-glow: 0 0 34px rgba(226, 84, 62, 0.25);
  /* the stamps */
  --accent: #e2543e;
  --accent-hover: #ef6b52;
  /* accent used as small text; on dark sheets the accent itself clears AA */
  --accent-ink: #e2543e;
  --on-accent: #160906;
  --good: #57e389;
  --bad: #ef6b52;
  --warn: #e8b64a;
  --link: #ef8a72;
  /* surfaces & depth */
  --glass: rgba(24, 16, 20, 0.45);
  --glass-border: rgba(244, 239, 226, 0.1);
  --glass-fx: inset 0 1px 0 rgba(244, 239, 226, 0.12), inset 0 -1px 0 rgba(244, 239, 226, 0.04), 0 12px 32px rgba(0, 0, 0, 0.5);
  --ghost-border: rgba(244, 239, 226, 0.2);
  --ghost-bg: rgba(244, 239, 226, 0.04);
  --card-shadow: 0 1px 0 rgba(244, 239, 226, 0.07) inset, 0 14px 34px rgba(0, 0, 0, 0.35);
  --card-shadow-hover: 0 1px 0 rgba(244, 239, 226, 0.06) inset, 0 22px 44px rgba(0, 0, 0, 0.5), 0 0 0 1px color-mix(in srgb, var(--accent) 12%, transparent);
  --hl-shadow: 0 1px 0 rgba(244, 239, 226, 0.05) inset, 0 14px 40px rgba(0, 0, 0, 0.4), 0 0 30px color-mix(in srgb, var(--accent) 10%, transparent);
  --term-border: rgba(244, 239, 226, 0.1);
  --term-shadow: 0 1px 0 rgba(244, 239, 226, 0.06) inset, 0 26px 60px rgba(0, 0, 0, 0.55), 0 0 44px rgba(87, 227, 137, 0.05);
  /* the exhibits (constant across themes) */
  --term-bg: #0b0709;
  --term-text: #c3cdd6;
  /* the run record — a printed run, not a terminal (theme-aware) */
  --rec-bg: #120c10;
  --rec-sheen: linear-gradient(180deg, rgba(244, 239, 226, 0.05), rgba(244, 239, 226, 0.014) 40%, transparent);
  --rec-ink: #cbc5b5;
  /* dim ink still clears WCAG AA (5.4:1 on --rec-bg) — don't darken it further */
  --rec-dim: #8d8778;
  --rec-rule: rgba(244, 239, 226, 0.12);
  --rec-mast: rgba(244, 239, 226, 0.025);
  /* atmosphere — a red/green duet: the wax red leads (it is the brand), the
     verdict green answers from the opposite corner, neither shouts */
  --dot: rgba(233, 227, 213, 0.05);
  --glow-a: rgba(226, 84, 62, 0.16);
  --glow-b: rgba(87, 227, 137, 0.1);
  --glow-c: rgba(87, 227, 137, 0.07);
  --glow-d: rgba(226, 84, 62, 0.06);
  --grain: 0.05;
  --margin-line: linear-gradient(to bottom, transparent, rgba(226, 84, 62, 0.34) 12%, rgba(226, 84, 62, 0.34) 88%, transparent);
  --serif: "Outfit", "Iowan Old Style", Georgia, serif;
  --sans: "Inter", "Segoe UI", Helvetica, Arial, sans-serif;
  --mono: "IBM Plex Mono", ui-monospace, "Cascadia Code", Consolas, monospace;
}

/* ── tokens: light ("daylight letterpress") ───────────────────────────── */
/* Bright, not beige: white sheets on warm porcelain, deeper lacquer red,
   the same glass and glow language. Applied when the OS prefers light (and
   no manual override says otherwise), or when the visitor picks light. */
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) {
    color-scheme: light;
    --bg: #f9f6ef;
    --bg2: #f1ebdd;
    --panel: #fffdf8;
    --panel-sheen: linear-gradient(180deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.25) 38%, transparent);
    --duet:
      radial-gradient(130% 90% at 0% 0%, rgba(201, 64, 43, 0.045), transparent 52%),
      radial-gradient(130% 95% at 100% 100%, rgba(21, 114, 74, 0.04), transparent 52%);
    --line: rgba(29, 23, 16, 0.15);
    --line-soft: rgba(29, 23, 16, 0.08);
    --chip-bg: rgba(29, 23, 16, 0.045);
    --list-bg: rgba(29, 23, 16, 0.03);
    --text: #1c1813;
    --head: #000000;
    --sub: #3a3227;
    --nav-link: #16191c;
    --nav-line: rgba(29, 23, 16, 0.32);
    --head-grad: linear-gradient(135deg, #1e1710 0%, #4a4234 100%);
    --head-glow: none;
    --q-glow: none;
    --accent: #c9402b;
    --accent-hover: #a93521;
    /* #c9402b is only 4.3:1 on paper at label sizes — go a shade deeper for text */
    --accent-ink: #a93521;
    --on-accent: #fff7f2;
    --good: #15724a;
    --bad: #b23a24;
    --warn: #8a5f05;
    --link: #b8442e;
    --glass: rgba(253, 251, 245, 0.45);
    --glass-border: rgba(29, 23, 16, 0.12);
    --glass-fx: inset 0 1px 0 rgba(255, 255, 255, 0.75), 0 12px 32px rgba(29, 23, 16, 0.12);
    --ghost-border: rgba(29, 23, 16, 0.28);
    --ghost-bg: rgba(255, 255, 255, 0.55);
    --card-shadow: 0 1px 0 rgba(255, 255, 255, 0.85) inset, 0 12px 30px rgba(29, 23, 16, 0.08);
    --card-shadow-hover: 0 1px 0 rgba(255, 255, 255, 0.85) inset, 0 18px 40px rgba(29, 23, 16, 0.13), 0 0 0 1px color-mix(in srgb, var(--accent) 14%, transparent);
    --hl-shadow: 0 1px 0 rgba(255, 255, 255, 0.85) inset, 0 14px 36px rgba(29, 23, 16, 0.1), 0 0 30px color-mix(in srgb, var(--accent) 9%, transparent);
    --term-border: rgba(29, 23, 16, 0.25);
    --term-shadow: 0 22px 50px rgba(29, 23, 16, 0.24);
    --rec-bg: #fbf8f0;
    --rec-sheen: linear-gradient(180deg, rgba(29, 23, 16, 0.035), rgba(29, 23, 16, 0.008) 40%, transparent);
    --rec-ink: #3a3323;
    /* dim ink still clears WCAG AA (5.3:1 on --rec-bg) — don't lighten it further */
    --rec-dim: #6f6754;
    --rec-rule: rgba(29, 23, 16, 0.16);
    --rec-mast: rgba(29, 23, 16, 0.03);
    --dot: rgba(29, 23, 16, 0.07);
    --glow-a: rgba(201, 64, 43, 0.12);
    --glow-b: rgba(21, 114, 74, 0.1);
    --glow-c: rgba(21, 114, 74, 0.075);
    --glow-d: rgba(201, 64, 43, 0.05);
    --grain: 0.04;
    --margin-line: linear-gradient(to bottom, transparent, rgba(201, 64, 43, 0.5) 12%, rgba(201, 64, 43, 0.5) 88%, transparent);
  }
}
:root[data-theme="light"] {
  color-scheme: light;
  --bg: #f9f6ef;
  --bg2: #f1ebdd;
  --panel: #fffdf8;
  --panel-sheen: linear-gradient(180deg, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0.25) 38%, transparent);
  --duet:
    radial-gradient(130% 90% at 0% 0%, rgba(201, 64, 43, 0.045), transparent 52%),
    radial-gradient(130% 95% at 100% 100%, rgba(21, 114, 74, 0.04), transparent 52%);
  --line: rgba(29, 23, 16, 0.15);
  --line-soft: rgba(29, 23, 16, 0.08);
  --chip-bg: rgba(29, 23, 16, 0.045);
  --list-bg: rgba(29, 23, 16, 0.03);
  --text: #1c1813;
  --head: #000000;
  --sub: #3a3227;
  --nav-link: #16191c;
  --nav-line: rgba(29, 23, 16, 0.32);
  --head-grad: linear-gradient(135deg, #1e1710 0%, #4a4234 100%);
  --head-glow: none;
  --q-glow: none;
  --accent: #c9402b;
  --accent-hover: #a93521;
  /* #c9402b is only 4.3:1 on paper at label sizes — go a shade deeper for text */
  --accent-ink: #a93521;
  --on-accent: #fff7f2;
  --good: #15724a;
  --bad: #b23a24;
  --warn: #8a5f05;
  --link: #b8442e;
  --glass: rgba(253, 251, 245, 0.45);
  --glass-border: rgba(29, 23, 16, 0.12);
  --glass-fx: inset 0 1px 0 rgba(255, 255, 255, 0.75), 0 12px 32px rgba(29, 23, 16, 0.12);
  --ghost-border: rgba(29, 23, 16, 0.28);
  --ghost-bg: rgba(255, 255, 255, 0.55);
  --card-shadow: 0 1px 0 rgba(255, 255, 255, 0.85) inset, 0 12px 30px rgba(29, 23, 16, 0.08);
  --card-shadow-hover: 0 1px 0 rgba(255, 255, 255, 0.85) inset, 0 18px 40px rgba(29, 23, 16, 0.13), 0 0 0 1px color-mix(in srgb, var(--accent) 14%, transparent);
  --hl-shadow: 0 1px 0 rgba(255, 255, 255, 0.85) inset, 0 14px 36px rgba(29, 23, 16, 0.1), 0 0 30px color-mix(in srgb, var(--accent) 9%, transparent);
  --term-border: rgba(29, 23, 16, 0.25);
  --term-shadow: 0 22px 50px rgba(29, 23, 16, 0.24);
  --rec-bg: #fbf8f0;
  --rec-sheen: linear-gradient(180deg, rgba(29, 23, 16, 0.035), rgba(29, 23, 16, 0.008) 40%, transparent);
  --rec-ink: #3a3323;
  /* dim ink still clears WCAG AA (5.3:1 on --rec-bg) — don't lighten it further */
  --rec-dim: #6f6754;
  --rec-rule: rgba(29, 23, 16, 0.16);
  --rec-mast: rgba(29, 23, 16, 0.03);
  --dot: rgba(29, 23, 16, 0.07);
  --glow-a: rgba(201, 64, 43, 0.12);
  --glow-b: rgba(21, 114, 74, 0.1);
  --glow-c: rgba(21, 114, 74, 0.075);
  --glow-d: rgba(201, 64, 43, 0.05);
  --grain: 0.04;
  --margin-line: linear-gradient(to bottom, transparent, rgba(201, 64, 43, 0.5) 12%, rgba(201, 64, 43, 0.5) 88%, transparent);
}

* { box-sizing: border-box; margin: 0; }
/* The tilted status stamps (.pill, rotate(-2deg)) bleed a few px past the right
   gutter, and a rotated box still counts toward scrollable overflow — enough to
   put a 2-6px horizontal scrollbar on the page. Their position is set by the
   text they follow, so no margin can pull them back; clip the decorative bleed
   instead. Needed on BOTH: on <body> alone the value propagates to the viewport
   and leaves body itself visible; on <html> alone the overflow box survives.
   `clip`, not `hidden`: it creates no scroll container, so the sticky
   letterhead keeps sticking and in-page #anchors still scroll. */
/* scroll-padding: in-page anchors land clear of the floating letterhead */
html { scroll-behavior: smooth; scroll-padding-top: 6.5rem; overflow-x: clip; }
body {
  background-color: var(--bg);
  background-image:
    radial-gradient(var(--dot) 1px, transparent 1px),
    radial-gradient(60% 42% at 12% -4%, var(--glow-a), transparent 62%),
    radial-gradient(90% 75% at 94% 10%, var(--glow-b), transparent 72%),
    radial-gradient(52% 34% at 62% -6%, var(--glow-d), transparent 60%),
    radial-gradient(130% 90% at 55% 114%, var(--glow-c), transparent 70%);
  background-size: 26px 26px, 100% 100%, 100% 100%, 100% 100%, 100% 100%;
  background-attachment: fixed;
  overflow-x: clip; /* see the note on html above — both are required */
  color: var(--text);
  font-family: var(--sans);
  font-size: 16.5px; line-height: 1.64;
  transition: background-color 0.25s ease, color 0.25s ease;
}
@media (min-width: 1240px) {
  body::before {
    content: ""; position: fixed; top: 0; bottom: 0;
    left: max(2.2rem, calc(50% - 620px));
    width: 1px; background: var(--margin-line);
    pointer-events: none; z-index: 1;
  }
}
/* Paper tooth over the desk, never over the sheets: the grain sits at
   z-index 1, below every .wrap (z-index 2), so it textures the canvas and
   the section bands while the glass cards and the type stay smooth. It also
   dithers the big soft glows, which would otherwise band on cheap panels. */
body::after {
  content: ""; position: fixed; inset: 0; z-index: 1; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 180px 180px;
  opacity: var(--grain); mix-blend-mode: overlay;
}
::selection { background: var(--accent); color: var(--bg); }
a { color: var(--link); text-decoration: underline; text-decoration-color: color-mix(in srgb, var(--link) 40%, transparent); text-decoration-thickness: 1px; text-underline-offset: 3px; transition: color 0.15s ease, text-decoration-color 0.15s ease; }
a:hover { color: var(--accent-hover); text-decoration-color: currentColor; }
code, .mono { font-family: var(--mono); font-size: 0.9em; }
.wrap { max-width: 1080px; margin: 0 auto; padding: 0 1.5rem; position: relative; z-index: 2; }

/* ── page-load choreography ───────────────────────────────────────────── */
@keyframes rise { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes stamp { 0% { opacity: 0; transform: scale(1.7) rotate(-15deg); } 60% { opacity: 1; transform: scale(0.94) rotate(-3deg); } 100% { transform: scale(1) rotate(-2deg); } }
.hero > *, .product-head > * { animation: rise 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
.hero > *:nth-child(1), .product-head > *:nth-child(1) { animation-delay: 0.04s; }
.hero > *:nth-child(2), .product-head > *:nth-child(2) { animation-delay: 0.13s; }
.hero > *:nth-child(3), .product-head > *:nth-child(3) { animation-delay: 0.22s; }
.hero > *:nth-child(4), .product-head > *:nth-child(4) { animation-delay: 0.31s; }
.hero > *:nth-child(5), .product-head > *:nth-child(5) { animation-delay: 0.4s; }
.hero > *:nth-child(6), .product-head > *:nth-child(6) { animation-delay: 0.49s; }
.hero > *:nth-child(7), .product-head > *:nth-child(7) { animation-delay: 0.58s; }
@supports (animation-timeline: view()) {
  section .card, section ol.steps li, section .demo-panel {
    animation: rise 0.7s cubic-bezier(0.2, 0.7, 0.2, 1) both;
    animation-timeline: view();
    animation-range: entry 0% entry 34%;
  }
  .grid2 > .card:nth-child(2), ol.steps > li:nth-child(2) { animation-range: entry 5% entry 39%; }
  .grid3 > .card:nth-child(2) { animation-range: entry 5% entry 39%; }
  .grid3 > .card:nth-child(3), ol.steps > li:nth-child(3) { animation-range: entry 10% entry 44%; }
  .grid3 > .card:nth-child(4), ol.steps > li:nth-child(4) { animation-range: entry 15% entry 49%; }
  /* The homepage router runs two rows of three, so its stagger has to follow the
     column rather than the card index — on the index alone, row two would enter
     backwards (card 4 last, cards 5 and 6 already in). */
  .router > .card:nth-child(4) { animation-range: entry 0% entry 34%; }
  .router > .card:nth-child(5) { animation-range: entry 5% entry 39%; }
  .router > .card:nth-child(6) { animation-range: entry 10% entry 44%; }
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.001s !important; animation-delay: 0s !important; transition: none !important; }
  html { scroll-behavior: auto; }
}

/* Off-screen until focused, then it lands as a proper letterhead tab. */
.skip-link {
  position: absolute; left: 1rem; top: -4rem; z-index: 20;
  padding: 0.6rem 1rem; border-radius: 0 0 10px 10px;
  background: var(--accent); color: var(--on-accent);
  font-family: var(--mono); font-size: 0.75rem; font-weight: 600;
  letter-spacing: 0.1em; text-transform: uppercase; text-decoration: none;
  transition: top 0.15s ease;
}
.skip-link:focus { top: 0; color: var(--on-accent); }

/* ── header: the glass letterhead ─────────────────────────────────────── */
header.top { position: sticky; top: 1.2rem; z-index: 10; padding: 0 1rem; }
.top-inner {
  display: flex; align-items: center; gap: 1rem; flex-wrap: nowrap;
  max-width: 1080px; margin: 0 auto; padding: 0.65rem 1.4rem;
  background: var(--glass);
  backdrop-filter: blur(32px) saturate(180%);
  -webkit-backdrop-filter: blur(32px) saturate(180%);
  border: 1px solid var(--glass-border);
  border-radius: 20px;
  box-shadow: var(--glass-fx), 0 8px 32px rgba(0, 0, 0, 0.05);
  transition: border-color 0.4s ease, box-shadow 0.4s ease, background 0.4s ease;
}
.top-inner:hover {
  border-color: color-mix(in srgb, var(--accent) 40%, var(--glass-border));
  box-shadow: var(--glass-fx), 0 12px 48px color-mix(in srgb, var(--accent) 15%, transparent);
}
.brand-link { display: block; line-height: 0; }
.brand { height: 40px; width: auto; display: block; }
/* Two real wordmarks rather than one filtered one: invert()+hue-rotate() is a
   matrix approximation, and it pushed the wax red to #ff6548 and the ink to a
   flat #16191c. Swap the asset instead, exactly as .shot-dark/.shot-light do. */
.brand-light { display: none; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .brand-dark { display: none; }
  :root:not([data-theme="dark"]) .brand-light { display: block; }
}
:root[data-theme="light"] .brand-dark { display: none; }
:root[data-theme="light"] .brand-light { display: block; }
:root[data-theme="dark"] .brand-dark { display: block; }
:root[data-theme="dark"] .brand-light { display: none; }
/* Twelve links live here since UK AI joined (2026-08-06), and the shell is a
   fixed 1080px: the row's whole budget is ~840px, and at the old 0.62rem
   pads + 0.01em tracking twelve labels need ~880px — the nav quietly wrapped
   to a second line at EVERY desktop width, since the width available never
   changes between the 1151px hamburger point and a full screen. Tighter pads,
   gap and tracking buy the row back with ~35px to spare — enough to survive
   the ~2% cross-platform drift in rendered text width. A thirteenth link
   will NOT fit: retire one, or widen the shell, before adding it. */
nav.main { margin-left: auto; display: flex; gap: 0.1rem; flex-wrap: wrap; align-items: center; }
nav.main a {
  position: relative; color: var(--nav-link, var(--sub)); font-family: var(--serif); font-size: 0.95rem; font-weight: 500;
  letter-spacing: 0.005em; padding: 0.34rem 0.45rem; text-decoration: none; border-radius: 8px;
  transition: color 0.15s ease, background 0.15s ease;
}
nav.main a::after {
  content: ""; position: absolute; left: 0.45rem; right: 100%; bottom: 0.14rem; height: 1px;
  background: var(--accent); transition: right 0.22s cubic-bezier(0.2, 0.7, 0.2, 1);
}
nav.main a:hover { color: var(--nav-link, var(--head)); }
nav.main a:hover::after { right: 0.45rem; }
nav.main a.active { color: var(--nav-link, var(--head)); }
nav.main a.active::after { right: 0.45rem; }
nav.main a.cta {
  color: var(--on-accent); background: var(--accent); font-weight: 600; border-radius: 9px;
  padding: 0.44rem 0.9rem; box-shadow: 0 6px 18px color-mix(in srgb, var(--accent) 24%, transparent);
  transition: transform 0.14s ease, box-shadow 0.14s ease, background 0.14s ease;
}
nav.main a.cta::after { display: none; }
nav.main a.cta:hover { background: var(--accent-hover); transform: translateY(-1px); box-shadow: 0 9px 24px color-mix(in srgb, var(--accent) 34%, transparent); }
.nav-check, .nav-toggle { display: none; }
.theme-toggle {
  font-family: var(--mono); font-size: 0.9rem; line-height: 1;
  color: var(--nav-link, var(--sub)); background: transparent; border: 1px solid var(--nav-line, var(--line));
  border-radius: 8px; padding: 0.3rem 0.55rem; margin: 0; cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
/* Rotate only where a real pointer can actually hover. On a touch screen the
   :hover state latches after a tap, which left the button stuck at rotate(-12deg)
   until the user tapped elsewhere — gating it on (hover: hover) removes that. */
@media (hover: hover) {
  .theme-toggle:hover { color: var(--accent); border-color: var(--accent); transform: rotate(-12deg); }
}
/* Press feedback that works for both mouse and touch and always releases when
   the press ends, so the toggle can never appear frozen mid-animation. */
.theme-toggle:active { transform: scale(0.9); }

/* At the point the letterhead would wrap, turn the links into a compact
   correspondence-style menu. The brand and controls keep their familiar row;
   the full navigation is available without making either desktop or mobile cramped. */
/* 1150px, not 1080px: the eleven links stop fitting on one line at ~1115px,
   which left a band where the letterhead silently grew to two ragged rows and
   96px tall. Hand over to the menu before the row breaks, not after. */
@media (max-width: 1150px) {
  header.top { padding: 0 0.75rem; }
  .top-inner { position: relative; gap: 0.6rem; padding: 0.5rem 0.75rem; }
  .brand { height: 34px; }
  .theme-toggle { margin-left: auto; }
  .nav-check {
    display: block; position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
  }
  .nav-toggle {
    display: inline-flex; align-items: center; gap: 0.48rem; min-height: 2.1rem;
    padding: 0.3rem 0.58rem; color: var(--nav-link, var(--sub)); background: transparent;
    border: 1px solid var(--nav-line, var(--line)); border-radius: 8px; cursor: pointer;
    font-family: var(--mono); font-size: 0.67rem; font-weight: 600; letter-spacing: 0.11em;
    text-transform: uppercase; transition: color 0.15s ease, border-color 0.15s ease, background 0.15s ease;
  }
  .nav-toggle:hover, .nav-check:focus-visible + .nav-toggle {
    color: var(--accent); border-color: var(--accent); background: color-mix(in srgb, var(--accent) 8%, transparent);
  }
  .nav-toggle-icon {
    position: relative; width: 13px; height: 10px; border-top: 1px solid currentColor;
    border-bottom: 1px solid currentColor; transition: transform 0.18s ease;
  }
  .nav-toggle-icon::before {
    content: ""; position: absolute; top: 4px; left: 0; right: 0; border-top: 1px solid currentColor;
  }
  .nav-check:checked + .nav-toggle { color: var(--accent); border-color: var(--accent); }
  .nav-check:checked + .nav-toggle .nav-toggle-icon { transform: rotate(90deg); }
  nav.main {
    display: none; position: absolute; top: calc(100% + 0.55rem); right: 0; z-index: 1;
    width: min(23rem, calc(100vw - 1.5rem)); padding: 0.48rem; margin: 0;
    grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.12rem;
    background: color-mix(in srgb, var(--bg) 96%, transparent); backdrop-filter: blur(18px) saturate(155%);
    -webkit-backdrop-filter: blur(18px) saturate(155%); border: 1px solid var(--glass-border);
    border-radius: 12px; box-shadow: var(--glass-fx), 0 14px 30px rgba(0, 0, 0, 0.16);
  }
  .nav-check:checked ~ nav.main { display: grid; animation: nav-open 0.25s cubic-bezier(0.2, 0.7, 0.2, 1) both; }
  nav.main a { width: auto; padding: 0.62rem 0.72rem; font-size: 0.8rem; }
  nav.main a::after { left: 0.72rem; }
  nav.main a:hover::after, nav.main a.active::after { right: 0.72rem; }
  nav.main a.cta { grid-column: 1 / -1; margin-top: 0.2rem; padding: 0.62rem 0.72rem; text-align: center; }
}
@keyframes nav-open { from { opacity: 0; transform: translateY(-0.5rem) scale(0.97); } to { opacity: 1; transform: translateY(0) scale(1); } }

/* ── hero / headings ──────────────────────────────────────────────────── */
.hero { padding: 4.8rem 0 2.9rem; }
.eyebrow, .kicker {
  font-family: var(--mono); font-size: 0.73rem; letter-spacing: 0.24em;
  color: var(--accent-ink); text-transform: uppercase;
}
.eyebrow::before, .kicker::before { content: "§ "; color: var(--sub); }
/* A kicker normally labels an h2, whose own top margin opens the gap beneath
   it. Labelling a grid directly, there is no such margin and the line sits
   flush on the first card. The stand-off matches .section-lede's 1.7rem, which
   is what every other run of copy above a grid already uses. */
.kicker + .pricing, .kicker + .grid3, .kicker + .grid2,
.kicker + .cards, .kicker + ol.steps, .kicker + .table-scroll { margin-top: 1.7rem; }
/* on guides/index the kicker is the section's real heading; keep the div look */
h2.kicker { font-weight: 400; line-height: 1.64; margin: 0; }
h1 {
  color: var(--head); font-family: var(--serif); font-weight: 800;
  font-size: clamp(2.45rem, 5.9vw, 4.35rem); line-height: 1.03;
  letter-spacing: -0.014em; margin: 1rem 0 0.9rem; max-width: 22ch;
  text-shadow: var(--head-glow);
  background: var(--head-grad, var(--head));
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  /* background-clip:text paints only inside the box; with line-height 1.03 the
     last line's descenders (p, q, the italic .q) fall below it and vanish.
     A little bottom padding extends the painted box so they render in full. */
  padding-bottom: 0.14em;
}
h1 .q {
  color: var(--accent); font-style: italic; font-weight: 500; text-shadow: var(--q-glow);
  -webkit-text-fill-color: var(--accent); background: none;
}
/* ── the wordmark, set inside a headline ────────────────────────────────
   At h1 scale the brand is the mark, never the name typed in the heading
   face. The sizing is derived from the asset's own geometry (viewBox
   500x150): the logotype's cap height is 59.3 units, so height:1.77em puts
   it on the heading's cap height; its baseline is 39.3% up from the bottom
   edge, hence the -0.7em drop onto the text baseline; and the mark starts at
   x=75 with the logotype ending at x=425, so there is ~0.89em of empty canvas
   either side. The margins pull back most but deliberately not all of it —
   the mark keeps clear space around it rather than being crowded by the
   sentence. Re-export the SVG and these need recomputing.
   The theme swap repeats the letterhead's because .brand-dark/.brand-light
   reveal as display:block, which would break the line. */
/* No max-width: capping the width while the height is fixed would squash the
   mark, and a distorted logo is a worse failure than a clipped one. */
.brand-word { display: inline-block; height: 1.77em; width: auto; vertical-align: -0.7em; margin: 0 -0.72em 0 -0.6em; }
.brand-word--light { display: none; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .brand-word--dark { display: none; }
  :root:not([data-theme="dark"]) .brand-word--light { display: inline-block; }
}
:root[data-theme="light"] .brand-word--dark { display: none; }
:root[data-theme="light"] .brand-word--light { display: inline-block; }
:root[data-theme="dark"] .brand-word--dark { display: inline-block; }
:root[data-theme="dark"] .brand-word--light { display: none; }
.lede { font-size: 1.14rem; color: var(--text); max-width: 60ch; }
.lede strong { color: var(--head); font-weight: 700; }
.cta-row { display: flex; gap: 0.85rem; margin: 1.9rem 0 0.85rem; flex-wrap: wrap; }
.btn {
  display: inline-block; padding: 0.74rem 1.45rem; font-weight: 700; font-size: 0.95rem;
  font-family: var(--sans); text-decoration: none; border: 1px solid transparent;
  border-radius: 10px; cursor: pointer;
  transition: transform 0.14s ease, box-shadow 0.14s ease, background 0.14s ease, border-color 0.14s ease;
}
@keyframes btn-sweep { 0% { left: -100%; opacity: 0; } 30% { opacity: 1; } 100% { left: 200%; opacity: 0; } }
@keyframes btn-pulse { 0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 40%, transparent); } 70% { box-shadow: 0 0 0 10px color-mix(in srgb, var(--accent) 0%, transparent); } 100% { box-shadow: 0 0 0 0 transparent; } }
.btn.primary { background: var(--accent); color: var(--on-accent); box-shadow: 0 8px 26px color-mix(in srgb, var(--accent) 22%, transparent); position: relative; overflow: hidden; animation: btn-pulse 3s infinite cubic-bezier(0.2, 0.7, 0.2, 1); }
.btn.primary::after { content: ""; position: absolute; top: 0; left: -100%; width: 50%; height: 100%; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.35), transparent); transform: skewX(-20deg); transition: none; opacity: 0; }
.btn.primary:hover { background: var(--accent-hover); transform: translateY(-3px); box-shadow: 0 14px 40px color-mix(in srgb, var(--accent) 36%, transparent); animation: none; }
.btn.primary:hover::after { animation: btn-sweep 1.2s ease-out; }
.btn.ghost {
  border-color: var(--ghost-border); color: var(--head);
  background: var(--ghost-bg); backdrop-filter: blur(6px);
}
.btn.ghost:hover { border-color: var(--accent); color: var(--accent-hover); transform: translateY(-2px); box-shadow: 0 10px 26px rgba(0, 0, 0, 0.18); }
/* The ring is a box-shadow, which Windows High Contrast / forced-colors mode
   discards entirely — the transparent outline is what survives there, and it
   is repainted as a real outline by the OS. */
.btn:focus-visible, a:focus-visible, button:focus-visible {
  outline: 2px solid transparent; outline-offset: 2px;
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 30%, transparent);
}
.under-cta { color: var(--sub); font-size: 0.86rem; }

/* ── hero proof strip: the ledger line ────────────────────────────────────
   A ruled row of stamped figures under the hero CTAs. Every figure restates
   a claim the page already makes — nothing here is new copy, it is the
   ledger's own footline promoted to the masthead. */
.hero-facts { display: flex; flex-wrap: wrap; gap: 0.8rem 2.2rem; margin-top: 2.2rem; padding-top: 1.2rem; border-top: 1px solid var(--line-soft); }
.hero-facts .fact { border-left: 1px solid var(--line-soft); padding-left: 1.1rem; }
.hero-facts .fact:first-child { border-left: none; padding-left: 0; }
.hero-facts .fact b {
  display: block; font-family: var(--mono); font-weight: 600; font-size: 1.04rem;
  color: var(--accent-ink); letter-spacing: 0.02em;
}
.hero-facts .fact span {
  font-family: var(--mono); font-size: 0.64rem; letter-spacing: 0.15em;
  text-transform: uppercase; color: var(--sub);
}
@media (max-width: 640px) {
  .hero-facts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.9rem 1.2rem; }
  .hero-facts .fact { border-left: none; padding-left: 0; }
}

section { padding: 3.9rem 0 0.5rem; }
h2 {
  color: var(--head); font-family: var(--serif); font-weight: 600;
  font-size: clamp(1.55rem, 2.9vw, 2rem); line-height: 1.14; margin: 0.55rem 0 0.8rem;
}
h3 { color: var(--head); }
.section-lede { color: var(--sub); max-width: 64ch; margin-bottom: 1.7rem; }

/* ── cards: sheets under lamplight ────────────────────────────────────── */
.grid2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr)); gap: 1.3rem; }
.grid3 { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); gap: 1.3rem; }
.card {
  position: relative; overflow: hidden; background: var(--glass); background-image: var(--panel-sheen), var(--duet);
  backdrop-filter: blur(24px) saturate(160%);
  -webkit-backdrop-filter: blur(24px) saturate(160%);
  border: 1px solid var(--glass-border); border-radius: 16px; padding: 1.75rem 1.7rem 2rem;
  box-shadow: var(--glass-fx), var(--card-shadow);
  transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.2, 1), box-shadow 0.3s ease, border-color 0.3s ease;
}
.card::before {
  content: ""; position: absolute; top: 0; left: 0; right: 0; bottom: 0;
  background: radial-gradient(800px circle at var(--mouse-x, -9999px) var(--mouse-y, -9999px), rgba(255, 255, 255, 0.07), transparent 40%);
  pointer-events: none; z-index: 1; opacity: 0; transition: opacity 0.4s ease;
}
.card:hover::before { opacity: 1; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .card::before { background: radial-gradient(800px circle at var(--mouse-x, -9999px) var(--mouse-y, -9999px), rgba(29, 23, 16, 0.04), transparent 40%); }
}
:root[data-theme="light"] .card::before { background: radial-gradient(800px circle at var(--mouse-x, -9999px) var(--mouse-y, -9999px), rgba(29, 23, 16, 0.04), transparent 40%); }

.card:hover {
  transform: translateY(-4px) scale(1.005); border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  box-shadow: var(--card-shadow-hover);
}
.card h3 { font-family: var(--serif); font-weight: 600; font-size: 1.13rem; margin-bottom: 0.5rem; }
.card p { color: var(--sub); font-size: 0.93rem; }
.card .tag {
  display: inline-block; font-family: var(--mono); font-size: 0.65rem; letter-spacing: 0.1em;
  text-transform: uppercase; padding: 0.16rem 0.6rem; border: 1px solid var(--line);
  border-radius: 999px; color: var(--sub); margin-bottom: 0.8rem; background: var(--chip-bg);
}
/* A marked card, not a hovered one. Two earlier attempts both shouted: a 55%
   accent border (louder than the 45% .card:hover paints, so hover said
   nothing), then a 3px red left rule — which on a grid marking three cards of
   three read as decoration rather than emphasis. Emphasis now rides the warmth
   already in --hl-shadow, plus a border tint kept well under :hover's 45% so
   the pointer still changes something. */
.card.hl {
  border-color: color-mix(in srgb, var(--accent) 22%, var(--glass-border));
  box-shadow: var(--hl-shadow);
}
.mono-line {
  font-family: var(--mono); font-size: 0.76rem; color: var(--rec-dim); background: var(--rec-bg);
  border: 1px solid var(--rec-rule); border-radius: 8px; padding: 0.48rem 0.75rem;
  margin-top: 0.8rem; overflow-x: auto; white-space: nowrap;
}

/* ── the split table: a ruled ledger ─────────────────────────────────── */
table.split {
  width: 100%; border-collapse: collapse; background: var(--panel); background-image: var(--panel-sheen);
  border: 1px solid var(--line); border-radius: 14px; overflow: hidden;
  box-shadow: var(--card-shadow);
}
table.split th {
  font-family: var(--mono); font-size: 0.71rem; text-transform: uppercase; letter-spacing: 0.12em;
  padding: 1rem 1.25rem; text-align: left; border-bottom: 3px double var(--line);
}
table.split th.code-side { color: var(--good); } table.split th.llm-side { color: var(--accent); }
table.split tr { transition: background 0.15s ease; }
table.split tr:not(:first-child):hover { background: var(--list-bg); }
table.split td { padding: 0.8rem 1.25rem; font-size: 0.92rem; color: var(--text); border-bottom: 1px solid var(--line-soft); vertical-align: top; }
table.split tr:last-child td { border-bottom: none; }
table.split td + td { border-left: 1px dashed var(--line-soft); }
.split-note { color: var(--sub); font-size: 0.88rem; margin-top: 0.9rem; max-width: 66ch; }
/* Copy set below a grid has to clear the cards' drop shadow, which reaches
   roughly 30px past their bottom edge. At the 0.9rem a note carries after
   plain text, the line sat inside that shadow and read as part of it — so the
   stand-off is stated once here, for every kind of box and every kind of copy
   that can follow one, rather than per page. */
:is(.card, .grid2, .grid3, .cards, .pricing, ol.steps, table.split, .table-scroll, .demo-panel)
  + :is(p, .split-note, .cta-row, .mono-line, .under-cta, ul, ol) { margin-top: 2rem; }
/* A kicker opens the next block, so it stands off a little further. */
:is(.card, .grid2, .grid3, .cards, .pricing, ol.steps, table.split, .table-scroll, .demo-panel)
  + .kicker { margin-top: 2.5rem; }
.table-scroll { overflow-x: auto; }

/* ── deadlines table: the console's compliance calendar, in miniature ──── */
table.deadlines { width: 100%; border-collapse: collapse; margin-top: 0.9rem; }
table.deadlines th {
  font-family: var(--mono); font-size: 0.68rem; text-transform: uppercase; letter-spacing: 0.1em;
  color: var(--sub); text-align: left; padding: 0.45rem 0.9rem 0.45rem 0; border-bottom: 3px double var(--line);
}
table.deadlines td { padding: 0.62rem 0.9rem 0.62rem 0; font-size: 0.92rem; color: var(--text); border-bottom: 1px solid var(--line-soft); vertical-align: middle; }
table.deadlines tr:last-child td { border-bottom: none; }
table.deadlines td.mono { font-family: var(--mono); font-size: 0.84rem; color: var(--head); white-space: nowrap; }

/* ── product notes: dated ledger entries ────────────────────────────────── */
.note-entry { border-left: 3px double var(--line); padding: 0.2rem 0 0.4rem 1.3rem; margin: 2rem 0; }
.note-entry .note-date { font-family: var(--mono); font-size: 0.74rem; letter-spacing: 0.08em; text-transform: uppercase; color: var(--sub); }
/* changelog entries are h2 (siblings under the page h1), styled as before */
.note-entry h2 { font-family: var(--sans); font-weight: 700; font-size: 1.17em; line-height: 1.64; margin: 0.35rem 0 0.5rem; }
.note-entry p { color: var(--text); max-width: 72ch; }

/* ── numbered steps: clauses ──────────────────────────────────────────── */
ol.steps { counter-reset: s; list-style: none; display: grid; grid-template-columns: repeat(auto-fit, minmax(min(230px, 100%), 1fr)); gap: 1.3rem; padding: 0; }
ol.steps li {
  counter-increment: s; background: var(--panel); background-image: var(--panel-sheen);
  border: 1px solid var(--line); border-radius: 14px; padding: 1.4rem 1.5rem;
  box-shadow: var(--card-shadow);
  transition: transform 0.3s cubic-bezier(0.2, 0.7, 0.2, 1), box-shadow 0.3s ease, border-color 0.3s ease;
}
ol.steps li:hover { transform: translateY(-4px) scale(1.005); border-color: color-mix(in srgb, var(--accent) 35%, transparent); box-shadow: var(--card-shadow-hover); }
ol.steps li::before {
  content: counter(s, decimal-leading-zero) "."; font-family: var(--mono); font-weight: 600;
  color: var(--accent-ink); font-size: 0.82rem; display: block; margin-bottom: 0.5rem;
  border-bottom: 1px solid var(--line-soft); padding-bottom: 0.4rem;
}
ol.steps b { color: var(--head); font-family: var(--serif); font-weight: 600; font-size: 1.05rem; display: block; margin-bottom: 0.3rem; }
ol.steps span { color: var(--sub); font-size: 0.89rem; }

/* ── mechanism diagrams: the pipeline, drawn ──────────────────────────── */
/* Inline SVG rather than an image, so the figures read the page's own tokens
   and follow the theme toggle with no second asset to keep in step — and so
   the labels are real text for a screen reader and for search.
   The figures are wide by nature (four zones of dense mono labelling). The
   scroller is the same escape hatch the wide tables use: on a phone the
   diagram scrolls at full size rather than shrinking 11px labels into
   illegibility. */
.diagram { margin: 2.1rem 0 0; }
.diagram-scroll { overflow-x: auto; padding-bottom: 0.2rem; }
/* The min-width is the legibility floor, not a guess: the smallest label in
   these figures is 11px in a 1080 viewBox, so below ~980px of render width it
   drops under 10px and the diagram stops being readable. Scroll instead. */
.diagram svg { display: block; width: 100%; min-width: 980px; height: auto; }
.diagram figcaption { color: var(--sub); font-size: 0.88rem; line-height: 1.62; margin-top: 1rem; max-width: 72ch; }

/* Surfaces. `dg-key` is the wax-red one and is spent only on the deterministic
   gate and the named approval — the two places the product actually stakes a
   claim. Everything else is ledger-neutral. */
.dg-panel { fill: var(--panel); stroke: var(--line); stroke-width: 1; }
.dg-panel-soft { fill: var(--list-bg); stroke: var(--line-soft); stroke-width: 1; }
.dg-panel-key {
  fill: color-mix(in srgb, var(--accent) 5%, var(--panel));
  stroke: color-mix(in srgb, var(--accent) 38%, transparent); stroke-width: 1;
}
/* The air-gap boundary: drawn, not filled — the point is that it is a line
   nothing crosses, so it reads as a perimeter rather than another panel. */
.dg-bound {
  fill: none; stroke: color-mix(in srgb, var(--accent) 42%, transparent);
  stroke-width: 1.5; stroke-dasharray: 7 5;
}
.dg-rule { stroke: var(--line-soft); stroke-width: 1; }
.dg-rule-key { stroke: color-mix(in srgb, var(--accent) 32%, transparent); stroke-width: 1; }
.dg-flow { stroke: var(--sub); stroke-width: 1.4; fill: none; }
.dg-arrow { fill: var(--sub); }

/* Type. Detail lines take --text, not --sub: at 11px they are the substance of
   the diagram, and --sub is only just over the contrast floor. */
.dg-band { fill: var(--accent-ink); font-family: var(--mono); font-size: 11px; letter-spacing: 0.17em; }
.dg-h { fill: var(--head); font-family: var(--serif); font-weight: 600; font-size: 15px; }
.dg-t { fill: var(--text); font-family: var(--sans); font-size: 12.5px; }
.dg-m { fill: var(--text); font-family: var(--mono); font-size: 11px; }
.dg-s { fill: var(--sub); font-family: var(--mono); font-size: 11px; }
.dg-key { fill: var(--accent-ink); font-family: var(--mono); font-size: 11px; letter-spacing: 0.06em; }
.dg-ok { fill: var(--good); font-family: var(--mono); font-size: 11px; }

/* ── status stamps ────────────────────────────────────────────────────── */
.pill {
  display: inline-block; font-family: var(--mono); font-weight: 600; font-size: 0.6rem;
  letter-spacing: 0.16em; text-transform: uppercase; padding: 0.2rem 0.62rem;
  border: 2px solid; border-radius: 3px; vertical-align: 0.3em; margin-left: 0.35rem;
  transform: rotate(-2deg); animation: stamp 0.55s cubic-bezier(0.2, 0.7, 0.3, 1.2) 0.6s both;
}
.pill.ga { color: var(--good); border-color: color-mix(in srgb, var(--good) 75%, transparent); background: color-mix(in srgb, var(--good) 8%, transparent); box-shadow: 0 0 18px color-mix(in srgb, var(--good) 14%, transparent); }
.pill.preview { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 70%, transparent); background: color-mix(in srgb, var(--warn) 7%, transparent); box-shadow: 0 0 18px color-mix(in srgb, var(--warn) 10%, transparent); }

/* ── run records: the exhibits (a printed run, not a terminal) ────────── */
.terminal {
  margin: 2.7rem 0 0; background: var(--rec-bg); background-image: var(--rec-sheen);
  border-radius: 4px; overflow: hidden;
  border: 1px solid var(--term-border);
  box-shadow: var(--term-shadow);
}
.term-bar {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem 0.62rem; padding: 0.6rem 1.05rem;
  border-bottom: 1px solid var(--rec-rule);
  background: var(--rec-mast);
}
/* the wax seal, in place of the borrowed macOS traffic-lights */
.rec-seal {
  width: 12px; height: 12px; border-radius: 50%; flex: none;
  background: radial-gradient(circle at 38% 34%, color-mix(in srgb, var(--accent) 72%, #fff 28%), var(--accent) 62%);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 15%, transparent), inset 0 1px 1px rgba(255, 255, 255, 0.35);
}
.rec-label {
  font-family: var(--mono); font-weight: 600; font-size: 0.62rem; letter-spacing: 0.2em;
  text-transform: uppercase; color: var(--accent-ink); white-space: nowrap;
}
.term-title { color: var(--rec-dim); font-family: var(--mono); font-size: 0.74rem; letter-spacing: 0.02em; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 560px) { .term-title { display: none; } }
/* a stamped provenance mark, letterpress-tilted like the status pills */
.rec-stamp {
  margin-left: auto; font-family: var(--mono); font-weight: 600; font-size: 0.58rem;
  letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent-ink);
  border: 1.5px solid color-mix(in srgb, var(--accent) 55%, transparent); border-radius: 3px;
  padding: 0.16rem 0.5rem; transform: rotate(-2.5deg);
}
.term-actions { margin-left: auto; display: flex; gap: 0.5rem; }
.term-actions button {
  font-family: var(--mono); font-size: 0.72rem; color: var(--rec-ink); white-space: nowrap;
  background: color-mix(in srgb, var(--accent) 6%, transparent);
  border: 1px solid var(--rec-rule); border-radius: 5px; padding: 0.26rem 0.72rem; cursor: pointer;
  transition: border-color 0.14s ease, color 0.14s ease, background 0.14s ease;
}
.term-actions button:hover { border-color: color-mix(in srgb, var(--accent) 60%, transparent); color: var(--accent); background: color-mix(in srgb, var(--accent) 10%, transparent); }
.terminal pre {
  padding: 1.25rem 1.4rem; font-family: var(--mono); font-size: 0.82rem; line-height: 1.66;
  overflow-x: auto; color: var(--rec-ink); min-height: 3em; margin: 0;
}
/* the record's footline — a document footer, not a shell prompt */
.rec-foot {
  display: flex; align-items: center; gap: 0.55rem; flex-wrap: wrap;
  padding: 0.6rem 1.05rem; border-top: 1px solid var(--rec-rule);
  background: var(--rec-mast);
  font-family: var(--mono); font-size: 0.68rem; letter-spacing: 0.02em; color: var(--rec-dim);
}
.rec-foot .rec-seal { width: 9px; height: 9px; box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 14%, transparent); }
.t-dim { color: var(--rec-dim); } .t-ok { color: var(--good); } .t-warn { color: var(--warn); } .t-bad { color: var(--bad); } .t-acc { color: var(--accent); }
.t-verdict { color: var(--good); font-weight: 600; }

/* ── product screenshots: the console (the real UI a team works in) ───── */
.shot { margin: 2.6rem 0 0; }
.shot .eyebrow { margin-bottom: 0.75rem; }
.shot-frame {
  border-radius: 12px; overflow: hidden;
  border: 1px solid var(--term-border); box-shadow: var(--term-shadow);
  background: #120c10;
}
.shot-frame img { width: 100%; height: auto; }
/* Show the console screenshot that matches the active theme (dark default). The
   selectors mirror the site's own token logic so the swap follows both the OS
   preference and the manual theme toggle. Scoped under .shot-frame so they beat
   the `.shot-frame img` base rule on specificity. */
.shot-frame .shot-dark { display: block; }
.shot-frame .shot-light { display: none; }
@media (prefers-color-scheme: light) {
  :root:not([data-theme="dark"]) .shot-frame .shot-dark { display: none; }
  :root:not([data-theme="dark"]) .shot-frame .shot-light { display: block; }
}
:root[data-theme="light"] .shot-frame .shot-dark { display: none; }
:root[data-theme="light"] .shot-frame .shot-light { display: block; }
:root[data-theme="dark"] .shot-frame .shot-dark { display: block; }
:root[data-theme="dark"] .shot-frame .shot-light { display: none; }
.shot figcaption { color: var(--sub); font-size: 0.92rem; line-height: 1.62; margin-top: 0.9rem; max-width: 70ch; }

/* ── interactive demo panels ─────────────────────────────────────────── */
.demo-panel {
  background: var(--glass); background-image: var(--panel-sheen), var(--duet);
  backdrop-filter: blur(24px) saturate(160%);
  -webkit-backdrop-filter: blur(24px) saturate(160%);
  border: 1px solid var(--glass-border); border-radius: 16px; padding: 1.4rem 1.5rem;
  box-shadow: var(--glass-fx), var(--card-shadow);
}
/* h2 on contact.html (panels are top-level page sections there), h3 on the demo
   pages (panels sit under a section h2). Same look either way. */
.demo-panel h2, .demo-panel h3 { font-family: var(--serif); font-weight: 600; font-size: 1.13rem; line-height: 1.64; margin: 0 0 0.35rem; }
.demo-panel .hint { color: var(--sub); font-size: 0.85rem; margin-bottom: 0.95rem; }
.field { margin-bottom: 0.85rem; }
.field label {
  display: block; font-family: var(--mono); font-size: 0.67rem; text-transform: uppercase;
  letter-spacing: 0.12em; color: var(--sub); margin-bottom: 0.32rem;
}
.field input, .field select, .field textarea {
  width: 100%; background: var(--rec-bg); color: var(--rec-ink); border: 1px solid var(--line);
  border-radius: 8px; padding: 0.58rem 0.82rem; font-family: var(--mono); font-size: 0.92rem;
  transition: border-color 0.14s ease, box-shadow 0.14s ease;
}
.field textarea { min-height: 8.5rem; resize: vertical; line-height: 1.55; }
.field input::placeholder, .field textarea::placeholder { color: var(--rec-dim); }
.field input:focus, .field select:focus, .field textarea:focus { outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 14%, transparent); }
.field-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.field-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(140px, 100%), 1fr)); gap: 0.7rem; }
.verdict-line {
  font-family: var(--mono); font-size: 0.84rem; font-weight: 600; border: 1px solid;
  border-radius: 8px; padding: 0.62rem 0.9rem; margin-top: 0.75rem; background: var(--rec-bg);
}
.verdict-line.ok { color: var(--good); border-color: color-mix(in srgb, var(--good) 45%, transparent); }
.verdict-line.fail { color: var(--bad); border-color: color-mix(in srgb, var(--bad) 48%, transparent); }
.verdict-line.warn { color: var(--warn); border-color: color-mix(in srgb, var(--warn) 45%, transparent); }
ul.rule-list { list-style: none; padding: 0; margin: 0.7rem 0 0; }
ul.rule-list li {
  font-family: var(--mono); font-size: 0.77rem; padding: 0.4rem 0.68rem;
  border-left: 3px solid var(--line); margin-bottom: 0.32rem; color: var(--sub);
  background: var(--list-bg); border-radius: 0 6px 6px 0;
}
ul.rule-list li.err { color: var(--bad); border-left-color: var(--bad); background: color-mix(in srgb, var(--bad) 6%, transparent); }
ul.rule-list li.warn { color: var(--warn); border-left-color: var(--warn); background: color-mix(in srgb, var(--warn) 5%, transparent); }
ul.rule-list li.ok { color: var(--good); border-left-color: var(--good); background: color-mix(in srgb, var(--good) 5%, transparent); }

/* ── pricing ──────────────────────────────────────────────────────────── */
.pricing { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr)); gap: 1.1rem; }
.price { font-size: 1.6rem; line-height: 1.2; color: var(--head); font-family: var(--serif); font-weight: 600; margin: 0.45rem 0 0.5rem; }
/* The qualifier sets its own leading and takes its own line. Inline, it
   inherited the body's 1.64 line-height at the price's 1.6rem size, so a
   qualifier long enough to wrap — "up to 50 VRNs, then £12/VRN" ran to eight
   lines — spaced itself like paragraphs inside the number. */
.price small {
  display: block; font-size: 0.76rem; line-height: 1.5; margin-top: 0.3rem;
  color: var(--sub); font-family: var(--mono); font-weight: 400;
}

/* ── honesty strip: the marginal note ─────────────────────────────────── */
.honesty {
  margin: 4.6rem 0 0; padding: 3.2rem 0; position: relative;
  background:
    radial-gradient(50% 90% at 50% 0%, color-mix(in srgb, var(--accent) 4%, transparent), transparent 70%),
    var(--bg2);
  border-top: 1px solid var(--line-soft); border-bottom: 1px solid var(--line-soft);
}
.honesty p {
  max-width: 62ch; color: var(--head); font-family: var(--serif); font-style: italic;
  font-weight: 500; font-size: 1.3rem; line-height: 1.52;
}
.honesty p b { font-style: normal; font-weight: 800; color: var(--accent); }
.honesty a { color: var(--accent-hover); }

/* ── footer ───────────────────────────────────────────────────────────── */
footer { padding: 2.6rem 0 3.4rem; color: var(--sub); font-size: 0.95rem; font-family: var(--serif); }
footer .cols { display: flex; gap: 3rem; flex-wrap: wrap; margin-bottom: 1.7rem; }
/* Column headings are h2, not h4: they are the footer landmark's own sections,
   and h4 after the page h1/h2 skipped a level on every page. Styling unchanged. */
footer .col-head {
  color: var(--head); font-family: var(--mono); font-size: 0.68rem; font-weight: 600;
  text-transform: uppercase; letter-spacing: 0.16em;
  /* reset the global h2 box so these render exactly as the old h4 did */
  line-height: inherit; margin: 0 0 0.6rem;
}
footer ul { list-style: none; padding: 0; }
footer li { margin: 0.3rem 0; }
footer a { color: var(--sub); text-decoration: none; transition: color 0.15s ease; }
footer a:hover { color: var(--accent-hover); }

/* Trust badge */
.trust-badge { transition: opacity 0.15s ease, transform 0.15s ease; cursor: default; }
.trust-badge:hover { opacity: 1 !important; transform: translateY(-1px); }

/* ── regime coverage explainer (index) ───────────────────────────────── */
.regime { padding-top: 1.9rem; margin-top: 1.9rem; border-top: 1px solid var(--line-soft); }
.regime:first-of-type { border-top: none; padding-top: 0.4rem; margin-top: 0; }
.regime-head { display: flex; align-items: center; gap: 0.7rem; flex-wrap: wrap; margin-bottom: 0.55rem; }
.regime-head .num { font-family: var(--mono); font-size: 0.7rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent); }
.regime-head h3 { font-family: var(--serif); font-weight: 600; font-size: 1.32rem; color: var(--head); margin: 0; }
.regime-lede { color: var(--sub); font-size: 0.96rem; max-width: 72ch; margin-bottom: 1.05rem; }
.regime-lede strong { color: var(--head); }
.coverage { display: grid; grid-template-columns: repeat(var(--n, 5), minmax(0, 1fr)); gap: 0.55rem; }
.seg {
  border: 1px solid var(--line); border-radius: 10px; padding: 0.85rem 0.9rem;
  background: var(--panel); background-image: var(--panel-sheen);
  display: flex; flex-direction: column; gap: 0.32rem; min-height: 6.6rem;
}
.seg .n { font-family: var(--mono); font-size: 0.61rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--sub); }
.seg .label { font-size: 0.85rem; color: var(--text); line-height: 1.32; }
.seg.dim { opacity: 0.85; }
.seg.covered { border-color: color-mix(in srgb, var(--accent) 60%, transparent); background-image: linear-gradient(180deg, color-mix(in srgb, var(--accent) 8%, transparent), transparent 72%); }
.seg .who { margin-top: auto; font-family: var(--mono); font-size: 0.65rem; letter-spacing: 0.03em; color: var(--sub); }
.seg.covered .who { color: var(--good); font-weight: 600; }
.regime-foot { margin-top: 0.9rem; font-size: 0.9rem; color: var(--sub); }
@media (max-width: 760px) { .coverage { grid-template-columns: repeat(2, minmax(0, 1fr)); } .seg { min-height: 0; } }
@media (max-width: 430px) { .coverage { grid-template-columns: 1fr; } }

/* company direction — roadmap strip */
.roadmap { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-top: 0.4rem; }
.roadmap .stop {
  font-family: var(--mono); font-size: 0.74rem; color: var(--text);
  border: 1px solid var(--line); border-radius: 999px; padding: 0.3rem 0.8rem; background: var(--chip-bg);
}
.roadmap .stop.now { border-color: color-mix(in srgb, var(--good) 55%, transparent); color: var(--head); }
.roadmap .stop.next { border-style: dashed; color: var(--sub); }
.roadmap .stop b { color: var(--accent); font-weight: 600; }

/* reveal-on-scroll — hidden only when the .js flag confirms scripting */
.js .reveal { opacity: 0; transform: translateY(22px); transition: opacity 0.6s ease, transform 0.6s cubic-bezier(0.2, 0.7, 0.2, 1); }
.js .reveal.in { opacity: 1; transform: none; }
.js .reveal .seg { opacity: 0; transform: translateY(12px); transition: opacity 0.5s ease, transform 0.5s cubic-bezier(0.2, 0.7, 0.2, 1); }
.js .reveal.in .seg { opacity: 1; transform: none; }
.js .reveal.in .seg:nth-child(1) { transition-delay: 0.10s; }
.js .reveal.in .seg:nth-child(2) { transition-delay: 0.18s; }
.js .reveal.in .seg:nth-child(3) { transition-delay: 0.26s; }
.js .reveal.in .seg:nth-child(4) { transition-delay: 0.34s; }
.js .reveal.in .seg:nth-child(5) { transition-delay: 0.42s; }
@keyframes segpulse {
  0%, 100% { box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 16%, transparent), 0 0 14px color-mix(in srgb, var(--accent) 7%, transparent); }
  50% { box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 45%, transparent), 0 0 26px color-mix(in srgb, var(--accent) 14%, transparent); }
}
.js .reveal.in .seg.covered { animation: segpulse 2.8s ease-in-out 0.9s infinite; }

/* ── product page header ─────────────────────────────────────────────── */
.product-head { padding: 3.5rem 0 0.4rem; }
.product-head .crumbs { font-family: var(--mono); font-size: 0.74rem; color: var(--sub); margin-bottom: 1.1rem; }
.product-head .crumbs a { color: var(--sub); text-decoration: none; }
.product-head .crumbs a:hover { color: var(--accent-hover); text-decoration: underline; }

@media (max-width: 640px) {
  .brand { height: 30px; }
  /* auto-hiding header: slides out of the way on scroll-down, back on scroll-up */
  header.top { top: 0.5rem; padding: 0 0.6rem; transition: transform 0.28s cubic-bezier(0.2, 0.7, 0.2, 1); }
  header.top.top--hidden:not(:has(.nav-check:checked)) { transform: translateY(-160%); }
  .top-inner { gap: 0.42rem; padding: 0.43rem 0.55rem; }
  .theme-toggle { padding: 0.28rem 0.48rem; }
  .nav-toggle { gap: 0.4rem; padding: 0.28rem 0.5rem; }
  nav.main {
    top: calc(100% + 0.45rem); right: 0; width: calc(100vw - 1.2rem);
    max-height: calc(100dvh - 4.8rem); overflow-y: auto;
  }
  .hero { padding: 3.1rem 0 2rem; }
  body { font-size: 15.5px; }
}

/* ── guides (long-form articles) ─────────────────────────────────────────── */
.guide { max-width: 760px; margin: 0 auto; }
.guide h2 { font-family: var(--serif); font-weight: 700; color: var(--head); font-size: 1.5rem; line-height: 1.2; margin: 2.5rem 0 0.8rem; max-width: 34ch; }
.guide h3 { font-family: var(--serif); font-weight: 600; color: var(--head); font-size: 1.16rem; margin: 1.9rem 0 0.5rem; }
.guide p, .guide li { color: var(--text); font-size: 1.06rem; line-height: 1.72; max-width: 68ch; }
.guide p { margin: 0 0 1.1rem; }
.guide h2 + p, .guide h3 + p { margin-top: 0; }
.guide ul, .guide ol { margin: 0 0 1.2rem; padding-left: 1.35rem; }
.guide li { margin: 0.45rem 0; }
.guide li::marker { color: var(--accent); }
.guide strong { color: var(--head); font-weight: 600; }
.guide .callout { max-width: 68ch; border: 1px solid var(--line); border-left: 3px solid var(--accent); background: var(--list-bg); border-radius: 9px; padding: 1rem 1.2rem; margin: 1.7rem 0; }
.guide .callout p:last-child { margin-bottom: 0; }
.guide .callout .callout-label { font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.16em; text-transform: uppercase; color: var(--accent-ink); display: block; margin-bottom: 0.45rem; }
.guide figure { margin: 1.7rem 0; }
.guide .table-scroll { overflow-x: auto; margin: 0.4rem 0 1.5rem; }
.guide table { width: 100%; border-collapse: collapse; font-size: 0.93rem; min-width: 30rem; }
.guide th, .guide td { text-align: left; padding: 0.55rem 0.75rem; border-bottom: 1px solid var(--line); color: var(--text); vertical-align: top; }
.guide th { font-family: var(--mono); font-size: 0.71rem; letter-spacing: 0.06em; text-transform: uppercase; color: var(--sub); white-space: nowrap; }
.guide code { font-family: var(--mono); font-size: 0.88em; color: var(--head); background: var(--chip-bg); padding: 0.06rem 0.32rem; border-radius: 4px; }
.guide .guide-meta { font-family: var(--mono); font-size: 0.74rem; color: var(--sub); margin: 0 0 1.7rem; letter-spacing: 0.03em; }
.guide .guide-cta { border-top: 1px solid var(--line); margin-top: 2.6rem; padding-top: 1.7rem; }
.guide .guide-cta .btn { margin: 0.3rem 0.5rem 0.3rem 0; }
.guide-tag { font-family: var(--mono); font-size: 0.66rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--accent); }


/* ── FAQ: a ruled question ledger ────────────────────────────────────────
   Questions read as one calm numbered index; each answer unfolds beneath
   its rule. Replaces the old stack of eight glass cards, which read as
   clutter. Markup: section.faq > .faq-list > details.faq-item >
   (summary > h3) + .faq-a — seo-schema.mjs derives FAQPage JSON-LD from
   exactly this shape, so change both together or not at all. */
.faq { max-width: 880px; }
.faq-list { margin-top: 1.9rem; border-top: 1px solid var(--line); counter-reset: faq; }
.faq-item { border-bottom: 1px solid var(--line); }
.faq-item summary {
  display: flex; align-items: baseline; gap: 1rem; padding: 1.1rem 0.15rem;
  cursor: pointer; list-style: none;
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::before {
  counter-increment: faq; content: counter(faq, decimal-leading-zero);
  font-family: var(--mono); font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.08em; color: var(--sub); flex: none;
  transition: color 0.2s ease;
}
.faq-item summary h3 {
  font-family: var(--serif); font-weight: 600; font-size: 1.05rem;
  color: var(--head); margin: 0; line-height: 1.35;
}
.faq-item summary::after {
  content: "+"; margin-left: auto; flex: none; align-self: center;
  font-family: var(--mono); font-size: 1rem; font-weight: 600;
  color: var(--accent); transition: transform 0.25s cubic-bezier(0.2, 0.7, 0.2, 1);
}
.faq-item[open] summary::after { transform: rotate(45deg); }
.faq-item[open] summary::before { color: var(--accent); }
.faq-item summary:hover h3 { color: var(--accent); transition: color 0.2s ease; }
.faq-a { padding: 0.05rem 0.15rem 1.25rem 2.55rem; max-width: 72ch; }
.faq-a p { color: var(--text); font-size: 0.95rem; line-height: 1.66; margin: 0; }
.faq-a p + p { margin-top: 0.65rem; }
.faq-a a { color: var(--link); }
@media (max-width: 560px) {
  .faq-item summary { gap: 0.7rem; }
  .faq-a { padding-left: 0.15rem; }
}

/* ── jobs board ──────────────────────────────────────────────────────────
   Search + filters over a list that is usually empty, so the empty state is
   the state worth designing: a stamped notice, not a shrug. The controls
   reuse .demo-panel and .field wholesale — a vacancy search is the same
   object as the interactive validators, and should not invent a second
   look for an input. */
.board-tools { display: grid; grid-template-columns: minmax(0, 1.7fr) minmax(0, 1fr) minmax(0, 1fr); gap: 0.85rem; align-items: end; margin-top: 1.6rem; }
/* The panel ships with [hidden] and the board script reveals it. A class
   setting display:grid outranks the UA sheet's `[hidden] { display: none }`,
   so without this line a visitor with no JavaScript gets a search box that
   looks live and can do nothing. */
.board-tools[hidden] { display: none; }
.board-tools .field { margin-bottom: 0; }
/* The count and the reset sit under the full width of the row. */
.board-foot { grid-column: 1 / -1; display: flex; align-items: center; justify-content: space-between; gap: 0.9rem; flex-wrap: wrap; }
.board-count { font-family: var(--mono); font-size: 0.7rem; font-weight: 600; letter-spacing: 0.16em; text-transform: uppercase; color: var(--sub); margin: 0; }
/* smaller than a page CTA — it is a reset, not a call to action — but never
   below a 44px touch target */
.board-clear { padding: 0.5rem 1.1rem; min-height: 44px; font-size: 0.85rem; }
.board-hint { grid-column: 1 / -1; color: var(--sub); font-size: 0.85rem; margin: 0; }
/* An empty board switches its own controls off rather than leaving a search box
   that looks live and can never match. Only the controls themselves dim —
   labels and the hint stay at full ink, because they are what explains why. */
.board-tools--idle input:disabled, .board-tools--idle select:disabled { opacity: 0.6; cursor: not-allowed; }
.board-tools--idle .btn:disabled { opacity: 0.55; cursor: not-allowed; }
@media (max-width: 720px) { .board-tools { grid-template-columns: 1fr; } }

.job-list { list-style: none; padding: 0; margin: 1.4rem 0 0; display: grid; gap: 1.2rem; }
.job-list:empty { margin: 0; }
.job h3 { font-family: var(--serif); font-weight: 600; font-size: 1.2rem; margin: 0 0 0.15rem; }
.job-meta { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0.7rem 0 0.9rem; }
/* same stamp as .card .tag, but repeatable in a row rather than a single label */
.job-meta .chip {
  font-family: var(--mono); font-size: 0.65rem; letter-spacing: 0.1em; text-transform: uppercase;
  padding: 0.16rem 0.6rem; border: 1px solid var(--line); border-radius: 999px;
  color: var(--sub); background: var(--chip-bg);
}
.job .btn { margin-top: 1rem; }

.board-empty { margin-top: 1.5rem; text-align: center; padding: 2.7rem 1.8rem; }
.board-empty h3 { font-family: var(--serif); font-weight: 600; font-size: 1.25rem; margin: 0.9rem 0 0.6rem; }
.board-empty p { color: var(--sub); font-size: 0.95rem; max-width: 56ch; margin: 0 auto; }
/* the "no vacancies" stamp: a .pill standing alone, so it loses the inline
   text alignment the status pills need when they trail a heading */
.pill.closed { color: var(--sub); border-color: var(--line); background: var(--chip-bg); }
.board-empty .pill { display: inline-block; margin: 0; vertical-align: baseline; }

/* ── utility classes (extracted from inline styles) ──────────────────── */
.u-link-list { margin-top: 1rem; color: inherit; display: flex; flex-direction: column; gap: 0.5rem; }
.u-fine       { font-size: 0.9rem; opacity: 0.8; line-height: 1.4; }
.u-mt-07      { margin-top: 0.7rem; }
.u-mt-08      { margin-top: 0.8rem; }
.u-mt-1       { margin-top: 1rem; }
.u-mt-11      { margin-top: 1.1rem; }
.u-mt-12      { margin-top: 1.2rem; }
.u-mt-14      { margin-top: 1.4rem; }
.u-mt-18      { margin-top: 1.8rem; }
.u-pt-14      { padding-top: 1.4rem; }
.u-center     { text-align: center; }
.u-good       { color: var(--good); }
.u-section    { margin: 3.4rem 0 0; }
.u-intro      { max-width: 64ch; margin: 0 auto 1.4rem; text-align: center; }
.u-narrow     { max-width: 940px; margin: 0 auto; }
.u-narrow-top { max-width: 940px; margin: 1.2rem auto 0; }
.u-mid        { max-width: 640px; }
.u-btn-inline { width: auto; margin-right: 0.5rem; }
.u-nowrap     { white-space: nowrap; }
