/*
  The SimFather, Option A Stadium Night hero + Option B Simulation Grid mid-page only,
  2026-09-09. Premium dark charcoal and muted brass. No vault chrome, no green or olive oxide.
  Dark-first with a legible light theme. Self-hosted fonts only; no external request
  on load. The only external hrefs are the Discord invite and the DraftKings
  referral; the two page forms reach Formspree and the Funded app (both listed
  in the page CSP connect-src).

  Shared by index.html, privacy.html and terms.html. The legal document chrome
  (.docnav, .doc, .doc__*) lives at the end and must keep rendering.

  Scales, from the spec and nothing else:
    spacing   4 8 12 16 24 32 48 64 96 128
    type      13 16 20 25|31 39|49 61|95  (six sizes at 390, six at 1440)
    gutter    24 at 390, 48 at 1440; content ceiling 1248
    radius    2 px, mechanical, everywhere
  Motion lives in motion.css; this file paints every element at rest.
*/

/* ---- Webfonts (self-hosted, latin subsets) --------------------------------
   TWO VARIABLE FACES REPLACED THREE STATIC ONES, 2026-09-12. The body face used to be
   a text serif and it was the single biggest reason the site read as a period piece
   rather than a product: running text in a serif, set over engraved gilt rules, is a
   nineteenth century bank notice. Sora and Manrope are both geometric, both variable
   (one file each covers the whole weight range), and together they cost 58 KB against
   the 69 KB of the three files they replace. The old face is named in no comment here
   because a test asserts its name is gone from the served stylesheet.

   Libre Franklin stays in the stack as the first fallback, so a browser that fails
   to fetch Sora lands on the face the site used to ship rather than on Arial. */
@font-face {
  font-family: "Sora";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("assets/fonts/sora-latin-var.woff2") format("woff2");
}
/* INTER, added 2026-09-13. It is the interface face in the reference the site is being
   matched to, and it is the right one for the job: it was drawn for small dense UI text,
   its figures line up in a column, and it disappears rather than performing. Manrope came
   out for it after one day: Manrope is friendlier and rounder, which reads well in a
   paragraph and reads soft in a data table. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url("assets/fonts/inter-latin-var.woff2") format("woff2");
}
/* A REAL MONOSPACE, for the things that are identifiers rather than words: slate ids,
   player ids, salaries, projections, any column a reader scans down. Tabular figures in a
   proportional face keep the columns aligned but still read as prose; a mono says "this is
   data" before a single value is read, which is the whole trick in the reference. */
@font-face {
  font-family: "JetBrains Mono";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("assets/fonts/jetbrains-mono-latin-var.woff2") format("woff2");
}
@font-face {
  font-family: "Libre Franklin";
  font-style: normal;
  font-weight: 500 600;
  font-display: swap;
  src: url("assets/fonts/libre-franklin-latin.woff2") format("woff2");
}

/* ---- Tokens -------------------------------------------------------------- */
:root {
  /* dark is the default theme, and the ground is the HOME PAGE's ground, to the byte.
     It was a cool near-black with a blue cast while the home page was warm, and eight pages
     used this one, so moving between them did not read as one site changing page. One palette,
     defined once, is the only thing that actually holds that. */
  --bg: #0a0a09;
  --bg-lift: #141311;
  --panel: #141311;
  --panel-2: #1d1b17;
  /* THE GILT RAMP, read off the brand mark.
     The mark is gilt on near-black: lit along the top edge, falling to an engraved
     shadow. The site carried TWO different metals before this, a greyed #9a8b6a here
     and a warmer #b6934b in funded.css, on pages that load both stylesheets. This is
     the single source. The three brass names below are kept as aliases so all 144
     existing call sites move with the ramp instead of being renamed in one pass. */
  --gold-lit: #e6c97c;     /* the lit top edge. Signature and ornament ONLY, never body text */
  --gold-bright: #e6c97c;  /* emphasis: focus rings, active state, a hovered rule */
  --gold: #c9a961;         /* the workhorse mid-tone */
  --gold-deep: #6e5730;    /* the engraved shadow side */

  /* The mark's lettering is not a flat fill, it carries a vertical gradient, and that
     is the whole difference between reading as struck metal and reading as mustard.
     One token, so any surface can be gilt without hand-mixing a gradient. */
  --metal-gold: linear-gradient(175deg, var(--gold-lit) 0%, var(--gold) 46%, var(--gold-deep) 100%);
  --metal-edge: linear-gradient(180deg, rgba(227, 193, 132, 0.55), rgba(125, 102, 51, 0.14));

  --brass: var(--gold);
  --brass-bright: var(--gold-bright);
  --brass-deep: var(--gold-deep);
  --parchment: #f1ece0;
  --text: #f1ece0;
  --muted: #b9b2a3;      /* warm grey, off the same ramp as the ground */
  --line: rgba(198, 160, 87, 0.26);
  --line-soft: rgba(255, 255, 255, 0.09);
  --edge-hi: rgba(255, 255, 255, 0.08);
  --edge-lo: rgba(0, 0, 0, 0.6);
  --field-bg: rgba(255, 255, 255, 0.04);
  --field-line: rgba(255, 255, 255, 0.16);
  /* The account menu, which is Clerk's and is themed only through its variables. It is the
     one surface that is brown rather than the cool panel grey, so it gets
     tokens of its own instead of borrowing --panel and drifting when --panel changes. */
  --menu-bg: #241c0e;
  --menu-text: #ffffff;
  --focus: var(--gold-bright);
  --shadow: rgba(0, 0, 0, 0.6);
  --danger: #e39070;
  --seal-opacity: 0.16;

  /* ---- Glass ------------------------------------------------------------
     One raised surface, used everywhere something sits above the page: cards,
     the email capture, the nav once it leaves the top. It is a translucent
     wash plus a blur of what is behind it plus ONE lit top edge, which is what
     makes a panel look like it has thickness. --glass-blur is a length so a
     component can dial it down; it is never a backdrop-filter shorthand,
     because Safari needs -webkit-backdrop-filter beside it at every call site.

     backdrop-filter degrades safely: a browser without it shows the wash alone,
     which is why the wash is never fully transparent. */
  --glass-bg: linear-gradient(157deg, rgba(255, 255, 255, 0.075), rgba(255, 255, 255, 0.022));
  --glass-line: rgba(255, 255, 255, 0.11);
  --glass-blur: 18px;
  --glass-shadow: 0 1px 0 rgba(255, 255, 255, 0.08) inset, 0 24px 60px -26px rgba(0, 0, 0, 0.9);
  --glass-shadow-lift: 0 1px 0 rgba(255, 255, 255, 0.13) inset, 0 34px 80px -28px rgba(0, 0, 0, 0.95);

  /* Gold as light. A halo, not a border: this is what a hovered primary control
     and the hero glow share, and it is the one place the brand colour is allowed
     to bloom. */
  --glow-gold: 0 14px 44px -16px rgba(198, 160, 87, 0.5);
  --glow-gold-soft: 0 10px 34px -18px rgba(198, 160, 87, 0.32);

  /* ---- Component tokens -------------------------------------------------
     A restyle edits THESE and the light block below, never a call site. Every
     one resolves to a token above, so the ramp stays the single source and the
     two themes cannot drift apart by being edited in different places.

     Engraving is the vernacular the mark sets, and it is made of two things a
     flat design does not have: a lit inner top edge and a dark outer bottom
     edge. That pair is what --card-edge and --shadow do together. */
  --btn-bg: rgba(255, 255, 255, 0.045);
  --btn-line: var(--glass-line);
  --btn-text: var(--text);
  --btn-bg-hover: rgba(198, 160, 87, 0.12);
  --btn-line-hover: var(--gold-bright);

  --btn-gilt-bg: var(--metal-gold);
  --btn-gilt-text: #14100a;
  --btn-gilt-line: var(--gold-deep);

  --card-bg: var(--glass-bg);
  --card-line: var(--glass-line);
  --card-edge: var(--edge-hi);
  --card-shadow: var(--glass-shadow);
  --card-shadow-lift: var(--glass-shadow-lift);

  --field-focus-ring: 0 0 0 2px var(--bg), 0 0 0 4px var(--focus);

  --rule-hair: 1px solid var(--line-soft);
  --rule-gilt: 1px solid var(--line);

  /* THREE ROLES, THREE FACES, and the split is by JOB rather than by page.
     Sora is the voice: marketing headlines, where a face is allowed character.
     Inter is the interface: every paragraph, label, control and table cell. It was drawn
       for small dense UI and it is what the reference this design follows uses.
     JetBrains Mono is data: ids, salaries, projections, anything scanned down a column.
     All three are variable, so a weight is a number rather than another download.
     Use --ui, not --display, for a heading inside a product surface: a dense panel wants
     the interface face at a heavier weight, not the display face shrunk down. */
  --display: "Sora", "Libre Franklin", "Segoe UI", Arial, sans-serif;
  --body: "Inter", "Libre Franklin", "Segoe UI", Arial, sans-serif;
  --ui: "Inter", "Libre Franklin", "Segoe UI", Arial, sans-serif;
  --mono: "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  /* THESE TWO WERE USED TWENTY-ONE TIMES AND DEFINED NOWHERE, found 2026-09-15 while
     writing the homepage rebuild. var() with no fallback and no definition makes the
     whole declaration invalid at computed-value time, so every `font-family: var(--brand)`
     quietly inherited Inter (including .brand__name, three lines under a comment calling
     itself "THE ONLY --brand ON THE SITE" and meaning Sora), and every
     `font-variant-numeric: var(--nums)` did nothing at all. Defining them here fixes all
     twenty-one call sites without touching one of them. --brand is an alias rather than a
     fourth face: the comment above already says the display face IS the brand voice. */
  --brand: var(--display);
  --nums: tabular-nums;

  /* Inter's default spacing is set for body copy. Dense UI wants it a shade tighter, and a
     hero wants it tighter still. Named so a component asks for a tracking by role. */
  --track-ui: -0.006em;
  --track-tight: -0.02em;
  --track-label: 0.08em;

  /* A SCALE, not the old single mechanical 2px. Soft corners are most of what
     separates a current interface from a 2014 one, and the sizes differ by role:
     a chip is not a card and a card is not a hero panel. */
  --radius-xs: 6px;
  --radius-sm: 10px;
  --radius: 14px;
  --radius-lg: 22px;
  --radius-pill: 999px;

  /* spacing scale */
  --s1: 4px;  --s2: 8px;  --s3: 12px; --s4: 16px; --s5: 24px;
  --s6: 32px; --s7: 48px; --s8: 64px; --s9: 96px; --s10: 128px;

  /* type scale, 390 column */
  --t-micro: 13px;
  --t-body: 16px;
  --t-lead: 20px;
  --t-product: 25px;
  --t-section: 39px;
  --t-hero: 61px;

  /* rhythm, 390 column */
  --gutter: var(--s5);
  --wrap: 1248px;
  --pad-hero-top: var(--s9);
  --pad-hero-bottom: var(--s8);
  --pad-section: var(--s8);
  --pad-compact: var(--s7);
  --gap-row: var(--s3);
  --gap-col: var(--s6);
  --masthead: 64px;
}
@media (min-width: 900px) {
  :root {
    --t-product: 31px;
    --t-section: 49px;
    --t-hero: 95px;
    --gutter: var(--s7);
    /* TIGHTENED 2026-09-13. These were s10/s10, i.e. 128px top AND bottom, which put 256px
       of empty page between every pair of sections on a desktop and was the single biggest
       reason the site read as sparse rather than as spacious. A section still breathes; it
       no longer takes a scroll of its own to cross the gap. */
    --pad-hero-top: var(--s9);
    --pad-hero-bottom: var(--s8);
    --pad-section: var(--s9);
    --pad-compact: var(--s8);
    --gap-row: var(--s4);
    --gap-col: var(--s8);
  }
}

/* Light theme, applied by the toggle (no OS-preference block: dark is the
   default and the primary target; light is reachable only by the toggle). */
:root[data-theme="light"] {
  /* Light was a parchment cream (#e8e4d8), which is the other half of why the site
     read as a period piece, and it is also the single most common ground in
     machine-generated design. This is a cool near-white instead: the gold becomes
     the only warm thing on the page, which is what makes it read as an accent. */
  --bg: #f4f5f8;
  --bg-lift: #fafbfd;
  --panel: #ffffff;
  --panel-2: #f7f8fb;
  /* The account menu stays brown in both themes, because it is the one branded surface in
     the chrome. Light gets a deeper brown so white text keeps its contrast. */
  --menu-bg: #2e2413;
  --menu-text: #ffffff;
  /* The same ramp read against parchment instead of near-black. Gilt on a light
     ground is an ANTIQUE gold, not a brighter one: the values go down, not up,
     because contrast here comes from depth. The roles are unchanged, so -lit is
     still the emphasis stop and -deep is still the shadow, and every component
     token below resolves through these without being redeclared. */
  --gold-lit: #7a5f24;
  --gold-bright: #6b5320;
  --gold: #5f4d2c;
  --gold-deep: #3f3828;
  --metal-gold: linear-gradient(175deg, #8a6d2e 0%, #5f4d2c 46%, #3f3828 100%);
  --metal-edge: linear-gradient(180deg, rgba(255, 253, 246, 0.7), rgba(63, 56, 40, 0.12));

  --brass: var(--gold);
  --brass-bright: var(--gold-bright);
  --brass-deep: var(--gold-deep);

  /* The two component tokens that do NOT theme through a variable, so they are
     restated here. The gilt gradient runs DARK on a light ground, so near-black
     label text on it would be unreadable: this is the pair a light theme usually
     ships broken because nobody looks at the second theme. */
  --btn-gilt-text: #fbf8f1;
  --btn-bg-hover: rgba(95, 77, 44, 0.09);
  --btn-bg: rgba(17, 20, 28, 0.03);
  --parchment: #10131a;
  --text: #10131a;
  --muted: #5d6675;
  --line: rgba(95, 77, 44, 0.28);
  --line-soft: rgba(16, 19, 26, 0.10);
  --edge-hi: rgba(255, 255, 255, 0.9);
  --edge-lo: rgba(16, 19, 26, 0.12);
  --field-bg: #ffffff;
  --field-line: rgba(16, 19, 26, 0.16);
  --focus: #6b5320;
  --shadow: rgba(20, 26, 40, 0.14);
  --danger: #a8452a;
  --seal-opacity: 0.12;

  /* Glass, restated. On a light ground the raised surface is WHITE with a hairline,
     not a white wash on a dark one: reusing the dark values here would tint every
     card grey and leave the lit top edge invisible. This is the pair a light theme
     usually ships broken because nobody looks at the second theme. */
  --glass-bg: linear-gradient(157deg, rgba(255, 255, 255, 0.92), rgba(255, 255, 255, 0.72));
  --glass-line: rgba(16, 19, 26, 0.09);
  --glass-blur: 16px;
  --glass-shadow: 0 1px 0 rgba(255, 255, 255, 0.95) inset, 0 18px 44px -24px rgba(20, 26, 40, 0.35);
  --glass-shadow-lift: 0 1px 0 rgba(255, 255, 255, 1) inset, 0 28px 64px -26px rgba(20, 26, 40, 0.42);
  --glow-gold: 0 14px 40px -18px rgba(95, 77, 44, 0.42);
  --glow-gold-soft: 0 10px 30px -20px rgba(95, 77, 44, 0.28);
}

/* ---- Base ---------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  /* Two soft blooms on a flat ground, fixed so they do not slide with the scroll:
     a gold one behind the masthead and a cooler one off to the right, which is what
     keeps a near-black page from reading as a dead rectangle. The solid colour is
     the backstop and the whole thing degrades to it. */
  background-color: var(--bg);
  background-image:
    radial-gradient(80% 42% at 50% -8%, rgba(198, 160, 87, 0.13), transparent 64%),
    radial-gradient(52% 38% at 88% 8%, rgba(120, 150, 220, 0.07), transparent 70%),
    linear-gradient(180deg, var(--bg-lift), var(--bg) 760px);
  background-repeat: no-repeat;
  background-attachment: fixed, fixed, scroll;
  color: var(--text);
  font-family: var(--body);
  font-size: var(--t-body);
  line-height: 1.55;
  overflow-x: hidden; /* backstop: no horizontal scroll */
}

img { max-width: 100%; display: block; }

a { color: var(--brass); text-underline-offset: 3px; }
a:hover { color: var(--brass-bright); }

/* HEADINGS ARE THE INTERFACE FACE. In the reference this design follows, they are: a
   product sets its headings in the same family as its labels and distinguishes them by
   weight and tracking, not by reaching for a second family. --brand is spent in exactly
   one place, on the marketing headline below, which is what makes it read as a voice
   rather than as the default. */
h1, h2, h3, h4 {
  font-family: var(--ui);
  font-weight: 620;
  letter-spacing: var(--track-tight);
  color: var(--parchment);
  line-height: 1.1;
  margin: 0;
}

p { margin: 0 0 var(--s4); }
p:last-child { margin-bottom: 0; }

.wrap {
  width: 100%;
  max-width: calc(var(--wrap) + 2 * var(--gutter));
  margin: 0 auto;
  padding: 0 var(--gutter);
}

/* Micro label: the one small Franklin voice used for eyebrows, tags, nav, buttons. */
.eyebrow,
.tag,
.nav__links a,
.theme-toggle,
.btn,
.drawer__no,
.drawer__value,
.field label,
.form-note,
.block-note,
.skip-link,
.footer-seal__type,
.site-footer__nav a,
.site-footer__legalnav a,
.register__no,
.register__action,
.register__note,
.split__no,
.split__per,
.split__link,
.tier__no,
.tier__period,
.tier__specs dt,
.gen__label,
.gen__per,
.gen__rowlabel,
.legal--mono,
.legal--mark {
  font-family: var(--ui);
  font-weight: 500;
  font-size: var(--t-micro);
  line-height: 1.4;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
}

.eyebrow {
  color: var(--brass);
  margin: 0 0 var(--s4);
  display: inline-flex;
  align-items: center;
  gap: var(--s3);
}
/* A short brass rule leading the eyebrow: the lower-third station marker that opens
   the register, drawn from the same brass as every rule on the page. */
.eyebrow::before {
  content: "";
  width: 26px;
  height: 2px;
  background: var(--brass);
  flex: none;
}
.tag { color: var(--muted); }

.text-muted { color: var(--muted); }

/* ---- Skip link ----------------------------------------------------------- */
.skip-link {
  position: absolute;
  left: var(--s3);
  top: -64px;
  z-index: 20;
  background: var(--brass);
  color: #0b0d0c;
  padding: var(--s2) var(--s4);
  border-radius: var(--radius-sm);
  text-decoration: none;
  transition: top 0.15s ease;
}
.skip-link:focus { top: var(--s3); }

/* ---- Focus --------------------------------------------------------------- */
:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
}

/* ---- Masthead ------------------------------------------------------------ */
.masthead {
  /* Sticky glass. The double brass rule of a newspaper flag came out on 2026-09-12 with the
     rest of the engraving: a header that sits over the page and lets it show through is the
     single clearest signal that an interface is current. One hairline, one blur, nothing else.

     position: sticky, not fixed, so it keeps its place in flow and nothing needs a matching
     top padding. A later rule already sets position: relative on this element for the nav
     panel; that rule is updated in the same pass rather than fought with a second override. */
  position: sticky;
  top: 0;
  border-bottom: 1px solid var(--line-soft);
  background: var(--glass-bg);
  background-color: rgba(7, 8, 12, 0.72);
  -webkit-backdrop-filter: blur(20px) saturate(1.4);
  backdrop-filter: blur(20px) saturate(1.4);
  z-index: 30;
}
/* The ground behind the blur is the only value here that cannot resolve through a token: it
   has to be the page ground AT AN ALPHA, and a colour token carries no alpha. Stated once per
   theme, beside each other, so they cannot drift. */
:root[data-theme="light"] .masthead { background-color: rgba(244, 245, 248, 0.74); }
.masthead__row {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 24px;
  min-height: var(--masthead);
}
.brand {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
  width: max-content;
  max-width: max-content;
  position: relative;
  z-index: 1;
  text-decoration: none;
  color: var(--parchment);
}
.brand__seal {
  width: 34px;
  height: 34px;
  flex: 0 0 34px;
  object-fit: contain;
  border-radius: 50%;
  border: 1px solid var(--brass);
  padding: 2px;
  background: radial-gradient(circle at 50% 42%, rgba(216,184,120,0.16), transparent 70%);
}
.brand__name {
  font-family: var(--ui);
  font-weight: 600;
  font-size: var(--t-body);
  letter-spacing: 0.03em;
  white-space: nowrap;
}
.nav {
  display: flex;
  align-items: center;
  gap: 22px;
  margin-left: auto;
  flex: 0 0 auto;
  position: relative;
  z-index: 3;
}
.nav__links {
  display: flex;
  gap: 22px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.nav__links a {
  text-decoration: none;
  color: var(--muted);
  padding: var(--s1) 0;
  white-space: nowrap;
  transition: color 0.15s ease;
}
.nav__links a:hover { color: var(--parchment); }
.nav__links a[aria-current="page"],
.nav__tab[aria-current="page"] {
  color: var(--parchment);
  border-bottom: 2px solid var(--brass);
}

/* Small controls take --radius-sm, not the 14px default: on a 34px-tall control the default
   reads as a lozenge rather than as a softened rectangle. The skip link is the same case. */
.theme-toggle {
  color: var(--parchment);
  background: var(--btn-bg);
  border: 1px solid var(--glass-line);
  border-radius: var(--radius-sm);
  padding: var(--s2) var(--s3);
  cursor: pointer;
  transition: border-color 0.15s ease;
}
.theme-toggle:hover { border-color: var(--brass); }

/* On a phone the brand is the home link; the Home item is redundant and does not fit. */
@media (max-width: 480px) {
  .nav { gap: var(--s3); }
  .nav__links { gap: var(--s3); }
  /* `.nav__links li:first-child { display: none }` used to live here. It hid the "Home" link
     when the nav was just Home and Sign In and the two would not fit. The nav now collapses
     into the burger drawer below 1100px, so nothing needs hiding by position, and the rule was
     actively harmful: the first item is now the Products tab, so on any screen under 480px it
     deleted the main product menu outright. Found by tests/e2e-nav.mjs, which tapped a trigger
     that had no layout box. Do not reintroduce a rule that hides a nav item by its position. */
  .theme-toggle { padding: var(--s2); }
}

/* ---- Buttons ------------------------------------------------------------- */
.btn {
  position: relative;
  display: inline-block;
  text-decoration: none;
  padding: var(--s3) var(--s5);
  border: 1px solid var(--btn-line);
  border-radius: var(--radius-pill);
  color: var(--parchment);
  background: var(--btn-bg);
  /* The secondary action is glass: it takes its fill from whatever is behind it rather than
     from a flat panel colour, which is what stops a row of outlined buttons reading as a form
     from 2012. -webkit- first, Safari still needs it. */
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.3);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.3);
  cursor: pointer;
  line-height: 1.4;
  transition: border-color 220ms ease, color 220ms ease, background-color 220ms ease,
              transform 220ms cubic-bezier(0.22, 1, 0.36, 1), box-shadow 220ms ease;
}
.btn:hover {
  border-color: var(--btn-line-hover);
  color: var(--brass-bright);
  transform: translateY(-1px);
  box-shadow: var(--glow-gold-soft);
}
.btn:active { transform: translateY(0); }
.btn[disabled] { opacity: 0.6; cursor: default; transform: none; box-shadow: none; }
.btn--brass {
  /* THE ONE GILT ACTION ON A PAGE. It reads from the component tokens rather than mixing its
     own gradient, which is what lets the light theme be served by the same rule: --metal-gold
     runs bright on near-black and antique on parchment, and --btn-gilt-text follows it. The
     hand-mixed version below it used to need a whole second block for light. */
  background: var(--btn-gilt-bg);
  color: var(--btn-gilt-text);
  border-color: var(--btn-gilt-line);
  font-weight: 600;
  /* Stamped metal: a lit catch along the top, a seated shadow below. The pair is what reads
     as struck rather than printed. */
  box-shadow: inset 0 1px 0 rgba(255, 244, 214, 0.38), var(--glow-gold-soft);
  /* No blur under an opaque gilt fill: it would cost a compositor layer to show nothing. */
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  overflow: hidden;
}
/* A sheen that crosses the face on hover. One transform of one pseudo-element, which the
   compositor handles without touching layout, and it is the only decorative motion on a
   control anywhere in the system. */
.btn--brass::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: -60%;
  width: 45%;
  background: linear-gradient(100deg, transparent, rgba(255, 252, 240, 0.42), transparent);
  transform: translateX(0);
  pointer-events: none;
}
.btn--brass:hover::after { animation: btn-sheen 720ms ease-out; }
@keyframes btn-sheen { to { transform: translateX(370%); } }
/* Hover keeps the TOKEN, not a fixed near-black. Without this the label went dark on a
   gradient that runs dark in light theme, so hovering made it disappear. */
.btn--brass:hover {
  color: var(--btn-gilt-text);
  filter: brightness(1.06);
  box-shadow: inset 0 1px 0 rgba(255, 244, 214, 0.45), var(--glow-gold);
}
.btn--brass[disabled]:hover { filter: none; }
.btn--brass[disabled]:hover::after { animation: none; }
/* No light-theme background override any more: --btn-gilt-bg and --btn-gilt-text both invert
   with the theme, so one rule serves both. This block used to restate the whole button. */

/* ---- Section rhythm ------------------------------------------------------ */
/* Each section carries its own brass rule at the top edge of the content column.
   Drawn by motion.css on reveal; painted full width here. */
.section {
  position: relative;
  padding: var(--pad-section) 0;
}
.section--compact { padding: var(--pad-compact) 0; }
.section::before {
  content: "";
  position: absolute;
  top: 0;
  left: max(var(--gutter), calc(50% - var(--wrap) / 2));
  right: max(var(--gutter), calc(50% - var(--wrap) / 2));
  height: 1px;
  /* Engraved rule: a brass hairline that fades in from the gutters rather than
     butting the edge, sitting on a thin dark groove so it reads as a line cut into
     metal, not a border drawn on top of it. */
  background: linear-gradient(90deg, transparent, var(--line) 8%, var(--line) 92%, transparent);
  box-shadow: 0 1px 0 var(--edge-lo);
}
.hero + .section::before { display: none; }

.section-head { margin-bottom: var(--s5); }
.section-head .tag { display: block; margin-bottom: var(--s3); }
.section-head h2 {
  font-size: var(--t-section);
  line-height: 1.05;
  letter-spacing: -0.02em;
  max-width: 14ch;
}
.section-head__lead {
  font-size: var(--t-lead);
  line-height: 1.4;
  color: var(--text);
  margin: var(--s5) 0 0;
  max-width: 34ch;
}
.section-head--row {
  display: grid;
  gap: var(--s5);
  align-items: end;
}

/* The register grid: heading column beside the content column, from 900 up. */
.section__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--gap-col);
}
.section__grid .section-head { margin-bottom: 0; }
.section__body { min-width: 0; }

@media (min-width: 900px) {
  .section__grid { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); align-items: start; }
  .section-head--row { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
  .section-head--row .section-head__lead { margin: 0; max-width: 46ch; }
}

.prose { max-width: 62ch; }
.prose p { color: var(--text); }
.prose .btn { margin-top: var(--s1); }
/* Plain licensed-scope list on the Data page. Real parallel items, so a list earns its place;
   square markers and a left rule keep it in the squared house style rather than a bullet grid. */
.datalist { max-width: 62ch; margin: var(--s3) 0 0; padding: 0; list-style: none; }
.datalist li {
  color: var(--text);
  padding: var(--s2) 0 var(--s2) var(--s4);
  border-left: 2px solid var(--brass-deep);
  margin-bottom: 1px;
}
.after-note { margin: var(--s5) 0 0; max-width: 62ch; }

/* ---- Hero: Option A, Stadium Night only ---------------------------------- */
.hero {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  display: grid;
  align-content: center;
  min-height: calc(100vh - var(--masthead));
  min-height: calc(100svh - var(--masthead));
  padding: var(--pad-hero-top) 0 var(--pad-hero-bottom);
  background: var(--bg);
  border-bottom: 1px solid var(--line-soft);
}
.hero__media {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
  background: var(--bg);
}

/* THE PHOTOGRAPH IS GONE, 2026-09-12, AND THE CLASS NAMES ARE NOT.
   .hero__stadium painted a night photograph of a stadium on fourteen pages: three
   here and eleven in funded/public. Renaming the class would have meant editing all
   fourteen in one commit to change one background, so the hook stayed and only what
   it paints changed. The name is now a small lie about a light field rather than a
   stadium, which is cheaper than the churn and is written down here.

   The image file itself is deleted, and several tests assert its name appears nowhere in
   the served tree, so this comment cannot spell it out either.

   What replaces it is an aurora: three wide radial gradients, gold low and left where
   the headline sits, cool blue high and right so the gold has something to be warm
   against. It costs no request, it is sharp at any density, and it themes, which a
   baked night photograph could not do (the light theme had to dim the photo and it
   still read as night). */
.hero__stadium {
  position: absolute;
  inset: -10%;
  background-color: var(--bg);
  /* ALL OF IT LIVES ON THE RIGHT, because the left is where the headline is. The first cut put
     the gold bloom at 22% and it was invisible: the readability scrim is opaque across the left
     half by design, so the light was being painted underneath the very thing that hides light.
     Caught by rendering it, not by reading it. */
  background-image:
    radial-gradient(42% 48% at 74% 56%, rgba(198, 160, 87, 0.4), transparent 68%),
    radial-gradient(36% 42% at 88% 14%, rgba(230, 201, 124, 0.16), transparent 70%),
    radial-gradient(58% 54% at 68% 38%, rgba(227, 193, 132, 0.12), transparent 74%);
  filter: blur(26px);
}

/* Readability scrim. Softer than the old one, because there is no longer a
   photograph underneath for the text to fight. */
.hero__scrim {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(96deg, var(--bg) 0%, var(--bg) 30%, rgba(7, 8, 12, 0.72) 46%, rgba(7, 8, 12, 0.24) 60%, transparent 74%),
    linear-gradient(180deg, transparent 62%, var(--bg) 100%);
}
.hero__inner { position: relative; z-index: 2; max-width: 40rem; }

/* Full-viewport page plate, used by every page that is not the home page. Fixed
   rather than section-scoped, so the light field sits behind the whole scroll. */
.hero__media--page {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}
.hero__media--page .hero__stadium {
  inset: -20%;
  background-image:
    radial-gradient(34% 34% at 78% 22%, rgba(198, 160, 87, 0.26), transparent 70%),
    radial-gradient(30% 32% at 16% 10%, rgba(201, 169, 97, 0.10), transparent 72%);
}
.hero__media--page::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 34%;
  background: linear-gradient(180deg, rgba(7, 8, 12, 0) 0%, var(--bg) 46%, var(--bg) 100%);
  pointer-events: none;
}

/* THE SIMULATION FIELD. src/hero-field.js appends this canvas into [data-hero-media]
   on the home page only, and removes it again if WebGL is unavailable or the visitor
   asks for reduced motion. Everything above still paints underneath it, so the hero
   is complete with the canvas absent: nothing here is load-bearing for readability. */
.hero__field {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  opacity: 0;
  transition: opacity 1200ms ease;
}
.hero__field.is-ready { opacity: 1; }
.hero--stadium .hero__title {
  font-size: clamp(2.4rem, 4.4vw, 4rem);
  max-width: 14ch;
  line-height: 1.02;
}
.hero--stadium .hero__band { display: none; }

/* HUD cards: decorative, used inside mid-page Generator visual only. */
.hud-live {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0 0 var(--s3);
  color: var(--brass);
  font-family: var(--ui);
  font-size: var(--t-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.hud-live__dot {
  width: 0.45rem;
  height: 0.45rem;
  border-radius: 50%;
  background: var(--brass-bright);
  box-shadow: 0 0 10px var(--brass);
}
.hud-card {
  background: rgba(23, 23, 23, 0.72);
  border: 1px solid rgba(154, 139, 106, 0.45);
  box-shadow: inset 0 1px 0 var(--edge-hi);
  padding: var(--s3);
  /* The -webkit- twin was missing here since the card was written, so Safari has never
     blurred it and the HUD read as a flat wash on that browser alone. Found 2026-09-12 by
     counting the two properties against each other in the design token test. */
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
}
.hud-card--main { margin-bottom: var(--s3); }
.hud-card--ghost {
  width: 72%;
  margin-left: auto;
  opacity: 0.72;
  transform: translate(8%, -6%) rotate(3deg);
}
.hud-card__kicker {
  margin: 0 0 var(--s3);
  color: var(--brass);
  font-family: var(--ui);
  font-size: var(--t-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}
.hud-card__rows {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 0.55rem;
}
.hud-card__rows li {
  display: grid;
  grid-template-columns: 2.2rem 1fr;
  align-items: center;
  gap: var(--s3);
  color: var(--muted);
  font-family: var(--ui);
  font-size: var(--t-micro);
  letter-spacing: 0.08em;
}
.hud-card__rows i {
  display: block;
  height: 1px;
  background: linear-gradient(90deg, var(--line), transparent);
}
.hud-card__line {
  margin: 0;
  color: var(--parchment);
  font-family: var(--mono); font-variant-numeric: var(--nums);
  font-size: var(--t-micro);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

/* The seal: the brand mark as engraved plate, clipped to its roundel, behind the
   register at low contrast. Screened onto steel in the dark theme; in the light theme
   the plate is inverted so the black ground drops out and the engraving prints in
   brass on parchment. */
.hero__seal {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  right: -38vw;
  bottom: -18vw;
  width: min(118vw, 780px);
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  overflow: hidden;
  opacity: var(--seal-opacity);
  mix-blend-mode: screen;
}
.hero__seal img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
:root[data-theme="light"] .hero__seal {
  mix-blend-mode: multiply;
}
:root[data-theme="light"] .hero__seal img {
  filter: invert(1) hue-rotate(180deg) saturate(1.2);
}

/* SORA IS THE MARKETING VOICE, and it is rationed. This said "THE ONLY --brand ON THE
   SITE" until 2026-09-15, when the homepage rebuild added four more: .shot__screen,
   .howstep__name, .plan-card__n and .ref__name, all of them a single marketing line or a
   price rather than a paragraph. Corrected rather than deleted, because the rule it was
   protecting still holds: a voice used everywhere is just a font. Count the call sites
   before you add the sixth. */
.hero__title {
  font-family: var(--brand);
  font-weight: 700;
  font-size: var(--t-hero);
  line-height: 1;
  letter-spacing: -0.025em;
  max-width: 18ch;
  margin: 0;
}
.hero__tone { color: var(--brass); }
.hero__lede {
  margin: var(--s4) 0 0;
  max-width: 42ch;
  color: var(--text);
}
.hero__chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin-top: var(--s4);
}
/* The chip is the smallest surface on the site, which is why it gets --radius-xs rather than
   the default: 14px on a 26px-tall pill is a lozenge, not a chip. The 3px gold bar down the
   left came off with the rest of the engraving; the gold is the hairline now. */
.hero__chip {
  display: inline-block;
  border: 1px solid var(--glass-line);
  border-radius: var(--radius-xs);
  padding: var(--s1) var(--s3);
  color: var(--muted);
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur));
  backdrop-filter: blur(var(--glass-blur));
}
.hero__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--s3);
  margin-top: var(--s6);
}
.hero__cta {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s2);
  max-width: 22rem;
}
.hero__cta-note {
  margin: 0;
  color: var(--muted);
  max-width: 28ch;
}
.hero--stadium .hero__seal { display: none; }

/* Email for later, on the hero. It was a solid brass slab with a black slot cut into it, and
   it was the most dated object on the page: a flat gold rectangle reads as a 2010 call-to-action
   no matter how good the gold is. It is now the same glass as every other raised surface, with
   a gold-tinted edge and a gold bloom to keep it the loudest thing in the hero.

   THE WHOLE INVERSION WENT WITH IT. The old plate needed literal colours in both themes (a brass
   plate cannot read theme tokens without going dark in light mode) and a dark button, because a
   brass button on a brass plate vanishes. On glass the ordinary gilt button is the right button,
   so this component now has no colour of its own at all: every value below resolves through the
   ramp and the theme handles itself. funded/tests/design-system.test.mjs keeps an exemption for
   .hero__list that is now unused, and that is the correct direction for it to be unused in. */
.hero__list {
  display: grid;
  gap: var(--s3);
  margin-top: var(--s5);
  max-width: 34rem;
  padding: var(--s5) var(--s5) var(--s4);
  border: 1px solid rgba(198, 160, 87, 0.34);
  border-radius: var(--radius-lg);
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.35);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.35);
  box-shadow: var(--glass-shadow), var(--glow-gold-soft);
}
.hero__list-label {
  color: var(--text);
  font-weight: 600;
  max-width: 44ch;
}
.hero__list-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
}
.hero__list-row input {
  flex: 1 1 14rem;
  min-width: 0;
  font-family: var(--body);
  font-size: var(--t-body);
  color: var(--text);
  background: var(--field-bg);
  border: 1px solid var(--field-line);
  border-radius: var(--radius-pill);
  padding: var(--s3) var(--s5);
  transition: border-color 200ms ease, box-shadow 200ms ease;
}
.hero__list-row input::placeholder { color: var(--muted); }
.hero__list-row input:focus-visible {
  outline: none;
  border-color: var(--gold-bright);
  box-shadow: var(--field-focus-ring);
}
.hero__list .form-note:empty { display: none; }
.badge-soon {
  display: inline-block;
  margin-left: var(--s2);
  padding: 0.15em 0.55em;
  border: 1px solid var(--line);
  color: var(--brass);
  font-family: var(--ui);
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  vertical-align: middle;
}
.hero__funded {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s2);
}
.hero__funded .btn { align-self: flex-start; }

/* ---- Mid-page ads + Option B grid, never on the hero --------------------- */
.ad-block {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-bottom: 1px solid var(--line-soft);
}
.ad-block__in {
  position: relative;
  z-index: 1;
  display: grid;
  gap: var(--s7);
}
@media (min-width: 900px) {
  .ad-block__in {
    grid-template-columns: minmax(18rem, 1.15fr) minmax(14rem, 0.85fr);
    align-items: center;
  }
  .ad-block--compact .ad-block__in { grid-template-columns: 1fr; }
}
.ad-block__price {
  margin: 0;
  color: var(--brass);
  font-family: var(--mono); font-variant-numeric: var(--nums);
  font-weight: 600;
}
.ad-block__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s3);
  margin-top: var(--s5);
}
.ad-block__visual {
  display: none;
  pointer-events: none;
  max-width: 20rem;
  justify-self: end;
}
@media (min-width: 900px) {
  .ad-block__visual { display: block; }
}
.atmos {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}
.atmos-grid {
  position: absolute;
  inset: 0;
  background-image:
    linear-gradient(rgba(154, 139, 106, 0.08) 1px, transparent 1px),
    linear-gradient(90deg, rgba(154, 139, 106, 0.08) 1px, transparent 1px);
  background-size: 48px 48px;
  mask-image: linear-gradient(180deg, transparent, rgba(0,0,0,0.55) 35%, rgba(0,0,0,0.25) 80%, transparent);
  -webkit-mask-image: linear-gradient(180deg, transparent, rgba(0,0,0,0.55) 35%, rgba(0,0,0,0.25) 80%, transparent);
  opacity: 0.7;
}
.atmos-grid::after {
  content: "";
  position: absolute;
  left: 6%;
  right: 6%;
  bottom: 0;
  height: 58%;
  background-image:
    linear-gradient(rgba(184, 166, 124, 0.12) 1px, transparent 1px),
    linear-gradient(90deg, rgba(184, 166, 124, 0.12) 1px, transparent 1px);
  background-size: 56px 28px;
  transform: perspective(520px) rotateX(58deg);
  transform-origin: 50% 100%;
  mask-image: linear-gradient(180deg, transparent, rgba(0,0,0,0.7) 40%, transparent);
  -webkit-mask-image: linear-gradient(180deg, transparent, rgba(0,0,0,0.7) 40%, transparent);
}
.atmos-grid--light { opacity: 0.4; }
:root[data-theme="light"] .atmos-grid { opacity: 0.35; }

/* ---- Rewards hub: tote board + two unequal lanes ------------------------- */
.rewards-hub {
  position: relative;
  z-index: 1;
}
.rewards-board {
  margin-top: var(--s6);
  padding: var(--s5);
  border: 1px solid var(--line);
  border-left: 4px solid var(--brass);
  background: var(--panel);
}
.rewards-board__kicker,
.rewards-lane__kicker {
  margin: 0 0 var(--s2);
  color: var(--brass);
  font-family: var(--ui);
  font-size: var(--t-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.rewards-board__name,
.rewards-lane__name {
  margin: 0 0 var(--s3);
  font-size: var(--t-product);
  line-height: 1.15;
  letter-spacing: -0.02em;
}
.rewards-board p,
.rewards-lane p {
  margin: 0;
  max-width: 52ch;
  color: var(--text);
}
.rewards-board__floors {
  list-style: none;
  margin: var(--s5) 0 0;
  padding: 0;
  display: grid;
  gap: 0;
  border-top: 1px solid var(--line);
}
.rewards-board__floors li {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--s3);
  padding: var(--s3) 0;
  border-bottom: 1px solid var(--line-soft);
  font-family: var(--ui);
  font-variant-numeric: tabular-nums;
}
.rewards-board__floors span { color: var(--muted); }
.rewards-board__floors strong {
  color: var(--parchment);
  font-weight: 600;
}
@media (min-width: 720px) {
  .rewards-board__floors {
    grid-template-columns: repeat(4, 1fr);
    gap: var(--s4);
    border-top: 0;
  }
  .rewards-board__floors li {
    flex-direction: column;
    align-items: flex-start;
    padding: var(--s3) 0 0;
    border-bottom: 0;
    border-top: 1px solid var(--line);
  }
}
.rewards-lanes {
  display: grid;
  gap: var(--s6);
  margin-top: var(--s7);
}
@media (min-width: 900px) {
  .rewards-lanes {
    grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
    align-items: start;
  }
}
.rewards-lane {
  padding-top: var(--s4);
  border-top: 1px solid var(--line);
}
.rewards-lane--coins {
  padding-left: 0;
}
@media (min-width: 900px) {
  .rewards-lane--coins {
    padding-left: var(--s6);
    padding-top: 0;
    border-top: 0;
    border-left: 1px solid var(--line);
  }
}
.simcoins-claim {
  margin-top: var(--s4);
}
.simcoins-claim__balance {
  margin: 0 0 var(--s3);
  font-family: var(--mono); font-variant-numeric: var(--nums);
  font-weight: 600;
  font-size: var(--t-lead);
  font-variant-numeric: tabular-nums;
  color: var(--brass-bright);
}
.simcoins-claim__note {
  margin: 0 0 var(--s3);
  color: var(--muted);
}
.simcoins-claim[data-busy] .btn { pointer-events: none; opacity: 0.6; }

/* /rewards and /referrals Stadium Night plate. Same still and scrim as
   the live homepage. Stacking keeps chrome above the fixed plate. */
.page-rewards,
.page-referrals {
  background: #0a0a0a;
}
.page-rewards .masthead,
.page-rewards main,
.page-rewards .site-footer,
.page-referrals .masthead,
.page-referrals main,
.page-referrals .site-footer {
  position: relative;
  z-index: 1;
}
.page-rewards .masthead,
.page-referrals .masthead {
  background: linear-gradient(180deg, rgba(20, 20, 20, 0.88), rgba(10, 10, 10, 0.72));
}
.page-rewards .site-footer,
.page-referrals .site-footer {
  background: rgba(10, 10, 10, 0.82);
}
.hero--rewards {
  min-height: auto;
  padding: var(--pad-hero-top) 0 var(--pad-compact);
  background: transparent;
  border-bottom: 0;
  box-shadow: none;
}
.hero--rewards .hero__title {
  color: var(--parchment);
  max-width: 16ch;
}
.hero--rewards .hero__lede {
  color: var(--brass-bright);
  max-width: 38ch;
}
.claim-stage {
  margin-top: var(--s6);
  padding: var(--s5);
  max-width: 28rem;
  background: rgba(15, 15, 15, 0.78);
  border: 1px solid var(--line);
  border-left: 4px solid var(--brass);
}
.claim-stage__kicker {
  margin: 0 0 var(--s3);
  color: var(--brass);
  font-family: var(--ui);
  font-size: var(--t-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.simcoins-claim[data-state="loading"] .simcoins-claim__balance {
  letter-spacing: 0.12em;
  color: var(--muted);
}
.simcoins-claim[data-state="error"] .simcoins-claim__note {
  color: var(--muted);
}
/* Mobile Social tab is 44px on the right edge. Keep rewards titles out of it. */
@media (max-width: 859px) {
  .page-rewards .hero__title,
  .page-rewards .section-head h2,
  .page-referrals .hero__title,
  .page-referrals .section-head h2 {
    padding-right: calc(var(--sf-rail-tab) + 8px);
  }
}
:root[data-theme="light"] .rewards-board__floors strong { color: var(--text); }
:root[data-theme="light"] .simcoins-claim__balance { color: var(--brass); }
.register__name .badge-soon { margin-left: var(--s3); vertical-align: 0.15em; }
/* On a phone the text sits over the middle of the field, not beside it, so the scrim
   goes vertical. Both stops are the theme's ground, never a baked black: a hard-coded
   black band tracked the viewport across every light-theme page before this. */
@media (max-width: 699px) {
  .hero__scrim {
    background: linear-gradient(180deg, rgba(7, 8, 12, 0.82) 0%, rgba(7, 8, 12, 0.62) 48%, var(--bg) 100%);
  }
  :root[data-theme="light"] .hero__scrim {
    background: linear-gradient(180deg, rgba(244, 245, 248, 0.86) 0%, rgba(244, 245, 248, 0.7) 48%, var(--bg) 100%);
  }
}
:root[data-theme="light"] .hero {
  background: var(--bg);
}
/* The aurora is built for a dark ground. On the light one the same gradients at full
   strength turn the page into a bruise, so it is dialled back and its blue stop is
   dropped by the lower opacity rather than by a second gradient stack to maintain. */
:root[data-theme="light"] .hero__stadium {
  opacity: 0.5;
}
:root[data-theme="light"] .hero__scrim {
  background:
    linear-gradient(96deg, var(--bg) 0%, var(--bg) 30%, rgba(244, 245, 248, 0.78) 46%, rgba(244, 245, 248, 0.32) 60%, transparent 74%),
    linear-gradient(180deg, transparent 62%, var(--bg) 100%);
}
/* The fixed page plate's bottom fade takes the theme's ground, not a baked black: in the
   light theme a black band tracked the viewport across every product page. */
/* HUD cards are charcoal glass in the dark theme; in the light theme they take the light
   ground's glass, so the figure stays readable on the pale plate. */
:root[data-theme="light"] .hud-card {
  background: rgba(255, 255, 255, 0.78);
}
:root[data-theme="light"] .hero__media--page::after {
  background: linear-gradient(180deg, rgba(232, 228, 216, 0) 0%, var(--bg) 42%, var(--bg) 100%);
}

/* The register: two ruled rows, one per product. Rules are ::before hairlines so
   motion.css can draw them. */
.register {
  display: grid;
  gap: var(--gap-row);
  margin-top: var(--s7);
}
.register__row {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas:
    "no name"
    "line line"
    "action action";
  column-gap: var(--s4);
  row-gap: var(--s2);
  padding: var(--s4) 0 var(--s2);
}
.register__row::before {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--brass);
  opacity: 0.6;
}
.register__no {
  grid-area: no;
  color: var(--muted);
  align-self: start;
  padding-top: 0.45em;
}
.register__name {
  grid-area: name;
  font-size: var(--t-product);
  line-height: 1.1;
  letter-spacing: -0.015em;
}
.register__line {
  grid-area: line;
  margin: 0;
  color: var(--text);
  max-width: 44ch;
}
.register__action {
  grid-area: action;
  justify-self: start;
  color: var(--brass);
  text-decoration: none;
  padding: var(--s1) 0;
  border-bottom: 1px solid var(--line);
}
.register__action:hover { color: var(--brass-bright); border-color: var(--brass-bright); }
.register__note {
  color: var(--muted);
  margin: var(--s5) 0 0;
}

@media (min-width: 900px) {
  .hero__actions { margin-top: var(--s7); }
  .hero__seal {
    right: -10vw;
    bottom: auto;
    top: 40%;
    transform: translateY(-50%);
    width: min(56vw, 860px);
  }
  .register {
    grid-template-columns: 1fr 1fr;
    gap: var(--gap-col);
    margin-top: var(--s8);
  }
  .register__row { padding: var(--s5) 0 var(--s3); }
  .register__note { text-align: right; }
}

/* ---- Safe-deposit drawer rows ------------------------------------------- */
.drawers { display: flex; flex-direction: column; gap: var(--s2); }
.drawer {
  display: grid;
  grid-template-columns: 40px 1fr auto;
  align-items: center;
  gap: var(--s4);
  background: linear-gradient(180deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line);
  border-left: 4px solid var(--brass);
  border-radius: var(--radius);
  padding: var(--s4);
  /* A machined drawer face: a thin lit edge along the top, a shadow underneath. */
  box-shadow: inset 0 1px 0 var(--edge-hi), 0 1px 2px var(--shadow);
  transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.drawer:hover {
  border-color: var(--brass);
  box-shadow: inset 0 1px 0 var(--edge-hi), 0 2px 8px var(--shadow);
}
.drawer__no { color: var(--muted); }
.drawer__label {
  font-family: var(--ui);
  font-weight: 500;
  font-size: var(--t-body);
  color: var(--parchment);
}
.drawer__value {
  color: var(--brass-bright);
  text-align: right;
}
:root[data-theme="light"] .drawer__value { color: var(--brass); }

/* ---- Forms --------------------------------------------------------------- */
.form {
  display: grid;
  gap: var(--s4);
  max-width: 480px;
  background: linear-gradient(180deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: var(--s5);
  box-shadow: inset 0 1px 0 var(--edge-hi), 0 2px 6px var(--shadow);
}
.field { display: grid; gap: var(--s2); }
.field label { color: var(--muted); }
.field input {
  font-family: var(--ui);
  font-size: var(--t-body);
  color: var(--text);
  background: var(--field-bg);
  border: 1px solid var(--field-line);
  border-radius: var(--radius);
  padding: var(--s3) var(--s4);
  /* Recessed slot: the input is cut into the raised plate around it. */
  box-shadow: inset 0 1px 2px var(--edge-lo);
  transition: border-color 0.15s ease;
}
.field input:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 1px;
  border-color: var(--brass);
}

/* ---- Date of birth: three dials in one machined plate ------------------------
   Replaces <input type="date">, which on a phone opened parked on today and made
   every visitor scroll back through their whole life to reach their birth year.
   Month, day and year are three separate <select>s so the phone gives its native
   wheel for each: three taps, no keyboard, no scrolling from this year.

   The three sit inside ONE recessed housing with hairline dividers rather than
   three separate boxes, so the control reads as a single field, which is what it
   is. Built by dob.js. -------------------------------------------------------- */
.dob {
  /* A fieldset, so the browser's own border, margin and padding all have to go. */
  border: 0;
  margin: 0;
  padding: 0;
  min-width: 0;
  display: grid;
  gap: 6px;
}
.dob__legend {
  /* Matches .field label exactly. A legend is not a label, so it cannot inherit it. */
  font-family: var(--ui);
  /* On the type scale (13px micro). Was 0.72rem, about 11.5px, which is off the scale
     entirely and the smallest text on the page. */
  font-size: var(--t-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
  padding: 0;
}
.dob__set {
  display: grid;
  grid-template-columns: 1.4fr 0.8fr 1fr;
  background: var(--field-bg);
  border: 1px solid var(--field-line);
  border-radius: var(--radius);
  box-shadow: inset 0 1px 2px var(--edge-lo);
  overflow: hidden;
}
.dob__cell {
  position: relative;
  min-width: 0;
  padding: 0;
}
.dob__cell + .dob__cell { border-left: 1px solid var(--field-line); }
/* Out of flow, so the <select> below spans the whole cell and the entire plate is
   thumb-sized. pointer-events: none passes the tap through to the select under it. */
.dob .dob__label {
  position: absolute;
  top: 8px;
  left: 10px;
  font-family: var(--ui);
  /* WAS 0.6rem, which computes to about 10px: the smallest type anywhere on the site, on
     the muted token, over the darkest panel. It was reported by hand as too hard to read on
     the date of birth row, and the type audit found it independently as the only off-scale
     size in the whole page. 13px is the scale's micro
     step, and the colour moves off muted so MONTH, DAY and YEAR are readable at arm's
     length rather than merely present. */
  font-size: var(--t-micro);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--parchment);
  pointer-events: none;
}
.dob__select {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  min-width: 0;
  /* Top padding clears the label sitting over the cell; 24px on the right keeps the
     longest month clear of the chevron. The label is now 13px rather than 10px, so the
     clearance and the housing both grow: 56px keeps the whole plate a comfortable thumb
     target instead of a tight one. */
  padding: 26px 24px 8px 10px;
  min-height: 56px;
  font-family: var(--ui);
  /* 16px, the body step. Was 0.95rem, about 15px, and off the scale. */
  font-size: var(--t-body);
  color: var(--text);
  background: transparent;
  border: 0;
  border-radius: 0;
  cursor: pointer;
}
/* Brass chevron, drawn rather than fetched, so it takes the theme's token and adds
   no request. On the cell, not the select, so it survives appearance: none. */
.dob__cell::after {
  content: "";
  position: absolute;
  right: 10px;
  bottom: 22px;
  width: 7px;
  height: 7px;
  border-right: 1.5px solid var(--brass);
  border-bottom: 1.5px solid var(--brass);
  transform: rotate(45deg);
  pointer-events: none;
}
/* The housing takes the focus ring, so focusing one dial lights the whole plate and
   the visitor can see which field they are in without hunting for a 1px edge. */
.dob__set:focus-within {
  outline: 2px solid var(--focus);
  outline-offset: 1px;
  border-color: var(--brass);
}
.dob__select:focus { outline: none; }
.dob__select:focus-visible { outline: none; }
/* The picked date read back in words, so a mis-tapped year is caught here and not by
   a 403 from the age gate. Empty until all three dials are set. */
.dob__readout {
  font-family: var(--ui);
  font-size: 0.78rem;
  color: var(--muted);
  margin: 0;
  min-height: 1.1em;
}
.dob__readout.is-ok { color: var(--muted); }
.dob__readout.is-refused { color: var(--danger); }

/* Under about 340px the three dials stop fitting side by side. Month takes its own
   row and day and year share the next one, which keeps every target thumb-sized. */
@media (max-width: 340px) {
  .dob__set { grid-template-columns: 1fr 1fr; }
  .dob__cell--month {
    grid-column: 1 / -1;
    border-bottom: 1px solid var(--field-line);
  }
  .dob__cell--day { border-left: 0; }
}

/* status line (aria-live) and its states */
.form-note {
  color: var(--muted);
  margin: 0;
  min-height: 1.4em;
  text-transform: none;
  letter-spacing: 0.02em;
}
.form-note.is-success { color: var(--brass-bright); }
:root[data-theme="light"] .form-note.is-success { color: var(--brass); }
.form-note.is-error { color: var(--danger); }

/* fine print under a form */
.form-fine {
  font-family: var(--body);
  font-size: var(--t-micro);
  line-height: 1.5;
  color: var(--muted);
  margin: 0;
  max-width: 52ch;
}
.form-fine a { color: var(--brass); }

/* small standalone note (referral) */
.block-note {
  color: var(--muted);
  margin-top: var(--s4);
  max-width: 60ch;
  text-transform: none;
  letter-spacing: 0.02em;
}

/* honeypot: kept in the DOM for bots, out of sight and out of the tab order */
.trap {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Age and terms gate on the signup form. Reads as a form field, not a warning. */
.consent {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s3);
  align-items: start;
}
.consent input {
  width: 16px;
  height: 16px;
  margin: 2px 0 0;
  accent-color: var(--brass);
  cursor: pointer;
}
.consent label {
  font-size: var(--t-micro);
  line-height: 1.5;
  color: var(--muted);
  cursor: pointer;
}
.consent a { color: var(--brass); }
.consent input:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

/* ---- The two products, side by side. Two plates divided by one brass rule, not two
        identical cards in a grid: the divider is the point, they are alternatives. ---- */
.split {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: linear-gradient(180deg, var(--panel-2), var(--panel));
  box-shadow: inset 0 1px 0 var(--edge-hi), 0 1px 3px var(--shadow);
  overflow: hidden;
}
.split__half { padding: var(--s5); }
.split__half + .split__half { border-top: 1px solid var(--line); }
.split__no { color: var(--muted); }
.split__name {
  font-size: var(--t-product);
  line-height: 1.1;
  letter-spacing: -0.015em;
  margin: var(--s2) 0 var(--s3);
}
.split__price {
  font-family: var(--mono);
  font-variant-numeric: var(--nums);
  font-weight: 600;
  font-size: var(--t-lead);
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
  color: var(--brass-bright);
  margin: 0 0 var(--s4);
}
.split__per {
  display: block;
  color: var(--muted);
  margin-top: var(--s1);
}
.split__body {
  color: var(--text);
  margin: 0 0 var(--s4);
  border-top: 1px solid var(--line-soft);
  padding-top: var(--s4);
}
.split__link { margin: 0; }
@media (min-width: 720px) {
  .split { grid-template-columns: 1fr 1fr; }
  .split__half { padding: var(--s6); }
  .split__half + .split__half { border-top: 0; border-left: 1px solid var(--line); }
}
:root[data-theme="light"] .split__price { color: var(--brass); }

/* ---- Pricing. Two plans blocks, each a product heading, a lead, the plates, notes. ---- */
.plan { margin-top: var(--s7); }
.plan__head {
  display: grid;
  gap: var(--s3);
  margin-bottom: var(--s5);
  padding-bottom: var(--s4);
  border-bottom: 1px solid var(--line);
}
.subhead {
  font-size: var(--t-product);
  line-height: 1.1;
  letter-spacing: -0.015em;
  color: var(--parchment);
}
.plan__lead {
  color: var(--text);
  max-width: 62ch;
  margin: 0;
}
.plan__notes { margin-top: var(--s5); }
.plan__notes p { margin-bottom: var(--s3); max-width: 62ch; }
@media (min-width: 900px) {
  .plan { margin-top: var(--s8); }
  .plan__head { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--gap-col); align-items: end; }
  /* Notes sit in the register's text column, under the lead, not under the label column. */
  .plan__notes { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); column-gap: var(--gap-col); }
  .plan__notes > * { grid-column: 2; }
}

/* Safe-deposit box faces, brass number plate, one featured. */
.tiers {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--gap-row);
}
.tier {
  position: relative;
  display: flex;
  flex-direction: column;
  background: var(--card-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.3);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.3);
  border: 1px solid var(--card-line);
  border-radius: var(--radius-lg);
  padding: var(--s6) var(--s5) var(--s5);
  box-shadow: var(--card-shadow);
  transition: transform 260ms cubic-bezier(0.22, 1, 0.36, 1), box-shadow 260ms ease,
              border-color 260ms ease;
}
/* The 4px brass cap on top of every card became a 1px gilt seam INSIDE it. A heavy coloured
   top border is the thing that made these read as filing cards; a seam that stops short of the
   corners reads as a lit edge on a piece of glass. */
.tier::before {
  content: "";
  position: absolute;
  top: 0;
  left: 12%;
  right: 12%;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
  opacity: 0.7;
}
.tier:hover {
  transform: translateY(-3px);
  border-color: rgba(198, 160, 87, 0.4);
  box-shadow: var(--card-shadow-lift);
}
/* The pulled-out box: a wider seam, a gold bloom under it, and a permanently lifted seat, so
   the top of the ladder is visibly the top without needing a second border colour.

   Its old background carried a malformed gradient, rgba(154, 139, 106), 0.10), which the parser
   threw away along with the whole declaration. The wash it was supposed to draw had never
   rendered on any page. Fixed 2026-09-12 by not hand-mixing one at all. */
.tier--feature {
  border-color: rgba(198, 160, 87, 0.42);
  box-shadow: var(--card-shadow-lift), var(--glow-gold-soft);
}
.tier--feature::before { left: 0; right: 0; opacity: 1; }
.tier__no { color: var(--muted); }
.tier__name {
  font-size: var(--t-body);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--parchment);
  margin: var(--s2) 0 var(--s3);
}
.tier__price {
  font-family: var(--mono);
  font-variant-numeric: var(--nums);
  font-weight: 600;
  font-size: var(--t-product);
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
  color: var(--brass-bright);
  margin: 0;
}
:root[data-theme="light"] .tier__price { color: var(--brass); }
.tier__period {
  display: block;
  color: var(--muted);
  margin-top: var(--s1);
}
/* Plan specs. A ruled list inside each box, not a row of check marks. */
.tier__specs {
  flex: 1 1 auto;
  margin: var(--s4) 0 0;
  border-top: 1px solid var(--line-soft);
  padding-top: var(--s2);
}
.tier__specs > div {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--s3);
  padding: var(--s2) 0;
}
.tier__specs > div + div { border-top: 1px solid var(--line-soft); }
.tier__specs dt { color: var(--muted); }
.tier__specs dd {
  margin: 0;
  font-family: var(--ui);
  font-weight: 500;
  font-size: var(--t-body);
  font-variant-numeric: tabular-nums;
  color: var(--parchment);
  text-align: right;
}
/* The button is pushed to the bottom of the card so the four CTAs line up across the
   row whatever the specs above them do. */
.tier__cta { margin: var(--s4) 0 0; }
.tier__cta .btn { display: block; width: 100%; text-align: center; }
@media (min-width: 600px) {
  .tiers { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1100px) {
  .tiers { grid-template-columns: repeat(4, 1fr); }
}

/* The generator. One wide plate with the intro price on the brass side, deliberately
   not a fifth tier card. */
.gen {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  background: linear-gradient(180deg, var(--panel-2), var(--panel));
  box-shadow: inset 0 1px 0 var(--edge-hi), 0 1px 3px var(--shadow);
}
.gen__now {
  padding: var(--s5);
  border-left: 4px solid var(--brass);
  border-bottom: 1px solid var(--line);
}
.gen__label { color: var(--muted); }
.gen__price {
  font-family: var(--mono);
  font-variant-numeric: var(--nums);
  font-weight: 600;
  font-size: var(--t-product);
  font-variant-numeric: tabular-nums;
  color: var(--brass-bright);
  margin: var(--s2) 0 0;
  line-height: 1.1;
}
:root[data-theme="light"] .gen__price { color: var(--brass); }
.gen__per {
  display: block;
  color: var(--muted);
  margin-top: var(--s1);
}
.gen__after {
  padding: var(--s5);
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.gen__row {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--s3);
  padding: var(--s2) 0;
}
.gen__row + .gen__row { border-top: 1px solid var(--line-soft); }
.gen__rowlabel { color: var(--muted); }
.gen__rowvalue {
  font-family: var(--ui);
  font-weight: 500;
  font-size: var(--t-body);
  font-variant-numeric: tabular-nums;
  color: var(--parchment);
}
@media (min-width: 720px) {
  .gen { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .gen__now { border-bottom: 0; border-right: 1px solid var(--line); }
}

/* ---- Legal document pages (privacy / terms) ----------------------------- */
.docnav {
  border-bottom: 1px solid var(--line-soft);
  background: var(--panel);
}
.docnav__in {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s5);
  align-items: center;
  min-height: var(--s7);
}
.docnav__in a {
  font-family: var(--ui);
  font-weight: 500;
  font-size: var(--t-micro);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--muted);
}
.docnav__in a:hover { color: var(--parchment); }
.docnav__in a[aria-current="page"] {
  color: var(--parchment);
  border-bottom: 2px solid var(--brass);
  padding-bottom: 2px;
}

.doc { padding: var(--pad-compact) 0 var(--pad-section); }
.doc__in { max-width: 70ch; margin: 0 auto; }
.doc__eyebrow {
  font-family: var(--ui);
  font-weight: 500;
  font-size: var(--t-micro);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--brass);
  margin: 0 0 var(--s3);
}
.doc h1 {
  font-size: var(--t-section);
  line-height: 1.05;
  letter-spacing: -0.02em;
  margin: 0 0 var(--s3);
}
.doc__meta {
  font-family: var(--ui);
  font-size: var(--t-micro);
  letter-spacing: 0.04em;
  color: var(--muted);
  margin: 0 0 var(--s6);
}
.doc__summary {
  background: linear-gradient(180deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line);
  border-left: 4px solid var(--brass);
  border-radius: var(--radius);
  padding: var(--s4) var(--s5);
  margin: 0 0 var(--s6);
  box-shadow: inset 0 1px 0 var(--edge-hi), 0 1px 3px var(--shadow);
}
.doc__summary p { color: var(--parchment); margin: 0; }
.doc h2 {
  font-size: var(--t-product);
  line-height: 1.15;
  margin: var(--s7) 0 var(--s3);
  padding-bottom: var(--s2);
  border-bottom: 1px solid var(--line-soft);
}
.doc h3 {
  font-size: var(--t-lead);
  margin: var(--s5) 0 var(--s2);
  color: var(--parchment);
}
.doc p, .doc li { color: var(--text); }
.doc ul {
  margin: 0 0 var(--s4);
  padding-left: var(--s5);
}
.doc li { margin-bottom: var(--s2); }
.doc a { color: var(--brass); }
.doc a:hover { color: var(--brass-bright); }
.doc strong { color: var(--parchment); }
.doc__contact {
  margin-top: var(--s7);
  padding-top: var(--s5);
  border-top: 1px solid var(--line);
  color: var(--muted);
}

/* ---- Footer -------------------------------------------------------------- */
.site-footer {
  border-top: 1px solid var(--line);
  box-shadow: inset 0 1px 0 var(--edge-hi);
  background: linear-gradient(0deg, var(--bg-lift), var(--bg));
  padding: var(--s7) 0 var(--s8);
}
.site-footer__row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s4);
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--s5);
}
.footer-seal {
  display: inline-flex;
  align-items: center;
  gap: var(--s3);
  text-decoration: none;
  color: var(--parchment);
}
.footer-seal img {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid var(--brass);
  padding: 2px;
  background: radial-gradient(circle at 50% 42%, rgba(216,184,120,0.16), transparent 70%);
}
.footer-seal__type {
  font-weight: 600;
  font-size: var(--t-body);
  letter-spacing: 0.03em;
  text-transform: none;
}
.site-footer__nav {
  display: flex;
  gap: var(--s5);
  list-style: none;
  margin: 0;
  padding: 0;
}
.site-footer__nav a {
  text-decoration: none;
  color: var(--muted);
}
.site-footer__nav a:hover { color: var(--parchment); }
.site-footer__tagline {
  margin: 0 0 var(--s4);
  color: var(--muted);
  font-size: var(--t-micro);
  letter-spacing: 0.02em;
}
.site-footer__legalnav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s4) var(--s5);
  margin: 0 0 var(--s5);
  padding-top: var(--s4);
  border-top: 1px solid var(--line-soft);
}
.site-footer__legalnav a {
  text-decoration: none;
  color: var(--muted);
}
.site-footer__legalnav a:hover { color: var(--parchment); }
.legal { max-width: 78ch; }
.legal p {
  font-size: var(--t-micro);
  line-height: 1.55;
  color: var(--muted);
  margin: 0 0 var(--s3);
}
.legal--mono {
  color: var(--muted);
  text-transform: none;
  letter-spacing: 0.02em;
}
.legal--mark {
  color: var(--muted);
  text-transform: none;
  letter-spacing: 0.02em;
}

/* ---- Small screens ------------------------------------------------------- */
@media (max-width: 560px) {
  .drawer { grid-template-columns: 32px 1fr; }
  .drawer__value { grid-column: 2 / -1; text-align: left; }
}

/* ---- PLACEHOLDER marker. Deliberately ugly. Nothing ships with one of these on it. ---- */
.fill {
  font-family: var(--ui);
  font-size: 0.86em;
  letter-spacing: 0.04em;
  color: #0b0d0c;
  background: var(--danger);
  border-radius: var(--radius);
  padding: 1px 6px;
  white-space: nowrap;
}


/* ---- "Where the Yards Went" board (Statyx) -------------------------------- */
/*
   A deposit-box index card. Brass hairline ruling, tabular figures, and one proportional
   brass bar per row drawn INSIDE the ruling rather than sitting on top of it, so the panel
   reads as an engraved gauge and not as a chart bolted onto the page. Same 2px radius,
   same two families, same spacing scale as everything else here; the only new idea is the
   bar, and it is the only place this panel spends any boldness.

   The bar width is quantised to 21 steps and selected by [data-fill], because the page CSP
   is style-src 'self' with no 'unsafe-inline' and gate.sh check 4 fails the build on any
   style attribute in the HTML. A stylesheet rule is the only honest way to vary a width here.
*/
[hidden] { display: none !important; }

.board__tabs {
  display: flex;
  gap: var(--s2);
  margin-bottom: var(--s4);
  flex-wrap: wrap;
}
.board__tab {
  font-family: var(--ui);
  font-weight: 600;
  font-size: var(--t-micro);
  letter-spacing: 0.08em;
  color: var(--muted);
  background: var(--panel);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  padding: var(--s2) var(--s4);
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.board__tab:hover { color: var(--brass-bright); border-color: var(--brass-deep); }
.board__tab[aria-selected="true"] {
  color: var(--parchment);
  border-color: var(--brass);
  /* The selected tab is the drawer that is pulled out: brass on its leading edge only. */
  border-left-width: 4px;
  border-left-color: var(--brass);
}

.board__rows { display: flex; flex-direction: column; gap: 1px; }
.board__row {
  position: relative;
  display: grid;
  grid-template-columns: 40px 1fr auto auto;
  align-items: baseline;
  gap: var(--s4);
  padding: var(--s3) var(--s4);
  background: linear-gradient(180deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  box-shadow: inset 0 1px 0 var(--edge-hi);
  overflow: hidden;
}
/* The gauge. Sits behind the figures, never over them. */
.board__row::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  background: linear-gradient(90deg, rgba(154, 139, 106), 0.20), rgba(154, 139, 106), 0.04));
  border-right: 1px solid var(--line);
  pointer-events: none;
}
.board__rank,
.board__team,
.board__yards,
.board__td { position: relative; }

.board__rank {
  font-family: var(--mono);
  font-variant-numeric: var(--nums);
  font-variant-numeric: tabular-nums;
  color: var(--muted);
}
.board__team {
  font-family: var(--ui);
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--parchment);
}
.board__yards {
  font-family: var(--mono);
  font-variant-numeric: var(--nums);
  font-variant-numeric: tabular-nums;
  color: var(--brass-bright);
  text-align: right;
}
.board__td {
  font-family: var(--mono);
  font-variant-numeric: var(--nums);
  font-variant-numeric: tabular-nums;
  font-size: var(--t-micro);
  color: var(--muted);
  text-align: right;
  min-width: 6ch;
}

/* The two ends of the ranking, named. Two rules, not a card grid: the board above is already
   the visual, and this is the one line a reader wanted from it. Deliberately NOT two equal
   boxes with icons, which is what this wants to become. */
.board__ends {
  margin-top: var(--s4);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s4) var(--s6);
  padding-top: var(--s4);
  border-top: 1px solid var(--line-soft);
}
.board__end { margin: 0; display: flex; align-items: baseline; gap: var(--s3); }
.board__end-k {
  font-family: var(--ui);
  font-size: var(--t-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}
.board__end-v {
  font-family: var(--mono);
  font-variant-numeric: var(--nums);
  font-variant-numeric: tabular-nums;
  color: var(--parchment);
}
/* The vendor credit. Present and legible, not apologetic and not a disclaimer in grey 10px:
   the licence is a thing we pay for and their name on it is what makes the embed terms work. */
.board__credit { font-size: var(--t-micro); color: var(--muted); }
.board__credit a { color: var(--brass-bright); }
:root[data-theme="light"] .board__credit a { color: var(--brass); }

/* ============================================================
   THE STATYX TOOLS. Two boards inside one section, added 2026-09-08.

   Every colour here is a token, so light theme is handled by the token flip at the top of
   this file rather than by a second copy of these rules. The one thing that is NOT a token is
   the impact tone, and that reads --danger / --brass / --muted, all three of which are already
   redefined for light theme above.

   The boards stack on a phone and sit side by side from 900px, where a 10-row wire and an
   8-row board are close enough in height to read as a pair.
   ============================================================ */
.tools { display: grid; gap: var(--s7); }
@media (min-width: 900px) {
  .tools { grid-template-columns: 1fr 1fr; gap: var(--s6); align-items: start; }
}
.tool__head { margin-bottom: var(--s4); }
.tool__name {
  font-family: var(--ui);
  font-size: var(--t-lead);
  letter-spacing: 0.02em;
  margin: 0 0 var(--s2);
  color: var(--parchment);
}
.tool__lead { margin: 0; color: var(--muted); font-size: var(--t-micro); max-width: 46ch; }

/* THE WIRE ROW. Three columns on a wide screen, two stacked blocks on a phone: the vendor
   note is the first thing to go, because a status and a name are the row's whole point and a
   180-character note at 390px is four lines of wrap. It is hidden, not removed, so the same
   markup serves both and nothing re-renders on resize. */
.wire__rows { display: flex; flex-direction: column; gap: 1px; }
.wire__row {
  display: grid;
  grid-template-columns: 8.5rem 1fr;
  align-items: baseline;
  gap: var(--s3) var(--s4);
  padding: var(--s3) var(--s4);
  background: linear-gradient(180deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  box-shadow: inset 0 1px 0 var(--edge-hi);
}
.wire__status {
  font-family: var(--ui);
  font-size: var(--t-micro);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  /* A left rule rather than a filled pill: the row is already a drawer face, and a coloured
     lozenge on it is the thing this design keeps refusing to become. */
  border-left: 2px solid var(--muted);
  padding-left: var(--s3);
  color: var(--muted);
}
.wire__row[data-impact="high"] .wire__status { border-left-color: var(--danger); color: var(--danger); }
.wire__row[data-impact="medium"] .wire__status { border-left-color: var(--brass); color: var(--brass-bright); }
.wire__who { display: flex; flex-direction: column; gap: var(--s1); min-width: 0; }
.wire__player {
  font-family: var(--ui);
  font-weight: 600;
  color: var(--parchment);
  /* A vendor name is arbitrary length and must not widen the grid past the viewport. */
  overflow-wrap: anywhere;
}
.wire__meta {
  font-family: var(--mono);
  font-variant-numeric: var(--nums);
  font-size: var(--t-micro);
  letter-spacing: 0.06em;
  color: var(--muted);
}
.wire__note {
  grid-column: 1 / -1;
  font-size: var(--t-micro);
  color: var(--muted);
  padding-top: var(--s2);
  border-top: 1px solid var(--line-soft);
}
@media (max-width: 620px) {
  .wire__row { grid-template-columns: 1fr; }
  /* The note is the row's least load-bearing part and the most expensive at this width. */
  .wire__note { display: none; }
}

:root[data-theme="light"] .board__yards { color: var(--brass); }
:root[data-theme="light"] .board__row::before {
  background: linear-gradient(90deg, rgba(138, 109, 51, 0.16), rgba(138, 109, 51, 0.03));
}

.board__row[data-fill="0"]::before { width: 0%; }
.board__row[data-fill="1"]::before { width: 5%; }
.board__row[data-fill="2"]::before { width: 10%; }
.board__row[data-fill="3"]::before { width: 15%; }
.board__row[data-fill="4"]::before { width: 20%; }
.board__row[data-fill="5"]::before { width: 25%; }
.board__row[data-fill="6"]::before { width: 30%; }
.board__row[data-fill="7"]::before { width: 35%; }
.board__row[data-fill="8"]::before { width: 40%; }
.board__row[data-fill="9"]::before { width: 45%; }
.board__row[data-fill="10"]::before { width: 50%; }
.board__row[data-fill="11"]::before { width: 55%; }
.board__row[data-fill="12"]::before { width: 60%; }
.board__row[data-fill="13"]::before { width: 65%; }
.board__row[data-fill="14"]::before { width: 70%; }
.board__row[data-fill="15"]::before { width: 75%; }
.board__row[data-fill="16"]::before { width: 80%; }
.board__row[data-fill="17"]::before { width: 85%; }
.board__row[data-fill="18"]::before { width: 90%; }
.board__row[data-fill="19"]::before { width: 95%; }
.board__row[data-fill="20"]::before { width: 100%; }

@media (max-width: 460px) {
  /* The TD column is the first thing to go: it is context, not the number being ranked. */
  .board__row { grid-template-columns: 32px 1fr auto; gap: var(--s3); }
  .board__td { display: none; }
}

/* ---- Visual pass, 2026-09-08 (W5 in the website work order) --------------- */
/*
   Additive only, per the work order: no new typeface, no new accent, no new radius, no copy
   change, no markup change.

   THE ONE REAL FINDING. At 1440 the hero seal was clipped by the VIEWPORT rather than by its
   own roundel, and the clip landed in the middle of the engraved wordmark, so the page read
   "THE SIMFATHE" in 200px letters. A crop through a word looks like a bug, not a decision,
   and it was the first thing on the page at desktop width. Two changes, both here:

   1. The plate now fits entirely inside the viewport at wide widths, so it reads as a complete
      engraved roundel. That is the object the design intended: a plate screened onto steel.
   2. Lower opacity above 900px than the shared token gives it. The plate is at its largest
      exactly where it sits behind the right-hand product column, and at 0.2 the brass letters
      competed with "The Lineup Generator" for the same eye. The two products being legible as
      two distinct things is the single job this page has in its first four seconds.

   At 390 nothing changes: the seal is already a faint texture low on the page, which is right.
*/
@media (min-width: 900px) {
  .hero__seal {
    /* Tangent to the right edge, so the roundel closes on screen. */
    right: 0;
    width: min(42vw, 620px);
    /* The plate is behind type here, so it sits further back than the shared token. */
    opacity: 0.12;
  }
  /* The plate is square art in a circular window; contain keeps the engraving whole
     rather than cropping its border away. */
  .hero__seal img { object-fit: contain; }
}
:root[data-theme="light"] .hero__seal { opacity: 0.1; }
@media (min-width: 900px) {
  :root[data-theme="light"] .hero__seal { opacity: 0.09; }
}

/* ---- Hero fits the first screen on a phone, 2026-09-08 --------------------- */
/*
   MEASURED, not judged. At 390x844 the hero was 888px tall: 105.2% of the viewport, so it
   overflowed the first screen and BOTH PRODUCT NAMES FELL BELOW THE FOLD.
   live-site/MOTION-SPEC.md is explicit that they must not: "At 390, they stack immediately
   below the headline and both names remain above the fold", and the four-second read it
   specifies depends on that. The reference sites that spec measured sit near 79% at this
   width. So this is a spec violation being closed, not a taste preference.

   Only vertical spacing moves. The headline stays at its 61px scale step, the register keeps
   both rows, and no copy is cut. Tokens only: 48 and 32 replace 96 and 64 on the hero
   padding, and the register rows give back one token each.
*/
@media (max-width: 899px) {
  :root {
    --pad-hero-top: var(--s7);      /* 48, was 96 */
    --pad-hero-bottom: var(--s6);   /* 32, was 64 */
  }
  /* The gap between the headline block and the register, which at 48 was the single
     largest interval inside a hero that did not fit. */
  .register { margin-top: var(--s5); }
  .register__row { padding: var(--s3) 0 var(--s2); }
  .hero__actions { margin-top: var(--s5); }
  .hero__lede { margin-top: var(--s3); }
  .hero__chips { margin-top: var(--s3); }
}

/* ---- How it works, and the FAQ, 2026-09-08 -------------------------------- */
/*
   Structure borrowed from the reference sites MOTION-SPEC.md measured. Nothing new is
   invented visually: the FAQ is a ruled register of rows, which is the same object the rest
   of the page is built from, and only the six type steps already on the scale are used.

   THE STEPS ARE A VERTICAL PATH, NOT A THREE-UP CARD GRID, and that was a deliberate
   revision. The first version was three equal cards side by side, each with an ordinal, a
   bold title and one sentence, which is the single most recognisable generated-page layout
   there is. It also lied about the content: three cards read as three parallel options, and
   these are three steps in an order. A numbered spine with the rule running between the
   marks reads as a sequence, reuses the brass register language already on the page, and
   could not be mistaken for anyone else's template.
*/
.steps {
  display: grid;
  gap: 0;
  max-width: 68ch;
}
.step {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: var(--s5);
  padding: var(--s5) 0;
}
/* The spine. Drawn between the marks rather than through them, so the ordinals read as
   stations on a line instead of beads on a wire. It stops short at the last step. */
.step::before {
  content: "";
  position: absolute;
  left: 15px;
  top: calc(var(--s5) + 32px);
  bottom: 0;
  width: 1px;
  background: linear-gradient(180deg, var(--brass-deep), var(--line-soft));
}
.step:last-child::before { display: none; }
.step__no {
  grid-row: 1 / span 2;
  align-self: start;
  display: grid;
  place-items: center;
  width: 31px;
  height: 31px;
  border: 1px solid var(--brass);
  border-radius: 50%;
  background: var(--bg);
  font-family: var(--ui);
  font-variant-numeric: tabular-nums;
  font-size: var(--t-micro);
  letter-spacing: 0.04em;
  color: var(--brass-bright);
}
.step__name {
  font-family: var(--ui);
  font-weight: 600;
  font-size: var(--t-product);
  line-height: 1.15;
  color: var(--parchment);
  margin: 0 0 var(--s2);
}
.step__line { margin: 0; }
:root[data-theme="light"] .step__no { background: var(--bg); color: var(--brass-deep); }

/* The FAQ. Native details/summary, so it works with JavaScript off and needs nothing from
   the CSP. The marker is drawn as a brass cross that becomes a minus when open, rather than
   the browser's triangle, so it takes the theme's tokens. */
.faq { display: grid; gap: 1px; }
.faq__item {
  background: linear-gradient(180deg, var(--panel-2), var(--panel));
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  box-shadow: inset 0 1px 0 var(--edge-hi);
}
.faq__item[open] {
  border-color: var(--line);
  box-shadow: inset 0 1px 0 var(--edge-hi), 0 2px 8px var(--shadow);
}
.faq__q {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--s4);
  padding: var(--s4);
  cursor: pointer;
  font-family: var(--ui);
  font-weight: 600;
  font-size: var(--t-body);
  color: var(--parchment);
  list-style: none;
}
.faq__q::-webkit-details-marker { display: none; }
.faq__q::after {
  content: "";
  width: 11px;
  height: 11px;
  /* A brass cross, drawn from two hairlines via a gradient pair. */
  background:
    linear-gradient(var(--brass), var(--brass)) center / 11px 1.5px no-repeat,
    linear-gradient(var(--brass), var(--brass)) center / 1.5px 11px no-repeat;
  transition: transform 0.14s cubic-bezier(0.2, 0, 0, 1);
}
/* Open: the vertical stroke rotates away, leaving a minus. */
.faq__item[open] .faq__q::after {
  background: linear-gradient(var(--brass-bright), var(--brass-bright)) center / 11px 1.5px no-repeat;
}
.faq__q:hover { color: var(--brass-bright); }
.faq__q:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: -2px;
}
.faq__a {
  margin: 0;
  padding: 0 var(--s4) var(--s4);
  max-width: 68ch;
  color: var(--text);
}

@media (prefers-reduced-motion: reduce) {
  .faq__q::after { transition: none; }
}

/* ---- Primary nav: grouped tabs with dropdown panels ------------------------
   Modelled on the prop-firm comparison shots kept in design-review/, where the nav carries
   product groups rather than two bare links. Ours had Home and Sign In, which told a
   first-time visitor nothing about what is sold here.

   IT OPENS WITHOUT JAVASCRIPT. :hover covers a mouse and :focus-within covers a keyboard, so
   every destination is reachable with scripting off. nav.js adds only what those two cannot do:
   a tap on a phone (there is no hover), Escape, and clicking away. See the header of nav.js.

   The panel is hidden with visibility rather than display:none so it can transition, and
   visibility (unlike opacity alone) genuinely removes it from the tab order while closed. */
.nav__group { position: relative; }
.nav__tab {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  font: inherit;
  color: var(--muted);
  background: transparent;
  border: 0;
  padding: var(--s1) 0;
  cursor: pointer;
  white-space: nowrap;
  transition: color 0.15s ease;
}
.nav__tab:hover,
.nav__group:not([data-shut]):hover > .nav__tab,
.nav__group[data-open] > .nav__tab { color: var(--parchment); }

/* A caret drawn in CSS rather than shipped as an icon file or an inline SVG: one less asset,
   and it inherits currentColor so it follows the theme with no second rule. */
.nav__caret {
  width: 6px;
  height: 6px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-2px) rotate(45deg);
  transition: transform 0.18s ease;
}
.nav__group:not([data-shut]):hover > .nav__tab .nav__caret,
.nav__group[data-open] > .nav__tab .nav__caret { transform: translateY(1px) rotate(225deg); }

.nav__panel {
  position: absolute;
  top: calc(100% + var(--s3));
  left: -var(--s4);
  left: calc(var(--s4) * -1);
  min-width: 22rem;
  display: grid;
  gap: 2px;
  padding: var(--s2);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  /* The same machined face the plates elsewhere carry: a lit top edge and a seated shadow, so
     the panel reads as a drawer pulled out of the wall rather than a floating card. */
  box-shadow: inset 0 1px 0 rgba(255, 246, 224, 0.10), 0 18px 40px rgba(0, 0, 0, 0.55);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-4px);
  transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s;
  z-index: 60;
}
/* The gap between the tab and the panel (top: 100% + s3) is dead space the cursor has to
   cross diagonally on the way down. :hover only holds while the pointer is over the element
   or a descendant, so that gap silently ends the hover before the panel is ever reached and
   the menu closes under the mouse. This pseudo-element extends .nav__group's own hover area
   up to the panel's top edge -- invisible, but keeps the hover chain unbroken across the gap. */
.nav__group::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  height: var(--s3);
}
.nav__group:not([data-shut]):hover > .nav__panel,
.nav:not([data-nav-js]) .nav__group:focus-within > .nav__panel,
.nav__group[data-open] > .nav__panel {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
.nav__panel a {
  display: grid;
  gap: 2px;
  padding: var(--s3) var(--s4);
  border-radius: var(--radius);
  white-space: normal;
}
.nav__panel a:hover,
.nav__panel a:focus-visible { background: rgba(154, 139, 106, 0.10); }
.nav__panel-name { color: var(--text); font-weight: 600; }
.nav__panel a:hover .nav__panel-name { color: var(--parchment); }
.nav__panel-note { color: var(--muted); font-size: 0.82rem; line-height: 1.45; }

/* The Sign Up pill. The comparison shots put a filled pill at the end of the nav and it is the one
   place on this site where a rounded shape is right: it reads as a button, not as a plate. */
.btn--pill { border-radius: 999px; padding-inline: var(--s5); }
.nav__cta a { padding: 0; }

/* The burger. Hidden on desktop; it is the only nav control below the breakpoint. */
.nav__burger {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 40px;
  height: 36px;
  padding: 0 8px;
  background: transparent;
  border: 1px solid var(--line-strong, var(--line));
  border-radius: var(--radius);
  cursor: pointer;
}
.nav__burger-bar {
  display: block;
  height: 1.5px;
  background: currentColor;
  color: var(--text);
}

/* Below this width the six items collide with the guild seal and the Products tab.
   1280 keeps the full row. 390 is seal + wordmark left, hamburger right. */
@media (max-width: 1100px) {
  .nav__burger { display: inline-flex; }
  .nav { gap: var(--s3); }
  .nav__links {
    position: absolute;
    top: 100%;
    right: 0;
    left: 0;
    display: none;
    flex-direction: column;
    gap: 0;
    padding: var(--s3) var(--s4) var(--s4);
    background: var(--panel);
    border-top: 1px solid var(--line);
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.55);
    z-index: 60;
  }
  .nav[data-nav-open] .nav__links { display: flex; }
  .nav__links > li { padding: var(--s2) 0; border-bottom: 1px solid var(--line); }
  .nav__links > li:last-child { border-bottom: 0; }
  .nav__panel {
    position: static;
    min-width: 0;
    opacity: 1;
    visibility: visible;
    transform: none;
    display: none;
    margin-top: var(--s2);
    background: transparent;
    border: 0;
    box-shadow: none;
    padding: 0;
  }
  /* On touch there is no hover, so the panel follows the button's state only. */
  .nav__group[data-open] > .nav__panel { display: grid; }
  .nav__group:hover > .nav__panel { display: none; }
  .nav__group[data-open]:hover > .nav__panel { display: grid; }
  .nav__panel a { padding: var(--s2) 0; }
  .nav__cta { padding-top: var(--s3); }
  .nav__cta a { display: inline-block; padding: var(--s3) var(--s5); }
}

/* The masthead has to be a positioning context for the mobile drawer and the desktop panels. */
/* The nav panel positions against the masthead. Sticky already establishes a containing block
   for an absolutely positioned child, so this no longer needs to set position at all: setting
   it to relative here is what would break the sticky header. */

@media (prefers-reduced-motion: reduce) {
  .nav__panel,
  .nav__caret,
  .nav__tab { transition: none; }
}

/* ---- Nav fixes found by looking at the render, not by reading the CSS ------
   Three defects were visible in design-review/nav-0908-1440-open.png and none of them would
   have shown up in a passing gate:

   1. THE PANEL WAS SHOUTING. `.nav__links a` is part of the micro-label group at the top of
      this file (uppercase, 0.08em tracking), which is right for a five-letter nav item and
      wrong for a sentence. "OPEN NOW. BUILDS LINEUPS FOR THE CONTESTS YOU ENTER YOURSELF."
      in tracked caps is close to unreadable, so the panel opts out and sets its own voice.
   2. THE SIGN UP PILL WAS SQUASHED and its text clipped, because `.nav__cta a { padding: 0 }`
      beat `.btn--pill`'s own padding. The list item needs the reset, not the anchor.
   3. THE TABS SAT OFF-BASELINE next to the links: a <button> does not inherit the anchor's
      line-height, so "Support" hung lower than "Pricing". */
.nav__panel a,
.nav__panel-name,
.nav__panel-note {
  text-transform: none;
  letter-spacing: normal;
  font-size: 0.9rem;
}
.nav__panel-name { font-size: 0.95rem; letter-spacing: 0.01em; }
.nav__panel-note { font-size: 0.82rem; }

.nav__cta { padding: 0; display: flex; align-items: center; }
.nav__cta a.btn {
  padding: 10px var(--s5);
  line-height: 1;
}

.nav__tab {
  font-size: var(--t-micro);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: inherit;
}
.nav__links { align-items: center; }

/* Two more caught in the render, both invisible to the gate:

   THE SIGN UP TEXT WAS BRASS ON BRASS. `.nav__links a { color: var(--muted) }` is a two-class
   selector and `.btn--brass` is one, so the muted brass label won over the button's own dark
   ink and the pill read as a blank gold lozenge. Fixed with a selector that actually reaches
   it rather than by adding !important.

   THE TAB BUTTONS WERE IN THE WRONG TYPEFACE. `.nav__tab` started at `font: inherit`, which
   on a <button> inside <body> means the body SERIF at weight 400, so "SUPPORT" was visibly a
   different face and weight from "PRICING" beside it. The micro-label group this nav belongs
   to sets family and weight together, so the tab has to as well. */
/* One line instead of two: --btn-gilt-text already inverts with the theme. */
.nav__cta a.btn--brass { color: var(--btn-gilt-text); }

.nav__tab {
  font-family: var(--ui);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

/* ---- the proof wall ----------------------------------------------------------
   Two screenshots, side by side on a wide screen and stacked on a phone. They are
   evidence, so they get a frame and a caption and no decoration: no gradient overlay, no
   hover zoom, nothing that makes a reader wonder whether the image was treated. */
.proof { display: grid; grid-template-columns: 1fr; gap: var(--s5); margin-top: var(--s4); }
@media (min-width: 700px) { .proof { grid-template-columns: 1fr 1fr; gap: var(--s6); } }
.proof__item { margin: 0; }
.proof__shot {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  background: var(--panel);
}
.proof__cap {
  margin-top: var(--s3);
  font-family: var(--ui); font-variant-numeric: tabular-nums;
  font-size: var(--t-micro); color: var(--muted);
}

/* ---- Page hero: the compact document-page opener -----------------------------
   Brings the home page's brand language to every sub-page without a full-viewport
   hero above a legal document: a short banded plate carrying the brass eyebrow,
   the title, and a faint engraved seal echo. Reuses .hero__band and the guilloche
   masks from motion.css, so the two drift bands and the brass fill are the same
   material the reference hero uses. Painted at rest with JavaScript off; the band
   drift runs only after motion.js marks <html> as motion, and stops under
   prefers-reduced-motion via the guards already in motion.css. No new animation
   is introduced here, so nothing on a legal page moves under or delays its text. */
.page-hero {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  padding: var(--s8) 0 var(--s7);
  background:
    radial-gradient(120% 96% at 12% -12%, rgba(154, 139, 106), 0.10), transparent 60%),
    linear-gradient(180deg, var(--bg-lift), var(--bg));
  border-bottom: 1px solid var(--line);
  box-shadow: inset 0 -2px 0 var(--edge-lo);
}
.page-hero__in {
  position: relative;
  z-index: 1;
  max-width: 70ch;
  margin: 0 auto;
}
/* The seal echo. Smaller than the reference hero's, sat off the right edge and
   clipped by the band, at the same low contrast. Static on purpose: the drift band
   is the moving signature, and a document page does not need a second one. */
.page-hero__seal {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  right: -12vw;
  top: 50%;
  transform: translateY(-50%);
  width: min(64vw, 340px);
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  overflow: hidden;
  opacity: var(--seal-opacity);
  mix-blend-mode: screen;
}
.page-hero__seal img { width: 100%; height: 100%; object-fit: cover; }
:root[data-theme="light"] .page-hero__seal { mix-blend-mode: multiply; }
:root[data-theme="light"] .page-hero__seal img {
  filter: invert(1) hue-rotate(180deg) saturate(1.2);
}
.page-hero__title {
  font-size: var(--t-section);
  line-height: 1.03;
  letter-spacing: -0.02em;
  margin: var(--s2) 0 0;
  max-width: 20ch;
}
.page-hero__lead {
  font-size: var(--t-lead);
  line-height: 1.4;
  color: var(--text);
  margin: var(--s5) 0 0;
  max-width: 52ch;
}
/* When the seal would crowd the title on a narrow screen, drop it. The band and
   eyebrow carry the brand on their own. */
@media (max-width: 640px) {
  .page-hero__seal { display: none; }
}

/* ---- Research strip (three official Statyx widgets + ATP) ----------------- */
/*
   Charcoal plates, brass ruling. No sage, no mint wrapper around their iframe.
   Widgets stack. A slot that never paints is hidden by statyx.js, not left
   showing Forbidden from a Vercel challenge.
*/
.research-stage .tag { color: var(--brass); }
.research-plate {
  padding: var(--s5);
  background: linear-gradient(180deg, #1c1c1c, #171717);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius);
  box-shadow: inset 0 1px 0 var(--edge-hi);
  margin-bottom: var(--s4);
}
:root[data-theme="light"] .research-plate {
  background: linear-gradient(180deg, #f7f1e2, #efe6d3);
}
.research-plate__kicker {
  font-family: var(--ui);
  font-size: var(--t-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--brass);
  margin: 0 0 var(--s2);
}
.research-plate__name {
  font-family: var(--ui);
  font-size: var(--t-lead);
  letter-spacing: 0.02em;
  color: var(--parchment);
  margin: 0 0 var(--s3);
}
.research-plate__body {
  margin: 0 0 var(--s4);
  color: var(--muted);
  max-width: 42ch;
}
.research-stage__board {
  padding: var(--s5);
  background: #171717;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: inset 0 1px 0 var(--edge-hi), 0 12px 40px var(--shadow);
}
:root[data-theme="light"] .research-stage__board {
  background: #f4efe0;
}
.research-sports-line {
  margin: 0 0 var(--s2);
  font-family: var(--ui);
  font-size: var(--t-micro);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--brass);
}
.research-widgets {
  display: flex;
  gap: var(--s5);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: var(--s3);
}
.research-widgets .research-widget {
  flex: 0 0 min(88vw, 22rem);
  scroll-snap-align: start;
}
@media (min-width: 80rem) {
  .research-widgets {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    overflow: visible;
    scroll-snap-type: none;
  }
  .research-widgets .research-widget { flex: none; }
}
.research-soon {
  display: grid;
  gap: var(--s4);
  margin-top: var(--s5);
}
@media (min-width: 40rem) {
  .research-soon { grid-template-columns: 1fr 1fr; }
}
.research-soon__card {
  padding: var(--s4);
  background: #171717;
  border: 1px dashed var(--line);
  border-radius: var(--radius);
}
:root[data-theme="light"] .research-soon__card {
  background: #f4efe0;
}
.gbi-hat {
  margin: 0 0 var(--s4);
  color: var(--parchment);
  font-family: var(--ui);
  letter-spacing: 0.02em;
}
.site-footer__refer {
  margin: var(--s3) 0 0;
  color: var(--muted);
}
.site-footer__refer a { color: var(--brass-bright); }
.ref-table-wrap { overflow-x: auto; margin: 0 0 var(--s4); }
.ref-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.95rem;
}
.ref-table th,
.ref-table td {
  text-align: left;
  padding: 0.55rem 0.7rem;
  border-bottom: 1px solid var(--line);
}
.ref-table th {
  font-family: var(--ui);
  font-size: var(--t-micro);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--brass);
}
.ref-empty,
.ref-signedout { color: var(--muted); }
.research-sport {
  min-width: 0;
  display: grid;
  gap: var(--s6);
}
.research-sport[hidden] { display: none; }
.research-widget {
  min-width: 0;
}
.research-widget[hidden] { display: none; }
.research-stage__board statyx-widget { display: block; }
.research-stage__board statyx-widget[hidden] { display: none; }
/* Soft-hide a slot until the hosted frame handshakes (#166). visibility
   on the widget (not display) so the iframe can still load. Collapse the
   plate so a soft-fail cannot paint a broken-image box. hideSlot then
   sets [hidden] and the slot leaves the layout. */
.research-widget:not(.is-live) {
  height: 0;
  overflow: hidden;
  margin: 0;
  padding: 0;
  border: 0;
  visibility: hidden;
}
.research-widget.is-live {
  height: auto;
  visibility: visible;
}
/* Cover the iframe until the hosted frame handshakes. visibility (not
   display) so a lazy iframe still loads. A Vercel 403 still sits in the
   frame; the visitor never sees the word Forbidden. */
.research-widget:not(.is-live) statyx-widget { visibility: hidden; }
.research-widget.is-live statyx-widget { visibility: visible; }
.research-stage__refer {
  margin: var(--s5) 0 var(--s2);
}

.partner-badge {
  margin: var(--s4) 0 0;
  font-family: var(--ui);
  font-size: var(--t-micro);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}
.partner-badge a { color: var(--brass-bright); }
:root[data-theme="light"] .partner-badge a { color: var(--brass); }

/* ---- SimChat rail (Phase A chrome; Stream UI kit mounts later) -----------
   Stadium Night lock: charcoal panel #0f0f0f, brass at 35 percent, parchment
   bubbles. Always-dark rail so the room stays night even on the light page.
   z above Statyx boards, below nav panels (60). Crisp, if it arrives, reads
   --sf-crisp-right so it sits 16px off the rail. */
:root {
  --sf-rail-width: 340px;
  --sf-rail-tab: 44px;
  --sf-rail-charcoal: #0f0f0f;
  --sf-rail-brass: rgba(154, 139, 106, 0.35);
  --sf-crisp-inset: 16px;
  --sf-crisp-right: calc(var(--sf-rail-tab) + var(--sf-crisp-inset));
  --sf-stream-bg: #0f0f0f;
  --sf-stream-brass: rgba(154, 139, 106, 0.35);
  --sf-stream-parchment: #ece6d6;
  --sf-stream-text: #e6e0d2;
  --sf-stream-muted: #9a9486;
}
html[data-sf-rail="open"] {
  --sf-crisp-right: calc(var(--sf-rail-width) + var(--sf-crisp-inset));
}
@media (min-width: 860px) {
  html[data-sf-rail="open"] body {
    padding-right: var(--sf-rail-width);
  }
}

.sf-rail {
  position: relative;
  z-index: 48;
  font-family: var(--ui);
}
.sf-rail__tab {
  position: fixed;
  top: 42%;
  right: 0;
  z-index: 49;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  width: var(--sf-rail-tab);
  min-height: 132px;
  padding: 14px 0 12px;
  color: #17130a;
  background: linear-gradient(180deg, var(--brass-bright), var(--brass) 62%, var(--brass-deep));
  border: 1px solid var(--brass-deep);
  border-right: 0;
  border-radius: var(--radius) 0 0 var(--radius);
  box-shadow: inset 0 1px 0 rgba(255, 244, 214, 0.35), -4px 6px 18px var(--shadow);
  cursor: pointer;
}
.sf-rail__tab:hover { filter: brightness(1.06); }
.sf-rail__tab:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
.sf-rail__seal {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 1px solid rgba(23, 19, 10, 0.35);
  background: #0f0f0f;
  object-fit: cover;
}
.sf-rail__tab .sf-rail__seal {
  border-color: rgba(23, 19, 10, 0.45);
}
.sf-rail__tab-label {
  writing-mode: vertical-rl;
  transform: rotate(180deg);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}
.sf-rail__unread {
  min-width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #f4e7b4;
  box-shadow: 0 0 0 2px rgba(23, 19, 10, 0.35);
  font-size: 0;
}
/* With takes waiting, the dot becomes a count. */
.sf-rail__unread.is-on {
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--mono, ui-monospace, monospace);
  font-size: 11px;
  font-weight: 600;
  line-height: 1;
  color: #17130a;
}
.sf-rail[data-state="open"] .sf-rail__tab { display: none; }

.sf-rail__panel {
  position: fixed;
  top: 0;
  right: 0;
  z-index: 48;
  display: flex;
  flex-direction: column;
  width: var(--sf-rail-width);
  height: 100%;
  min-height: 100dvh;
  background: var(--sf-rail-charcoal);
  border-left: 1px solid var(--sf-rail-brass);
  box-shadow: -18px 0 40px rgba(0, 0, 0, 0.45);
  color: var(--sf-stream-text);
}
.sf-rail__panel[hidden] { display: none; }
.sf-rail__handle {
  display: none;
  width: 40px;
  height: 4px;
  margin: 10px auto 0;
  border-radius: 2px;
  background: var(--sf-rail-brass);
}
.sf-rail__head {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 16px 12px;
  border-bottom: 1px solid var(--sf-rail-brass);
}
.sf-rail__pulse {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--brass-bright);
  box-shadow: 0 0 0 0 rgba(184, 166, 124, 0.55);
  animation: sf-rail-pulse 1.8s ease-out infinite;
}
.sf-rail__chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: none;
  padding: 2px 8px 2px 6px;
  border: 1px solid var(--sf-rail-brass);
  border-radius: 999px;
  background: rgba(184, 166, 124, 0.14);
  color: var(--brass-bright);
}
.sf-rail__chip-text {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  line-height: 1.2;
}
.sf-rail__title {
  flex: 1;
  margin: 0;
  font-size: 13px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--sf-stream-parchment);
}
.sf-rail__close {
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid var(--sf-rail-brass);
  border-radius: var(--radius);
  background: transparent;
  color: var(--sf-stream-parchment);
  cursor: pointer;
  background-image: linear-gradient(var(--brass-bright), var(--brass-bright));
  background-repeat: no-repeat;
  background-position: center;
  background-size: 10px 1.5px;
}
.sf-rail__close:hover { border-color: var(--brass-bright); }
.sf-rail__close:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

.sf-rail__stream {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
}
.sf-rail__feed {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  gap: 10px;
  padding: 16px 16px 12px;
}
.sf-rail__row {
  max-width: 100%;
  padding: 8px 10px;
  background: rgba(236, 230, 214, 0.08);
  border: 1px solid rgba(154, 139, 106, 0.22);
  border-radius: var(--radius);
}
.sf-rail__row--system {
  font-size: 12px;
  color: var(--sf-stream-parchment);
}
.sf-rail__row--simcoin {
  background: transparent;
  border-color: var(--sf-rail-brass);
  opacity: 0.88;
}
.sf-rail__row-tag {
  display: inline-block;
  margin-right: 6px;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--brass);
}
.sf-rail__row-text {
  display: inline;
  margin: 0;
  font-family: var(--body);
  font-size: 12px;
  color: var(--sf-stream-parchment);
}
.sf-rail__row--simcoin .sf-rail__row-text {
  color: var(--brass-bright);
}
/* A take from the room: handle, time, then the line. */
.sf-rail__row--user {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 8px;
  row-gap: 2px;
  align-items: baseline;
}
.sf-rail__row-handle {
  margin-right: 0;
  color: var(--brass-bright);
  font-weight: 600;
}
.sf-rail__row-when {
  font-size: 10px;
  letter-spacing: 0.04em;
  color: var(--sf-stream-muted);
  text-align: right;
}
.sf-rail__row--user .sf-rail__row-text {
  grid-column: 1 / -1;
  display: block;
  overflow-wrap: anywhere;
}
.sf-rail__empty {
  margin: 8px 0 0;
  font-family: var(--body);
  font-size: 16px;
  color: var(--sf-stream-parchment);
}

.sf-rail__compose {
  padding: 12px 16px 10px;
  border-top: 1px solid var(--sf-rail-brass);
}
.sf-rail__gate {
  margin: 0 0 10px;
  font-family: var(--body);
  font-size: 14px;
  color: var(--sf-stream-muted);
}
.sf-rail__signin { display: inline-block; }
.sf-rail__form { display: grid; gap: 8px; }
.sf-rail__input {
  width: 100%;
  resize: none;
  padding: 10px 12px;
  border: 1px solid var(--sf-rail-brass);
  border-radius: var(--radius);
  background: #171717;
  color: var(--sf-stream-parchment);
  font-family: var(--body);
  font-size: 15px;
  line-height: 1.4;
}
.sf-rail__input:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}
.sf-rail__form-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.sf-rail__soon {
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--brass);
}
.sf-rail__send { padding: 8px 16px; }

.sf-rail__help {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 14px;
  padding: 10px 16px calc(12px + var(--sf-crisp-inset));
  border-top: 1px solid var(--sf-rail-brass);
  font-size: 11px;
  letter-spacing: 0.04em;
}
.sf-rail__help a {
  color: var(--sf-stream-muted);
  text-decoration: none;
}
.sf-rail__help a:hover { color: var(--brass-bright); }

@keyframes sf-rail-pulse {
  0% { box-shadow: 0 0 0 0 rgba(184, 166, 124, 0.5); }
  70% { box-shadow: 0 0 0 8px rgba(184, 166, 124, 0); }
  100% { box-shadow: 0 0 0 0 rgba(184, 166, 124, 0); }
}

@media (max-width: 859px) {
  html[data-sf-rail="open"] body { padding-right: 0; }
  .sf-rail__tab {
    top: auto;
    bottom: calc(120px + env(safe-area-inset-bottom, 0px));
  }
  .sf-rail__panel {
    top: auto;
    bottom: 0;
    width: 100%;
    height: 70vh;
    min-height: 70vh;
    border-left: 0;
    border-top: 1px solid var(--sf-rail-brass);
    border-radius: 6px 6px 0 0;
    box-shadow: 0 -18px 40px rgba(0, 0, 0, 0.5);
  }
  .sf-rail__handle { display: block; }
}

@media (prefers-reduced-motion: reduce) {
  .sf-rail__pulse { animation: none; }
  .sf-rail__tab { transition: none; }
}

/* ---- Support chrome (Crisp-shaped; never the social rail) ---------------- */
.sf-support {
  position: fixed;
  right: var(--sf-crisp-right);
  bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  z-index: 46;
  font-family: var(--ui);
}
.sf-support__tab {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding: 6px 12px 6px 6px;
  color: #17130a;
  background: linear-gradient(180deg, var(--brass-bright), var(--brass) 62%, var(--brass-deep));
  border: 1px solid var(--brass-deep);
  border-radius: 999px;
  box-shadow: inset 0 1px 0 rgba(255, 244, 214, 0.35), 0 8px 18px var(--shadow);
  cursor: pointer;
}
.sf-support__tab:hover { filter: brightness(1.06); }
.sf-support__tab:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}
.sf-support__seal {
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: 1px solid rgba(23, 19, 10, 0.35);
  background: #0f0f0f;
  object-fit: cover;
}
.sf-support__tab-label {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.sf-support__panel {
  position: absolute;
  right: 0;
  bottom: calc(100% + 10px);
  width: min(280px, calc(100vw - 32px));
  display: grid;
  gap: 10px;
  padding: 14px 16px 16px;
  background: #0f0f0f;
  border: 1px solid var(--sf-rail-brass);
  box-shadow: -8px 12px 28px rgba(0, 0, 0, 0.45);
  color: var(--sf-stream-text);
}
.sf-support__panel[hidden] { display: none; }
.sf-support__head {
  display: flex;
  align-items: center;
  gap: 10px;
}
.sf-support__title {
  flex: 1;
  margin: 0;
  font-size: 13px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--sf-stream-parchment);
}
.sf-support__close {
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid var(--sf-rail-brass);
  border-radius: var(--radius);
  background: transparent;
  color: var(--sf-stream-parchment);
  cursor: pointer;
  background-image: linear-gradient(var(--brass-bright), var(--brass-bright));
  background-repeat: no-repeat;
  background-position: center;
  background-size: 10px 1.5px;
}
.sf-support__close:hover { border-color: var(--brass-bright); }
.sf-support__lede {
  margin: 0;
  font-family: var(--body);
  font-size: 14px;
  color: var(--sf-stream-muted);
}
.sf-support__mail,
.sf-support__discord {
  color: var(--brass-bright);
  text-decoration: none;
  font-size: 13px;
}
.sf-support__mail:hover,
.sf-support__discord:hover { color: var(--parchment); }

@media (max-width: 859px) {
  .sf-support {
    right: var(--sf-crisp-right);
    bottom: calc(16px + env(safe-area-inset-bottom, 0px));
  }
  .sf-support__tab {
    width: 44px;
    height: 44px;
    min-width: 44px;
    min-height: 44px;
    padding: 0;
    gap: 0;
    justify-content: center;
  }
  .sf-support__tab-label { display: none; }
  html[data-sf-rail="open"] .sf-support { visibility: hidden; }
}

/* ---- The Statyx catalogue on data.html: a ruled list, one board per row ---- */
.catalogue { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.catalogue__row {
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  gap: var(--s3) var(--s4);
  padding: var(--s4) 0;
  border-bottom: 1px solid var(--line-soft);
}
.catalogue__sport {
  font-family: var(--ui);
  font-size: var(--t-micro);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--brass);
  padding-top: 0.35em;
}
.catalogue__name { font-size: var(--t-lead); margin: 0 0 var(--s2); line-height: 1.2; }
.catalogue__note {
  display: inline-block;
  margin-left: var(--s2);
  padding: 0.15em 0.55em;
  border: 1px solid var(--line);
  color: var(--brass);
  font-family: var(--ui);
  font-size: var(--t-micro);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  vertical-align: middle;
}
.catalogue__desc { margin: 0 0 var(--s2); max-width: 62ch; color: var(--text); }
.catalogue__slug {
  font-family: ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace;
  font-size: var(--t-micro);
  color: var(--muted);
}
@media (max-width: 480px) {
  .catalogue__row { grid-template-columns: 1fr; gap: var(--s1); }
  .catalogue__sport { padding-top: 0; }
}
/* ---- 2026-09-11 production sweep ------------------------------------------ */

/* With the chat rail open the masthead row loses 340px, so up to 1440 the nav
   collapses to the hamburger exactly as it does below 1100. Before this the
   Sign Up button and the theme toggle sat under the rail panel at 1280. */
@media (min-width: 1101px) and (max-width: 1440px) {
  html[data-sf-rail="open"] .nav__burger { display: inline-flex; }
  html[data-sf-rail="open"] .nav { gap: var(--s3); }
  html[data-sf-rail="open"] .nav__links {
    position: absolute;
    top: 100%;
    right: 0;
    left: 0;
    display: none;
    flex-direction: column;
    gap: 0;
    padding: var(--s3) var(--s4) var(--s4);
    background: var(--panel);
    border-top: 1px solid var(--line);
    box-shadow: 0 18px 40px rgba(0, 0, 0, 0.55);
    z-index: 60;
  }
  html[data-sf-rail="open"] .nav[data-nav-open] .nav__links { display: flex; }
  html[data-sf-rail="open"] .nav__links > li { padding: var(--s2) 0; border-bottom: 1px solid var(--line); }
  html[data-sf-rail="open"] .nav__links > li:last-child { border-bottom: 0; }
  html[data-sf-rail="open"] .nav__panel {
    position: static;
    min-width: 0;
    opacity: 1;
    visibility: visible;
    transform: none;
    display: none;
    margin-top: var(--s2);
    background: transparent;
    border: 0;
    box-shadow: none;
    padding: 0;
  }
  html[data-sf-rail="open"] .nav__group[data-open] > .nav__panel { display: grid; }
  html[data-sf-rail="open"] .nav__group:hover > .nav__panel { display: none; }
  html[data-sf-rail="open"] .nav__group[data-open]:hover > .nav__panel { display: grid; }
  html[data-sf-rail="open"] .nav__panel a { padding: var(--s2) 0; }
}

/* Every action is a real target. Reported 2026-09-11: a link needs a bigger, easier area
   that shows it is one. 48px tall, heavier type, a brighter edge on the
   outlined buttons, and underlined links inside body copy. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s2);
  min-height: 48px;
  padding: var(--s3) var(--s6);
  font-weight: 600;
  letter-spacing: 0.01em;
  border-color: var(--brass-bright, var(--brass));
  text-align: center;
}
/* Was two hardcoded gold washes that stayed identical in both themes, so the outlined button
   sat on a dark film over parchment. Both now resolve through the ramp. */
.btn:not(.btn--brass) { background: var(--btn-bg-hover); }
.btn:not(.btn--brass):hover { background: var(--btn-bg-hover); border-color: var(--btn-line-hover); }
.register__action {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-weight: 600;
}
.plan__notes a,
.split__link a,
.prose a,
.block-note a,
.faq a,
.section-head__lead a { font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }
@media (max-width: 599px) {
  .hero__actions .btn,
  .ad-block__actions .btn { width: 100%; }
}

/* The logo you run for the logo rate, shown next to the button that downloads it.
   Reported 2026-09-11: the download area needs an example of the logo beside it. */
.logo-grab {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--s5);
  align-items: start;
  margin: var(--s5) 0;
  padding: var(--s5);
  border: 1px solid var(--line);
  border-left: 3px solid var(--brass);
  background: var(--panel);
}
.logo-grab__img {
  display: block;
  width: 112px;
  height: 112px;
  padding: var(--s2);
  background: #0e120d;
  border: 1px solid var(--brass);
}
.logo-grab__title { margin: 0 0 var(--s2); font-family: var(--ui); font-size: var(--t-h4, 1.15rem); }
.logo-grab__body > p { margin-top: 0; }
.logo-grab .ad-block__actions { margin-top: var(--s3); }
@media (max-width: 599px) {
  .logo-grab { grid-template-columns: 1fr; }
  .logo-grab__img { width: 96px; height: 96px; }
}

/* ---- The workspace, shown (homepage #products) ---------------------------- */
/* A still of the Generator: settings rail, player pool, built lineups. Inert, sample
   rows, nothing wired. Vault surfaces: ruled, 2px corners, one brass. */
.ad-block--stage .ad-block__in { grid-template-columns: 1fr; align-items: start; }
.gen-preview {
  --gp-ink: var(--parchment);
  --gp-mono: var(--mono, ui-monospace, "SFMono-Regular", Menlo, Consolas, monospace);
  margin-top: var(--s5);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  background: var(--panel);
  box-shadow: 0 1px 0 rgba(255, 244, 214, 0.06) inset, 0 24px 60px -30px rgba(0, 0, 0, 0.8);
  color: var(--gp-ink);
  font-family: var(--ui);
  font-size: 0.82rem;
  overflow: hidden;
  user-select: none;
}
.gp-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s3) var(--s5);
  padding: var(--s3) var(--s4);
  border-bottom: 1px solid var(--line);
  background: linear-gradient(180deg, rgba(255, 244, 214, 0.04), transparent);
}
.gp-brand { display: inline-flex; align-items: center; gap: var(--s2); font-weight: 600; }
.gp-brand__seal { width: 18px; height: 18px; border-radius: 50%; border: 1px solid var(--brass); box-shadow: inset 0 0 0 3px var(--panel), inset 0 0 0 4px var(--brass); }
.gp-tabs { display: inline-flex; gap: var(--s4); font-family: var(--gp-mono); font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
.gp-tabs b { color: var(--gp-ink); font-weight: 600; box-shadow: 0 2px 0 var(--brass); padding-bottom: 4px; }
.gp-slate { color: var(--muted); }
.gp-live { margin-left: auto; display: inline-flex; align-items: center; gap: var(--s2); font-family: var(--gp-mono); font-size: 0.7rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--brass); }
.gp-live i { width: 7px; height: 7px; border-radius: 50%; background: var(--brass); box-shadow: 0 0 0 3px rgba(154, 139, 106, 0.25); }
/* A CONTAINER QUERY, NOT A VIEWPORT ONE, and the difference is the whole bug it fixes.
   This mock is a picture of a three column workspace. The three columns used to be keyed on
   @media (min-width: 1000px), which asks how wide the WINDOW is. That was fine while the
   mock was the full width of the page. The moment it moved into a hero column it was still
   being told "the window is 1440px, use three columns" inside a 620px box, and 15.5rem plus
   17rem of fixed columns collided into the middle one: overlapping text, unreadable.
   @container asks how wide THE MOCK is, which is the question that was always meant.
   A browser without container query support falls back to the single column stack, which is
   legible rather than broken, so there is no need to keep the media query beside it. */
.gen-preview { container-type: inline-size; }
.gp-grid { display: grid; gap: 0; }
/* Two steps, because the mock has to read as a three column workspace in a hero column as
   well as at full page width. The rails simply get narrower rather than the layout
   collapsing: 248px + 272px of fixed rail plus a usable middle needs about 700px, so that
   is where three columns start, and they take their full width once there is room. */
@container (min-width: 700px) {
  .gp-grid { grid-template-columns: 12.5rem minmax(0, 1fr) 13.5rem; }
  .gp-rail { border-right: 1px solid var(--line); border-bottom: 0; }
  .gp-built { border-left: 1px solid var(--line); border-top: 0; }
}
/* A GRID ITEM WILL NOT SHRINK BELOW ITS CONTENT unless it is told it may: min-width
   defaults to auto, so the lineup cards in the third column held it open past its track
   and painted straight over the player table beside it. .gp-pool already had min-width: 0
   for exactly this reason; the other two never needed it until the mock moved into a hero
   column and the tracks got narrow. Clipping is the right answer for a mock: it is a
   picture of a screen, and a real screen crops rather than reflows. */
.gp-rail, .gp-built { min-width: 0; overflow: hidden; }
@container (min-width: 900px) {
  .gp-grid { grid-template-columns: 15.5rem minmax(0, 1fr) 17rem; }
}
.gp-rail { padding: var(--s3) var(--s4) var(--s4); border-bottom: 1px solid var(--line); }
.gp-kicker { margin: var(--s4) 0 var(--s2); font-family: var(--gp-mono); font-size: 0.66rem; letter-spacing: 0.14em; text-transform: uppercase; color: var(--muted); }
.gp-kicker:first-child { margin-top: 0; }
.gp-seg { display: inline-flex; margin: 0 var(--s2) var(--s2) 0; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; }
.gp-seg > * { padding: 5px 10px; color: var(--muted); border-right: 1px solid var(--line); }
.gp-seg > :last-child { border-right: 0; }
.gp-seg > b { color: var(--btn-gilt-text, #17130a); background: var(--brass); font-weight: 600; }
.gp-seg--tight > * { padding: 3px 8px; font-size: 0.72rem; }
.gp-rows { list-style: none; margin: 0; padding: 0; }
.gp-row { display: flex; justify-content: space-between; align-items: center; gap: var(--s3); padding: 5px 0; border-bottom: 1px solid var(--line-soft, rgba(154, 139, 106, 0.16)); }
.gp-row > span:first-child { color: var(--muted); }
.gp-val { min-width: 4.5rem; padding: 2px 8px; text-align: right; font-variant-numeric: tabular-nums; border: 1px solid var(--line); border-radius: var(--radius); background: rgba(0, 0, 0, 0.25); }
.gp-toggle { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); font-family: var(--gp-mono); font-size: 0.68rem; letter-spacing: 0.08em; text-transform: uppercase; }
.gp-toggle i { width: 26px; height: 14px; border-radius: 7px; border: 1px solid var(--line); background: rgba(0, 0, 0, 0.3); position: relative; }
.gp-toggle i::after { content: ""; position: absolute; top: 2px; left: 2px; width: 8px; height: 8px; border-radius: 50%; background: var(--muted); }
.gp-toggle--on { color: var(--brass); }
.gp-toggle--on i { border-color: var(--brass); background: rgba(154, 139, 106, 0.22); }
.gp-toggle--on i::after { left: auto; right: 2px; background: var(--brass); }
.gp-chips { display: flex; flex-wrap: wrap; gap: 6px; }
.gp-chip { padding: 3px 9px; border: 1px solid var(--line); border-radius: var(--radius); color: var(--muted); }
.gp-chip--on { color: var(--gp-ink); border-color: var(--brass); background: rgba(154, 139, 106, 0.16); }
.gp-pool { min-width: 0; padding: var(--s3) var(--s4) var(--s4); }
.gp-pool__head, .gp-built__head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s3); margin-bottom: var(--s3); }
.gp-pool__head .gp-kicker, .gp-built__head .gp-kicker { margin: 0; }
.gp-table { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.gp-table th { text-align: left; font-family: var(--gp-mono); font-size: 0.64rem; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); font-weight: 500; padding: 6px 6px; border-bottom: 1px solid var(--line); }
.gp-table td { padding: 7px 6px; border-bottom: 1px solid var(--line-soft, rgba(154, 139, 106, 0.16)); white-space: nowrap; }
.gp-table td:first-child { font-family: var(--gp-mono); font-size: 0.7rem; color: var(--brass); }
.gp-table tbody tr:nth-child(2) { background: rgba(154, 139, 106, 0.08); }
.gp-name { display: inline-block; height: 0.7em; border-radius: 2px; background: linear-gradient(90deg, rgba(236, 230, 214, 0.55), rgba(236, 230, 214, 0.25)); vertical-align: middle; }
.gp-name.w2 { width: 3.2rem; } .gp-name.w3 { width: 4.6rem; } .gp-name.w4 { width: 5.6rem; } .gp-name.w5 { width: 6.4rem; } .gp-name.w6 { width: 7.3rem; }
.gp-mini { display: inline-block; margin-right: 4px; padding: 2px 7px; border: 1px solid var(--brass); border-radius: var(--radius); font-size: 0.68rem; color: var(--brass); }
.gp-mini--ban { border-color: var(--line); color: var(--muted); }
.gp-more { margin: var(--s3) 0 0; color: var(--brass); text-decoration: underline; text-underline-offset: 3px; }
.gp-built { padding: var(--s3) var(--s4) var(--s4); border-top: 1px solid var(--line); }
/* color was a hard-coded #17130a. On the light theme the gilt ramp darkens and that label
   measured 2.3:1, unreadable, on every primary button the generator has. --btn-gilt-text is
   the token both themes already define for text on gilt (6.9:1 and up in light, unchanged
   to the eye in dark). Found by the a11y seat 2026-09-15. */
.gp-cta { padding: 5px 10px; border-radius: var(--radius); background: linear-gradient(180deg, var(--brass-bright), var(--brass) 62%, var(--brass-deep)); color: var(--btn-gilt-text, #17130a); font-weight: 600; font-size: 0.76rem; }
.gp-lineups { display: grid; gap: var(--s3); grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr)); }
/* background was rgba(0,0,0,0.22), a dark-theme assumption: in light theme every built lineup
   was a grey card on a white panel. --bg-lift is the fill the other card surfaces on the page
   already use and it follows the theme. Design seat, 2026-09-15. */
.gp-lineup { border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg-lift); }
.gp-lineup header, .gp-lineup footer { display: flex; justify-content: space-between; padding: 6px 9px; font-family: var(--gp-mono); font-size: 0.66rem; letter-spacing: 0.1em; text-transform: uppercase; color: var(--muted); }
.gp-lineup header { border-bottom: 1px solid var(--line); color: var(--gp-ink); }
.gp-lineup footer { border-top: 1px solid var(--line); color: var(--brass); }
.gp-lineup ul { list-style: none; margin: 0; padding: 4px 9px; }
.gp-lineup li { display: flex; align-items: center; gap: var(--s3); padding: 3px 0; }
.gp-lineup li span { width: 2.6rem; font-family: var(--gp-mono); font-size: 0.66rem; color: var(--muted); }
.gp-foot { margin: 0; padding: var(--s3) var(--s4); border-top: 1px solid var(--line); color: var(--muted); font-family: var(--gp-mono); font-size: 0.68rem; letter-spacing: 0.08em; text-transform: uppercase; }
@media (max-width: 999px) {
  .gp-table th:nth-child(6), .gp-table td:nth-child(6) { display: none; }
  .gp-lineups > :nth-child(n + 3) { display: none; }
}
@media (max-width: 599px) {
  .gen-preview { font-size: 0.78rem; }
  .gp-table th:nth-child(3), .gp-table td:nth-child(3) { display: none; }
  .gp-lineups > :nth-child(n + 2) { display: none; }
}
/* The rail is a long list. Cap it like the real one (it scrolls there) and fade the cut, so the
   frame stays the height of the pool and the lineups instead of the height of every setting. */
.gp-rail { max-height: 46rem; overflow: hidden; -webkit-mask-image: linear-gradient(180deg, #000 88%, transparent); mask-image: linear-gradient(180deg, #000 88%, transparent); }
@media (max-width: 999px) {
  .gp-rail { max-height: 24rem; }
}
/* Exposure rows: a check, the label, a bar, the figure. Leverage reads up or down. */
.gp-row--exp { justify-content: flex-start; gap: var(--s2); }
.gp-row--exp > span:nth-child(2) { flex: 1 1 auto; color: var(--gp-ink); }
.gp-check { width: 12px; height: 12px; flex: none; border: 1px solid var(--brass); border-radius: var(--radius); background: var(--brass); box-shadow: inset 0 0 0 2px var(--panel); }
.gp-check--off { background: transparent; border-color: var(--line); }
/* The exposure track inside a stack row. Scoped to the row: a bare .gp-bar is the workspace
   toolbar above, and the two used to share one name, which shrank the toolbar to a 5px strip. */
.gp-row--exp .gp-bar { width: 4.2rem; height: 5px; flex: none; border-radius: 3px; background: rgba(0, 0, 0, 0.35); overflow: hidden; padding: 0; gap: 0; }
.gp-bar__fill { display: block; height: 100%; background: var(--brass); }
.gp-bar__fill--10 { width: 10%; } .gp-bar__fill--20 { width: 20%; } .gp-bar__fill--30 { width: 30%; } .gp-bar__fill--40 { width: 40%; }
.gp-pct { min-width: 2.4rem; text-align: right; font-variant-numeric: tabular-nums; color: var(--muted); }
.gp-up { color: var(--brass-bright, var(--brass)); } .gp-down { color: var(--muted); }
@media (max-width: 999px) { .gp-table th:nth-child(7), .gp-table td:nth-child(7) { display: none; } }

/* ---- Privacy preferences ------------------------------------------------- */
/* The rounded outer shell is intentionally softer than the site's ruled 2px
   panels. Inside it, categories return to square, divided rows. */
.cookie-dialog {
  width: min(660px, calc(100vw - 48px));
  max-width: none;
  max-height: min(78vh, 720px);
  max-height: min(78dvh, 720px);
  margin: auto;
  padding: 0;
  overflow: hidden;
  color: var(--text);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 22px;
  box-shadow:
    0 1px 0 var(--edge-hi) inset,
    0 36px 100px rgba(0, 0, 0, 0.68),
    0 8px 28px rgba(0, 0, 0, 0.42);
}
.cookie-dialog::backdrop {
  background: rgba(3, 3, 3, 0.72);
  -webkit-backdrop-filter: blur(5px);
  backdrop-filter: blur(5px);
}
.cookie-dialog[open] {
  animation: cookie-dialog-in 190ms cubic-bezier(0.2, 0.8, 0.2, 1);
}
.cookie-dialog[open]::backdrop { animation: cookie-backdrop-in 160ms ease-out; }
.cookie-dialog__shell {
  display: grid;
  grid-template-rows: auto minmax(0, 1fr) auto;
  max-height: min(78vh, 720px);
  max-height: min(78dvh, 720px);
}
.cookie-dialog__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s4);
  padding: var(--s5) var(--s6) var(--s4);
  border-bottom: 1px solid var(--line-soft);
  background:
    linear-gradient(110deg, rgba(184, 166, 124, 0.08), transparent 44%),
    var(--panel);
}
.cookie-dialog__heading {
  display: flex;
  align-items: center;
  gap: var(--s4);
  min-width: 0;
}
.cookie-dialog__icon {
  display: grid;
  flex: 0 0 44px;
  width: 44px;
  height: 44px;
  place-items: center;
  color: var(--brass-bright);
  border: 1px solid var(--line);
  border-radius: 50%;
  background: var(--field-bg);
  box-shadow: 0 1px 0 var(--edge-hi) inset;
}
.cookie-dialog__icon svg { fill: currentColor; }
.cookie-dialog__eyebrow {
  margin: 0 0 2px;
  color: var(--brass);
  font-family: var(--ui);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  line-height: 1.4;
  text-transform: uppercase;
}
.cookie-dialog__title {
  font-size: clamp(22px, 4vw, 29px);
  letter-spacing: -0.02em;
  text-wrap: balance;
}
.cookie-dialog__close {
  display: grid;
  flex: 0 0 44px;
  width: 44px;
  height: 44px;
  margin: 2px -6px 0 0;
  padding: 0;
  place-items: center;
  color: var(--muted);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 50%;
  cursor: pointer;
}
.cookie-dialog__close:hover {
  color: var(--parchment);
  border-color: var(--line);
  background: var(--field-bg);
}
.cookie-dialog__close svg { fill: currentColor; }
.cookie-dialog__body {
  min-height: 0;
  padding: var(--s5) var(--s6);
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-color: var(--brass-deep) transparent;
  scrollbar-width: thin;
}
.cookie-dialog__description {
  max-width: 61ch;
  margin-bottom: var(--s5);
  color: var(--text);
  font-size: 17px;
  line-height: 1.55;
}
.cookie-dialog__notice {
  margin-bottom: var(--s5);
  padding: var(--s4);
  color: var(--muted);
  border: 1px solid var(--line);
  border-left: 3px solid var(--brass);
  border-radius: var(--radius);
  background: var(--field-bg);
}
.cookie-dialog__notice p { margin-bottom: var(--s2); }
.cookie-dialog__policy-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s3) var(--s5);
  font-family: var(--ui);
  font-size: var(--t-micro);
  font-weight: 600;
}
.cookie-dialog__categories {
  border-top: 1px solid var(--line);
}
.cookie-category {
  padding: var(--s4) 0;
  border-bottom: 1px solid var(--line);
}
.cookie-category__main {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--s5);
}
.cookie-category__copy { min-width: 0; }
.cookie-category__title {
  margin-bottom: var(--s2);
  font-size: 16px;
  line-height: 1.3;
}
.cookie-category__description {
  max-width: 54ch;
  margin: 0;
  color: var(--muted);
  font-size: 15px;
  line-height: 1.45;
}
.cookie-category__status {
  flex: none;
  margin-top: 1px;
  padding: 5px 9px;
  color: var(--brass-bright);
  font-family: var(--ui);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.07em;
  line-height: 1.3;
  text-transform: uppercase;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: rgba(154, 139, 106, 0.09);
}
.cookie-switch {
  position: relative;
  display: inline-grid;
  flex: 0 0 46px;
  width: 46px;
  height: 26px;
  margin-top: 1px;
  cursor: pointer;
}
.cookie-switch__input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}
.cookie-switch__track {
  grid-area: 1 / 1;
  border: 1px solid var(--field-line);
  border-radius: 999px;
  background: var(--field-bg);
  transition: border-color 180ms ease, background-color 180ms ease;
}
.cookie-switch__thumb {
  grid-area: 1 / 1;
  align-self: center;
  width: 18px;
  height: 18px;
  margin-left: 4px;
  border-radius: 50%;
  background: var(--muted);
  box-shadow: 0 1px 3px var(--shadow);
  transition: transform 180ms ease, background-color 180ms ease;
}
.cookie-switch__input:checked ~ .cookie-switch__track {
  border-color: var(--brass-bright);
  background: var(--brass-deep);
}
.cookie-switch__input:checked ~ .cookie-switch__thumb {
  background: var(--parchment);
  transform: translateX(20px);
}
.cookie-switch__input:focus-visible ~ .cookie-switch__track {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
}
.cookie-category__details-button {
  margin-top: var(--s3);
  padding: 2px 0;
  color: var(--brass);
  font-family: var(--ui);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  background: transparent;
  border: 0;
  border-bottom: 1px solid transparent;
  cursor: pointer;
}
.cookie-category__details-button:hover {
  color: var(--brass-bright);
  border-bottom-color: currentColor;
}
.cookie-category__details {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows 190ms ease, opacity 150ms ease;
}
.cookie-category__details-inner { overflow: hidden; }
.cookie-category__details-list {
  margin: var(--s3) 0 0;
  padding: var(--s3) var(--s4) var(--s2) calc(var(--s4) + 16px);
  color: var(--muted);
  font-size: 14px;
  border-left: 2px solid var(--line);
  background: rgba(154, 139, 106, 0.045);
}
.cookie-category__details-list li { margin-bottom: 5px; }
.cookie-category.is-open .cookie-category__details {
  grid-template-rows: 1fr;
  opacity: 1;
}
.cookie-dialog__actions {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: var(--s3);
  padding: var(--s4) var(--s6) var(--s5);
  border-top: 1px solid var(--line);
  background: var(--panel);
  box-shadow: 0 -16px 32px rgba(0, 0, 0, 0.16);
}
/* SELF CONTAINED ON PURPOSE, AND THIS IS THE REASON.
   chrome.css is GENERATED from this file, keeping only the rules the home page needs, and
   the home page does not load style.css at all. These buttons carried no look of their own,
   they borrowed .btn, and .btn cannot come across: it collides with the home page's own
   .btn. So the whole consent panel arrived on the home page as a browser-default <dialog>,
   white with square corners, while /pricing rendered it correctly. Every visitor's first
   screen. Fixed by owning the look here rather than inheriting it, which is what lets the
   extractor carry the panel across intact. */
.cookie-dialog .cookie-dialog__action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 46px;
  padding: 10px var(--s3);
  color: var(--parchment);
  font: inherit;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.4;
  text-align: center;
  text-decoration: none;
  border: 1px solid var(--line);
  /* THE SITE HAS ONE BUTTON SHAPE AND THIS IS IT. Written as a 12px rectangle first, which
     turned every consent button on every style.css page from the site's pill into something
     out of family. Caught in pre-merge review, measuring computed border-radius in a browser. */
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.04);
  cursor: pointer;
  transition: border-color 200ms ease, background-color 200ms ease, color 200ms ease;
}
.cookie-dialog .cookie-dialog__action:hover {
  color: var(--brass-bright);
  border-color: var(--brass);
  background: rgba(255, 255, 255, 0.07);
}
.cookie-dialog .cookie-dialog__action.btn--brass {
  color: var(--btn-gilt-text);
  border-color: var(--brass-bright);
  background: linear-gradient(180deg, var(--brass-bright), var(--brass));
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.28) inset;
}
.cookie-dialog .cookie-dialog__action.btn--brass:hover {
  color: var(--btn-gilt-text);
  background: linear-gradient(180deg, var(--brass-bright), var(--brass-bright));
}
.cookie-preferences-trigger {
  padding: 0;
  color: var(--brass);
  font-family: var(--ui);
  font-size: var(--t-micro);
  font-weight: 500;
  letter-spacing: 0.08em;
  line-height: 1.4;
  text-transform: uppercase;
  background: transparent;
  border: 0;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}
.cookie-preferences-trigger:hover { color: var(--brass-bright); }

@keyframes cookie-dialog-in {
  from { opacity: 0; transform: translateY(8px) scale(0.985); }
  to { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes cookie-backdrop-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@media (max-width: 680px) {
  .cookie-dialog {
    width: min(560px, calc(100% - 24px));
    max-height: min(74vh, 620px);
    max-height: min(74dvh, 620px);
    margin: auto;
    border-radius: 18px;
  }
  .cookie-dialog__shell {
    max-height: min(74vh, 620px);
    max-height: min(74dvh, 620px);
  }
  .cookie-dialog__header { padding: var(--s4) var(--s5) var(--s3); }
  .cookie-dialog__body { padding: var(--s4) var(--s5); }
  .cookie-dialog__icon {
    flex-basis: 38px;
    width: 38px;
    height: 38px;
  }
  .cookie-dialog__icon svg { width: 21px; height: 21px; }
  .cookie-dialog__title { font-size: 21px; }
  .cookie-dialog__description { font-size: 16px; }
  .cookie-category__main { gap: var(--s3); }
  .cookie-category__status {
    padding: 4px 7px;
    white-space: nowrap;
  }
  .cookie-dialog__actions {
    grid-template-columns: 1fr;
    gap: var(--s2);
    padding: var(--s3) var(--s5) calc(var(--s3) + env(safe-area-inset-bottom));
  }
  /* SCOPED TO MATCH THE BASE RULE. The base is .cookie-dialog .cookie-dialog__action now
     (it has to be, to out-specify the .btn that cookie-consent.js puts on these buttons),
     and this override was left unscoped, so 0,1,0 lost to 0,2,0 at every width and the
     compact 44px never applied anywhere again. It had been working. Caught in pre-merge review,
     measuring computed min-height on /pricing at 390px: 44px before this change, 46px after. */
  .cookie-dialog .cookie-dialog__action { width: 100%; min-height: 44px; }
}

@media (max-width: 390px) {
  .cookie-dialog__header,
  .cookie-dialog__body,
  .cookie-dialog__actions { padding-right: var(--s4); padding-left: var(--s4); }
  .cookie-dialog__heading { gap: var(--s3); }
  .cookie-dialog__eyebrow { display: none; }
  .cookie-category__status {
    max-width: 82px;
    white-space: normal;
    text-align: center;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cookie-dialog[open],
  .cookie-dialog[open]::backdrop { animation: none; }
  .cookie-switch__track,
  .cookie-switch__thumb,
  .cookie-category__details { transition: none; }
}

/* ---- The guilloche band -------------------------------------------------
   The one ornament the brand mark actually carries, and the reason this site
   can look engraved rather than merely dark. A guilloche is interlocking arcs,
   the pattern on a banknote or a watch dial, and it is built here from two
   offset repeating radial gradients rather than an image so it inherits the
   gilt ramp and themes for free.

   USE IT ONCE PER PAGE, at most. It is the signature. A page that bands every
   section has no signature, it has wallpaper. The mask fades both ends so the
   band reads as inlaid rather than as a border that ran out of room. */
.guilloche {
  /* IT WAS AN ENGRAVED GUILLOCHE BAND, the interlaced pattern off a banknote, and on
     2026-09-12 that was exactly the problem: the site read as a nineteenth century
     certificate. What a modern page wants in the same slot is a single filament of light.

     The name stays because it is the signature's slot, not its drawing, and the class is in
     the served HTML and in the pattern library. Same rule as .hero__stadium above: change
     what it paints, not what it is called.

     STILL ONCE PER PAGE, at most. A page that bands every section has no signature, it has
     wallpaper. */
  height: 1px;
  border: 0;
  margin: var(--s8) 0;
  opacity: 0.85;
  background-image: linear-gradient(90deg,
    transparent, var(--gold-deep) 22%, var(--gold-lit) 50%, var(--gold-deep) 78%, transparent);
  box-shadow: 0 0 18px -2px rgba(198, 160, 87, 0.45);
}

/* Hairline and gilt rules, from the same tokens the rest of the system uses, so a separator
   never has to invent its own colour. */
.rule { border: 0; border-top: var(--rule-hair); margin: var(--s5) 0 var(--s3); }
.rule--gilt { border-top: var(--rule-gilt); }

/* ---- Reduced motion, for everything added in the 2026-09-12 restyle ---------
   The rest of the site's motion lives in motion.css behind its own guard. These four
   are in style.css because they are states of a component rather than page choreography,
   so their off switch has to be here too. gate.sh requires this block wherever a
   transition or an animation exists in a file.

   Hover still CHANGES, it just stops moving: the colour and the edge do the work that the
   lift and the sheen were doing, so a control never stops answering the pointer. */
@media (prefers-reduced-motion: reduce) {
  .btn,
  .tier {
    transition: none;
  }
  .btn:hover,
  .btn:active,
  .tier:hover {
    transform: none;
  }
  .btn--brass:hover::after { animation: none; }
  .hero__field { transition: none; }
}


/* ===========================================================================
   COMPONENTS ADDED 2026-09-13, when the page was still reading as empty.
   Every one of them resolves through the tokens above. None invents a colour.
   =========================================================================== */

/* ---- Ambient section light ------------------------------------------------
   A single soft bloom behind a section, so the middle of a long dark page is not a
   flat rectangle. Decorative and aria-hidden in the markup; it carries no content.
   Two placements, so consecutive sections do not light the same spot. */
.spot {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  overflow: hidden;
}
.spot::before {
  content: "";
  position: absolute;
  width: 60%;
  height: 120%;
  top: -30%;
  right: -10%;
  background: radial-gradient(50% 50% at 50% 50%, rgba(198, 160, 87, 0.13), transparent 70%);
  filter: blur(30px);
}
.spot--left::before {
  right: auto;
  left: -10%;
  background: radial-gradient(50% 50% at 50% 50%, rgba(201, 169, 97, 0.09), transparent 70%);
}
.section > .wrap { position: relative; z-index: 1; }

/* ---- The ticker -----------------------------------------------------------
   A slow band of what the builder actually supports. It is a marquee, which is a thing
   to be careful with: it moves for ever, so it carries no information a visitor has to
   read, and it stops dead under reduced motion rather than being hidden (the text is
   still true, it just sits still).

   Two identical lists side by side and a 50% translation, which is the only way to loop
   a marquee with no visible seam. aria-hidden on the second copy, or a screen reader
   reads everything twice. */
.ticker {
  position: relative;
  overflow: hidden;
  border-top: 1px solid var(--line-soft);
  border-bottom: 1px solid var(--line-soft);
  background: linear-gradient(90deg, transparent, rgba(198, 160, 87, 0.05), transparent);
  padding: var(--s4) 0;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.ticker__track {
  display: flex;
  width: max-content;
  animation: ticker 46s linear infinite;
}
.ticker__list {
  display: flex;
  align-items: center;
  gap: var(--s7);
  padding-right: var(--s7);
  margin: 0;
  list-style: none;
}
.ticker__list li {
  display: flex;
  align-items: center;
  gap: var(--s3);
  white-space: nowrap;
  font-family: var(--ui);
  font-size: var(--t-micro);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--muted);
}
.ticker__list li::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--gold);
  box-shadow: 0 0 10px var(--gold);
  flex: 0 0 auto;
}
.ticker:hover .ticker__track { animation-play-state: paused; }
@keyframes ticker { to { transform: translateX(-50%); } }

/* ---- Figures --------------------------------------------------------------
   A row of real numbers. Every one on the page is a published contest rule, not a
   performance claim: a roster size, a salary cap, a minimum. The approved-claims rule is
   why this component exists in that shape and must stay in it. */
.figures {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s4);
  margin-top: var(--s6);
}
.figure {
  padding: var(--s5);
  border: 1px solid var(--glass-line);
  border-radius: var(--radius-lg);
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.3);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.3);
  box-shadow: var(--card-shadow);
  transition: transform 260ms var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
              border-color 260ms ease, box-shadow 260ms ease;
}
.figure:hover {
  transform: translateY(-3px);
  border-color: rgba(198, 160, 87, 0.4);
  box-shadow: var(--card-shadow-lift);
}
.figure__n {
  display: block;
  font-family: var(--mono); font-variant-numeric: var(--nums);
  font-size: clamp(2rem, 4.5vw, 3.1rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.03em;
  background: var(--metal-gold);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  /* A fallback for a browser that cannot clip a gradient to text: without this the text
     is transparent on transparent and the figure is invisible rather than unstyled. */
  -webkit-text-fill-color: transparent;
  font-variant-numeric: tabular-nums;
}
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .figure__n { color: var(--gold-lit); -webkit-text-fill-color: currentColor; }
}
.figure__label {
  display: block;
  margin-top: var(--s3);
  font-family: var(--ui);
  font-size: var(--t-micro);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.figure__note { margin: var(--s2) 0 0; color: var(--text); font-size: var(--t-micro); }

/* ---- Format cards ---------------------------------------------------------
   One per contest format the builder knows. The roster line is the site's own published
   shape, so the card is documentation rather than marketing. */
.formats {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s4);
  margin-top: var(--s6);
}
.format {
  position: relative;
  display: grid;
  gap: var(--s3);
  padding: var(--s5);
  border: 1px solid var(--glass-line);
  border-radius: var(--radius-lg);
  background: var(--glass-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.3);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.3);
  box-shadow: var(--card-shadow);
  overflow: hidden;
  transition: transform 260ms var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
              border-color 260ms ease, box-shadow 260ms ease;
}
.format::before {
  content: "";
  position: absolute;
  top: 0;
  left: 10%;
  right: 10%;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
  opacity: 0.6;
  transition: opacity 260ms ease, left 360ms var(--ease-out, ease), right 360ms var(--ease-out, ease);
}
.format:hover {
  transform: translateY(-3px);
  border-color: rgba(198, 160, 87, 0.4);
  box-shadow: var(--card-shadow-lift);
}
.format:hover::before { opacity: 1; left: 0; right: 0; }
.format__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s3);
}
.format__name {
  margin: 0;
  font-family: var(--ui);
  font-size: var(--t-product);
  line-height: 1.15;
  letter-spacing: -0.01em;
}
.format__cap {
  font-family: var(--mono);
  font-variant-numeric: var(--nums);
  font-size: var(--t-micro);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--gold-bright);
  font-variant-numeric: tabular-nums;
}
.format__roster {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  margin: 0;
  padding: 0;
  list-style: none;
}
.format__roster li {
  padding: 0.28rem 0.6rem;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-xs);
  background: rgba(255, 255, 255, 0.03);
  font-family: var(--ui);
  font-size: var(--t-micro);
  letter-spacing: 0.06em;
  color: var(--text);
}
.format__roster li.is-key {
  border-color: rgba(198, 160, 87, 0.55);
  color: var(--gold-lit);
  background: rgba(198, 160, 87, 0.1);
}
.format__rule { margin: 0; color: var(--muted); font-size: var(--t-micro); }

@media (min-width: 700px) {
  .figures { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .formats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---- Reduced motion for everything above ---------------------------------
   The ticker STOPS rather than hiding: its text is true standing still, and a band that
   vanishes for some visitors is a band that cannot be trusted to carry anything. */
@media (prefers-reduced-motion: reduce) {
  .ticker__track { animation: none; }
  .figure,
  .format,
  .format::before { transition: none; }
  .figure:hover,
  .format:hover { transform: none; }
}

/* ===========================================================================
   THE MACHINE. A scroll-driven lid that opens onto the workspace and then stays.
   ===========================================================================
   The brief was a MacBook-style scroll reveal where the screen contents are the
   Lineup Generator and, crucially, where it STAYS on screen afterwards so it can be
   read rather than scrolled past. That second half is what the sticky stage and the
   tall runway below are for: the lid finishes opening in the first 55 percent of the
   runway and the remaining 45 percent is dwell.

   WHY THIS IS NOT REACT. The published component for this is React plus Tailwind plus
   Framer Motion, on a site with no build step and a CSP of script-src 'self'. The effect
   itself is one rotateX, one scale and one translate driven by a scroll position, which
   is what follows. macbook.js sets --p and touches nothing else.

   THE DEFAULT STATE IS THE OPEN STATE. Every transform below multiplies by
   (1 - var(--p)), and --p defaults to 0, so with JavaScript off, under reduced motion or
   if the script never runs, the lid is flat open and the workspace is simply visible.
   An animation must never be the thing standing between a visitor and the product. */

/* THE DEFAULT LIVES ON [data-macbook], NOT HERE, AND THAT IS NOT A STYLE PREFERENCE.
   --p: 0 used to be declared on .macbook. macbook.js writes --p to whichever element carries
   data-macbook, and on 2026-09-13 that moved UP to the hero section so the runway and the
   driver were the same box. .macbook then sat BETWEEN the section and the lid, and its own
   --p: 0 shadowed the inherited value: the section said 1, the lid read 0, and the laptop
   never moved. Nothing errored. The custom property was being set correctly the whole time
   and simply never reached the element that uses it.
   Declaring the default on the same element the script writes to makes shadowing impossible.
   tests pin it, because the failure is completely silent. */
[data-macbook] { --p: 0; }  /* 0 = open and settled. macbook.js drives this from 1 to 0. */
.macbook {
  position: relative;
  /* The runway. The stage is sticky inside it, so this height IS the dwell time. */
  height: 230vh;
  margin: var(--s7) 0 0;
}
.macbook__stage {
  position: sticky;
  top: var(--masthead);
  height: calc(100vh - var(--masthead));
  height: calc(100svh - var(--masthead));
  display: grid;
  align-content: center;
  justify-items: center;
  /* The perspective lives on the stage, not the lid: a perspective set on the element
     being rotated is applied after the rotation and the hinge reads as flat. */
  perspective: 1400px;
  perspective-origin: 50% 42%;
}

/* A bloom behind the machine, brightening as the lid opens. */
.macbook__glow {
  position: absolute;
  inset: 8% 4% 12%;
  background: radial-gradient(50% 50% at 50% 55%, rgba(198, 160, 87, 0.28), transparent 70%);
  filter: blur(40px);
  opacity: calc(1 - var(--p));
  pointer-events: none;
}

.macbook__lid {
  position: relative;
  width: min(96vw, 1180px);
  /* The hinge is the BOTTOM edge, which is what a laptop lid turns on. */
  transform-origin: 50% 100%;
  /* 62deg was not enough to read as a CLOSED laptop: at that angle the screen is still
     mostly facing you and the whole thing looked like a panel that tilts slightly, which is
     why it was reported as "not animating at all". 88deg is genuinely shut, edge on, and the
     lift and scale make it arrive rather than just rotate. */
  transform:
    translateY(calc(var(--p) * 9vh))
    rotateX(calc(var(--p) * 88deg))
    scale(calc(1 - var(--p) * 0.26));
  /* No transition: the value is driven every frame from the scroll position, and a
     transition on top of that lags behind the finger and feels broken. */
  will-change: transform;
}
.macbook__bezel {
  position: relative;
  padding: 10px;
  border-radius: 16px;
  background: linear-gradient(180deg, #22252d, #0f1116);
  border: 1px solid rgba(255, 255, 255, 0.1);
  box-shadow:
    0 1px 0 rgba(255, 255, 255, 0.14) inset,
    0 40px 90px -30px rgba(0, 0, 0, 0.9),
    var(--glow-gold-soft);
  overflow: hidden;
}
/* The screen's own sheen, strongest while the lid is still tipped back. */
.macbook__bezel::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(196deg, rgba(255, 255, 255, 0.16), transparent 42%);
  opacity: calc(0.25 + var(--p) * 0.75);
  pointer-events: none;
}
.macbook__notch {
  position: absolute;
  top: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 108px;
  height: 8px;
  border-radius: 0 0 7px 7px;
  background: #0f1116;
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-top: 0;
}

/* The base, seen edge on. It is a slab, not a drawing of a keyboard: at this angle that
   is all a real one reads as, and a literal key grid would look like a sticker. */
.macbook__base {
  width: min(96vw, 1180px);
  height: 14px;
  margin-top: -2px;
  border-radius: 0 0 14px 14px;
  background: linear-gradient(180deg, #2a2e37, #13151a 60%, #0a0c10);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-top: 0;
  box-shadow: 0 30px 60px -28px rgba(0, 0, 0, 0.95);
  position: relative;
}
.macbook__pad {
  position: absolute;
  left: 50%;
  top: 3px;
  transform: translateX(-50%);
  width: 120px;
  height: 3px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.07);
}
.macbook__keys { display: none; }

.macbook__hint {
  margin: var(--s5) 0 0;
  font-family: var(--ui);
  font-size: var(--t-micro);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--muted);
  /* Visible only while there is still something to scroll for. */
  opacity: var(--p);
  transition: opacity 200ms ease;
}

/* The workspace fills the screen rather than sitting in it. */
.macbook__bezel .gen-preview {
  margin: 0;
  border-radius: 8px;
  overflow: hidden;
}

/* A phone has no room for a laptop and no pointer to dwell with. The runway collapses,
   the stage stops being sticky, and the workspace is shown flat. */
@media (max-width: 760px) {
  .macbook { height: auto; }
  .macbook__stage { position: static; height: auto; perspective: none; }
  .macbook__lid { transform: none; width: 100%; }
  .macbook__base, .macbook__hint, .macbook__glow { display: none; }
  .macbook__bezel .gen-preview { max-height: none; }
}

/* Reduced motion: --p is never driven (macbook.js returns early), so the lid is already
   open. These rules make the rest of it stand still too. */
@media (prefers-reduced-motion: reduce) {
  .macbook { height: auto; }
  .macbook__stage { position: static; height: auto; }
  .macbook__lid { transform: none; }
  .macbook__hint { display: none; }
}

/* The machine's own section. It is full width and, critically, does NOT clip: an ancestor
   with overflow other than visible silently disables position:sticky on every descendant,
   which is exactly how the first attempt failed inside .ad-block--stage. */
.macbook-section {
  overflow: visible;
  padding-bottom: 0;
}
.macbook-section > .wrap { margin-bottom: var(--s6); }

/* Fill the screen properly. Inside the bezel the workspace gets a real viewport rather
   than whatever a grid column left it: the first attempt squashed it to 291px tall. */
.macbook__bezel .gen-preview {
  height: min(62vh, 620px);
  max-height: none;
}

/* ===========================================================================
   THE SPLIT HERO. Copy left, machine right, the row pinned while the lid opens.
   ===========================================================================
   Scrolling down from the headline is what opens the machine. That is why the runway
   lives on the SECTION and data-macbook is on the section too: macbook.js sets --p there
   and it inherits down to the transforms, which is the whole reason those are written as
   custom properties rather than as a class the script toggles. */

.hero--split {
  /* The runway. The row inside is sticky, so this height is how long the lid has to open
     and then sit still being looked at. */
  min-height: 0;
  height: 260vh;
  padding: 0;
  align-content: start;
  /* MUST NOT CLIP. An ancestor whose overflow is not visible silently disables
     position:sticky on every descendant, which is exactly how the first version of the
     machine failed. .hero sets overflow:hidden for the aurora, so this undoes it and the
     aurora is clipped by .hero__media instead, which has its own overflow:hidden. */
  overflow: visible;
}
.hero--split .hero__pin {
  position: sticky;
  top: var(--masthead);
  height: calc(100vh - var(--masthead));
  height: calc(100svh - var(--masthead));
  display: grid;
  align-content: center;
}
/* NAMED hero__cols, NOT hero__grid. hero__grid is a retired vault-era class and
   tests/homepage-hero-photo.test.mjs asserts it never comes back; reusing the name would
   have read as the old hero being restored. Found by that test, which is what it is for. */
.hero--split .hero__cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s6);
  align-items: center;
}
.hero--split .hero__inner { max-width: 34rem; }
/* The pin is one viewport tall. Anything in the left column that does not fit inside it
   pushes the headline up under the masthead, which is what the register row was doing.
   It is not lost: the products section below says the same thing with more room. */
@media (min-width: 1000px) {
  .hero--split .register { display: none; }
}

/* From 1000px the two columns exist. Below that the machine goes under the copy and the
   whole pin is dropped: a phone has neither the width for a laptop nor a pointer to dwell
   with, and a 210vh runway on a small screen is just a very long empty scroll. */
@media (min-width: 1000px) {
  .hero--split .hero__cols {
    /* The machine gets the bigger half: it has to hold a three column workspace at a size
       a person can actually read, and the copy column only has to hold 34rem of text. */
    grid-template-columns: minmax(0, 0.68fr) minmax(0, 1.32fr);
    gap: var(--s6);
  }
}
@media (max-width: 999px) {
  .hero--split { height: auto; padding: var(--pad-hero-top) 0 var(--pad-hero-bottom); }
  .hero--split .hero__pin { position: static; height: auto; }
}

/* The machine inside a hero column. It loses the full-page stage it had as its own
   section: the hero's pin is doing that job now, so this is only the sizing. */
.hero__machine .macbook { height: auto; margin: 0; }
.hero__machine .macbook__stage {
  position: static;
  height: auto;
  perspective: 1500px;
  perspective-origin: 50% 45%;
}
.hero__machine .macbook__lid,
.hero__machine .macbook__base { width: 100%; }
/* THE SCREEN IS SCALED, NOT REFLOWED, and that is the fix for a whole class of bug.
   Squeezing a three column product UI into a hero column meant fighting it: the tracks got
   narrow, grid items refused to shrink below their content and painted over each other, and
   every breakpoint I added moved the collision somewhere else. A photograph of a laptop does
   not reflow the screen, it shrinks it.
   So the workspace is laid out at a real desktop width, 1240px, exactly as it would be on a
   monitor, and then scaled to whatever the lid is wide. 100cqw is the bezel's own inner
   width, so the fit is exact at every viewport with no breakpoint at all, and the mock can
   never collide with itself again because it is always being laid out at full size. */
.hero__machine .macbook__bezel {
  container-type: inline-size;
  aspect-ratio: 16 / 10;
  padding: 0;
}
.hero__machine .macbook__bezel .gen-preview {
  position: absolute;
  top: 0;
  left: 0;
  width: 1240px;
  height: 775px;                /* 1240 at 16:10, so the scale is uniform */
  margin: 0;
  border: 0;
  border-radius: 0;
  transform-origin: 0 0;
  /* 1240px, NOT 1240. scale() takes a unitless number, and a length divided by a plain
     number is still a length, so scale(calc(100cqw / 1240)) is invalid and a browser drops
     the whole transform silently: the screen rendered at full size and simply overflowed the
     lid, which looks like a layout bug rather than a unit bug. Length over length is a
     number, which is what this needs. */
  transform: scale(calc(100cqw / 1240px));
}
.hero__machine .macbook__hint {
  display: block;
  margin: var(--s4) 0 0;
  text-align: center;
}
.hero__machine .macbook__glow { inset: 0; }

@media (max-width: 999px) {
  /* Stacked, and the machine is shown flat: no runway means no scroll to open it with.
     The scaled screen still works here, and still at 16:10, so a phone gets a legible
     miniature of the same workspace rather than a stack of collapsed panels. */
  .hero__machine .macbook__lid { transform: none; }
  .hero__machine .macbook__base { display: none; }
}

/* ---- Pricing page ---------------------------------------------------------
   Two cards and a table. The table is the reason this page exists: a reader can check the
   arithmetic rather than take a saving on trust, which is the difference between a price
   list and a pitch. */
.price-pair {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s5);
  margin-top: var(--s6);
}
.price-card {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: var(--s6) var(--s5) var(--s5);
  border: 1px solid var(--card-line);
  border-radius: var(--radius-lg);
  background: var(--card-bg);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(1.3);
  backdrop-filter: blur(var(--glass-blur)) saturate(1.3);
  box-shadow: var(--card-shadow);
  transition: transform 260ms var(--ease-out, cubic-bezier(0.22, 1, 0.36, 1)),
              border-color 260ms ease, box-shadow 260ms ease;
}
.price-card::before {
  content: "";
  position: absolute;
  top: 0;
  left: 14%;
  right: 14%;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--gold), transparent);
  opacity: 0.65;
}
.price-card:hover {
  transform: translateY(-3px);
  border-color: rgba(198, 160, 87, 0.4);
  box-shadow: var(--card-shadow-lift);
}
.price-card--feature {
  border-color: rgba(198, 160, 87, 0.42);
  box-shadow: var(--card-shadow-lift), var(--glow-gold-soft);
}
.price-card--feature::before { left: 0; right: 0; opacity: 1; }
.price-card__name {
  margin: 0;
  font-family: var(--ui);
  font-size: var(--t-micro);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--muted);
}
.price-card__amount {
  display: flex;
  align-items: baseline;
  gap: var(--s3);
  margin: var(--s3) 0 0;
}
.price-card__num {
  font-family: var(--mono);
  font-variant-numeric: var(--nums);
  font-size: clamp(2.6rem, 5vw, 3.6rem);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.03em;
  background: var(--metal-gold);
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  -webkit-text-fill-color: transparent;
}
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
  .price-card__num { color: var(--gold-lit); -webkit-text-fill-color: currentColor; }
}
.price-card__per { color: var(--muted); font-size: var(--t-body); }
.price-card__line { margin: var(--s4) 0 0; color: var(--text); }
.price-card__list {
  margin: var(--s5) 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: var(--s3);
}
.price-card__list li {
  position: relative;
  padding-left: var(--s5);
  color: var(--muted);
  font-size: var(--t-micro);
}
/* A gilt tick drawn in CSS, so the list needs no icon font and no image request. */
.price-card__list li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 0.34em;
  width: 6px;
  height: 10px;
  border: solid var(--gold);
  border-width: 0 1.5px 1.5px 0;
  transform: rotate(42deg);
}
.price-card__cta { margin: var(--s6) 0 0; }
.price-card__note { margin: var(--s3) 0 0; color: var(--muted); font-size: var(--t-micro); }

/* The table. Figures right-aligned and tabular so a column can be read down. */
.price-table-wrap { margin-top: var(--s6); overflow-x: auto; }
.price-table {
  width: 100%;
  border-collapse: collapse;
  font-variant-numeric: var(--nums);
}
.price-table__cap {
  caption-side: top;
  text-align: left;
  padding-bottom: var(--s4);
  color: var(--muted);
  font-size: var(--t-micro);
}
.price-table th,
.price-table td {
  padding: var(--s4) var(--s4);
  text-align: left;
  border-bottom: var(--rule-hair);
}
.price-table thead th {
  font-family: var(--ui);
  font-size: var(--t-micro);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--muted);
  font-weight: 600;
}
.price-table tbody th { font-weight: 600; color: var(--text); }
.price-table .num {
  font-family: var(--mono);
  text-align: right;
  color: var(--text);
}
.price-table .is-best th,
.price-table .is-best .num { color: var(--gold-lit); }
.price-table .is-best { background: rgba(198, 160, 87, 0.07); }
.price-foot { margin-top: var(--s4); font-size: var(--t-micro); }

@media (min-width: 820px) {
  .price-pair { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ---- The rates, side by side ----------------------------------------------
   One row, cheapest first, each card the same height whatever its copy runs to. Three products
   in two stacked groups read as two unrelated offers and buried the cheapest one.

   AUTO-FIT, NOT repeat(3), AND THAT IS THE WHOLE POINT OF THIS RULE. The day pass card is
   hidden until /api/config says the offer is on sale, so this grid has to hold two cards as
   often as three. A fixed three-column track leaves a hole where the hidden card was; auto-fit
   drops to two tracks on its own and the row stays centred and even.

   align-items is not set, so the grid stretches every card to the tallest, and .price-card is
   already a flex column. Its .price-card__cta therefore needs margin-top auto to sit the
   buttons on one line, which is what the reference layout does and what makes a row of cards
   read as a row rather than as three unrelated boxes. */
/* THE THREE LINES ABOVE THE RATES. Narrow on purpose: it is the one fact the row of cards
   cannot say by itself (all three rates buy the same product), and a full-width paragraph at
   this size reads as a hero, which is what was removed from this page for pushing the prices
   below the fold. */
.plans-lede {
  max-width: 62ch;
  margin-top: var(--s5);
}
.plans-lede p {
  margin: 0;
  color: var(--muted);
  line-height: 1.6;
}
.plans-lede p + p { margin-top: var(--s3); }
/* The first line is the thesis, so it carries the weight the deleted headline used to. */
.plans-lede p:first-child {
  color: var(--text);
  font-size: var(--t-lead, 1.125rem);
}

/* THE ELIGIBILITY BOX, ABOVE THE BUTTONS IT GATES. On /subscribe this sat below the button,
   which is how a customer on a phone tapped, got nothing, and never saw the reason: it was off
   screen underneath their thumb (reported live 2026-09-18). Here it is passed on the way down
   the page, and pricing-checkout.js still scrolls to it if somebody reaches a button first. */
.plans-consent {
  max-width: 62ch;
  margin-top: var(--s5);
  padding: var(--s4);
  border: 1px solid var(--card-line);
  border-radius: var(--radius);
  background: var(--panel);
}
.plans-consent input[aria-invalid="true"] { outline: 2px solid var(--danger); outline-offset: 2px; }
/* Reserves no space when empty, so the row does not shift the first time the page speaks. */
.plans-status {
  margin: var(--s3) 0 0;
  font-size: var(--t-micro);
  color: var(--muted);
}
.plans-status:empty { display: none; }
.plans-status.is-warn { color: var(--gold-lit); }
.plans-status.is-err { color: var(--danger); }

.price-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--s5);
  margin-top: var(--s6);
}
/* THE NOTE SITS ABOVE THE BUTTON, not under it, and the pair is pinned to the bottom of the
   card. Two reasons, and the second is the important one.

   It lines the buttons up. Each card's note runs to a different number of lines (the day pass
   disclosure is four, "Billed monthly. Cancel anytime." is one), so with the note last the
   button floated to a different height in every card and the row read as three unrelated boxes.

   And on the day pass it puts the four facts about the charge directly above the thing that
   takes the card, rather than below it. For a negative option offer that is the whole point:
   the disclosure has to be read BEFORE the button, not found afterwards. */
.price-row .price-card__note { margin-top: auto; padding-top: var(--s5); }
.price-row .price-card__cta { margin-top: var(--s4); }

@media (min-width: 720px) {
  .price-row { grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); }
}

/* .hero--tight is gone with the pricing hero it was written for. It shortened a block that has
   since been deleted outright, and no other page used it.

   WHAT REPLACES IT IS SMALLER. With no hero, #plans is the first thing in <main> on the pricing
   page, and .section's full top rhythm is sized to follow a hero rather than to open a page. It
   left a band of nothing above the prices, which is the whole thing that was being removed. */
#plans { padding-top: var(--s5); }
@media (prefers-reduced-motion: reduce) {
  .price-card { transition: none; }
  .price-card:hover { transform: none; }
}

/* A PAGE hero, not the home page's. Short, left aligned, no runway and no machine: it
   introduces a page rather than being the page. The home hero is a full viewport because
   it has a laptop to open in it; every other hero just needs a title and a line. */
.hero--page {
  min-height: 0;
  height: auto;
  align-content: start;
  padding: var(--pad-hero-top) 0 var(--pad-compact);
}
.hero--page .hero__title { font-size: clamp(2.2rem, 5vw, 3.4rem); max-width: 16ch; }
.hero--page .hero__lede { margin-top: var(--s5); max-width: 44ch; }

/* ---- SIGNED IN, EVERYWHERE ----------------------------------------------
   Signed in has to mean signed in on every page: no Sign In link, no Make an account button,
   no separate change-password screen, and a user menu showing initials instead.

   data-clerk-user is stamped on <html> by clerk-auth.js once Clerk reports a session, on every
   page of both Workers. One attribute, so a page does not have to know anything about auth to
   stop asking for it.

   Two selectors rather than one, deliberately. The :has() rule removes the whole nav item, so
   a signed-in visitor does not get an empty <li> holding a gap where "Sign In" used to be. The
   plain rule catches the same links anywhere else (hero buttons, the footer, a mid-page
   prompt) and is the fallback in any engine without :has(). Hiding is CSS rather than script
   so it lands with the attribute, in one paint, instead of flickering.

   THE LINKS ARE HIDDEN, NEVER REMOVED. Sign out and they are simply there again, no reload
   needed, because nothing was deleted from the document. */
[data-clerk-user="on"] li:has(> a[href*="/signin"]),
[data-clerk-user="on"] li:has(> a[href*="/signup"]) { display: none; }

[data-clerk-user="on"] a[href*="/signin"],
[data-clerk-user="on"] a[href*="/signup"] { display: none; }

/* The hero's primary button is the one place where hiding alone would be worse than useless:
   it would leave a signed-in visitor looking at a hero with no way into the product. So
   clerk-auth.js repoints it at the Generator instead, and this keeps it visible when it has
   been repointed. The attribute is set by script, so an unrepointed button still hides. */
[data-clerk-user="on"] a[data-hero-primary][data-signed-in-cta] { display: inline-flex; }

/* Anything a page wants gone for a signed-in visitor that is not a link: the app's own
   set-a-password card, which Clerk's user menu now owns. */
[data-clerk-user="on"] [data-signed-out-only] { display: none; }

/* The user menu itself. Clerk paints the button; this only gives it a seat in the nav that
   matches the pill beside it and does not collapse the row on a phone. */
.nav__user {
  display: flex;
  align-items: center;
  min-height: 34px;
}
.nav__user:empty { display: none; }

/* =========================================================================
   HOMEPAGE, 2026-09-15 REBUILD
   The homepage mock rebuilt on this site's tokens. Five new
   blocks: the two-lane compare, the three how-steps, the winners' wall, the
   split pricing panel, and the referral pair.

   NOT TAKEN FROM THE MOCK: its font stack and its raw hex. The mock loads
   Fraunces and IBM Plex Sans from Google Fonts, which the CSP refuses outright
   (no external font host), and its gold is #C9A961 against our --gold #c6a057,
   a difference no eye resolves. So the palette was already a match and the type
   stays Sora and Inter, which is a deliberate 2026-09-13 decision, not an
   oversight. Everything below resolves to a token, so the light theme comes
   free and a restyle never edits a call site.
   ===================================================================== */

/* ---- The two lanes. Seven steps against three. --------------------------
   The point is made by LENGTH, so the lanes are equal-width columns and the
   pills wrap. Do not make our lane wider to be kinder to it. */
.compare {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--gutter, 24px);
  margin-top: 40px;
}
.lane {
  padding: 22px;
  border: var(--rule-hair);
  border-radius: var(--radius);
  background: var(--panel);
}
.lane--us {
  border: var(--rule-gilt);
  background: var(--card-bg);
  box-shadow: var(--card-shadow);
}
.lane__name {
  font-family: var(--ui);
  font-weight: 600;
  font-size: 1rem;
  margin: 0;
  color: var(--text);
}
.lane--us .lane__name { color: var(--brass); }
.lane__note {
  margin: 2px 0 14px;
  font-size: 0.86rem;
  color: var(--muted);
}
.pills {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.pill {
  font-family: var(--ui);
  font-size: 0.82rem;
  line-height: 1;
  padding: 9px 12px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--field-line);
  background: var(--field-bg);
  color: var(--muted);
}
.pill--lit {
  border-color: var(--line);
  color: var(--text);
  background: rgba(198, 160, 87, 0.1);
}

/* ---- The three steps ---------------------------------------------------
   .shot is a browser frame with NO screenshot in it yet, which is why it is
   sized by aspect-ratio rather than by an image: drop an <img> in and the
   frame keeps its shape instead of jumping. */
.howsteps {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--gutter, 24px);
  margin-top: 40px;
}
.howstep { min-width: 0; }
.shot {
  border: var(--rule-hair);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--panel);
  box-shadow: var(--card-shadow);
}
.shot__bar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 9px 12px;
  background: var(--panel-2);
  border-bottom: var(--rule-hair);
}
.shot__bar i {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--field-line);
  flex: 0 0 auto;
}
.shot__bar span {
  margin-left: 8px;
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.02em;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.shot__body {
  aspect-ratio: 16 / 10;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 18px;
  text-align: center;
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(198, 160, 87, 0.09), transparent 62%),
    var(--bg-lift);
}
.shot__screen {
  margin: 0;
  font-family: var(--brand);
  font-size: 1.05rem;
  color: var(--text);
}
.shot__hint {
  margin: 0;
  font-size: 0.8rem;
  line-height: 1.45;
  color: var(--muted);
  max-width: 28ch;
}
.howstep__n {
  margin: 18px 0 6px;
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--brass);
}
.howstep__where { color: var(--muted); }
.howstep__name {
  margin: 0 0 8px;
  font-family: var(--brand);
  font-size: 1.15rem;
  line-height: 1.25;
  color: var(--text);
}
.howstep__line {
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--muted);
}
.howfoot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px;
  margin-top: 40px;
}
.howfoot p { margin: 0; }

/* ---- The winners' wall -------------------------------------------------
   auto-fit, so approving a third winner widens the wall with no CSS change. */
.wall {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--gutter, 24px);
  margin-top: 32px;
}
.win {
  margin: 0;
  padding: 14px;
  border: var(--rule-gilt);
  border-radius: var(--radius);
  background: var(--card-bg);
  box-shadow: var(--card-shadow);
}
.win__shot {
  width: 100%;
  height: auto;
  display: block;
  border-radius: var(--radius-sm);
}
.win__cap {
  margin: 12px 2px 0;
  font-family: var(--ui);
  font-size: 0.88rem;
  color: var(--text);
}
.wall__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 20px;
  margin-top: 28px;
}
.wall__foot p {
  flex: 1 1 42ch;
  margin: 0;
  font-size: 0.78rem;
  line-height: 1.6;
}

/* ---- Pricing, said on the left and sold on the right ------------------- */
.price-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr);
  gap: 48px;
  align-items: start;
}
.ease {
  margin: 28px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 12px;
}
.ease li {
  position: relative;
  padding-left: 26px;
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--muted);
}
.ease li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.5em;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: rgba(198, 160, 87, 0.18);
}
.plan-card {
  padding: 28px;
  border: var(--rule-gilt);
  border-radius: var(--radius-lg);
  background: var(--card-bg);
  box-shadow: var(--card-shadow-lift);
}
.plan-card__top { margin-bottom: 14px; }
.plan-card__name {
  font-family: var(--ui);
  font-weight: 600;
  font-size: 0.95rem;
  color: var(--brass);
}
.plan-card__price {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin: 0 0 10px;
}
.plan-card__n {
  font-family: var(--brand);
  font-size: 3rem;
  line-height: 1;
  color: var(--text);
  font-variant-numeric: var(--nums);
}
.plan-card__per {
  font-size: 0.9rem;
  color: var(--muted);
}
.plan-card__sub {
  margin: 0 0 20px;
  font-size: 0.92rem;
  line-height: 1.55;
  color: var(--muted);
}
.plan-card__list {
  margin: 0 0 24px;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 10px;
  border-top: var(--rule-hair);
  padding-top: 20px;
}
.plan-card__list li {
  position: relative;
  padding-left: 22px;
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--text);
}
.plan-card__list li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.55em;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--brass);
}
.plan-card__cta { margin: 0 0 12px; }
.plan-card__foot {
  margin: 0;
  font-size: 0.78rem;
  line-height: 1.55;
  color: var(--muted);
}

/* ---- The referral pair ------------------------------------------------- */
.refs {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--gutter, 24px);
  margin-top: 32px;
}
/* COLUMN, NOT A WRAPPING ROW. This was a row with flex-wrap and space-between, and the
   two cards came out different shapes in a browser: DraftKings' longer note pushed its
   button onto a second line while FanDuel's stayed beside the text, so a pair meant to
   read as a pair read as two unrelated cards. Where the button lands must not depend on
   how long the sentence above it is. margin-top:auto puts both buttons on the same
   baseline whatever the notes do. */
.ref {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 18px;
  padding: 22px;
  border: var(--rule-hair);
  border-radius: var(--radius);
  background: var(--panel);
}
.ref .btn { margin-top: auto; }
.ref__say { min-width: 0; }
.ref__name {
  margin: 0 0 4px;
  font-family: var(--brand);
  font-size: 1.05rem;
  color: var(--text);
}
.ref__say p:last-child { margin: 0; font-size: 0.88rem; }
.refs__note {
  margin: 24px 0 0;
  font-size: 0.78rem;
  line-height: 1.6;
}

/* ---- A bigger primary, for the one CTA per section --------------------- */
.btn--lg {
  min-height: 52px;
  padding-inline: 28px;
  font-size: 1rem;
}

/* ---- Narrow ------------------------------------------------------------
   One breakpoint, because every grid above is two or three equal columns and
   they all want the same thing at phone width: one column. */
@media (max-width: 900px) {
  .compare,
  .howsteps,
  .refs { grid-template-columns: minmax(0, 1fr); }
  .price-split {
    grid-template-columns: minmax(0, 1fr);
    gap: 32px;
  }
}
@media (max-width: 560px) {
  .plan-card { padding: 22px; }
  .plan-card__n { font-size: 2.5rem; }
  .howfoot .btn,
  .plan-card__cta .btn { width: 100%; }
}

/* The product's one-line description. A chrome-copy test pins it to the homepage, so it
   lives wherever the homepage sells the Generator; on 2026-09-15 that moved from the old
   #products ad block to here. Do not name the pinning test file in this comment: one of
   its sibling checks asserts the stylesheet never mentions the retired hero photograph,
   and it does that by substring, so the file name alone failed it. */
.plan-card__what {
  margin: 0 0 16px;
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--text);
}

/* THE MASTHEAD IS STICKY AND NOTHING ALLOWED FOR IT. Nine nav links across eight pages
   point at index.html#products, and #faq and #chat have nine each; every one of them
   dropped its own heading underneath the bar. Found 2026-09-15 by screenshotting a
   section after scrollIntoView and seeing the masthead sitting on the h2. One rule,
   every anchor target on the site, rather than a value per section. */
main [id],
section[id] {
  scroll-margin-top: 88px;
}
