/* ==========================================================================
   LEFT BRAIN SNIPER — design system
   Section numbering follows the build brief.
   4.1 Colour · 4.2 Typography · 4.3 The crimson rule · 4.4 Spacing · 4.5 Components
   ========================================================================== */

/* --- Fonts (self-hosted, latin subset, display: swap) --------------------- */
@font-face {
  font-family: 'Anton';
  src: url('/assets/fonts/anton-400.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Oswald';
  src: url('/assets/fonts/oswald-var.woff2') format('woff2');
  font-weight: 200 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('/assets/fonts/inter-var.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* --- 4.1 Colour — these values only --------------------------------------- */
:root {
  --ink: #0D0D0D;
  --ink-warm: #14120F;
  --bone: #F3EEE4;
  --bone-deep: #E8E1D4;
  --silver: #CCCCCC;
  --silver-dim: #8A8A8A;
  --crimson: #A8282E;
  --crimson-dark: #9B252A;      /* crimson darkened 8%, hover only */

  /* Crimson TEXT is routed through --accent so the dark-ground value can be
     changed in one place. See TODO.md: "Crimson eyebrow contrast on ink".
     crimson on ink measures 2.78:1, below the WCAG 2.2 AA 4.5:1 minimum
     (and below the 3:1 large-text minimum). The brief specifies crimson
     eyebrows on ink, so that is what ships; switching --accent-on-dark to
     var(--silver) makes every dark ground pass without touching markup.
     Crimson RULES, borders and fills are non-text and stay --crimson. */
  --accent: var(--crimson);
  --accent-on-dark: var(--crimson);

  /* SURFACE TOKENS. A component styled against these works on either ground,
     which is what let the quiz pages move from ink to bone without rewriting
     every rule. The bare :root values are the bone ground; .ground-ink
     rebinds them below. There is no muted tone for light grounds in §4.1, so
     secondary text on bone is ink-warm differentiated by size, never colour. */
  --surface: var(--bone);
  --surface-text: var(--ink-warm);
  --surface-dim: var(--ink-warm);
  --surface-line: var(--bone-deep);
  --surface-field: var(--white);
  /* The sticky bars sit over scrolling content. On bone a hairline alone
     guillotines a white option card mid-row and reads as a paint bug, so the
     bars also cast a short shadow. Dark grounds carry no cast shadow — ink on
     ink shows nothing — and rely on the hairline. */
  --surface-shadow: rgba(20, 18, 15, 0.14);
  /* WCAG 1.4.11 wants 3:1 between a control's boundary and what surrounds
     it. A white field on bone measures 1.17:1 and the bone-deep hairline
     1.12:1 against the fill — on a light ground the fields had no
     perceivable edge at all, which only became obvious once the quizzes
     moved off ink. Controls are ruled in ink-warm, which is also how the
     book's own worksheet is drawn. Dividers keep --hairline-light: a
     faint rule is right there and it is not a control. */
  --control-edge: var(--ink-warm);

  /* Gold as a second semantic: crimson means ACT, gold means WHERE YOU STAND.
     Taken from the cover, where crimson is the crosshair and the word SNIPER,
     and gold is the hemisphere being aimed at. Applies to the arena scale
     markers, the framework's level numerals, the "Level N of 7" label and the
     book's four outcome words.

     TO REVERT: set this to var(--accent). That restores the first three
     exactly; the book's four outcome words become crimson rather than the
     silver-dim they were before Part 2, so `git revert` is the pixel-exact
     undo. Gold is used on ink only — it measures 1.12:1 on bone. */
  --position: var(--gold);
  --gold: #F4E548;
  --white: #FFFFFF;

  --hairline-dark: #242424;      /* borders on dark grounds */
  --hairline-light: var(--bone-deep);

  /* --- 4.4 Spacing — 8px base ------------------------------------------- */
  --s-1: 8px;
  --s-2: 16px;
  --s-3: 24px;
  --s-4: 32px;
  --s-5: 40px;
  --s-6: 48px;
  --s-8: 64px;
  --s-10: 80px;
  --s-14: 112px;
  --s-18: 144px;

  --section-y: 80px;
  --container: 1200px;
  --gutter: 24px;

  --measure: 68ch;

  /* --- 4.2 Typography scale (mobile → desktop) --------------------------- */
  --display-xl: 44px;
  --display-lg: 34px;
  --display-md: 26px;
  --eyebrow: 12px;
  --lead: 18px;
  --body: 16px;
  --small: 14px;
  --label: 13px;

  --font-display: 'Anton', 'Arial Narrow', Impact, sans-serif;
  --font-subhead: 'Oswald', 'Arial Narrow', sans-serif;
  --font-body: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;
}

@media (min-width: 768px) {
  :root {
    --section-y: 140px;
    --gutter: 48px;
    --display-xl: 88px;
    --display-lg: 64px;
    --display-md: 44px;
    --eyebrow: 14px;
    --lead: 22px;
    --body: 18px;
  }
}

/* --- Reset ---------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
body {
  font-family: var(--font-body);
  font-size: var(--body);
  line-height: 1.6;
  color: var(--ink-warm);
  background: var(--bone);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img, svg, video { display: block; max-width: 100%; height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
ul, ol { padding: 0; list-style: none; }
/* Component display rules share specificity with [hidden] and come later in
   the cascade, so the attribute needs to win outright. */
[hidden] { display: none !important; }

/* --- Focus (2px crimson outline, 2px offset) ------------------------------ */
:focus-visible {
  outline: 2px solid var(--crimson);
  outline-offset: 2px;
}
.on-dark :focus-visible,
.ground-ink :focus-visible {
  outline-color: var(--crimson);
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  background: var(--crimson);
  color: var(--bone);
  padding: var(--s-2) var(--s-3);
  font-family: var(--font-subhead);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: var(--label);
  text-decoration: none;
}
.skip-link:focus { left: 0; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* --- 4.2 Type tokens ------------------------------------------------------ */
.display-xl, .display-lg, .display-md {
  font-family: var(--font-display);
  font-weight: 400;
  text-transform: uppercase;
  line-height: 1.05;
}
.display-xl { font-size: var(--display-xl); letter-spacing: -0.01em; }
.display-lg { font-size: var(--display-lg); letter-spacing: -0.01em; }
.display-md { font-size: var(--display-md); letter-spacing: 0; }

/* THE SMALL-CAPS TIERS. There are exactly two, and nothing may add a third.
   Subhead — Oswald 600, --lead, 0.06em: a heading that owns a block.
   Label    — Oswald 600, --label, 0.12em: meta, captions, field labels,
              eyebrows. COLOUR is the only variant; weight and tracking are not.
   Enforced by verify.py. §4.2 specified the eyebrow at 0.18em and 12→14px;
   folded into Label because the two differed by one pixel, one weight step and
   0.06em, which reads as a mistake rather than a distinction. */
.eyebrow {
  font-family: var(--font-subhead);
  font-weight: 600;
  font-size: var(--label);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  line-height: 1.3;
  color: var(--accent);
}

.label {
  font-family: var(--font-subhead);
  font-weight: 600;
  font-size: var(--label);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  line-height: 1.3;
}

.lead { font-size: var(--lead); line-height: 1.55; }
.small { font-size: var(--small); }

.measure { max-width: var(--measure); }
.measure-center { max-width: var(--measure); margin-inline: auto; }

/* Paragraph rhythm comes from the container's `gap`. Only flowing prose,
   which has no grid container, sets its own. */

/* --- 4.3 The crimson rule — 3px × 64px ------------------------------------ */
.rule {
  display: block;
  width: 64px;
  height: 3px;
  background: var(--crimson);
  border: 0;
  flex: none;
}
.rule--center { margin-inline: auto; }

/* Crimson underline beneath a key headline word. */
.mark {
  box-shadow: inset 0 -0.12em 0 var(--crimson);
}

/* --- 4.4 Layout ----------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding-block: var(--section-y); }
.section--tight { padding-block: calc(var(--section-y) * 0.65); }

.ground-ink { background: var(--ink); color: var(--silver); }
.ground-bone { background: var(--bone); color: var(--ink-warm); }
.ground-ink .display-xl,
.ground-ink .display-lg,
.ground-ink .display-md { color: var(--silver); }
.ground-bone .display-xl,
.ground-bone .display-lg,
.ground-bone .display-md { color: var(--ink-warm); }

.dim { color: var(--silver-dim); }          /* 14px+ only, never essential info */
/* silver-dim measures 2.97:1 on bone — under AA, and .dim carries real
   sentences (the assessment's "no right or wrong level" line, hero trust
   lines). §4.1 has no muted tone for light grounds, so secondary text on bone
   is ink-warm differentiated by size, matching .muted-light above. */
.ground-bone .dim { color: var(--ink-warm); }
/* The palette carries no muted tone for light grounds. Secondary text on
   bone stays ink-warm and is differentiated by size, never by colour. */
.muted-light { color: var(--ink-warm); }

/* Dark grounds rebind the text accent. */
.ground-ink,
.header,
.mobile-nav,
.footer {
  --accent: var(--accent-on-dark);
  --surface: var(--ink);
  --surface-text: var(--silver);
  --surface-dim: var(--silver-dim);
  --surface-line: var(--hairline-dark);
  --surface-field: var(--ink);
  --surface-shadow: transparent;
  --control-edge: var(--hairline-dark);
}

/* Gold measures 14.94:1 on ink and 1.12:1 on bone — unreadable. The position
   axis is therefore gold on dark grounds and ink-warm on light ones, with
   crimson carrying the filled extent either way. */
.ground-bone { --position: var(--ink-warm); }

/* --- TextureBackground ---------------------------------------------------- */
.texture {
  position: relative;
  isolation: isolate;
}
.texture::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image: url('/images/texture-mosaic.png');
  background-repeat: repeat;
  /* The tile is 1024px square. At 512px it maps 1:1 on a 2x display and
     downscales cleanly on a 1x one, which keeps the engraved hatching crisp —
     the lines are only a few pixels wide and turn to mush if resampled twice.
     Opacity measured against the cover's own background: at 6% the tile lands
     on median 13 / p95 22 / p99 26, the cover on 14 / 22-24 / 28-30. Tune
     between 4% and 8% rather than regenerating the tile. */
  background-size: 512px 512px;
  opacity: 0.06;
  pointer-events: none;
}
/* The same tile on a light ground. The artwork is near-white with alpha, so
   painting it directly on bone shows nothing — it is masked instead and filled
   with ink-warm, which is how the section seam already draws it.
   Opacity matched by arithmetic rather than by eye: on ink, 6% white lifts the
   ground by 0.06 x (255-13) = 14.5 units at the tile's peak alpha. The same
   14.5-unit *drop* on bone needs 14.5 / (243-20) = 6.5%. Dark-on-light reads
   heavier than light-on-dark at equal delta, so it ships a little under that. */
.ground-bone.texture::before {
  background-image: none;
  background-color: var(--ink-warm);
  -webkit-mask: url('/images/texture-mosaic.png') 0 0 / 512px 512px repeat;
  mask: url('/images/texture-mosaic.png') 0 0 / 512px 512px repeat;
  /* 0.045, not the arithmetic 0.065. Measured off the rendered page rather than
     off the formula: at 0.05 the bone tile landed on median 2 / p95 10 / p99 11
     against the ink tile's 0 / 9 / 10, so it was running ~10% hot. */
  opacity: 0.045;
}
/* No texture asset → flat ink. Toggled by adding .texture--absent. */
.texture--absent::before { display: none; }

/* --- Grid helpers --------------------------------------------------------- */
.grid { display: grid; gap: var(--s-6); }
.grid-2 { grid-template-columns: 1fr; }
.grid-3 { grid-template-columns: 1fr; }
.grid-4 { grid-template-columns: 1fr; }
@media (min-width: 768px) {
  .grid-2 { grid-template-columns: repeat(2, 1fr); }
  .grid-3 { grid-template-columns: repeat(3, 1fr); }
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) {
  .grid-4 { grid-template-columns: repeat(4, 1fr); }
}

/* --- 4.5 Buttons ---------------------------------------------------------- */
.btn {
  display: inline-block;
  font-family: var(--font-subhead);
  font-weight: 600;
  font-size: var(--label);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  line-height: 1.2;
  text-decoration: none;
  border-radius: 2px;
  padding: 18px 32px;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color 150ms ease, color 150ms ease, border-color 150ms ease;
}
.btn--primary {
  background: var(--crimson);
  color: var(--bone);
  border-color: var(--crimson);
}
.btn--primary:hover { background: var(--crimson-dark); border-color: var(--crimson-dark); }
/* Gold fill, ink label. Gold is unusable as text on a light ground — 1.12:1 —
   but as a fill it is the inverse and measures 14.94:1, so this button works
   anywhere. It marks the book and only the book: the cover's own accent, and
   the colour this site already sets the four outcome words in, so the one
   action that IS the book does not read as another step in the funnel. Matches
   how leftbrainsniperbook.com uses its yellow. */
.btn--gold {
  background: var(--gold);
  color: var(--ink);
  border-color: var(--gold);
}
.btn--gold:hover {
  background: var(--bone);
  border-color: var(--bone);
  color: var(--ink);
}

/* White on crimson, for the CTA band. §4.1 reserves white for rare
   highlights; one button per page qualifies. Crimson on white measures
   6.74:1 — comfortably AA. */
.btn--invert {
  background: var(--white);
  color: var(--crimson);
  border-color: var(--white);
}
.btn--invert:hover { background: var(--bone); border-color: var(--bone); }
.btn--secondary {
  background: transparent;
  color: var(--accent);
  border-color: var(--crimson);
}
.btn--secondary:hover { background: var(--crimson); color: var(--bone); }
.btn[disabled], .btn[aria-disabled='true'] {
  opacity: 0.55;
  cursor: not-allowed;
  pointer-events: none;
}

.btn-ghost {
  display: inline-block;
  font-family: var(--font-subhead);
  font-weight: 600;
  font-size: var(--label);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  text-decoration: underline;
  text-decoration-color: var(--crimson);
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
  color: inherit;
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  transition: color 150ms ease;
}
.btn-ghost:hover { color: var(--accent); }
.ground-ink .btn-ghost { color: var(--silver); }
.ground-ink .btn-ghost:hover { color: var(--accent); }

.btn-ghost--disabled {
  color: var(--silver-dim);
  text-decoration: none;
  cursor: not-allowed;
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
}
.ground-bone .btn-ghost--disabled { color: var(--ink-warm); }
.coming-soon { color: var(--accent); }

/* --- 4.5 SectionHeader ---------------------------------------------------- */
.section-header { display: grid; gap: var(--s-3); }
.section-header .rule { margin-block: var(--s-1); }
.section-header--center { justify-items: center; text-align: center; }
.section-header + * { margin-top: var(--s-10); }

/* --- 4.5 Card ------------------------------------------------------------- */
/* The ground is textured now, so a card with no fill showed the pattern running
   through its middle and stopped reading as an object on the page. */
.card {
  background: var(--surface);
  border: 1px solid var(--hairline-light);
  border-radius: 2px;
  padding: var(--s-5);
  display: grid;
  gap: var(--s-3);
  align-content: start;
}
.ground-ink .card { border-color: var(--hairline-dark); }
.card h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--display-md);
  line-height: 1.05;
  text-transform: uppercase;
}
.ground-ink .card h3 { color: var(--silver); }
.card p { color: inherit; }
.ground-ink .card p { color: var(--silver); }

.card__meta {
  font-family: var(--font-subhead);
  font-weight: 600;
  font-size: var(--label);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--accent);
}

/* --- 4.5 Accordion (native details/summary, no JS) ------------------------ */
.accordion { border-top: 1px solid var(--hairline-light); }
.ground-ink .accordion { border-top-color: var(--hairline-dark); }
.accordion > details {
  border-bottom: 1px solid var(--hairline-light);
}
.ground-ink .accordion > details { border-bottom-color: var(--hairline-dark); }
/* The one deliberate exception to the uppercase rule: FAQ questions are
   sentences, so this Subhead stays in sentence case. */
.accordion > details > summary {
  cursor: pointer;
  list-style: none;
  padding: var(--s-4) var(--s-6) var(--s-4) 0;
  position: relative;
  display: flex;
  align-items: baseline;
  gap: var(--s-3);
  font-family: var(--font-subhead);
  font-weight: 600;
  font-size: var(--lead);
  line-height: 1.35;
}
.accordion > details > summary::-webkit-details-marker { display: none; }
.accordion > details > summary::after {
  content: '';
  position: absolute;
  right: 0;
  top: calc(var(--s-4) + 0.6em);
  width: 14px;
  height: 3px;
  background: var(--crimson);
  transition: transform 150ms ease;
}
.accordion > details > summary::before {
  content: '';
  position: absolute;
  right: 0;
  top: calc(var(--s-4) + 0.6em);
  width: 14px;
  height: 3px;
  background: var(--crimson);
  transform: rotate(90deg);
  transition: opacity 150ms ease;
}
.accordion > details[open] > summary::before { opacity: 0; }
.accordion > details > summary:hover { color: var(--accent); }
.accordion__panel {
  padding: 0 var(--s-6) var(--s-6) 0;
  max-width: var(--measure);
  display: grid;
  gap: var(--s-3);
}
.ground-ink .accordion__panel { color: var(--silver); }

/* Level accordion header composition */
.level-summary__num {
  color: var(--position);
  font-family: var(--font-display);
  font-weight: 400;   /* Anton has no bold; without this a UA default synthesises one */
  font-size: var(--display-md);
  line-height: 1;
  flex: none;
  min-width: 1.4em;
}
.level-summary__name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--display-md);
  line-height: 1.05;
  text-transform: uppercase;
  color: var(--silver);
}
.level-summary__sub {
  margin-left: var(--s-2);
  white-space: nowrap;
  font-family: var(--font-subhead);
  font-weight: 600;
  font-size: var(--label);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--silver-dim);
}
.level-block { display: grid; gap: var(--s-1); }
.level-block__label {
  font-family: var(--font-subhead);
  font-weight: 600;
  font-size: var(--label);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--accent);
}
.bullets { display: grid; gap: var(--s-1); }
.bullets li { position: relative; padding-left: var(--s-3); }
.bullets li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.7em;
  width: 10px;
  height: 2px;
  background: var(--crimson);
}

/* --- Announcement bar ----------------------------------------------------- */
.announce {
  background: var(--crimson);
  color: var(--bone);
  min-height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  padding: var(--s-1) var(--s-6) var(--s-1) var(--s-3);
  position: relative;
  text-align: center;
}
.announce[hidden] { display: none; }
.announce a {
  color: var(--bone);
  font-family: var(--font-subhead);
  font-weight: 500;
  font-size: var(--label);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  text-decoration: none;
}
.announce a:hover { text-decoration: underline; text-underline-offset: 4px; }
.announce__dismiss {
  position: absolute;
  right: var(--s-1);
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: 0;
  color: var(--bone);
  cursor: pointer;
  width: 32px;
  height: 32px;
  line-height: 1;
  font-size: 18px;
  display: grid;
  place-items: center;
}
.announce__dismiss:focus-visible { outline-color: var(--bone); }

/* --- Header --------------------------------------------------------------- */
.header {
  position: sticky;
  top: 0;
  z-index: 50;
  height: 72px;
  background: var(--ink);
  border-bottom: 1px solid var(--hairline-dark);
}
.header__inner {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-4);
}
.header__brand { display: flex; align-items: center; flex: none; }
.header__brand img, .header__brand .emblem-fallback { width: 40px; height: 40px; }
.header__nav { display: none; }
@media (min-width: 1024px) {
  .header__nav { display: flex; align-items: center; gap: var(--s-4); }
}
.header__nav a {
  font-family: var(--font-subhead);
  font-weight: 500;
  /* §6 specifies the nav at Oswald 500; the size is the Label token. */
  font-size: var(--label);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--silver);
  text-decoration: none;
  transition: color 150ms ease;
}
.header__nav a:hover, .header__nav a[aria-current='page'] { color: var(--accent); }
.header__cta { display: none; }
@media (min-width: 1024px) {
  .header__cta { display: inline-block; padding: 14px 24px; }
}
.header__toggle {
  display: inline-grid;
  place-content: center;   /* rows sized by content, not stretched to 44px */
  justify-items: center;
  width: 44px;
  height: 44px;
  background: none;
  border: 0;
  cursor: pointer;
  gap: 5px;
}
@media (min-width: 1024px) { .header__toggle { display: none; } }
.header__toggle span {
  display: block;
  width: 22px;
  height: 2px;
  background: var(--silver);
}

/* Mobile overlay */
.mobile-nav {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: var(--ink);
  padding: var(--s-3) var(--gutter) var(--s-10);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}
.mobile-nav[hidden] { display: none; }
.mobile-nav__top {
  height: 72px;
  display: flex;
  align-items: center;
  justify-content: flex-end;
}
.mobile-nav__close {
  width: 44px; height: 44px;
  background: none; border: 0; cursor: pointer;
  color: var(--silver);
  font-size: 24px; line-height: 1;
  display: grid; place-items: center;
}
/* The <nav> must grow for the CTA's `margin-top: auto` to push it to the
   bottom of the overlay. */
.mobile-nav > nav { flex: 1; display: flex; flex-direction: column; }
.mobile-nav__list { display: grid; gap: var(--s-4); margin-top: var(--s-6); }
.mobile-nav__list a {
  font-family: var(--font-display);
  font-weight: 400;   /* Anton has no bold; without this a UA default synthesises one */
  font-size: var(--display-md);
  text-transform: uppercase;
  color: var(--silver);
  text-decoration: none;
  line-height: 1.05;
}
.mobile-nav__list a:hover { color: var(--accent); }
.mobile-nav .btn { margin-top: auto; text-align: center; }
.mobile-nav .btn { margin-bottom: var(--s-4); }

/* --- CTA band ------------------------------------------------------------- */
/* Sits between </main> and <footer>, on every page but the three quiz pages.
   The one place the accent runs full-bleed, so it stays flat — no texture. */
.cta-band { background: var(--crimson); color: var(--bone); }
.cta-band__inner {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s-5);
  padding-block: var(--s-8);
}
@media (min-width: 860px) {
  .cta-band__inner {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-8);
    padding-block: var(--s-6);
  }
}
.cta-band__copy { display: grid; gap: var(--s-2); }
.cta-band .display-md { color: var(--bone); margin: 0; }
.cta-band__lead { font-size: var(--body); max-width: 52ch; color: var(--bone); }

/* --- Footer --------------------------------------------------------------- */
.footer {
  background: var(--ink);
  color: var(--silver);
  padding-block: var(--s-10);
  /* A hairline of light along the top edge, so the footer reads as a plane
     below the crimson band rather than butting straight into it. */
  box-shadow: inset 0 1px 0 rgba(204, 204, 204, 0.10);
}
/* The footer is the one place type sits directly on the engraved texture at
   small sizes. A tight ink shadow lifts it off the pattern — legibility, not
   ornament, so it stays subtle enough not to read as an effect. */
.footer p,
.footer h2,
.footer a,
.footer label { text-shadow: 0 1px 2px rgba(13, 13, 13, 0.9); }
.footer__grid {
  display: grid;
  gap: var(--s-8);
  grid-template-columns: 1fr;
}
@media (min-width: 700px) { .footer__grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) {
  .footer__grid { grid-template-columns: 1.3fr 1fr 1fr 1.5fr; }
}
.footer h2 {
  display: inline-block;
  font-family: var(--font-subhead);
  font-weight: 600;
  font-size: var(--label);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--silver);
  /* The crimson rule, scaled to the width of the heading it marks. */
  border-bottom: 2px solid var(--crimson);
  padding-bottom: var(--s-1);
  margin-bottom: var(--s-3);
}
.footer__brand { display: grid; gap: var(--s-2); align-content: start; }
.footer__brand-line { font-size: var(--small); color: var(--silver); margin-top: var(--s-2); }
.footer__brand-sub { color: var(--silver-dim); max-width: 26ch; }
.footer__links { display: grid; gap: var(--s-2); }
.footer__links a {
  color: var(--silver);
  text-decoration: none;
  font-size: var(--small);
}
.footer__links a:hover { color: var(--accent); }
.footer__signup-lead { color: var(--silver-dim); margin-bottom: var(--s-3); max-width: 30ch; }

/* Tier 2 — the claim gets its own band rather than sitting as a caption. */
.footer__trust {
  position: relative;
  isolation: isolate;
  border-top: 1px solid var(--hairline-dark);
  border-bottom: 1px solid var(--hairline-dark);
  margin-top: var(--s-10);
  padding-block: var(--s-6);
  text-align: center;
}
/* Darker, not lighter. Crimson sits mid-luminance, so lifting the ground
   toward bone REDUCES its contrast — measured 2.78 on ink, 2.47 under a 6%
   bone veil, 1.63 under 20%. Darkening cannot move the ground either, since
   the palette holds nothing below ink. What it does do is kill the engraved
   texture behind 13px letterspaced type, which is the actual legibility
   problem: the icons peak around 25 and fall back to the ground under this
   veil. See TODO.md §3.1 — crimson text on a dark ground still fails AA, and
   only that open decision fixes it properly. */
.footer__trust::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(
    ellipse 62% 150% at 50% 50%,
    rgba(13, 13, 13, 0.97) 0%,
    rgba(13, 13, 13, 0.90) 40%,
    rgba(13, 13, 13, 0.55) 68%,
    rgba(13, 13, 13, 0) 88%
  );
}
/* The site's one gold element, per §4.1's "once per page maximum". Gold rather
   than crimson for two reasons: it is the brand's second colour and appeared
   nowhere, and crimson here measured 2.78:1 — the only text on the site failing
   AA. Gold on ink is 14.94:1. It sits alone in its own tier, so it is nowhere
   near crimson. The shadow stays; it lifts the claim off the engraved texture. */
/* One treatment for one recurring claim. It was gold in the footer band and
   crimson in the /book/ hero — the same sentence in two colours reads as two
   different things. Gold everywhere; every place it appears is a dark ground,
   which is the only kind gold can be text on. */
.bestseller,
.footer__bestseller {
  color: var(--gold);
  margin: 0;
  font-weight: 600;
  text-shadow: 0 1px 3px rgba(13, 13, 13, 1);
}

/* Tier 3 */
.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3) var(--s-6);
  padding-top: var(--s-5);
  color: var(--silver-dim);
}
.footer__legal { margin-right: auto; }
.footer__legal a { color: var(--silver-dim); text-decoration: none; }
.footer__legal a:hover { color: var(--accent); }

/* --- Social --------------------------------------------------------------- */
/* §13 forbids icon sets; these two are here by instruction. See TODO.md §3. */
.social { display: flex; align-items: center; gap: var(--s-2); margin-top: var(--s-3); }
.social__link {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  color: var(--silver);
  border: 1px solid var(--hairline-dark);
  border-radius: 2px;
  /* Sunk very slightly into the ground, so the glyphs read as objects rather
     than as marks printed on the texture. */
  background: rgba(13, 13, 13, 0.55);
  box-shadow: inset 0 1px 0 rgba(204, 204, 204, 0.06);
  transition: color 150ms ease, border-color 150ms ease, background-color 150ms ease;
}
.social__link:hover {
  color: var(--accent);
  border-color: var(--crimson);
  background: rgba(168, 40, 46, 0.12);
}
/* No URL supplied yet — the glyph shows, un-linked and dimmed, the same way
   the /speaking/ downloads render until their file exists. */
.social__link--pending { color: var(--silver-dim); cursor: default; }

/* --- Forms ---------------------------------------------------------------- */
.form { display: grid; gap: var(--s-4); max-width: 640px; }
.form--center { margin-inline: auto; }
.field { display: grid; gap: var(--s-1); }
.field > label {
  font-family: var(--font-subhead);
  font-weight: 600;
  font-size: var(--label);
  text-transform: uppercase;
  letter-spacing: 0.12em;
}
.ground-ink .field > label { color: var(--silver); }
.field input,
.field select,
.field textarea {
  width: 100%;
  padding: 14px 16px;
  border-radius: 2px;
  border: 1px solid var(--control-edge);
  background: var(--white);
  color: var(--ink-warm);
  font-size: var(--body);
  line-height: 1.5;
}
.ground-ink .field input,
.ground-ink .field select,
.ground-ink .field textarea {
  background: var(--ink);
  border-color: var(--hairline-dark);
  color: var(--bone);
}
.field textarea { min-height: 132px; resize: vertical; }
.field input:hover, .field select:hover, .field textarea:hover { border-color: var(--crimson); }
.field .hint { font-size: var(--small); color: var(--ink-warm); }
.ground-ink .field .hint { color: var(--silver-dim); }
.field .error {
  font-size: var(--small);
  color: var(--accent);
  font-weight: 500;
}
.field .error:empty { display: none; }
.field input[aria-invalid='true'],
.field select[aria-invalid='true'],
.field textarea[aria-invalid='true'] { border-color: var(--crimson); border-width: 2px; }
.req { color: var(--accent); }

/* Honeypot */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.form__status {
  font-size: var(--small);
  font-weight: 500;
  color: var(--accent);   /* one accent: success and error both crimson */
}
.form__status:empty { display: none; }

.form__note { font-size: var(--small); margin-top: var(--s-3); }
.ground-ink .form__note { color: var(--silver-dim); }
.ground-bone .form__note { color: var(--ink-warm); }

/* Inline footer signup */
.signup { display: grid; gap: var(--s-2); }
.signup input {
  padding: 14px 16px;
  border-radius: 2px;
  border: 1px solid var(--hairline-dark);
  background: var(--ink);
  color: var(--bone);
  width: 100%;
}
.signup .btn { width: 100%; text-align: center; }

/* --- Hero ----------------------------------------------------------------- */
.hero { padding-block: var(--section-y); }

/* Ambient light from above, so the dark heroes read as a space rather than a
   flat panel. Bone rather than white — white is reserved for rare highlights.
   Measured over ink: result = 13 + 226a, so the 0.055 peak lands on ~25 (#19),
   about the value the brightest texture icons already reach, and the ramp is
   gone by 62% down the hero. Tune the three alphas together.

   `.texture` already supplies the stacking context and paints its tile at
   z-index -1; negative-z siblings paint in order, so this ::after lands above
   it — light over texture. The position/isolation line is a guard for a hero
   that ever renders without .texture. */
.hero.ground-ink { position: relative; isolation: isolate; }
.hero.ground-ink::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(
    ellipse 100% 62% at 50% 0%,
    rgba(243, 238, 228, 0.055) 0%,
    rgba(243, 238, 228, 0.028) 38%,
    rgba(243, 238, 228, 0.008) 66%,
    rgba(243, 238, 228, 0)     82%
  );
}

.hero__grid {
  display: grid;
  gap: var(--s-8);
  align-items: center;
  grid-template-columns: 1fr;
}
@media (min-width: 900px) {
  .hero__grid { grid-template-columns: 1.05fr 0.95fr; gap: var(--s-10); }
  .hero__grid--image-left .hero__body { order: 2; }
  .hero__grid--image-left .hero__media { order: 1; }
}
.hero__body { display: grid; gap: var(--s-4); align-content: start; }
.hero__body .lead { max-width: 34ch; }
.hero__actions { margin-top: var(--s-2); }
.hero__trust { font-size: var(--small); }

/* --- Media (placeholder-aware) -------------------------------------------- */
.media { position: relative; width: 100%; }
.media img { width: 100%; height: 100%; object-fit: cover; }
/* A transparent render must not be cropped to fill its box. */
.media--contain img { object-fit: contain; }
.placeholder {
  display: grid;
  place-items: center;
  width: 100%;
  border: 1px dashed var(--crimson);
  background: rgba(168, 40, 46, 0.05);
  padding: var(--s-4);
  text-align: center;
}
.placeholder span {
  font-family: var(--font-subhead);
  font-weight: 600;
  font-size: var(--label);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--accent);
  word-break: break-word;
}
.emblem-fallback {
  display: grid;
  place-items: center;
  border: 1px solid var(--crimson);
  color: var(--accent);
  font-family: var(--font-display);
  font-weight: 400;   /* Anton has no bold; without this a UA default synthesises one */
  font-size: 15px;
  line-height: 1;
}

/* --- Numbered steps ------------------------------------------------------- */
.steps { display: grid; gap: var(--s-8); grid-template-columns: 1fr; }
@media (min-width: 768px) { .steps { grid-template-columns: repeat(3, 1fr); } }
.steps--4 { grid-template-columns: 1fr; }
@media (min-width: 768px) { .steps--4 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .steps--4 { grid-template-columns: repeat(4, 1fr); } }
.step { display: grid; gap: var(--s-2); align-content: start; }
.step__num {
  font-family: var(--font-display);
  font-weight: 400;   /* Anton has no bold; without this a UA default synthesises one */
  font-size: var(--display-md);
  line-height: 1;
  color: var(--accent);
}
/* Subhead tier — see the note on .eyebrow. */
.step h3,
.qualify__col h3 {
  font-family: var(--font-subhead);
  font-weight: 600;
  font-size: var(--lead);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  line-height: 1.25;
}

/* --- Two-column qualify list ---------------------------------------------- */
.qualify { display: grid; gap: var(--s-8); grid-template-columns: 1fr; }
@media (min-width: 768px) { .qualify { grid-template-columns: repeat(2, 1fr); } }
.qualify__col { display: grid; gap: var(--s-3); align-content: start; }

/* --- Arena list (framework) ------------------------------------------------ */
.arena-list { display: grid; gap: 0; border-top: 1px solid var(--hairline-light); }
.arena-list li {
  display: grid;
  gap: var(--s-2);
  padding-block: var(--s-5);
  border-bottom: 1px solid var(--hairline-light);
}
@media (min-width: 768px) {
  .arena-list li { grid-template-columns: 280px 1fr; gap: var(--s-6); align-items: start; }
}
.arena-list h3 {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--display-md);
  text-transform: uppercase;
  line-height: 1.05;
}

/* --- Rule-separated line list (retreat waitlist benefits) ------------------ */
.rule-list { display: grid; }
.rule-list li { padding-block: var(--s-5); }
.rule-list li + li { border-top: 1px solid var(--hairline-dark); }
.ground-bone .rule-list li + li { border-top-color: var(--hairline-light); }
.rule-list p { font-size: var(--lead); }

/* --- Pricing table -------------------------------------------------------- */
.table-wrap { overflow-x: auto; }
table.tiers {
  width: 100%;
  border-collapse: collapse;
  text-align: left;
  min-width: 420px;
}
table.tiers th, table.tiers td {
  padding: var(--s-3) var(--s-2);
  border-bottom: 1px solid var(--hairline-light);
}
.ground-ink table.tiers th, .ground-ink table.tiers td { border-bottom-color: var(--hairline-dark); }
table.tiers th {
  font-family: var(--font-subhead);
  font-weight: 600;
  font-size: var(--label);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--accent);
}

/* --- Prose (legal, about body) -------------------------------------------- */
.prose { max-width: var(--measure); }
.prose p + p { margin-top: var(--s-3); }
.prose h2 {
  font-family: var(--font-display);
  font-weight: 400;   /* Anton has no bold; without this a UA default synthesises one */
  font-size: var(--display-md);
  text-transform: uppercase;
  line-height: 1.05;
  margin-top: var(--s-8);
  margin-bottom: var(--s-3);
}
.placeholder-inline {
  display: inline-block;
  font-family: var(--font-subhead);
  font-weight: 600;
  letter-spacing: 0.12em;
  color: var(--accent);
  border: 1px dashed var(--crimson);
  padding: var(--s-3) var(--s-4);
  margin-top: var(--s-4);
}

/* The four outcome words, gold exactly as the cover sets them. */
.outcome { color: var(--position); }

/* --- Attribution ---------------------------------------------------------- */
.attribution { color: var(--accent); margin-top: var(--s-5); }

/* --- Centred stack -------------------------------------------------------- */
.stack-center {
  display: grid;
  gap: var(--s-4);
  justify-items: center;
  text-align: center;
}
.stack { display: grid; gap: var(--s-4); align-content: start; }

/* ==========================================================================
   QUIZ — shared by the assessment, the coaching application and the retreat
   waitlist. One question per screen; see dist/assets/js/quiz.js.
   ========================================================================== */
/* A quiz section pays none of the marketing page's vertical rhythm — 140px of
   section padding plus the container's own was pushing the first option past
   the fold on step 1. */
.quiz-section { padding-block: var(--s-4) 0; }
/* Two columns above 1024px, as the reference lead-gen build does: the quiz, and
   a sticky sidebar carrying the named step rail. Below that it is one column
   and the sidebar falls under the quiz. */
.quiz-layout {
  width: 100%;
  max-width: 780px;
  margin-inline: auto;
  display: grid;
  gap: var(--s-8);
  align-items: start;
}
@media (min-width: 1024px) {
  .quiz-layout {
    max-width: none;
    grid-template-columns: minmax(0, 1fr) 300px;
  }
}
.quiz-main {
  min-width: 0;
  /* A quiz is a task, not a marketing page — the 140px section rhythm pushed
     the controls off-screen. The bottom padding clears the sticky nav. */
  padding-block: var(--s-5) calc(var(--s-14) + 72px);
}
.quiz-intro { display: grid; gap: var(--s-2); margin-bottom: var(--s-4); }
.quiz-intro h1 { font-size: var(--display-md); }
.quiz-intro .lead { max-width: 46ch; }
/* From step 2 the intro collapses: the lead goes and the h1 drops a size. The
   h1 stays in the DOM throughout — one per page, and the outline holds. */
[data-quiz]:not([data-step-index="1"]) .quiz-intro .lead,
[data-quiz]:not([data-step-index="1"]) .quiz-intro .rule { display: none; }
[data-quiz]:not([data-step-index="1"]) .quiz-intro { margin-bottom: var(--s-4); }
[data-quiz]:not([data-step-index="1"]) .quiz-intro h1 {
  font-size: var(--display-md);
}

/* --- The two sticky bars -------------------------------------------------- */
/* Progress pins under the site header and carries the persistent reassurance
   strip; Back/Next pins to the bottom. Before this the Next button sat
   off-screen on every quiz at every viewport. */
.quiz-bar {
  position: sticky;
  top: 72px;
  z-index: 20;
  background: var(--surface);
  border-bottom: 1px solid var(--surface-line);
  box-shadow: 0 10px 16px -14px var(--surface-shadow);
  padding-block: var(--s-2);
  margin-bottom: var(--s-4);
  display: grid;
  gap: var(--s-1);
}
.quiz-bar__row { display: flex; align-items: center; gap: var(--s-3); }
/* On a phone the count runs to "Step 3 of 5 · Almost there" and left the
   segmented track about 120px wide — five cells reading as dashes. Below 640px
   the count takes its own line and the track spans the column. */
@media (max-width: 639px) {
  .quiz-bar__row { display: grid; gap: var(--s-1); }
}
.quiz-bar__strip { color: var(--surface-dim); margin: 0; }
/* One cell per step rather than a continuous fill. The book's worksheet is a
   grid of ruled cells and the result map is 5x7 of them, so the bar reads in the
   same vocabulary — and it answers "how many left", which a continuous bar
   cannot. --steps is written server-side; the JS still only sets the fill
   width. */
.quiz-progress__track {
  flex: 1;
  --seg: calc(100% / var(--steps, 1));
  position: relative;
  height: 10px;
  background: var(--bone-deep);
  border: 1px solid var(--control-edge);
}
.quiz-progress__track::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: repeating-linear-gradient(to right,
    transparent 0 calc(var(--seg) - 1px),
    var(--control-edge) calc(var(--seg) - 1px) var(--seg));
}
.ground-ink .quiz-progress__track { background: var(--surface-line); }
/* quiz.js writes a width to this on every step change, but it had no rule at
   all — no height, no fill — so the progress bar has been an empty track
   since it shipped. Crimson on the bone-deep track measures 5.4:1. */
.quiz-progress__fill {
  height: 100%;
  background: var(--crimson);
  transition: width 220ms ease;
}
@media (prefers-reduced-motion: reduce) {
  .quiz-progress__fill { transition: none; }
}
.quiz-progress__count { color: var(--surface-dim); flex: none; margin: 0; }

.quiz-nav {
  position: sticky;
  bottom: 0;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin-top: var(--s-6);
  padding-block: var(--s-3);
  background: var(--surface);
  border-top: 1px solid var(--surface-line);
  box-shadow: 0 -10px 16px -14px var(--surface-shadow);
}
/* Content scrolls under the bar. A hairline alone slices a white option card
   through the middle of its text; the fade dissolves it instead. Gradients
   interpolate premultiplied, so `transparent` adds no grey fringe. */
.quiz-nav::before {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 100%;
  height: 36px;
  background: linear-gradient(to top, var(--surface), transparent);
  pointer-events: none;
}
.quiz-nav .btn-ghost { margin-right: auto; }
/* Next is disabled until the step is answered. The global 0.55 opacity over
   crimson on bone renders a washed pink carrying white text — it reads broken,
   not inert. On light grounds the disabled state is drawn explicitly instead. */
.ground-bone .btn[disabled],
.ground-bone .btn[aria-disabled='true'] {
  opacity: 1;
  background: var(--bone-deep);
  border-color: var(--bone-deep);
  color: var(--silver-dim);
}

/* --- Submitting and error ------------------------------------------------- */
.quiz-state {
  display: grid;
  gap: var(--s-3);
  justify-items: start;
  padding-block: var(--s-10);
}
.quiz-state__title { color: var(--surface-text); margin: 0; }
.quiz-state__body { color: var(--surface-dim); max-width: 44ch; }

.quiz-fieldset { border: 0; padding: 0; margin: 0; }
/* Focus is moved here on screen change so screen readers announce the new
   question. It is not an interactive target, so it paints no ring. */
.quiz-question:focus { outline: none; }
.quiz-question { scroll-margin-top: 160px; }
.quiz-legend { display: contents; }
.quiz-eyebrow { display: block; margin-bottom: var(--s-2); }
/* Casing law: quiz questions run over six words, so they are set in sentence
   case in Inter rather than in Anton caps. Sized at display-md. */
.quiz-question {
  display: block;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: clamp(24px, 4vw, 34px);
  line-height: 1.2;
  letter-spacing: -0.01em;
  margin-bottom: var(--s-6);
  color: var(--surface-text);
  max-width: 22ch;
}
.quiz-options { display: grid; gap: var(--s-2); }
.quiz-option { position: relative; display: block; }
.quiz-option input {
  position: absolute;
  opacity: 0;
  width: 1px; height: 1px;
}
.quiz-option__box {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  border: 1px solid var(--control-edge);
  border-radius: 2px;
  padding: 18px 20px;
  background: var(--surface-field);
  cursor: pointer;
  transition: border-color 150ms ease, background-color 150ms ease;
  min-height: 60px;
}
.quiz-option__box:hover { border-color: var(--crimson); }
.quiz-option input:checked + .quiz-option__box {
  border-color: var(--crimson);
  background: rgba(168, 40, 46, 0.12);
}
.quiz-option input:focus-visible + .quiz-option__box {
  outline: 2px solid var(--crimson);
  outline-offset: 2px;
}
.quiz-option__marker {
  width: 14px; height: 14px;
  border: 1px solid var(--surface-dim);
  border-radius: 50%;
  flex: none;
}
.quiz-option input:checked + .quiz-option__box .quiz-option__marker {
  border-color: var(--crimson);
  background: var(--crimson);
  box-shadow: inset 0 0 0 3px var(--surface-field);
}
.quiz-option__text { color: var(--surface-text); }
.quiz-option--na .quiz-option__text { color: var(--surface-dim); }

.quiz-fields { display: grid; gap: var(--s-4); max-width: 30rem; }
.quiz-fields input,
.quiz-fields textarea {
  background: var(--surface-field);
  border-color: var(--control-edge);
  color: var(--surface-text);
  padding: 16px 18px;
}
.quiz-fields textarea { min-height: 150px; }
.quiz-hint { font-size: var(--small); color: var(--surface-dim); }

/* --- /book/ : the seven levels ------------------------------------------- */
/* The same gold numeral the framework page and the result map use for a level.
   Gold is the fixed structure — where you stand — and crimson is what to do
   about it; this list is structure. */
.book-levels {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  counter-reset: bl;
}
.book-levels li {
  display: grid;
  grid-template-columns: 2.5rem 1fr;
  gap: var(--s-1) var(--s-3);
  align-items: baseline;
  padding-block: var(--s-3);
  border-top: 1px solid var(--hairline-dark);
}
.book-levels li:first-child { border-top: 0; }
.book-levels__num {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--display-md);
  line-height: 1;
  color: var(--position);
}
.book-levels__name {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--display-md);
  line-height: 1;
  text-transform: uppercase;
  color: var(--surface-text);
}
.book-levels__sub {
  grid-column: 2;
  color: var(--surface-dim);
}

/* --- Section seam --------------------------------------------------------- */
/* Two sections of the same ground butt together on /, /coaching/, /retreat/,
   /speaking/ and /about/ and read as one undifferentiated block.
   This was a 150px band of the mosaic until the mosaic went onto every bone
   section — a denser patch of the same pattern over a patterned ground read as
   a hard-edged smudge, not a seam. A hairline does the job and does not compete
   with the ground. --surface-line is bone-deep, 1.12:1 on bone and invisible, so
   the rule is drawn from the text colour at low alpha instead. */
.ground-bone + .ground-bone,
.ground-ink + .ground-ink { position: relative; }
.ground-bone + .ground-bone::after,
.ground-ink + .ground-ink::after {
  content: '';
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 1px;
  pointer-events: none;
  background: var(--surface-text);
  opacity: 0.14;
}

/* --- Thank you ------------------------------------------------------------ */
.ty-next { display: grid; justify-items: start; gap: var(--s-3); }
.ty-next > [data-ty-next] { display: grid; justify-items: start; gap: var(--s-3); }
.ty-links { margin-top: var(--s-3); }
.ty-list {
  display: grid;
  gap: var(--s-2);
  margin: var(--s-2) 0 0;
  padding: 0;
  list-style: none;
  counter-reset: ty;
  max-width: 46ch;
}
.ty-list li {
  position: relative;
  padding-left: var(--s-5);
  font-size: var(--lead);
  line-height: 1.4;
}
/* The list carries the same ruled-cell marker as the quiz rail: a number where
   the order is real, a crimson tick where it is not. */
.ty-list--num li { counter-increment: ty; }
.ty-list--num li::before {
  content: counter(ty);
  position: absolute;
  left: 0; top: 0.15em;
  width: 24px; height: 24px;
  display: grid; place-items: center;
  border: 1px solid var(--control-edge);
  font-family: var(--font-subhead);
  font-size: var(--label);
  font-weight: 600;
  line-height: 1;
}
.ty-list:not(.ty-list--num) li::before {
  content: '';
  position: absolute;
  left: 0; top: 0.62em;
  width: 20px; height: 3px;
  background: var(--crimson);
}
.ty-links { display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-6); }
.ty-tail--bare { padding-block: var(--s-6); }
.ty-tail--bare .ty-links { margin-top: 0; }

/* --- The sidebar ---------------------------------------------------------- */
.quiz-side { display: grid; gap: var(--s-6); align-content: start; }
@media (min-width: 1024px) {
  .quiz-side {
    position: sticky;
    top: calc(72px + var(--s-3));
    padding-block: var(--s-5);
  }
}
.quiz-side__h {
  margin: 0 0 var(--s-2);
  color: var(--surface-text);
}
.quiz-side__block { display: grid; }
.quiz-side__block .rule { margin-bottom: var(--s-3); }
.quiz-side__steps {
  list-style: none;
  margin: 0; padding: 0;
  display: grid;
  gap: var(--s-2);
}
.quiz-side__steps li {
  display: flex;
  align-items: flex-start;
  gap: var(--s-2);
  font-size: var(--small);
  line-height: 1.4;
  color: var(--surface-text);
}
.quiz-side__num {
  flex: none;
  width: 20px; height: 20px;
  display: grid; place-items: center;
  border: 1px solid var(--control-edge);
  font-family: var(--font-subhead);
  font-size: 11px;
  font-weight: 600;
}
.quiz-side__points { font-size: var(--small); }
.quiz-side__body,
.quiz-side__note { margin: 0; font-size: var(--small); line-height: 1.5; }
.quiz-side__note { margin-top: var(--s-3); }
.quiz-side__block .quiz-side__body { color: var(--surface-text); }

/* The named step rail. "Step 3 of 7" says how far but never what of, and every
   step already carries a short eyebrow. States are told apart structurally —
   filled / outlined / hairline marker — because §4.1 has no muted tone on a
   light ground. Seven named rows do not earn their height on a phone, where the
   segmented bar is already the stepper, so the rail is desktop only. */
.quiz-rail { display: none; }
@media (min-width: 1024px) {
  .quiz-rail { display: block; }
}
.quiz-rail__list {
  list-style: none;
  margin: 0; padding: 0;
  display: grid;
}
.quiz-rail__go {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  width: 100%;
  padding: 10px 0;
  background: none;
  border: 0;
  text-align: left;
  color: var(--surface-text);
  cursor: pointer;
}
.quiz-rail__go[disabled] { cursor: default; }
.quiz-rail__num {
  flex: none;
  width: 24px; height: 24px;
  display: grid; place-items: center;
  border: 1px solid var(--control-edge);
  font-family: var(--font-subhead);
  font-size: var(--label);
  font-weight: 600;
  line-height: 1;
}
.quiz-rail__label {
  font-family: var(--font-subhead);
  font-size: var(--label);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
[data-state="done"] .quiz-rail__num {
  background: var(--crimson);
  border-color: var(--crimson);
  color: var(--bone);
}
[data-state="current"] .quiz-rail__num {
  border: 2px solid var(--crimson);
  color: var(--crimson);
}
[data-state="todo"] .quiz-rail__go { opacity: 0.55; }
.quiz-rail__go:focus-visible {
  outline: 2px solid var(--crimson);
  outline-offset: 2px;
}
.quiz-rail__go:not([disabled]):hover .quiz-rail__label { color: var(--crimson); }


/* --- Result: the five-arena map ------------------------------------------ */
/* A 5 x 7 grid, one column per arena, rows 7 down to 1. Each column fills from
   row 1 up to that arena's level, so height IS the reading — reproducing the
   worksheet from the book. Gold numbers the level axis; crimson is the filled
   extent. */
.arena-grid-wrap { overflow-x: auto; margin: 0; }
/* The framework page's copy of the worksheet, below the arena list it diagrams.
   Capped: at full container width the five columns run to 205px and
   aspect-ratio: 4/3 makes the grid 1130px tall — a wall of black. At 620 the
   cells land near the printed worksheet's proportions. Left-aligned, not
   centred: everything else in the section is, and a centred block floated. */
.framework-map { margin-top: var(--s-10); }
.framework-map .arena-grid-wrap { max-width: 620px; margin-inline: 0; }
.arena-grid {
  display: grid;
  grid-template-columns: 2.2rem repeat(5, minmax(84px, 1fr));
  gap: 6px;
  min-width: 520px;
}
.arena-grid__head {
  font-family: var(--font-subhead);
  font-weight: 600;
  font-size: var(--label);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  line-height: 1.2;
  color: var(--surface-text);
  text-align: center;
  align-self: end;
  padding-bottom: var(--s-1);
  hyphens: auto;
}
.arena-grid__head--na { color: var(--surface-dim); }
.arena-grid__level {
  font-family: var(--font-display);
  font-weight: 400;   /* Anton has no bold; without this a UA default synthesises one */
  font-size: var(--display-md);
  line-height: 1;
  color: var(--position);
  display: grid;
  place-items: center;
}
.arena-grid__cell {
  aspect-ratio: 4 / 3;
  /* Black on either ground: the book's worksheet prints black empty cells on
     white, so this is the artwork rather than a dark-mode choice. */
  border: 1px solid var(--surface-line);
  border-radius: 2px;
  background: var(--ink);
}
/* Filled. The gradient is crimson to its own 8% darkening — the two values the
   palette already carries — which gives the panel its slight sheen. */
.arena-grid__cell--on {
  background: linear-gradient(135deg, var(--crimson) 0%, var(--crimson-dark) 100%);
  border-color: var(--crimson);
}
.arena-grid__cell--na { opacity: 0.45; }

/* The result is a stack, so rhythm comes from the container's gap rather than
   per-element margins — the global `p + p` rule was removed earlier and the
   two level paragraphs were running together with no space between them. */
[data-result] {
  display: grid;
  gap: var(--s-3);
  align-content: start;
}
[data-result] > .rule { margin-block: var(--s-5); }
[data-result] > .gate { margin-top: var(--s-5); }
.result-headline { margin: 0; }
.result-headline:focus { outline: none; }
.result-map__title { margin: 0; }
.gate {
  border: 1px solid var(--surface-line);
  border-radius: 2px;
  padding: var(--s-6);
  margin-top: var(--s-10);
  display: grid;
  gap: var(--s-3);
}
.gate h3 {
  font-family: var(--font-display);
  font-weight: 400;   /* Anton has no bold; without this a UA default synthesises one */
  font-size: var(--display-md);
  text-transform: uppercase;
  line-height: 1.05;
  color: var(--surface-text);
}
.gate .field input { background: var(--surface-field); border-color: var(--control-edge); color: var(--surface-text); }

/* --- Result pages --------------------------------------------------------- */
.result-page__level {
  color: var(--position);
  font-family: var(--font-subhead);
  font-weight: 600;
  font-size: var(--label);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--accent);
}
.pull {
  border-left: 3px solid var(--crimson);
  padding-left: var(--s-4);
  font-size: var(--lead);
  max-width: var(--measure);
}
/* A centred section cannot carry a left rule. The crimson tick sits above the
   line instead, which is the same device every heading on the site opens with. */
.pull--center {
  border-left: 0;
  padding-left: 0;
  margin-inline: auto;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--display-md);
  line-height: 1.1;
  text-transform: uppercase;
  text-wrap: balance;
}
.pull--center::before {
  content: '';
  display: block;
  width: 64px;
  height: 3px;
  margin: var(--s-6) auto var(--s-4);
  background: var(--crimson);
}

/* --- Utilities ------------------------------------------------------------ */
.mt-1 { margin-top: var(--s-1); }
.mt-2 { margin-top: var(--s-2); }
.mt-3 { margin-top: var(--s-3); }
.mt-4 { margin-top: var(--s-4); }
.mt-5 { margin-top: var(--s-5); }
.mt-6 { margin-top: var(--s-6); }
.mt-8 { margin-top: var(--s-8); }
.mt-10 { margin-top: var(--s-10); }
