/* GENERATED - written by scripts/build_academy_site.mjs. Edits here are lost on rebuild. */

/* ---------------------------------------------------------------------------
   Tokens. The light palette is defined on bare :root so a page always has a
   complete set; dark redefines only what changes, twice - once for the system
   preference and once for an explicit toggle, so the toggle wins both ways.
   --------------------------------------------------------------------------- */
:root {
  color-scheme: light dark;

  /* Brand, per governance. These three do not get invented or nudged. */
  --brand: #0346EF;
  --gold: #EFAC03;
  --navy: #011548;
  /* The dark-blue sections (hero, footer) run from the brand navy at the top to black at the bottom
     (owner 2026-10-08); plain navy stays underneath as the fallback. */
  --navy-fade: linear-gradient(180deg, var(--navy) 0%, #000000 100%);
  /* The header wordmark (owner 2026-10-07): the name in the dark brand blue, its "by" line in the
     primary blue (6.7:1 on white). Dark mode swaps the roles to colors that read on #080b1c: the
     name in the dark theme's light brand blue (9.1:1), the "by" line near-white (15:1). The literal
     swap was measured and refused: navy on the dark header is 1.1:1. */
  --brand-name: var(--navy);
  --brand-by: var(--brand);

  --bg: #ffffff;
  --bg-alt: #f5f7fb;
  --surface: #ffffff;
  --surface-2: #f0f3fa;
  --ink: #10132b;
  --ink-dim: #4d5470;
  /* 5.13:1 on --bg. The obvious pick, #6f7690, lands on exactly 4.50 - it passes AA and has
     no margin at all, which is the wrong side of the line to design onto when the text it
     colors is metadata a reader is already squinting at. */
  --ink-faint: #666d85;
  --line: #dfe4f0;
  --line-strong: #c3cbde;
  --link: #0346EF;
  --link-hover: #0231ad;
  --on-brand: #ffffff;
  --shadow: 0 1px 2px rgba(1, 21, 72, .06), 0 8px 24px -12px rgba(1, 21, 72, .18);
  --shadow-lg: 0 2px 4px rgba(1, 21, 72, .06), 0 24px 48px -24px rgba(1, 21, 72, .3);

  /* Triage severities. Amber is the brand gold; the others are neutral to it. */
  --sev-live: #c2410c;
  --sev-live-bg: #fff2e8;
  --sev-build: #0346EF;
  --sev-build-bg: #eaf0ff;
  --sev-ok: #12704a;
  --sev-ok-bg: #e7f5ee;

  /* Height of the sticky header. Two other rules depend on it - the sticky catalog controls
     that sit below it, and the scroll-margin that stops an in-page jump landing underneath it -
     and both were hard-coded to 60px while the header was free to grow. Measured at 61px on
     desktop and 60px on a phone once the brand sub-line is out of the way. */
  --head-h: 60px;

  --radius: 10px;
  --radius-lg: 16px;
  --measure: 38rem;
  --wide: 72rem;

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #080b1c;
    --bg-alt: #0d1228;
    --surface: #111731;
    --surface-2: #182040;
    --brand-name: #8fb0ff;
    --brand-by: #e9ecf7;
    --ink: #e9ecf7;
    --ink-dim: #a8b0cb;
    --ink-faint: #8890ad;
    --line: #232c4e;
    --line-strong: #33406b;
    --link: #8fb0ff;
    --link-hover: #b9cdff;
    --shadow: 0 1px 2px rgba(0, 0, 0, .4);
    --shadow-lg: 0 24px 48px -24px rgba(0, 0, 0, .7);
    --sev-live: #ffa76b;
    --sev-live-bg: #3a1e0c;
    --sev-build: #8fb0ff;
    --sev-build-bg: #16224a;
    --sev-ok: #6fd4a4;
    --sev-ok-bg: #0d2b1f;
  }
}
:root[data-theme="dark"] {
  --bg: #080b1c;
  --bg-alt: #0d1228;
  --surface: #111731;
  --surface-2: #182040;
  --brand-name: #8fb0ff;
  --brand-by: #e9ecf7;
  --ink: #e9ecf7;
  --ink-dim: #a8b0cb;
  --ink-faint: #8890ad;
  --line: #232c4e;
  --line-strong: #33406b;
  --link: #8fb0ff;
  --link-hover: #b9cdff;
  --shadow: 0 1px 2px rgba(0, 0, 0, .4);
  --shadow-lg: 0 24px 48px -24px rgba(0, 0, 0, .7);
  --sev-live: #ffa76b;
  --sev-live-bg: #3a1e0c;
  --sev-build: #8fb0ff;
  --sev-build-bg: #16224a;
  --sev-ok: #6fd4a4;
  --sev-ok-bg: #0d2b1f;
}

/* --------------------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 17px/1.6 var(--font);
  -webkit-font-smoothing: antialiased;
}
img, video { max-width: 100%; height: auto; display: block; }
a { color: var(--link); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--link-hover); }
:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; border-radius: 3px; }

h1, h2, h3, h4 { line-height: 1.18; margin: 0 0 .5em; letter-spacing: -.015em; font-weight: 700; }
h1 { font-size: clamp(2rem, 1.3rem + 3vw, 3.4rem); letter-spacing: -.025em; }
h2 { font-size: clamp(1.5rem, 1.15rem + 1.5vw, 2.1rem); }
h3 { font-size: 1.15rem; }
p { margin: 0 0 1rem; }
ul, ol { margin: 0 0 1rem; padding-left: 1.2em; }
li { margin-bottom: .35rem; }
code, kbd { font-family: var(--mono); font-size: .88em; }

.wrap { width: 100%; max-width: var(--wide); margin: 0 auto; padding: 0 1.25rem; }
.prose { max-width: var(--measure); }
.sr-only {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}
.skip {
  position: absolute; left: .5rem; top: -3rem; z-index: 100; padding: .6rem 1rem;
  background: var(--gold); color: var(--navy); border-radius: var(--radius); font-weight: 650;
  transition: top .15s;
}
.skip:focus { top: .5rem; }

/* --- Header ---------------------------------------------------------------- */
.site-head {
  position: sticky; top: 0; z-index: 50;
  background: color-mix(in srgb, var(--bg) 88%, transparent);
  backdrop-filter: saturate(1.6) blur(10px);
  border-bottom: 1px solid var(--line);
}
.site-head .wrap { display: flex; align-items: center; gap: 1rem; min-height: var(--head-h); }
.brand { display: flex; align-items: center; gap: .55rem; font-weight: 700; color: var(--brand-name); text-decoration: none; letter-spacing: -.01em; }
.brand img { height: 26px; width: auto; flex: 0 0 auto; }
/* The round emblem (BRAND_MARK "emblem") is the whole seal, so it gets 40px: the height of the
   two-line wordmark beside it, inside the 60px header. */
.brand img.emblem { height: 40px; }
/* The wordmark is one block: the name centered over its "by" line (owner 2026-10-07), with
   tight line heights so the two read as one unit instead of the body's 1.6 spacing. */
.brand > span { line-height: 1.2; text-align: center; }
/* .brand is a div holding two links (the emblem and the name both go home) and the "by" line,
   whose QuantKey name links to quantkey.com: a link cannot sit inside the home link. */
.brand a { color: inherit; text-decoration: none; }
.brand .brand-mark { display: block; line-height: 0; }
.brand .brand-sub a:hover { text-decoration: underline; }
.brand .brand-sub { display: block; font-weight: 450; font-size: .68rem; line-height: 1.3; color: var(--brand-by); letter-spacing: .01em; }
.site-nav { margin-left: auto; display: flex; align-items: center; gap: .35rem; flex-wrap: wrap; }
/* These base rules must come BEFORE the narrow-screen media queries below. They used to follow
   them, and at equal specificity the later rule wins, so the phone padding and font size were
   silently overridden: measured 2026-09-14 at 375px, "Join free" ended at x=412, 37px past the
   screen edge, and the page scrolled sideways on every page. */
.site-nav a { text-decoration: none; padding: .4rem .6rem; border-radius: var(--radius); font-size: .93rem; font-weight: 550; }
/* Colours are for the plain nav links only. ".site-nav a" outranks ".btn-primary" (0,1,1 against
   0,1,0), so when these three rules matched every link, the "Join free" button in the header
   took the nav grey on the brand gold: 1.09:1 in the dark theme, 3.75:1 in light. On hover the
   gold was replaced by the nav hover tint, which is why only the resting state looked broken.
   With :not(.btn) the button keeps its own #2a1d00 on gold (8.3:1; 6.7:1 on hover). Size and
   padding still come from ".site-nav a", which the phone-width fits below were measured with. */
.site-nav a:not(.btn) { color: var(--ink-dim); }
.site-nav a:not(.btn):hover { background: var(--surface-2); color: var(--ink); }
.site-nav a:not(.btn)[aria-current="page"],
.site-nav a:not(.btn)[aria-current="location"] { color: var(--ink); background: var(--surface-2); }
.theme-toggle {
  border: 1px solid var(--line-strong); background: var(--surface); color: var(--ink-dim);
  border-radius: var(--radius); padding: .35rem .55rem; cursor: pointer; font: inherit; font-size: .85rem;
}
.theme-toggle:hover { color: var(--ink); }
/* The log-in control (owner 2026-10-08): icon only, an arrow entering a doorway, named "Log in" by
   aria-label, in a square the size of the theme toggle beside the gold "Join free". Its colours are the
   nav link's (".site-nav a:not(.btn)" and its hover), on a transparent ground with the toggle's border.
   ".site-nav .nav-login" (0,2,0) outranks ".site-nav a" (0,1,1), so the nav padding never reaches it.
   The focus ring is pulled inside by 2px: at the default +2px it ran into the gold button beside it. */
.site-nav .nav-login {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.25rem; height: 2.25rem; padding: 0;
  border: 1px solid var(--line-strong); background: transparent;
}
.site-nav .nav-login svg { width: 18px; height: 18px; flex: none; }
.site-nav .nav-login:focus-visible { outline-offset: -2px; }

/* Below this width the brand's second line wraps and the sticky header grows to 162px - a
   fifth of a phone screen, permanently, on every page. The full attribution is not lost by
   hiding it here: BRAND_FULL is printed in the footer of all 36 pages, and the required
   disclaimer names QuantKey again directly beneath it. */
@media (max-width: 46rem) {
  .site-head .wrap { gap: .5rem; }
  .brand .brand-sub { display: none; }
  .brand { font-size: .95rem; }
  .site-nav { gap: .15rem; }
  .site-nav a { padding: .4rem .45rem; font-size: .88rem; }
  /* The brand wordmark comes OUT below this width, and the crest stands in for it.
     Measured, because the two obvious alternatives are both worse: letting the text wrap gives
     "Trading / Vendor / Academy" and a 162px header, and pinning it with white-space:nowrap
     locks 211px of a 390px bar so the nav wraps one item per row and the header hits 152px.
     Three nav links plus a call to action do not fit beside a three-word name on a phone, so
     the name is the thing that goes: it is in the page title, the footer of all 237 pages, and
     the crest itself. The link keeps its accessible name through aria-label. */
  .brand span { display: none; }
  .brand { flex: 0 0 auto; }
  /* Alone in the bar here, the emblem steps down to 32px: every pixel goes to the nav, which
     already overflowed a 375px phone by 12px with the 26px crest (measured 2026-10-07). */
  .brand img.emblem { height: 32px; }
  .site-nav { flex: 1 1 auto; justify-content: flex-end; flex-wrap: nowrap; }
}
/* Home is the first thing to go when the bar is short of room: the emblem beside it already links
   home. Measured 2026-10-07: with Home the header needs about 854px on one row (251px wordmark,
   532px nav, 16px gap, 40px padding, scrollbar); at 820px it wrapped and the header grew to 76px.
   The log-in square (2026-10-08) costs about 40px more, so this moved from 55rem to 58rem and the theme
   toggle goes too while the wordmark shows (the next rule); the square takes its place. Measured
   2026-10-08 (headless Edge, Segoe UI): one row at 790-1280px, iPad 810-834 portrait included, where the
   square with 55rem alone wrapped; 737-789px still wraps to two rows exactly as before. The theme still
   follows the system setting, and a choice saved on a wider screen still applies. */
@media (max-width: 58rem) {
  .site-nav .nav-home { display: none; }
}
/* The toggle leaves only where it does not fit beside the square: kept at 46-58rem, it pushed the bar
   onto two rows up to 831px instead of 789px. Below 46rem the wordmark is gone and it fits from about
   518px with a classic scrollbar, so it stays until the phone rules below hide it (measured 2026-10-08). */
@media (min-width: 46.01rem) and (max-width: 58rem) {
  .theme-toggle { display: none; }
}
/* 35rem, not 28rem (2026-10-08): from 449px up to 464px (479px with a classic scrollbar) the 46rem link
   sizes pushed "Join free" up to 31px past the edge, before and after the log-in square. With these rules
   the bar is one row and in bounds from about 340px (355px with a classic scrollbar) to 560px. */
@media (max-width: 35rem) {
  /* Phones, and the CTA is never what goes: the theme already follows the system setting. Measured
     2026-09-14 with the 46rem rules above actually applying: with the toggle shown, a 390px phone
     scrolled sideways to 413px, and at 375px the nav still needed 320px beside the crest with 301
     free, so "Join free" ran through the right gutter. Hiding the toggle up to 28rem, with a little
     less link padding and no gap, fit the bar at 360-448px - until "Blog" joined the nav and the
     emblem took 32px: measured 2026-10-07 at 375px the nav needed 335px with 295 free, and the page
     scrolled to 395px. A .78rem link font with .2rem side padding brings the nav to 276px, and a
     .4rem gap beside the emblem fits the whole bar on one row from about 355px up. */
  .theme-toggle { display: none; }
  .site-head .wrap { gap: .4rem; }
  .site-nav { gap: 0; }
  .site-nav a { padding: .4rem .2rem; font-size: .78rem; }
  /* Below that the nav wraps onto a second row rather than pushing the page sideways. Wrapping is
     allowed across the whole phone range, not from a guessed breakpoint, so the next nav link
     costs a second row instead of a sideways scroll (the old 22rem cut-off left 352-361px
     overflowing once the nav grew). */
  .site-nav { flex-wrap: wrap; row-gap: .15rem; }
  /* The log-in square stays on phones, where returning members look for it (2026-10-08): 32px here,
     the height of "Join free" at this size, and Glossary steps out of the bar to make the room (it is
     in every footer). Measured: one row from about 340px up, two rows with no sideways scroll at 320. */
  .site-nav .nav-glossary { display: none; }
  .site-nav .nav-login { width: 2rem; height: 2rem; margin: 0 .25rem; }
}

.btn {
  display: inline-block; padding: .7rem 1.15rem; border-radius: var(--radius);
  font-weight: 650; text-decoration: none; border: 1px solid transparent; cursor: pointer;
  font: inherit; font-weight: 650; line-height: 1.3; text-align: center;
}
.btn-primary { background: var(--gold); color: #2a1d00; }
.btn-primary:hover { background: #d99a02; color: #2a1d00; }
.btn-ghost { border-color: var(--line-strong); color: var(--ink); background: transparent; }
.btn-ghost:hover { background: var(--surface-2); color: var(--ink); }
.btn-sm { padding: .45rem .8rem; font-size: .9rem; }
/* A two-word call to action should never break across two lines inside its own button. */
.btn { white-space: nowrap; }

/* --- Hero ------------------------------------------------------------------ */
.hero {
  background-color: var(--navy);
  background-image: var(--navy-fade);
  color: #eef1fb;
  padding: clamp(2.5rem, 1rem + 6vw, 5rem) 0 clamp(2rem, 1rem + 4vw, 3.5rem);
  /* The gold line frames the hero above and below (owner 2026-10-08). */
  border-top: 3px solid var(--gold);
  border-bottom: 3px solid var(--gold);
}
.hero h1 { color: #ffffff; }
/* Plain links on the dark hero (the "Guide: Bruce DeVault" line) use the footer's light link colour:
   the brand blue was unreadable on navy-to-black (owner 2026-10-08). Links in the white signup card
   keep the normal link colour. */
.hero a:not(.btn) { color: #d7def3; text-decoration: underline; }
.hero a:not(.btn):hover { color: #ffffff; }
.hero .signup a:not(.btn) { color: var(--link); }
.hero-grid { display: grid; gap: clamp(2rem, 4vw, 3.5rem); align-items: start; }
@media (min-width: 62rem) {
  .hero-grid { grid-template-columns: 1.05fr .95fr; }
  /* The left column is the argument and runs long; the form is short. Left as-is that leaves a
     tall panel of empty navy to the right of the promise and the stat row. Sticking the form
     means the ask follows the argument down the page instead of scrolling away from it. */
  .hero-grid > .signup { position: sticky; top: calc(var(--head-h) + 1rem); }
}

.eyebrow {
  display: inline-flex; align-items: center; gap: .5rem;
  font-size: .78rem; font-weight: 650; letter-spacing: .09em; text-transform: uppercase;
  color: var(--gold); margin-bottom: 1rem;
}
.eyebrow::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--gold); }

/* The pain list. Each line is one beat of the founder's cold open, so they are set
   as separate rules rather than as a bulleted list - a bullet would make them look
   like features. */
.pain { list-style: none; padding: 0; margin: 0 0 1.75rem; max-width: 34rem; }
.pain li {
  padding: .55rem 0 .55rem 1.25rem; margin: 0;
  border-left: 2px solid rgba(239, 172, 3, .45);
  font-size: clamp(1rem, .95rem + .3vw, 1.15rem);
  color: #d6dcf0;
}
.pain li:last-child { color: #eef1fb; }

.hero-promise {
  font-size: clamp(1.05rem, 1rem + .4vw, 1.3rem);
  color: #ffffff; font-weight: 550; line-height: 1.45;
  border-top: 1px solid rgba(255, 255, 255, .18);
  padding-top: 1.5rem; margin: 0 0 1.25rem; max-width: 34rem;
}
.hero-meta { display: flex; flex-wrap: wrap; gap: .5rem 1.5rem; color: #aab4d4; font-size: .92rem; margin: 0; }
.hero-meta strong { color: var(--gold); font-weight: 650; }

/* --- Registration card ----------------------------------------------------- */
/* The header is sticky, so an in-page jump lands the target UNDER it unless the target says
   how much room to leave. This matters most on mobile, where the hero argument pushes the form
   about a screen and a half down and the header's "Join free" is the main route to it - a jump
   that hides the card's own heading reads as a broken link. */
[id] { scroll-margin-top: 5.5rem; }

.signup {
  background: var(--surface); color: var(--ink);
  border-radius: var(--radius-lg); padding: clamp(1.25rem, 1rem + 1.5vw, 1.9rem);
  box-shadow: var(--shadow-lg); border: 1px solid var(--line);
}
.signup h2 { font-size: 1.3rem; margin-bottom: .35rem; }
.signup .lede { color: var(--ink-dim); font-size: .95rem; margin-bottom: 1.25rem; }
.field { margin-bottom: .9rem; }
.field label { display: block; font-size: .85rem; font-weight: 650; margin-bottom: .3rem; color: var(--ink); }
.field input {
  width: 100%; padding: .7rem .8rem; font: inherit; font-size: 1rem;
  color: var(--ink); background: var(--bg);
  border: 1.5px solid var(--line-strong); border-radius: var(--radius);
}
.field input:focus { outline: none; border-color: var(--brand); box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand) 22%, transparent); }
.signup .btn { width: 100%; }
.signup .fineprint { font-size: .82rem; color: var(--ink-faint); margin: .9rem 0 0; line-height: 1.5; }
.signup .fineprint a { color: var(--link); }
.notice {
  margin: 0 0 1rem; padding: .65rem .8rem; border-radius: var(--radius);
  background: var(--sev-live-bg); color: var(--sev-live);
  border: 1px solid color-mix(in srgb, var(--sev-live) 35%, transparent);
  font-size: .85rem; font-weight: 600;
}

/* Video: a real element only when the file is present at build time. */
.hero-video { margin: 0 0 1.25rem; border-radius: var(--radius); overflow: hidden; background: #000; }
.hero-video video { width: 100%; display: block; }

/* --- Section scaffolding ---------------------------------------------------- */
section { padding: clamp(2.75rem, 2rem + 3vw, 4.5rem) 0; }
section.alt { background: var(--bg-alt); }
.section-head { max-width: 46rem; margin-bottom: 2rem; }
.section-head p { color: var(--ink-dim); font-size: 1.05rem; margin-bottom: 0; }
.kicker {
  font-size: .75rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-faint); margin: 0 0 .6rem;
}
/* "Who is teaching this" on the home page: the headshot sits beside the kicker and the name, so
   the face and the name read as one unit above the paragraphs. alt="" because the name is the
   heading right next to it. */
.who-head { display: flex; align-items: center; gap: 1.25rem; margin-bottom: 1rem; }
.who-head h2 { margin-bottom: 0; }
.who-photo { width: 120px; height: 120px; flex: none; border-radius: 50%; object-fit: cover; border: 1px solid var(--line); }
@media (max-width: 28rem) {
  .who-head { gap: 1rem; }
  .who-photo { width: 96px; height: 96px; }
}
/* At 320px a 96px photo left the name 153px, and "Bruce DeVault" broke over two lines. */
@media (max-width: 22rem) {
  .who-head { gap: .85rem; }
  .who-photo { width: 80px; height: 80px; }
}
/* The About page's bio paragraph (#bruce, where every "Guide: Bruce DeVault" line and blog byline
   lands): the same portrait floated into the paragraph. A plain float, not shape-outside: hugging
   the circle gave the wrapped lines a ragged left edge on a phone. */
.bio-photo { float: left; width: 96px; height: 96px; margin: .3rem 1rem .4rem 0; border-radius: 50%; object-fit: cover; border: 1px solid var(--line); }
.bio-with-photo::after { content: ""; display: table; clear: both; }
@media (max-width: 22rem) {
  .bio-photo { width: 80px; height: 80px; margin-right: .85rem; }
}

.grid { display: grid; gap: 1rem; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr)); }

/* ORPHANS.
   auto-fit packs as many columns as will fit, which is right for an open-ended list and wrong
   for a set with a known size. Four track cards became 3 + 1, and five realities became 4 + 1 -
   a full row, then one card alone beside a field of empty space. Both sets are fixed in size,
   so their column counts are stated rather than discovered: four tracks read as 2x2, and five
   realities as 3 + 2, which looks deliberate because it is. */
@media (min-width: 46rem) {
  .grid-tracks { grid-template-columns: repeat(2, 1fr); }
  .grid-five { grid-template-columns: repeat(3, 1fr); }
}
/* Cards in one row should be one height; a card is a comparison unit, not a paragraph. */
.grid-tracks > *, .grid-five > * { height: 100%; }

.card {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-lg); padding: 1.25rem; box-shadow: var(--shadow);
}
.card h3 { margin-bottom: .4rem; }
.card p:last-child { margin-bottom: 0; }
/* The five realities are a numbered list, so they are an <ol> - the counter is content, not
   decoration, and a screen reader should hear "1 of 5". list-style is off because the marker
   is drawn as a badge instead. */
.reality-list { list-style: none; padding: 0; margin: 0; counter-reset: reality; }
.reality-list > li { margin: 0; }
.reality-list > li::before {
  counter-increment: reality; content: counter(reality);
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.6rem; height: 1.6rem; border-radius: 50%;
  background: var(--sev-build-bg); color: var(--sev-build);
  font-size: .8rem; font-weight: 700; margin-bottom: .7rem;
}
.reality-list p { margin: 0; color: var(--ink-dim); }
.reality-list strong { color: var(--ink); }

.card .num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 1.6rem; height: 1.6rem; border-radius: 50%;
  background: var(--sev-build-bg); color: var(--sev-build);
  font-size: .8rem; font-weight: 700; margin-bottom: .7rem;
}

/* --- Track cards ------------------------------------------------------------ */
a.track-card { text-decoration: none; color: inherit; display: flex; flex-direction: column; }
a.track-card:hover { border-color: var(--line-strong); box-shadow: var(--shadow-lg); }
.track-card .track-name { font-size: 1.25rem; font-weight: 700; margin: 0 0 .15rem; color: var(--ink); }
.track-card .track-counts { font-size: .85rem; color: var(--ink-faint); margin: 0 0 .75rem; font-variant-numeric: tabular-nums; }
.track-card p { color: var(--ink-dim); font-size: .95rem; }
.track-card .more { margin-top: auto; padding-top: .75rem; font-weight: 650; color: var(--link); font-size: .92rem; }

/* Severity chip - the triage vocabulary, used consistently for track posture. */
.chip {
  display: inline-flex; align-items: center; gap: .4rem;
  font-size: .72rem; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  padding: .2rem .5rem; border-radius: 999px; margin-bottom: .7rem;
}
.chip::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
/* A chip is a label, not a banner. Inside the column-flex track card it was stretching to the
   card's full width, which read as a coloured header bar rather than a status tag. */
.chip { align-self: flex-start; }
.chip-live { background: var(--sev-live-bg); color: var(--sev-live); }
.chip-build { background: var(--sev-build-bg); color: var(--sev-build); }
.chip-ok { background: var(--sev-ok-bg); color: var(--sev-ok); }

/* --- Symptom router --------------------------------------------------------- */
.router-filter { margin-bottom: 1.5rem; max-width: 32rem; }
.router-filter input {
  width: 100%; padding: .8rem .95rem; font: inherit; font-size: 1.05rem;
  color: var(--ink); background: var(--surface);
  border: 2px solid var(--line-strong); border-radius: var(--radius);
}
.router-filter input:focus { outline: none; border-color: var(--brand); }
.router-stat { font-size: .85rem; color: var(--ink-faint); margin: .5rem 0 0; }

.symptom {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 1rem 1.1rem; margin-bottom: .75rem;
}
.symptom[hidden] { display: none; }
.symptom h3 { font-size: 1rem; margin-bottom: .5rem; }
.says { list-style: none; padding: 0; margin: 0 0 .7rem; display: flex; flex-wrap: wrap; gap: .35rem; }
.says li {
  margin: 0; font-size: .85rem; color: var(--ink-dim);
  background: var(--surface-2); border-radius: 999px; padding: .2rem .6rem;
}
.errs { list-style: none; padding: 0; margin: 0 0 .7rem; display: flex; flex-wrap: wrap; gap: .35rem; }
.errs li {
  margin: 0; font-family: var(--mono); font-size: .8rem;
  color: var(--sev-live); background: var(--sev-live-bg);
  border: 1px solid color-mix(in srgb, var(--sev-live) 30%, transparent);
  border-radius: 4px; padding: .15rem .45rem;
}
.routes-to { font-size: .9rem; margin: 0; color: var(--ink-dim); }
.routes-to strong { color: var(--ink); font-weight: 650; }
.router-more { margin: .5rem 0 0; width: 100%; }
@media (min-width: 40rem) { .router-more { width: auto; } }

/* --- Lesson anatomy --------------------------------------------------------- */
.anatomy { list-style: none; padding: 0; margin: 0; counter-reset: step; }
.anatomy li {
  position: relative; padding: 0 0 1.4rem 2.5rem; margin: 0;
  border-left: 2px solid var(--line); margin-left: .7rem;
}
.anatomy li:last-child { border-left-color: transparent; padding-bottom: 0; }
.anatomy li::before {
  counter-increment: step; content: counter(step);
  position: absolute; left: -.75rem; top: 0;
  width: 1.5rem; height: 1.5rem; border-radius: 50%;
  background: var(--brand); color: #fff;
  font-size: .75rem; font-weight: 700;
  display: flex; align-items: center; justify-content: center;
}
.anatomy strong { display: block; font-size: 1rem; margin-bottom: .2rem; }
.anatomy span { color: var(--ink-dim); font-size: .95rem; }

/* --- For / not for ---------------------------------------------------------- */
.forlist { list-style: none; padding: 0; margin: 0; }
.forlist li { position: relative; padding-left: 1.6rem; margin-bottom: .6rem; color: var(--ink-dim); }
.forlist li::before {
  position: absolute; left: 0; top: -.05rem; font-weight: 700; font-size: 1rem;
}
.forlist.yes li::before { content: "\2713"; color: var(--sev-ok); }
.forlist.no li::before { content: "\00d7"; color: var(--sev-live); }

/* --- Quote ------------------------------------------------------------------ */
blockquote.pull {
  margin: 0; padding: 1.25rem 1.5rem;
  border-left: 3px solid var(--gold); background: var(--surface);
  border-radius: 0 var(--radius) var(--radius) 0;
  font-size: clamp(1.05rem, 1rem + .4vw, 1.25rem); line-height: 1.5; color: var(--ink);
}
blockquote.pull p:last-child { margin-bottom: 0; }
blockquote.pull cite { display: block; margin-top: .6rem; font-size: .85rem; font-style: normal; color: var(--ink-faint); }

/* --- Statement band ---------------------------------------------------------- */
/* The positioning line on the home page, right after the five realities it concludes (owner
   2026-10-08: "important, but it's barely visible"). The hero's navy-to-black fade and gold rules, so
   it reads as a brand beat and looks the same in both themes (--navy is not redefined in dark). The
   largest non-heading type on the page, set in three balanced lines at desktop and phone widths. */
.statement-band {
  background-color: var(--navy); background-image: var(--navy-fade);
  border-top: 3px solid var(--gold); border-bottom: 3px solid var(--gold);
  padding: clamp(2.25rem, 1.5rem + 3vw, 3.75rem) 0; text-align: center;
}
.statement-line {
  max-width: 30ch; margin: 0 auto; color: #ffffff;
  font-size: clamp(1.4rem, 1.05rem + 1.8vw, 2.2rem); font-weight: 650; line-height: 1.28;
  letter-spacing: -.015em; text-wrap: balance;
}

/* --- Course + lesson lists --------------------------------------------------- */
.course-list { display: grid; gap: .75rem; }
a.course-row {
  display: block; text-decoration: none; color: inherit;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); padding: .9rem 1.1rem;
}
a.course-row:hover { border-color: var(--line-strong); box-shadow: var(--shadow); }
.course-row .code {
  font-family: var(--mono); font-size: .78rem; font-weight: 600;
  color: var(--ink-faint); letter-spacing: .02em;
}
.course-row .name { font-weight: 650; font-size: 1.05rem; margin: .1rem 0 .25rem; color: var(--ink); }
.course-row .meta { font-size: .82rem; color: var(--ink-faint); font-variant-numeric: tabular-nums; }
.course-row .blurb { font-size: .93rem; color: var(--ink-dim); margin: .35rem 0 0; }

.lessons { list-style: none; padding: 0; margin: 0; }
.lessons > li {
  padding: .85rem 0; margin: 0; border-top: 1px solid var(--line);
}
.lessons > li:first-child { border-top: none; }
/* A track page's "every lesson" index is titles only: compact rows in columns, not one 72px row per
   title (Build It Right's ran 135 rows, ~11,400px; owner review 2026-10-06). */
.lessons-compact { column-width: 22rem; column-gap: 2rem; }
.lessons-compact > li { padding: .3rem 0; border-top: none; break-inside: avoid; }
.lessons-compact .lesson-head { margin: 0; }
.lessons[hidden], .lessons > li[hidden] { display: none; }
.lesson-head { display: flex; gap: .6rem; align-items: baseline; flex-wrap: wrap; }
.lesson-head .code {
  font-family: var(--mono); font-size: .76rem; font-weight: 600; color: var(--ink-faint);
  background: var(--surface-2); border-radius: 4px; padding: .1rem .35rem;
}
.lesson-head .name { font-weight: 600; }
.lesson-tldr { margin: .3rem 0 0; font-size: .93rem; color: var(--ink-dim); max-width: 46rem; }
/* A lesson page's Video Brief, right under the summary (owner pilot on SH, 2026-10-07). It continues the
   page head, so it takes only a little space above; the 16:9 box is reserved before the poster loads. */
.lesson-video { padding-top: 1.5rem; }
.video-frame { margin: 0; max-width: 52rem; }
.video-frame video { display: block; width: 100%; height: auto; aspect-ratio: 16 / 9; background: #000; border-radius: var(--radius-lg); border: 1px solid var(--line); }
.video-frame figcaption { margin-top: .5rem; font-size: .85rem; color: var(--ink-faint); }
/* The Audio Brief (second SH pilot, owner 2026-10-07): a plain player in a light card under the video,
   its transcript closed until asked for. */
.audio-frame { margin: 1.25rem 0 0; max-width: 52rem; padding: .9rem 1rem; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); }
.audio-frame figcaption { font-size: .85rem; font-weight: 650; color: var(--ink-dim); margin-bottom: .5rem; }
.audio-frame audio { display: block; width: 100%; }
.audio-frame .transcript { margin-top: .6rem; font-size: .93rem; }
.audio-frame .transcript summary { cursor: pointer; color: var(--link); font-size: .88rem; }
.audio-frame .transcript p { color: var(--ink-dim); margin: .6rem 0 0; }

/* --- Catalog ---------------------------------------------------------------- */
.catalog-controls { position: sticky; top: 60px; z-index: 20; background: var(--bg); padding: 1rem 0; border-bottom: 1px solid var(--line); margin-bottom: 1.5rem; }
.catalog-controls .row { display: flex; gap: .6rem; flex-wrap: wrap; align-items: center; }
.catalog-controls input[type="search"] {
  flex: 1 1 16rem; padding: .7rem .85rem; font: inherit; font-size: 1rem;
  color: var(--ink); background: var(--surface);
  border: 2px solid var(--line-strong); border-radius: var(--radius);
}
.catalog-controls input[type="search"]:focus { outline: none; border-color: var(--brand); }
.catalog-controls select {
  padding: .7rem .8rem; font: inherit; color: var(--ink); background: var(--surface);
  border: 2px solid var(--line-strong); border-radius: var(--radius);
}
.catalog-group { margin-bottom: 2rem; }
.catalog-group[hidden] { display: none; }
.catalog-group h2 { font-size: 1.15rem; margin-bottom: .1rem; }
.catalog-group .track-of { font-size: .8rem; color: var(--ink-faint); margin: 0 0 .6rem; text-transform: uppercase; letter-spacing: .06em; font-weight: 650; }


/* --- Blog ------------------------------------------------------------------- */
/* Cards, chips, bylines, the pager and the post page (owner ruling 2026-10-07). Only brand tokens and
   the neutrals above; the chips reuse the triage colours by track posture. */
.chips { display: flex; flex-wrap: wrap; gap: .5rem; margin: 0 0 1.5rem; }
.chips .chip, .post-card-meta .chip, .post-head .chip { margin-bottom: 0; text-decoration: none; }
.chips .chip span { font-weight: 600; opacity: .75; }
.chips .chip[aria-current="page"] { outline: 2px solid currentColor; outline-offset: 1px; }
.chip-all { background: var(--surface-2); color: var(--ink-dim); }
.chip-sched { background: var(--surface-2); color: var(--ink-faint); }
.post-card { padding: 0; overflow: hidden; display: flex; flex-direction: column; }
.post-card:hover { border-color: var(--line-strong); box-shadow: var(--shadow-lg); }
.post-card-media { display: block; background: var(--surface-2); }
.post-card-media img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }
.post-card-body { padding: 1rem 1.25rem 1.25rem; display: flex; flex-direction: column; gap: .55rem; flex: 1; }
.post-card-meta { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; margin: 0; font-size: .8rem; color: var(--ink-faint); }
.post-card-title { font-size: 1.08rem; line-height: 1.3; margin: 0; }
.post-card-title a { color: var(--ink); text-decoration: none; }
.post-card-title a:hover { color: var(--link); text-decoration: underline; }
.post-card-excerpt { color: var(--ink-dim); font-size: .95rem; margin: 0; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.post-card .byline { margin: auto 0 0; padding-top: .35rem; }
.post-featured { grid-column: 1 / -1; }
@media (min-width: 52rem) {
  .post-featured { display: grid; grid-template-columns: 1.35fr 1fr; }
  .post-featured .post-card-media img { height: 100%; aspect-ratio: auto; }
  .post-featured .post-card-title { font-size: 1.45rem; }
  .post-featured .post-card-excerpt { -webkit-line-clamp: 5; font-size: 1.02rem; }
}
.byline { display: flex; align-items: center; flex-wrap: wrap; gap: .45rem; font-size: .92rem; color: var(--ink-dim); margin: 0 0 1rem; }
.byline a { color: var(--ink); font-weight: 650; text-decoration: none; }
.byline a:hover { text-decoration: underline; }
.byline .avatar { width: 48px; height: 48px; aspect-ratio: 1; object-fit: cover; border-radius: 50%; display: inline-block; flex: none; border: 1px solid var(--line); }
.byline-sm { font-size: .82rem; color: var(--ink-faint); margin: 0; }
.byline-sm .avatar { width: 24px; height: 24px; }
.post-head h1 { max-width: 30ch; }
.post-head .byline { margin: .25rem 0 0; }
.post-hero { margin: 0 0 1.5rem; }
.post-hero img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; border-radius: var(--radius-lg); border: 1px solid var(--line); }
.toc { background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius); padding: 1rem 1.25rem; margin: 0 0 1.5rem; }
.toc ol { margin: 0; padding-left: 1.2rem; }
.toc li { margin: .25rem 0; }
.lesson-article h3[id] { scroll-margin-top: calc(var(--head-h) + 1rem); }
.related-posts { padding: 2.5rem 0; border-top: 1px solid var(--line); }
.related-posts h2 { margin-bottom: 1rem; }
.pager { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; margin: 2rem 0 1rem; }
.pager ol { display: flex; flex-wrap: wrap; gap: .25rem; list-style: none; margin: 0; padding: 0; }
.pager li { margin: 0; }
.pager a, .pager [aria-current], .pager .gap { display: inline-flex; min-width: 2.2rem; justify-content: center; padding: .4rem .6rem; border-radius: var(--radius); border: 1px solid var(--line); text-decoration: none; color: var(--ink); font-variant-numeric: tabular-nums; }
.pager a:hover { border-color: var(--line-strong); }
.pager [aria-current] { background: var(--brand); color: var(--on-brand); border-color: var(--brand); }
.pager .gap { border: 0; }
.blog-search { max-width: 32rem; margin: 0 0 1.5rem; }
.blog-results { margin-bottom: 1.5rem; }
.blog-more { margin: 1rem 0 0; }

/* --- Footer ----------------------------------------------------------------- */
.site-foot {
  background-color: var(--navy); background-image: var(--navy-fade); color: #b9c2de;
  /* The same gold line above the footer, and none below (owner 2026-10-08). */
  border-top: 3px solid var(--gold);
  padding: 2.5rem 0 2rem; margin-top: 0; font-size: .9rem; line-height: 1.6;
}
.site-foot a { color: #d7def3; }
.site-foot a:hover { color: #ffffff; }
.site-foot .foot-grid { display: grid; gap: 1.5rem; margin-bottom: 2rem; }
@media (min-width: 48rem) { .site-foot .foot-grid { grid-template-columns: 1.4fr 1fr 1fr; } }
.site-foot h2 { font-size: .78rem; text-transform: uppercase; letter-spacing: .08em; color: #8d98bd; margin-bottom: .6rem; font-weight: 700; }
.site-foot ul { list-style: none; padding: 0; margin: 0; }
.site-foot li { margin-bottom: .3rem; }
.site-foot .brandline { color: #ffffff; font-weight: 650; margin-bottom: .4rem; }
.legal {
  border-top: 1px solid rgba(255, 255, 255, .14); padding-top: 1.25rem;
  font-size: .82rem; color: #98a3c6; max-width: 60rem;
}
.legal p { margin-bottom: .7rem; }
.legal p:last-child { margin-bottom: 0; }
.legal strong { color: #ccd4ec; }

/* --- Breadcrumb -------------------------------------------------------------- */
.crumb { font-size: .85rem; color: var(--ink-faint); margin: 0 0 .6rem; }
.crumb a { color: var(--ink-dim); text-decoration: none; }
.crumb a:hover { color: var(--link); text-decoration: underline; }
/* padding-top only: a padding shorthand here zeroed .wrap's side padding (both are one class, and
   this rule comes later), so on a phone the crumb and H1 sat on the screen edge on every page
   with a page head (measured 2026-09-14 at 375px: x=0 against the sections' x=20). */
.page-head { padding-top: clamp(2rem, 1.5rem + 2vw, 3rem); }
.page-head h1 { max-width: 24ch; }
.page-head .lede { font-size: clamp(1.05rem, 1rem + .4vw, 1.2rem); color: var(--ink-dim); max-width: 44rem; }
/* A lesson page's TL;DR shows as its own paragraphs (owner review 2026-10-06): the ones after the lede
   keep the lede's column and color, a step smaller, so the summary reads as one block of paragraphs. */
.page-head .lede ~ p:not(.crumb):not(.fineprint) { color: var(--ink-dim); max-width: 44rem; font-size: 1.02rem; margin: .8rem 0 0; }

/* --- CTA band ---------------------------------------------------------------- */
.cta-band { background: var(--bg-alt); border-top: 1px solid var(--line); }
.cta-band .inner { display: grid; gap: 1.25rem; align-items: center; }
@media (min-width: 52rem) { .cta-band .inner { grid-template-columns: 1fr auto; } }
.cta-band h2 { margin-bottom: .3rem; }
.cta-band p { color: var(--ink-dim); margin: 0; }
.cta-band .actions { display: flex; gap: .6rem; flex-wrap: wrap; }

.attrib { font-size: .85rem; color: var(--ink-faint); margin-top: 1.5rem; }

/* --- Report page -------------------------------------------------------------- */
/* The only page that renders tables, fenced templates and a callout, all quoted from
   TVA_Feedback_Collection.md. Scoped to .report so no other page changes. The templates wrap
   rather than scroll: a reporter on a phone copies them line by line, and a sideways-scrolling
   box hides the right half of the worked example. */
.report .prose { max-width: 46rem; }
/* One left edge at desktop width: the page head sits in the same centred 46rem column as the
   quoted sections and the form card, instead of on the full-width grid beside them. */
.report .page-head { max-width: 46rem; }
.report h2 { margin-top: .25rem; }
.report pre {
  font-family: var(--mono); font-size: .85rem; line-height: 1.5;
  white-space: pre-wrap; overflow-wrap: anywhere;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--radius); padding: .9rem 1rem; margin: 0 0 1.25rem;
}
.report .table-scroll { overflow-x: auto; margin: 0 0 1.25rem; }
.report table { border-collapse: collapse; width: 100%; font-size: .93rem; }
.report th, .report td { text-align: left; vertical-align: top; padding: .5rem .7rem; border-bottom: 1px solid var(--line); }
.report th { font-size: .8rem; text-transform: uppercase; letter-spacing: .05em; color: var(--ink-faint); }
.report blockquote {
  margin: 0 0 1.25rem; padding: .75rem 1rem;
  border-left: 3px solid var(--gold); background: var(--surface);
  border-radius: 0 var(--radius) var(--radius) 0;
}
.report li blockquote { margin: .5rem 0 0; font-size: .93rem; }
.report blockquote p:last-child { margin-bottom: 0; }
.report .report-form iframe { display: block; width: 100%; border: 0; }
.stat-row { display: flex; flex-wrap: wrap; gap: 1.5rem 2.5rem; margin: 1.5rem 0 0; padding: 0; list-style: none; }
.stat-row li { margin: 0; }
.stat-row .n { display: block; font-size: clamp(1.6rem, 1.3rem + 1.2vw, 2.2rem); font-weight: 700; color: var(--ink); line-height: 1.1; font-variant-numeric: tabular-nums; }
.stat-row .l { font-size: .85rem; color: var(--ink-faint); }
.hero .stat-row .n { color: var(--gold); }
.hero .stat-row .l { color: #aab4d4; }

/* Tables inside prose scroll rather than pushing the page sideways. */
.scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }
