/* Five Level Fit — single stylesheet.
   Tokens + component specs: docs/styleguide.md. Palette: docs/brand.md §2.
   Rule of thumb: sizes and gaps come from the token scale below — no ad-hoc
   values in component rules without a comment saying why. */

/* ---------- 0. Display typeface ----------
   Archivo (variable, latin subset, 35KB) — SELF-HOSTED, no external requests
   (license: assets/fonts/OFL-Archivo.txt). Display layer only: headings,
   level numbers. Body/UI text stays system for speed and native feel. */
@font-face {
  font-family: 'Archivo';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url(../assets/fonts/archivo-var-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ---------- 1. Tokens ---------- */
:root {
  /* Brand palette (docs/brand.md §2 — never alter, never add hues) */
  --l1: #0777bb; /* Level 1 Beginner — blue   */
  --l2: #1aa96b; /* Level 2 Novice   — green  */
  --l3: #f9aa1a; /* Level 3 Advanced — amber  */
  --l4: #eb4335; /* Level 4 Expert   — red    */
  --l5: #2f2f2f; /* Level 5 Pro      — black  */

  /* Semantic color */
  --ink: #232323;
  --muted: #5f6a72;
  --bg: #ffffff;
  --bg-soft: #f5f9fc;
  --line: #e3e9ee;
  --action: var(--l1);  /* default action/link color (brand.md §4) */
  --cta: var(--l3);     /* high-emphasis CTA; ALWAYS charcoal text on it */
  /* Dark surfaces — blue-biased night, never pure black (BIS v2 ch.03) */
  --night: #10161b;
  --night-ink: #eef3f7;
  --night-muted: #93a1ac;
  /* The spectrum: all five in scale order — the ONLY blended use of level
     color. Appears exactly twice per page: header top edge + end-cap edge. */
  --spectrum: linear-gradient(to right,
    var(--l1) 0 20%, var(--l2) 20% 40%, var(--l3) 40% 60%,
    var(--l4) 60% 80%, var(--l5) 80% 100%);

  /* Spacing scale — every margin/padding/gap uses one of these */
  --s1: .25rem;
  --s2: .5rem;
  --s3: .75rem;
  --s4: 1rem;
  --s5: 1.5rem;
  --s6: 2rem;
  --s7: 3rem;
  --s8: 4rem;
  --section: clamp(2.4rem, 1.8rem + 1.8vw, 3.2rem); /* rhythm between page sections */

  /* Type scale (fluid where it matters — no per-breakpoint heading overrides) */
  --fs-xs: .8rem;   /* uppercase micro-labels: table headers, card labels */
  --fs-sm: .9rem;   /* meta, hints, chips, footnotes, footer */
  --fs-lg: clamp(1.05rem, .95rem + .4vw, 1.2rem);   /* lead paragraphs */
  --fs-h3: 1.15rem;
  --fs-h2: clamp(1.35rem, 1.2rem + .75vw, 1.6rem);
  --fs-h1: clamp(1.85rem, 1.5rem + 1.6vw, 2.3rem);

  /* Typefaces: Archivo carries the display voice, system carries the text */
  --font-display: 'Archivo', system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  --font-text: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  /* Shape & elevation */
  --radius: 12px;
  --r-pill: 999px;
  --shadow: 0 1px 2px rgba(15, 35, 52, .05), 0 8px 24px rgba(15, 35, 52, .08);

  /* Motion */
  --ease: cubic-bezier(.2, .7, .2, 1);
  --quick: .18s;

  /* Layout */
  --max: 1060px;
  --pad: clamp(1rem, 3.5vw, 1.5rem); /* page gutter */

  font-size: 17px;
}

/* ---------- 2. Base ---------- */
/* Cross-document view transitions (BIS v2 ch.07): page-to-page navigation
   cross-fades; the nav and end-cap persist as stable frames. Progressive —
   browsers without support get normal loads. */
@view-transition { navigation: auto; }
header.site { view-transition-name: site-nav; }
footer.site { view-transition-name: end-cap; }
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}

/* Scroll-entrance reveal (BIS v2 ch.07): js/reveal.js tags below-fold
   sections with .rv, then .rv-in on first view — once, staggered in grids */
.rv { opacity: 0; transform: translateY(12px); transition: opacity .5s var(--ease), transform .5s var(--ease); }
.rv-in { opacity: 1; transform: none; }

* { box-sizing: border-box; }

/* Reserve the scrollbar gutter even on pages too short to scroll, so the
   centered .wrap (and the nav logo with it) never shifts between pages */
html { scrollbar-gutter: stable; }

body {
  margin: 0;
  font-family: var(--font-text);
  color: var(--ink);
  background: var(--bg);
  line-height: 1.6;
  /* Sticky footer: full-height column so a short page still pushes the dark
     end-cap to the viewport bottom — no white strip beneath it. dvh handles
     mobile browser chrome; vh is the fallback. */
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}
/* The page body grows to absorb any leftover height; the footer sits below it */
main { flex: 1 0 auto; }

h1, h2, h3 { font-family: var(--font-display); line-height: 1.2; font-weight: 800; }
h1 { font-size: var(--fs-h1); letter-spacing: -.02em; margin: 0 0 var(--s2); }
h2 { font-size: var(--fs-h2); letter-spacing: -.01em; margin: var(--section) 0 var(--s3); }
h3 { font-size: var(--fs-h3); margin: var(--s5) 0 var(--s2); }
p  { margin: var(--s3) 0; }
a  { color: var(--action); }
[id] { scroll-margin-top: 80px; } /* anchor jumps clear the sticky header */
:focus-visible { outline: 2px solid var(--action); outline-offset: 2px; }
::selection { background: rgba(7, 119, 187, .15); }

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

/* Page head: every subpage opens the same way — h1 + lead directly in main */
main.wrap > h1:first-child { margin-top: var(--s7); }
p.lead { font-size: var(--fs-lg); color: var(--muted); max-width: 42rem; margin: var(--s2) 0 var(--s5); }
.hint { color: var(--muted); font-size: var(--fs-sm); }
#quiz ~ .hint { margin-top: var(--s6); } /* breathing room after the quiz */

/* ---------- 3. Header / nav ---------- */
header.site {
  border-bottom: 1px solid var(--line);
  background: var(--bg); /* fallback when backdrop-filter is unsupported */
  position: sticky; top: 0; z-index: 10;
}
/* Spectrum hairline #1: the page's top edge (rides with the sticky nav) */
header.site::before { content: ""; display: block; height: 6px; background: var(--spectrum); }
/* Frosted-glass nav: translucent white over a blur/saturate of whatever
   scrolls beneath. Values are the effect's own — not from the token scale. */
@supports ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  header.site {
    background: rgba(255, 255, 255, .72);
    -webkit-backdrop-filter: saturate(1.8) blur(14px);
            backdrop-filter: saturate(1.8) blur(14px);
    border-bottom-color: rgba(227, 233, 238, .65);
  }
}
header.site .wrap {
  display: flex; align-items: center; gap: var(--s5);
  min-height: 64px;
}
/* Nav brand: the full-color mark stands alone (the link's aria-label carries the name) */
.logo { display: flex; align-items: center; text-decoration: none; }
.logo .logo-mark { display: block; height: 34px; width: auto; }
nav.main { margin-left: auto; display: flex; gap: var(--s4); flex-wrap: wrap; }
nav.main a {
  text-decoration: none; color: var(--ink); font-weight: 600;
  padding: var(--s2) 0; white-space: nowrap;
}
nav.main a:hover, nav.main a[aria-current="page"] { color: var(--action); box-shadow: 0 2px 0 var(--action); }
@media (max-width: 600px) {
  header.site .wrap { min-height: 56px; }
  .logo .logo-mark { height: 30px; }
  nav.main { gap: clamp(.65rem, 2.5vw, 1.05rem); }
  nav.main a { font-size: .95rem; } /* fits four links beside the mark at 320px */
}

/* ---------- 4. Buttons ---------- */
.btn {
  display: inline-block; padding: .7rem 1.3rem; border-radius: var(--radius);
  background: var(--action); color: #fff; text-decoration: none; font-weight: 700;
  border: 0; cursor: pointer; font-size: 1rem; line-height: 1.3;
  transition: filter var(--quick) var(--ease), background var(--quick) var(--ease);
}
.btn:hover { filter: brightness(1.08); }
.btn:active { transform: translateY(1px); }
.btn.secondary { background: var(--bg); color: var(--action); border: 2px solid var(--action); }
.btn.big { font-size: 1.15rem; padding: .9rem 1.7rem; }
.btn.cta-amber { background: var(--cta); color: var(--l5); } /* brand guide §4: dark text on amber */

/* ---------- 5. Level system ----------
   The color IS the level (brand.md §4). .lv1–.lv5 set the accent once;
   every level-colored component consumes the same custom properties. */
.lv1 { --level: var(--l1); --level-ink: #fff; }
.lv2 { --level: var(--l2); --level-ink: #fff; }
.lv3 { --level: var(--l3); --level-ink: var(--l5); } /* dark text on amber (§4) */
.lv4 { --level: var(--l4); --level-ink: #fff; }
.lv5 { --level: var(--l5); --level-ink: #fff; }

.levels { display: grid; grid-template-columns: repeat(5, 1fr); gap: var(--s3); margin: var(--s5) 0 var(--s6); }
.level-card {
  background: var(--level); color: var(--level-ink);
  border-radius: var(--radius); padding: var(--s4) var(--s3); text-align: center;
}
.level-card .num { font-family: var(--font-display); font-size: 1.9rem; font-weight: 800; display: block; }
.level-card .name { font-weight: 700; }

.level-chip {
  display: inline-block; background: var(--level); color: var(--level-ink);
  border-radius: var(--r-pill); padding: .1rem .7rem;
  font-weight: 700; font-size: var(--fs-sm); white-space: nowrap;
}

/* ---------- 6. Cards / grids ---------- */
.grid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s5); margin: var(--s5) 0 var(--s6); }
.card {
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: var(--s5); background: var(--bg);
}
.card h3 { margin-top: 0; }
.card .meta { color: var(--muted); font-size: var(--fs-sm); }
.card .btn { margin-top: var(--s2); }
/* Blog index: the whole card is the link — one big tap target */
a.card {
  display: block; text-decoration: none; color: inherit;
  transition: border-color var(--quick) var(--ease), box-shadow var(--quick) var(--ease);
}
a.card h3 { color: var(--action); }
a.card:hover { border-color: var(--action); box-shadow: var(--shadow); }
a.card:hover h3 { text-decoration: underline; }

/* ---------- 7. Home hero — bright white stage, looping push-up footage ---------- */
.hero-wow {
  position: relative; overflow: hidden; color: var(--ink);
  background: radial-gradient(120% 100% at 82% 28%, #edf4fb 0%, #f6fafe 44%, #ffffff 74%);
  height: min(88vh, 780px); min-height: 540px;
  /* Ultrawide: cap the stage so copy and footage never drift apart
     (the radial ground is already white at the box edges — seamless).
     width:100% is required because body is a flex column (sticky footer) —
     the auto margins otherwise cancel the default stretch and the hero
     collapses to its content width, cutting the footage off the right edge. */
  width: 100%; max-width: 1920px; margin: 0 auto;
}
/* Right-side footage, feathered into the white stage. Wide screens: subject
   stays SHARP — the mask alone melts the left edge; the readability wash only
   exists at widths where the copy actually runs into the footage (below). */
.hero-media {
  position: absolute; top: 0; right: 0; bottom: 0;
  width: min(62%, 820px); z-index: 2; pointer-events: none;
  -webkit-mask-image: linear-gradient(to right, transparent 0%, rgba(0,0,0,.55) 22%, #000 48%);
          mask-image: linear-gradient(to right, transparent 0%, rgba(0,0,0,.55) 22%, #000 48%);
}
.hero-media video, .hero-media .hero-poster {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 60% 22%;
  filter: saturate(.98) contrast(1.01);
}
.hero-media .hero-poster { display: none; } /* shown on mobile / reduced-motion in place of the video */
/* Wide screens: NO white overlay at all — the mask is the only feather.
   ::after exists solely to carry the readability wash at the widths below. */
.hero-media::after {
  content: ""; position: absolute; inset: 0;
}
/* Below 1360px the copy nears the footage: reframe the crop so the subject
   slides RIGHT, out from under the text (object-position X drops 60%→38%) */
@media (min-width: 821px) and (max-width: 1359px) {
  .hero-media video, .hero-media .hero-poster { object-position: 38% 22%; }
}
/* 1080–1359px: subject clears the copy after the reframe — keep her SHARP,
   wash only the left half where the text actually sits */
@media (min-width: 1080px) and (max-width: 1359px) {
  .hero-media {
    -webkit-mask-image: linear-gradient(to right, transparent 0%, rgba(0,0,0,.5) 26%, #000 60%);
            mask-image: linear-gradient(to right, transparent 0%, rgba(0,0,0,.5) 26%, #000 60%);
  }
  .hero-media::after {
    background: linear-gradient(to right, rgba(255,255,255,.95) 0%, rgba(255,255,255,.35) 30%, rgba(255,255,255,0) 55%);
  }
}
/* 821–1079px: no room beside the copy even after reframing — the footage
   becomes an ambient backdrop, washed enough that all text stays readable */
@media (min-width: 821px) and (max-width: 1079px) {
  .hero-media {
    -webkit-mask-image: linear-gradient(to right, transparent 0%, rgba(0,0,0,.45) 30%, #000 75%);
            mask-image: linear-gradient(to right, transparent 0%, rgba(0,0,0,.45) 30%, #000 75%);
  }
  .hero-media::after {
    background: linear-gradient(to right, rgba(255,255,255,.97) 0%, rgba(255,255,255,.6) 40%, rgba(255,255,255,0) 88%);
  }
}
.hero-wow .content {
  position: relative; z-index: 5; height: 100%;
  display: flex; align-items: center;
}
/* Crest lockup: mark left, statement right, one shared horizontal axis */
.hero-lockup { display: flex; align-items: center; gap: clamp(1.4rem, 3vw, 2.4rem); }
/* Full-color mark directly on the light ground (docs/brand.md §3.1 default) */
.hero-logo { flex-shrink: 0; }
.hero-mark { display: block; width: clamp(110px, 15vw, 150px); filter: drop-shadow(0 4px 10px rgba(20,40,60,.09)); }
.hero-kicker {
  color: var(--muted); font-weight: 600;
  font-size: clamp(1rem, 1.6vw, 1.25rem); margin: 0 0 .3rem;
}
.hero-wow h1 {
  color: var(--l5); font-size: clamp(2.5rem, 6.4vw, 4.6rem); /* display size — above the scale */
  letter-spacing: -.02em; line-height: 1.04; margin: 0;
}
/* Cycling level number — two stacked digits so the slot is never empty:
   #lv-next slides in from below while #lv-cur slides out the top */
.hero-level {
  position: relative; display: inline-block; width: .64em;
  text-align: center; color: var(--l1);
}
.hero-level .lv {
  display: inline-block;
  transition: transform .3s cubic-bezier(.3,.8,.3,1), opacity .3s;
}
#lv-next { position: absolute; left: 0; right: 0; top: 0; opacity: 0; transform: translateY(.45em); }
.hero-level.swap #lv-cur { opacity: 0; transform: translateY(-.45em); }
.hero-level.swap #lv-next { opacity: 1; transform: none; }
.hero-level.instant .lv { transition: none; }
/* Reduced-motion static state: the full 1-5 ladder, not a frozen single digit */
.hero-level.lv-static { width: auto; }
.hero-level.lv-static .lv { position: static; opacity: 1; transform: none; }
.hero-lead {
  color: var(--muted); font-size: clamp(1rem, 1.5vw, 1.2rem);
  max-width: 34rem; margin: .9rem 0 0;
}
.hero-cta-row { display: flex; align-items: center; gap: var(--s4); flex-wrap: wrap; margin: var(--s5) 0 0; }
/* Entrance: logo → kicker → headline → CTAs rise in sequence */
@keyframes hero-rise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}
.rise { opacity: 0; animation: hero-rise .6s var(--ease) forwards; }
.d1 { animation-delay: .05s; } .d2 { animation-delay: .2s; }
.d3 { animation-delay: .32s; } .d4 { animation-delay: .46s; }
.d5 { animation-delay: .6s; }
.sr-only {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap;
}
@media (prefers-reduced-motion: reduce) {
  .hero-media video { display: none; }
  .hero-media .hero-poster { display: block; }
  .rise { animation: none; opacity: 1; }
  .hero-level .lv { transition: none; }
}
@media (max-width: 820px) {
  /* Mobile = the LOOP plays below the copy (poster remains the
     reduced-motion/while-loading fallback) */
  .hero-wow {
    height: auto; min-height: 0; padding: var(--s6) 0 0;
    display: flex; flex-direction: column;
  }
  .hero-wow .content { height: auto; order: 1; }
  .hero-media {
    /* relative, NOT static: the absolute video/poster + ::after must resolve
       against this strip, not bleed across the whole hero */
    position: relative; order: 2; width: 100%; margin-top: var(--s5);
    aspect-ratio: 16 / 10;
    /* feather BOTH ends: melts up into the copy and down into the page white */
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, #000 16%, #000 84%, transparent 100%);
            mask-image: linear-gradient(to bottom, transparent 0%, #000 16%, #000 84%, transparent 100%);
  }
  .hero-media::after { background: none; }
}
@media (max-width: 560px) {
  /* Phones: crest LEFT of the statement (kicker + headline); lead and CTAs
     span full width beneath. Grid via display:contents — no extra markup. */
  .hero-lockup {
    display: grid; grid-template-columns: auto 1fr;
    /* row-gap 0: the desktop flex gap would otherwise wedge the rows apart —
       kicker/headline spacing is the kicker's own margin; generous column air */
    gap: 0 var(--s5); align-items: center;
  }
  .hero-copy { display: contents; }
  .hero-logo { grid-column: 1; grid-row: 1 / 3; align-self: center; }
  /* Kicker bottom-aligned + headline top-aligned = the pair stays TIGHT;
     the crest's spare row height lands around them, not between them */
  .hero-kicker { grid-column: 2; grid-row: 1; align-self: end; }
  .hero-wow h1 { grid-column: 2; grid-row: 2; align-self: start; font-size: clamp(2rem, 10.5vw, 2.65rem); }
  .hero-lead { grid-column: 1 / -1; grid-row: 3; }
  .hero-cta-row { grid-column: 1 / -1; grid-row: 4; }
  .hero-mark { width: clamp(72px, 24vw, 96px); }
  /* Both CTAs share one row: equal halves, fluid label size, no wrapping */
  .hero-cta-row { flex-wrap: nowrap; gap: var(--s3); }
  .hero-cta-row .btn {
    flex: 1 1 0; min-width: 0; text-align: center; white-space: nowrap;
    /* near-zero side padding + .78rem floor: the long label clears 320px */
    padding: .85rem .1rem; font-size: clamp(.78rem, 4.1vw, 1.05rem);
  }
}

/* ---------- 8. Quiz (Level Test) ---------- */
.quiz { max-width: 560px; }
.quiz .step { margin: var(--s5) 0; }
.quiz label { font-weight: 700; display: block; margin-bottom: var(--s2); }
.quiz input[type="number"] {
  font-size: 1.3rem; /* comfortably above 16px — no iOS zoom-on-focus */
  padding: .55rem .8rem; width: 9rem;
  border: 2px solid var(--line); border-radius: var(--radius);
  transition: border-color var(--quick) var(--ease);
}
.quiz input[type="number"]:focus { border-color: var(--action); outline: none; }
/* Rep input + Next on one shared row; the input yields, the button never shrinks */
.answer-row { display: flex; gap: var(--s3); align-items: stretch; }
.answer-row input[type="number"] { flex: 0 1 9rem; min-width: 0; }
.answer-row .btn { flex-shrink: 0; }
.choice-row { display: flex; gap: var(--s3); flex-wrap: wrap; }
.choice {
  border: 2px solid var(--line); border-radius: var(--radius); background: var(--bg);
  padding: .8rem 1.2rem; font-size: 1.05rem; font-weight: 700; cursor: pointer;
  transition: border-color var(--quick) var(--ease), color var(--quick) var(--ease);
}
.choice:hover, .choice.selected { border-color: var(--action); color: var(--action); }
/* The result is the page's ONE kinetic moment (BIS v2 ch.07/08):
   the card sweeps in over 400ms; leveltest.js counts the digit 1→N */
@keyframes result-in {
  from { opacity: 0; transform: translateY(10px) scale(.985); }
  to   { opacity: 1; transform: none; }
}
.result-card {
  border-radius: var(--radius); color: #fff; padding: var(--s6);
  margin-top: var(--s5); box-shadow: var(--shadow);
  animation: result-in .4s var(--ease) both;
}
@media (prefers-reduced-motion: reduce) {
  .result-card { animation: none; }
}
.result-card h2 { margin: 0 0 var(--s2); }
.result-card a { color: #fff; }
.result-card .btn { background: rgba(255,255,255,.18); border: 2px solid #fff; margin-top: var(--s3); }
.result-actions { display: flex; gap: var(--s3); flex-wrap: wrap; margin-top: var(--s4); }

/* ---------- 9. Download tables ---------- */
table.downloads { width: 100%; border-collapse: collapse; margin: var(--s4) 0 var(--s6); font-variant-numeric: tabular-nums; }
table.downloads th, table.downloads td { padding: var(--s2) var(--s3); text-align: left; border-bottom: 1px solid var(--line); }
table.downloads th { font-size: var(--fs-xs); text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
table.downloads tr:hover td { background: var(--bg-soft); }
/* The level ladder (BIS v2 ch.08): a 4px level rail on each desktop row.
   :has() is progressive — browsers without it just show no rail. */
@media (min-width: 601px) {
  table.downloads tr:has(.level-chip.lv1) { box-shadow: inset 4px 0 0 var(--l1); }
  table.downloads tr:has(.level-chip.lv2) { box-shadow: inset 4px 0 0 var(--l2); }
  table.downloads tr:has(.level-chip.lv3) { box-shadow: inset 4px 0 0 var(--l3); }
  table.downloads tr:has(.level-chip.lv4) { box-shadow: inset 4px 0 0 var(--l4); }
  table.downloads tr:has(.level-chip.lv5) { box-shadow: inset 4px 0 0 var(--l5); }
  table.downloads td:first-child, table.downloads th:first-child { padding-left: var(--s4); }
  /* The PDF chip: compact pill, fills on hover (mobile keeps its full-width button) */
  table.downloads td:last-child a {
    display: inline-block; border: 1.5px solid var(--action); color: var(--action);
    border-radius: var(--r-pill); padding: .15rem .7rem;
    font-size: var(--fs-sm); font-weight: 700; text-decoration: none; white-space: nowrap;
    transition: background var(--quick) var(--ease), color var(--quick) var(--ease);
  }
  table.downloads td:last-child a:hover { background: var(--action); color: #fff; }
}
/* Narrow screens: each row becomes a card — nothing hides off-screen.
   Column order is fixed sitewide: chip / exercise / you-can-do-now / goal / PDF.
   The exercise column drops there (the now/goal cells already name the exercise). */
@media (max-width: 600px) {
  table.downloads, table.downloads tbody { display: block; }
  table.downloads tr:first-child { display: none; } /* header row */
  table.downloads tr {
    display: grid; grid-template-columns: 1fr 1fr; gap: .1rem var(--s4);
    border: 1px solid var(--line); border-radius: var(--radius);
    padding: var(--s4); margin-bottom: var(--s3);
  }
  table.downloads tr:hover td { background: none; }
  table.downloads td { display: block; padding: 0; border: 0; }
  table.downloads td:nth-child(1) { grid-column: 1 / -1; margin-bottom: var(--s2); }
  table.downloads td:nth-child(2) { display: none; }
  table.downloads td:nth-child(3)::before,
  table.downloads td:nth-child(4)::before {
    display: block; content: "You can do now";
    font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase;
    letter-spacing: .04em; color: var(--muted);
  }
  table.downloads td:nth-child(4)::before { content: "Day-30 goal"; }
  table.downloads td:nth-child(5) { grid-column: 1 / -1; margin-top: var(--s3); }
  table.downloads td:nth-child(5) a {
    display: block; text-align: center; background: var(--action); color: #fff;
    text-decoration: none; font-weight: 700; padding: .6rem 1rem;
    border-radius: var(--radius);
  }
}

/* ---------- 10. Blog ---------- */
/* Two-column article (per original FLF blog concept: text left, levels right) */
.blog-cols { display: grid; grid-template-columns: 1.6fr 1fr; gap: var(--s6); align-items: start; }
.blog-cols aside { position: sticky; top: 84px; }
.step-level {
  border-left: 6px solid var(--level, var(--line)); border-radius: 6px;
  background: var(--bg-soft); padding: var(--s3) var(--s4); margin-bottom: var(--s3);
}
.step-level strong { display: block; }
.footnotes {
  font-size: var(--fs-sm); color: var(--muted);
  border-top: 1px solid var(--line); margin-top: var(--s7); padding-top: var(--s4);
}
.footnotes li { margin-bottom: var(--s2); overflow-wrap: anywhere; }
sup a { text-decoration: none; }

/* ---------- 11. The dark end-cap (BIS v2 ch.08) ----------
   Signup + footer are ONE night block with the spectrum top edge —
   every page ends the same calm way. Signup lives INSIDE footer.site. */
footer.site {
  background: var(--night); color: var(--night-muted);
  margin-top: var(--s8); padding: var(--s7) 0 var(--s6);
  font-size: var(--fs-sm); position: relative;
}
/* Spectrum hairline #2: the end-cap's top edge */
footer.site::before { content: ""; position: absolute; inset: 0 0 auto 0; height: 6px; background: var(--spectrum); }
footer.site a { color: var(--night-muted); }
footer.site a:hover { color: var(--night-ink); }
.signup { color: var(--night-ink); margin: 0 0 var(--s6); max-width: 640px; }
.signup h2 { margin: 0 0 var(--s1); }
.signup p { color: var(--night-muted); margin-top: 0; }
.signup form { display: flex; gap: var(--s2); flex-wrap: wrap; margin-top: var(--s4); }
.signup input[type="email"] {
  flex: 1 1 240px; padding: .7rem .9rem; border-radius: var(--radius);
  border: 0; font-size: 1rem; /* 17px — no iOS zoom-on-focus */
}
.signup .btn { background: var(--cta); color: var(--l5); } /* dark text on amber (§4) */
.signup .ok { color: var(--l2); font-weight: 700; }
.foot-meta { display: flex; gap: var(--s5); flex-wrap: wrap; justify-content: space-between; }
/* Only draw the divider when a signup sits above the meta line */
.signup + .foot-meta { border-top: 1px solid rgba(255,255,255,.09); padding-top: var(--s5); }

/* ---------- 13. Responsive ---------- */
@media (max-width: 820px) {
  .levels { gap: var(--s1); }
  .level-card { padding: var(--s2) var(--s1); }
  .level-card .num { font-size: 1.3rem; }
  .level-card .name { font-size: var(--fs-xs); }
  .grid3 { grid-template-columns: 1fr; gap: var(--s4); }
  .blog-cols { grid-template-columns: 1fr; }
  .blog-cols aside { position: static; }
  main.wrap > h1:first-child { margin-top: var(--s6); }
}
@media (max-width: 480px) {
  /* Level Test: exercise choices stack full-width — unmissable thumb targets */
  .choice { flex: 1 1 100%; text-align: center; padding: .9rem 1.2rem; }
  .answer-row input[type="number"] { flex: 1 1 auto; }
  .result-card { padding: var(--s5); }
  .result-card .btn, .result-actions .btn { flex: 1 1 100%; display: block; text-align: center; }
  .signup .btn { flex: 1 1 100%; }
}
