/* ==========================================================================
   MaRS project site — design system
   Tokens are exactly WEBSITE_BUILD_STATUS.md section 3.6 /
   MARS_WEBSITE_BUILD_GUIDE.md section 3, inherited from the poster and video.

   TWO HARD RULES, both encoded here and checked by tools/audit_claims.py:

   1. --gold is ONLY EVER A FILL — background, pill, bar, underline, border.
      REVISED 2026-09-07 (stage 1.5, WEBSITE_BUILD_STATUS.md 3.6): the
      "large display numeral" exemption is GONE. Gold on mint measures
      1.73:1, which fails even the 3:1 large-text bar, so the four gain
      numerals are now DARK on a GOLD PLATE (8.64:1) instead of gold on mint.

      Gold-coloured TEXT on a light surface uses --aged-fg, which resolves to
      --aged on PAPER (4.51:1) and --aged-text on every MINT surface (5.00:1).
      Never write `color: var(--aged)` — write `color: var(--aged-fg)` and let
      the surface pick. Fills keep `var(--aged)`.

      --gold as a `color:` survives in exactly one role: gold TEXT ON INK,
      which measures 9.36:1 and is the poster's wordmark. That role has its
      own token, --ink-accent, so `--gold` never appears in a `color:`
      declaration anywhere in this file and the fill-only rule stays greppable.

   2. --ink is used in EXACTLY TWO PLACES on the main page: the sticky nav strip
      and the closing BibTeX/footer band. The demo lab's sidebar is the third,
      sanctioned use, and it lives on demos/index.html only.
   ========================================================================== */

:root {
  /* ---- palette ---- */
  --gold:  #CFB991;   /* FILL ONLY — background, pill, bar, underline, border */
  --aged:  #8E6F3E;   /* AGED gold: fills, borders, and TEXT on PAPER (4.51:1) */
  --dark:  #1F1F1F;   /* body text on light backgrounds */
  --mint:  #ECF6EF;   /* panel fill for alternating content bands */
  --green: #0E7A46;   /* Simulator / correct / fast */
  --blue:  #2E6DA4;   /* Theory / neutral annotation */
  --red:   #B03A2E;   /* Poisson / wrong / slow — used sparingly */
  --grey:  #5A5A5A;   /* captions, secondary body text */
  --paper: #FAFBFA;   /* light content background — the default page ground */
  --ink:   #14181A;   /* dark — nav strip and closing band only */

  /* ---- derived text tokens (stage 1.5) ---------------------------------
     --aged-text is the ONLY new brand-adjacent value: same hue (36.7deg) and
     saturation (39.2%) as --aged, lightness 4 points lower. Measured 5.00:1
     on MINT and 5.33:1 on PAPER, against --aged's 4.23:1 on MINT.

     --aged-fg is the indirection that makes it automatic: it holds the gold
     TEXT colour for whatever surface you are currently on. :root sets it to
     --aged (the PAPER default); every mint surface re-points it to
     --aged-text a few rules below. Every gold-coloured TEXT rule in this file
     uses var(--aged-fg); fills keep var(--aged).

     --ink-accent is GOLD used as TEXT ON INK ONLY (9.36:1) — the nav wordmark,
     the BibTeX heading, the closing links. It is a separate token so that
     --gold itself never appears in a `color:` declaration.
     -------------------------------------------------------------------- */
  --aged-text:  #806438;   /* gold-coloured TEXT on MINT surfaces */
  --aged-fg:    var(--aged);   /* per-surface gold TEXT colour; see above */
  --ink-accent: #CFB991;   /* GOLD as TEXT, permitted on INK surfaces only */

  /* ---- derived / utility ---- */
  --ink-soft:   #20262a;   /* hairlines inside ink bands */
  --rule:       #e3e6e4;   /* hairline on light surfaces */
  --gold-soft:  #f2ebdd;   /* very light gold wash for pill hovers */

  /* ---- type ---- */
  --font-head: Poppins, "Trebuchet MS", system-ui, sans-serif;
  --font-body: Inter, "Helvetica Neue", Arial, sans-serif;
  --font-mono: ui-monospace, "SFMono-Regular", "Cascadia Mono", Menlo,
               Consolas, "Liberation Mono", monospace;

  /* ---- layout ---- */
  --measure: 1080px;      /* the content column */
  --nav-h: 52px;
  --band-y: clamp(2.5rem, 5vw, 4.25rem);
  --radius: 10px;
  --radius-pill: 999px;
}

/* --------------------------------------------------------------------------
   MINT SURFACES — the one place --aged-fg is re-pointed.

   Anything in this list is painted --mint (or a near-mint tint), so gold
   TEXT inside it must be --aged-text (5.00:1) rather than --aged (4.23:1).
   The property cascades, so a mint card sitting on a paper band gets the
   right value automatically and nothing has to be scoped by hand.

   STAGE 02 AND LATER: if you introduce a NEW mint-painted surface, add its
   selector here. Do not write `color: var(--aged-text)` at the use site —
   write `color: var(--aged-fg)` and let this list decide.
   -------------------------------------------------------------------------- */

.mars-band.is-mint,
.mars-card,
.mars-eq,
.mars-media__frame,
.mars-lab__caveat,
#playground-root {
  --aged-fg: var(--aged-text);
}

/* --------------------------------------------------------------------------
   Reset / base
   -------------------------------------------------------------------------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* anchor scrolls must clear the sticky nav */
  scroll-padding-top: calc(var(--nav-h) + 12px);
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--dark);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 {
  font-family: var(--font-head);
  line-height: 1.2;
  margin: 0 0 0.5em;
  font-weight: 600;
}

p { margin: 0 0 1em; }
p:last-child { margin-bottom: 0; }

a { color: var(--aged-fg); }
a:hover { color: var(--dark); }

img, video { max-width: 100%; height: auto; display: block; }

:focus-visible {
  outline: 3px solid var(--aged);
  outline-offset: 2px;
  border-radius: 4px;
}

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

/* Skip link — keyboard users should not have to tab the whole nav */
.mars-skip {
  position: absolute;
  left: 8px; top: -60px;
  z-index: 200;
  background: var(--aged);
  color: #fff;
  padding: 10px 16px;
  border-radius: var(--radius);
  font-family: var(--font-head);
  font-weight: 600;
  text-decoration: none;
  transition: top 0.15s ease;
}
.mars-skip:focus { top: 8px; color: #fff; }

/* --------------------------------------------------------------------------
   Sticky nav — INK USE 1 OF 2
   -------------------------------------------------------------------------- */

.mars-nav {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--ink);
  border-bottom: 1px solid var(--ink-soft);
}

.mars-nav__inner {
  max-width: var(--measure);
  margin: 0 auto;
  min-height: var(--nav-h);
  padding: 0 clamp(1rem, 3vw, 1.75rem);
  display: flex;
  align-items: center;
  gap: 1rem;
}

.mars-nav__brand {
  font-family: var(--font-head);
  font-weight: 700;
  font-size: 1.0625rem;
  letter-spacing: 0.01em;
  color: var(--ink-accent);    /* GOLD as text on INK: 9.36:1 — the one
                                  sanctioned gold-text role. See rule 1. */
  text-decoration: none;
  flex: 0 0 auto;
}
.mars-nav__brand:hover { color: #e2d3b6; }

.mars-nav__links {
  margin-left: auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 0.15rem;
}

/* Holds the eight anchors + divider; the Demo lab pill sits outside it so a
   mid-width overflow scrolls the anchors and never hides the pill. */
.mars-nav__scroll {
  display: flex;
  align-items: center;
  gap: 0.15rem;
  list-style: none;
  padding: 0;
  margin: 0;
}

.mars-nav__link {
  display: inline-block;
  padding: 0.45rem 0.6rem;
  font-size: 0.875rem;
  color: #d7dbd9;
  text-decoration: none;
  border-radius: 6px;
  white-space: nowrap;
}
.mars-nav__link:hover,
.mars-nav__link:focus-visible { color: #fff; background: var(--ink-soft); }

.mars-nav__divider {
  width: 1px;
  align-self: stretch;
  margin: 0.6rem 0.55rem;
  background: #343c40;
  flex: 0 0 auto;
}

/* The one filled-gold pill in the nav. Gold is a FILL here; the label is
   --ink, i.e. dark text on gold — that direction passes contrast. */
.mars-nav__pill {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  padding: 0.4rem 0.85rem;
  border-radius: var(--radius-pill);
  background: var(--gold);
  color: var(--ink);
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 0.8125rem;
  text-decoration: none;
  white-space: nowrap;
  flex: 0 0 auto;
}
.mars-nav__pill:hover { background: #ddcaa8; color: var(--ink); }

.mars-nav__burger {
  display: none;
  margin-left: auto;
  background: transparent;
  border: 1px solid #3b4347;
  border-radius: 8px;
  color: #e7eae9;
  font-size: 1.25rem;
  line-height: 1;
  padding: 0.3rem 0.55rem;
  cursor: pointer;
}

/* NAV BREAKPOINTS.
   MARS_WEBSITE_BUILD_GUIDE.md 4.1 says the nav collapses to a hamburger
   "under ~600px". Stage 01 measured that it cannot: with EIGHT anchors, the
   divider and the Demo lab pill, the row needs 851px at full size and 688px
   at the smallest legible tightening, while a 740px viewport only offers a
   696px content column. Hence three regimes rather than two, and hamburger at
   740px rather than 600px.

   STAGE 1.5 CHANGED HOW THE MIDDLE REGIME IS CHOSEN, and this is the point.
   Stage 01's 741-919px range was a constant derived from a fixed list of
   eight anchors. That list is no longer fixed: the stub gate removes a nav
   anchor for every unfinished section, so the nav ships today with TWO
   anchors and grows back towards eight as stage 02 lands. A hard-coded range
   would tighten a two-anchor nav that has 400px of room to spare, and would
   silently clip once the count went back up.

   So the tightening is now MEASURED rather than assumed: js/mars-nav.js
   compares the row's scrollWidth against its clientWidth and adds
   `.mars-nav.is-tight` only when the content genuinely does not fit. The
   styles below are unchanged from stage 01 — only their trigger moved. The
   width guard keeps the tightened type off phones, where the hamburger owns
   the layout instead.

       fits at full size          full-size nav
       does not fit, >= 741px     .is-tight  (measured, not assumed)
       <= 740px                   hamburger

   Nothing has to be re-measured when the anchor list changes again. The
   anchors also sit in their own overflow-x scroller with the pill pinned
   OUTSIDE it, so any residual overflow scrolls the anchors and can never
   hide the pill. */
@media (min-width: 741px) {
  .mars-nav.is-tight .mars-nav__inner { gap: 0.5rem; }
  .mars-nav.is-tight .mars-nav__links { gap: 0; min-width: 0; }
  .mars-nav.is-tight .mars-nav__scroll {
    min-width: 0;
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
  }
  .mars-nav.is-tight .mars-nav__scroll::-webkit-scrollbar { display: none; }
  .mars-nav.is-tight .mars-nav__link {
    font-size: 0.78125rem;
    padding: 0.4rem 0.32rem;
  }
  .mars-nav.is-tight .mars-nav__divider { margin: 0.6rem 0.3rem; }
  .mars-nav.is-tight .mars-nav__pill {
    font-size: 0.75rem;
    padding: 0.34rem 0.62rem;
  }
}

@media (max-width: 740px) {
  .mars-nav__burger { display: inline-block; }
  .mars-nav__links {
    position: absolute;
    left: 0; right: 0;
    top: 100%;
    margin: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--ink);
    border-bottom: 1px solid var(--ink-soft);
    padding: 0.4rem clamp(1rem, 3vw, 1.75rem) 0.9rem;
  }
  .mars-nav__links[hidden] { display: none; }
  .mars-nav__scroll {
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    overflow: visible;
    width: 100%;
  }
  .mars-nav__link { padding: 0.6rem 0.35rem; font-size: 0.9375rem; }
  .mars-nav__divider { display: none; }
  .mars-nav__pill { align-self: flex-start; margin-top: 0.5rem; }
  .mars-nav__inner { position: relative; }
}

/* --------------------------------------------------------------------------
   Bands — the PAPER / MINT alternation that separates sections
   -------------------------------------------------------------------------- */

.mars-band { background: var(--paper); }
.mars-band.is-mint { background: var(--mint); }
.mars-band.is-ink  { background: var(--ink); color: #e7eae9; }

.mars-band__inner {
  max-width: var(--measure);
  margin: 0 auto;
  padding: var(--band-y) clamp(1rem, 3vw, 1.75rem);
}

.mars-band__inner.is-tight { padding-top: 2rem; padding-bottom: 2rem; }

/* --------------------------------------------------------------------------
   Eyebrow labels + section headings
   -------------------------------------------------------------------------- */

.mars-eyebrow {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 0.75rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin: 0 0 0.6rem;
}
.mars-eyebrow.is-neutral   { color: var(--aged-fg); }
.mars-eyebrow.is-theory    { color: var(--blue); }
.mars-eyebrow.is-simulator { color: var(--green); }
.mars-eyebrow.is-utility   { color: var(--aged-fg); }
.mars-eyebrow.is-muted     { color: var(--grey); }

/* ICONS — inline SVG, not a webfont (Q10, stage 06).
   The site used the Tabler icons webfont from jsDelivr for nine decorative
   glyphs. Measured on the live site at Slow 3G: ONE request, 801 KB of
   tabler-icons.woff2, 20.5 s of a 26.6 s load — the whole remaining gap
   between DCL and load, for nine outline shapes. The nine are now inline
   <svg class="mars-ico"> in the markup, taken from the same Tabler 3.31.0
   outline set the font was built from, so nothing external is fetched.

   Two things this rule has to preserve, because the webfont gave them away
   for free and an SVG does not:
     - COLOUR. Tabler outline glyphs are strokes, so every inline SVG carries
       stroke="currentColor" and fill="none". That is what keeps the five
       .mars-eyebrow colour variants (blue / green / aged / grey) working.
       Never hard-code a stroke colour on one of these.
     - SIZE. A webfont glyph is 1em by definition. `width/height: 1em` plus
       the baseline nudge reproduces that in every context the icons appear
       in — the nav burger (1.25rem), the gold demo-lab pill (0.8125rem), the
       section eyebrows (0.75rem) and the lab back-link (0.9375rem) all size
       their icon from their own font-size, exactly as before. The width and
       height ATTRIBUTES in the markup are only a no-CSS fallback: CSS beats a
       presentation attribute, so 1em still governs. */
.mars-ico {
  width: 1em;
  height: 1em;
  vertical-align: -0.125em;
  flex: 0 0 auto;
}

.mars-eyebrow .mars-ico { width: 1.15em; height: 1.15em; vertical-align: 0; }

.mars-section__title {
  font-size: clamp(1.5rem, 3vw, 2rem);
  margin: 0 0 0.75rem;
}
.mars-section__lede {
  max-width: 68ch;
  color: var(--dark);
  font-size: 1.0625rem;
}

/* --------------------------------------------------------------------------
   Hero
   -------------------------------------------------------------------------- */

.mars-hero__inner { padding-top: clamp(2rem, 4vw, 3.25rem); }

.mars-badge {
  display: inline-block;
  background: var(--aged);        /* AGED fill, white text: 4.9:1 */
  color: #fff;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 0.78125rem;
  letter-spacing: 0.03em;
  padding: 0.3rem 0.8rem;
  border-radius: var(--radius-pill);
  margin-bottom: 1.1rem;
}

/* The hero title. One line, ONE FONT SIZE throughout; the contrast between
   `MaRS`/`Ma`/`R`/`S` and the rest comes from COLOUR AND WEIGHT ONLY.

   The numbers below are measured, not guessed. At `letter-spacing: -0.02em`
   the 50-character line is 26.08 em wide in Poppins — and Poppins is the
   WIDEST of the stack (Trebuchet MS and system-ui measure 24.06 and 23.63 em),
   so sizing for Poppins is the safe case and a failed webfont load can only
   make the line shorter, never wrap it.

   Available width is `min(1080px, 100vw) - 2 x clamp(1rem, 3vw, 1.75rem)`.
   Dividing that by 26.08 em gives the largest size that fits:
       1440px viewport -> 1024px column -> 39.3px max
       1024px          ->  968px        -> 37.1px max
        768px          ->  722px        -> 27.7px max
        381px          ->  349px        -> 13.4px max
   The 3.42vw coefficient with a 2.42rem cap sits 3-6% under that ceiling at
   every width, which is the margin for platform font-metric variation.
   If you change the font, the tracking, or --measure, RE-MEASURE THIS. */
.mars-hero__title {
  font-size: clamp(0.8rem, 3.42vw, 2.42rem);
  font-weight: 400;
  color: var(--dark);
  letter-spacing: -0.02em;
  margin: 0 0 0.85rem;
  white-space: nowrap;          /* the guide: must never wrap to two lines */
}

.mars-hl { color: var(--aged-fg); font-weight: 500; }

/* Below ~380px, 51 characters at any legible size will not fit one line. The
   guide sanctions exactly one fallback: `MaRS` at full size with the full
   title smaller beneath it. */
.mars-hero__title--narrow { display: none; }

/* THE NARROW HERO TITLE — breakpoint and a11y both corrected in stage 06.
   Two measured findings, both in the band of widths that is most of the
   conference's phone traffic:

   1. The breakpoint was 380px, and the wide title's clamp() floor is 0.8rem
      = 12.8px. So between 381px and 467px the <h1> rendered BELOW body size
      while the narrow fallback built for exactly this case stayed switched
      off — measured 14.36px at 420px and 13.3px at 390px, against 16px body
      copy and a 17px subhead. 381-467px covers essentially every mainstream
      phone in portrait: 390, 393, 402, 414, 428, 430. The breakpoint is now
      467px, which is the width where the nowrap title reaches exactly 1rem
      (3.42vw = 16.006px at 468px). The rule is therefore principled rather
      than picked: the narrow fallback owns every width at which the single
      line would be smaller than the body text it sits above.

   2. `display: none` on the <h1> took it out of the ACCESSIBILITY TREE, and
      the narrow replacement below is aria-hidden="true" — so below the
      breakpoint the page had NO <h1> at all for assistive technology. The
      first heading a screen reader met was the visually-hidden "Headline
      results" <h2>. Measured at 375px before this change. The <h1> is now
      visually hidden instead (the same declarations as
      .mars-visually-hidden), so it stays in the tree and keeps naming the
      hero <section> through aria-labelledby, while the narrow block carries
      the visual treatment. */
@media (max-width: 467px) {
  .mars-hero__title {
    position: absolute;
    width: 1px; height: 1px;
    margin: -1px; padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
  }
  .mars-hero__title--narrow { display: block; }
  .mars-hero__title--narrow .mars-hero__acronym {
    display: block;
    font-family: var(--font-head);
    font-size: 2.75rem;
    font-weight: 500;
    color: var(--aged-fg);
    line-height: 1.05;
  }
  .mars-hero__title--narrow .mars-hero__full {
    display: block;
    font-family: var(--font-head);
    font-size: 1.0625rem;
    font-weight: 400;
    color: var(--dark);
    margin-top: 0.3rem;
    line-height: 1.3;
  }
}

.mars-hero__subhead {
  font-family: var(--font-head);
  font-weight: 400;
  font-size: clamp(1.0625rem, 1.9vw, 1.3125rem);
  color: var(--grey);
  max-width: 62ch;
  margin: 0 0 1.4rem;
}

.mars-hero__authors {
  font-size: 1.0625rem;
  margin: 0 0 0.3rem;
}
.mars-hero__authors a { text-decoration: none; border-bottom: 1px solid #d8cdb5; }
.mars-hero__authors a:hover { border-bottom-color: var(--aged); }

.mars-hero__affil {
  color: var(--grey);
  font-size: 0.9375rem;
  margin: 0 0 1.5rem;
}

.mars-hero__buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.mars-hero__note {
  margin-top: 0.9rem;
  font-size: 0.8125rem;
  color: var(--grey);
}

/* --------------------------------------------------------------------------
   Buttons
   -------------------------------------------------------------------------- */

.mars-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 0.9375rem;
  padding: 0.55rem 1.05rem;
  border-radius: var(--radius);
  border: 1.5px solid var(--aged);
  text-decoration: none;
  cursor: pointer;
  background: transparent;
  color: var(--aged-fg);
  white-space: nowrap;
}

.mars-btn.is-primary {
  background: var(--aged);
  color: #fff;
  border-color: var(--aged);
}
.mars-btn.is-primary:hover { background: #7b5f34; color: #fff; }

.mars-btn.is-outline:hover { background: var(--gold-soft); color: var(--dark); }

/* A URL that does not exist yet. Non-clickable by construction: rendered as a
   <span>, not an <a>, so there is nothing to activate and nothing to focus. */
.mars-btn.is-soon {
  border-color: #cfcfcf;
  border-style: dashed;
  color: #8b8b8b;
  cursor: default;
  background: transparent;
}
.mars-btn.is-soon:hover { background: transparent; color: #8b8b8b; }

.mars-btn__soon {
  font-weight: 400;
  font-size: 0.8125rem;
  color: #8b8b8b;
}

/* --------------------------------------------------------------------------
   Four gains — .mars-stat

   RE-TREATED IN STAGE 1.5. Stage 01 built these as GOLD numerals on MINT,
   which the guide asked for and which measures 1.73:1 — failing even the 3:1
   large-text bar. WEBSITE_BUILD_STATUS.md 3.6 resolves it by moving the gold
   BEHIND the numeral instead of inside it: each numeral now sits on a gold
   rounded plate with a DARK numeral on top, at 8.64:1.

   The plate is deliberately the poster's "gold rounded header bar per module,
   mint rounded panel beneath" motif (PROJECT_BRIEF.md 6) — the gold sits on
   top of the cell and the grey caption sits beneath it, so the band still
   reads as the page's gold moment.

   Still deliberately NO circle badges (guide 4.3 dropped them), and the
   order is fixed: 30x -> 1000x -> 40x -> +17dB (non-negotiable #11).
   -------------------------------------------------------------------------- */

.mars-stats {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(1rem, 3vw, 2.25rem);
  margin: 0;
  padding: 0;
  list-style: none;      /* it is a <ul> for semantics, not for bullets */
}

.mars-stat { text-align: center; }

/* The gold PLATE. Gold is the background; the numeral on it is --dark. */
.mars-stat__num {
  display: block;
  background: var(--gold);
  border-radius: var(--radius);
  padding: 0.55rem 0.5rem 0.6rem;
  font-family: var(--font-head);
  font-weight: 700;
  font-size: clamp(1.9rem, 4.1vw, 2.75rem);
  line-height: 1.1;
  color: var(--dark);            /* DARK on GOLD = 8.64:1 */
  letter-spacing: -0.02em;
}

.mars-stat__cap {
  display: block;
  margin-top: 0.55rem;
  font-size: 0.875rem;
  line-height: 1.4;
  color: var(--grey);
}

@media (max-width: 720px) {
  .mars-stats { grid-template-columns: repeat(2, 1fr); row-gap: 1.75rem; }
}

/* --------------------------------------------------------------------------
   Cards — Contributions (Theory = BLUE, Simulator = GREEN)
   -------------------------------------------------------------------------- */

.mars-cards {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.25rem;
}
@media (max-width: 760px) { .mars-cards { grid-template-columns: 1fr; } }

.mars-card {
  background: var(--mint);
  border: 2px solid var(--rule);
  border-radius: var(--radius);
  padding: 1.35rem 1.4rem;
}
.mars-card.is-theory    { border-color: var(--blue); }
.mars-card.is-simulator { border-color: var(--green); }

.mars-card__title {
  font-size: 1.125rem;
  font-weight: 600;
  margin: 0 0 0.65rem;
}
.mars-card__list {
  margin: 0 0 1rem;
  padding-left: 1.1rem;
  font-size: 0.9375rem;
  color: var(--dark);
}
.mars-card__list li { margin-bottom: 0.3rem; }
.mars-card__link {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 0.9375rem;
  text-decoration: none;
}
.mars-card.is-theory    .mars-card__link { color: var(--blue); }
.mars-card.is-simulator .mars-card__link { color: var(--green); }

/* --------------------------------------------------------------------------
   Switch bar — the site's signature interaction
   Markup contract: WEBSITE_BUILD_STATUS.md section 3.4. Panels toggle via the
   `hidden` attribute plus `.is-active`, NEVER style.display.
   -------------------------------------------------------------------------- */

.mars-switch {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin: 0 0 1.1rem;
}

.mars-switch__pill {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 0.875rem;
  padding: 0.42rem 0.95rem;
  border-radius: var(--radius-pill);
  border: 1.5px solid var(--aged);
  background: transparent;
  color: var(--grey);
  cursor: pointer;
  white-space: nowrap;
}
.mars-switch__pill:hover { background: var(--gold-soft); color: var(--dark); }

/* Active: gold FILL, aged border, dark text. */
.mars-switch__pill.is-active {
  background: var(--gold);
  border-color: var(--aged);
  color: var(--dark);
}

.mars-panel[hidden] { display: none; }

.mars-panel__title {
  font-size: 1.1875rem;
  margin: 0 0 0.5rem;
}
.mars-panel__desc {
  max-width: 68ch;
  margin: 0 0 1.1rem;
}

/* --------------------------------------------------------------------------
   Media slots — 16:9 boxes that never reflow
   Markup contract: WEBSITE_BUILD_STATUS.md section 3.3.

   The placeholder is drawn by the FIGURE, not by the video: the <video> sits
   transparently on top, so with assets/media/ empty the labelled 16:9 frame
   shows through and there is no broken-media icon and no layout shift.
   -------------------------------------------------------------------------- */

.mars-media { margin: 0; }
/* Stage 01 stacks two slots in Theory and two in Simulator; stage 02 moves
   them into switch panels. Either way, consecutive slots need separation. */
.mars-media + .mars-media { margin-top: 1.25rem; }

.mars-media__frame {
  position: relative;
  aspect-ratio: 16 / 9;
  width: 100%;
  background: var(--mint);
  border: 1.5px dashed #c9b998;
  border-radius: var(--radius);
  overflow: hidden;
  display: grid;
  place-items: center;
}

.mars-band.is-mint .mars-media__frame { background: #e2eee6; }

/* the "animation not built yet" label, sitting under the video layer */
.mars-media__placeholder {
  text-align: center;
  padding: 1rem;
  font-family: var(--font-head);
  font-size: 0.8125rem;
  font-weight: 500;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--aged-fg);
  pointer-events: none;
}
.mars-media__placeholder small {
  display: block;
  margin-top: 0.35rem;
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--grey);
}

.mars-media__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: transparent;      /* nothing painted until media actually loads */
}

/* set by js/mars-media.js once a source has genuinely loaded */
.mars-media.has-media .mars-media__placeholder { display: none; }
.mars-media.has-media .mars-media__frame {
  border-style: solid;
  border-color: var(--rule);
  background: var(--paper);
}

.mars-media__caption {
  margin-top: 0.6rem;
  font-size: 0.875rem;
  color: var(--grey);
}

/* The animation's own burned-in title, repeated here as REAL text (§3.2,
   revised 2026-09-13). Not a duplicate: text inside a video cannot be
   selected, translated, searched or read by a screen reader, and at a 375 px
   viewport the media frame is only 343 CSS px wide, so the burned-in plot
   furniture is decorative anyway. The caption is what carries the point to a
   phone reader and to assistive technology; the burned-in title is what keeps
   the file self-contained when someone downloads it. Both, always.
   Deliberately NOT gold: this sits on PAPER inside a mint frame's figure, and
   --dark keeps it out of the --aged-fg mint-surface list entirely. */
.mars-media__title {
  color: var(--dark);
  font-weight: 700;
}

/* --------------------------------------------------------------------------
   Figures (static images) and tables
   -------------------------------------------------------------------------- */

.mars-figure { margin: 0 0 1.25rem; }
.mars-figure img {
  width: 100%;
  border-radius: var(--radius);
  border: 1px solid var(--rule);
  background: var(--paper);
}
.mars-figure__caption {
  margin-top: 0.55rem;
  font-size: 0.875rem;
  color: var(--grey);
}

/* --------------------------------------------------------------------------
   The hook figure — stage 1.5.

   One figure, one caption line, sitting between the four gains and the content
   bands. It is `.mars-figure` plus a `.mars-hook` modifier rather than a new
   component, so stage 02's static poster graphics keep the same base styling.

   The caption is the page's one-line argument, so it is set larger and darker
   than a normal figure caption and centred under the image. It is NOT a
   `.mars-eq` and carries no numbers — see the markup comment in index.html for
   why the teaser's timings stay off this caption.
   -------------------------------------------------------------------------- */

.mars-hook {
  max-width: 900px;
  margin: 0 auto;
}
.mars-hook img { border: 0; }

.mars-hook__caption {
  margin-top: 0.9rem;
  text-align: center;
  font-family: var(--font-head);
  font-weight: 500;
  font-size: clamp(1rem, 2.2vw, 1.1875rem);
  line-height: 1.45;
  color: var(--dark);            /* DARK on PAPER = 15.89:1 */
}

/* EVERY data table scrolls inside its own container, never the page body. */
.mars-table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--paper);
}

.mars-table {
  border-collapse: collapse;
  width: 100%;
  min-width: 34rem;
  font-size: 0.9375rem;
}
.mars-table th,
.mars-table td {
  padding: 0.55rem 0.85rem;
  text-align: left;
  border-bottom: 1px solid var(--rule);
  white-space: nowrap;
}
.mars-table thead th {
  font-family: var(--font-head);
  font-weight: 600;
  background: var(--mint);
  color: var(--dark);
}
.mars-table tbody tr:last-child td { border-bottom: 0; }
/* `> *` rather than `td`: stage 02's tables put the model name in a
   <th scope="row"> so screen readers announce it with every cell, and a
   `td`-only selector left that first cell unwashed on the MaRS row. */
.mars-table tr.is-ours > * { background: var(--gold-soft); font-weight: 600; }

/* --------------------------------------------------------------------------
   The one display equation on the whole site.
   `.mars-eq` is the sanctioned display-equation container and there must be
   EXACTLY ONE of it across every HTML file. tools/audit_claims.py counts them
   and fails on more than one. Stage 01 creates ZERO.
   -------------------------------------------------------------------------- */

.mars-eq {
  margin: 1.25rem 0;
  padding: 1.1rem 1.25rem;
  background: var(--mint);
  border-left: 4px solid var(--gold);
  border-radius: var(--radius);
  font-family: var(--font-mono);
  font-size: 1.0625rem;
  overflow-x: auto;
}

/* STAGE 02. The equation lives in the Theory band, which is MINT, so the
   mint ground above made it disappear into the band and left only the gold
   bar. Paper here, exactly as .mars-media__frame and .mars-table-wrap already
   do on a mint band, so it reads as a panel. .mars-eq stays in the MINT
   SURFACES list at the top of this file: it carries no gold text, and
   --aged-text measures 5.33:1 on paper, so nothing regresses either way. */
.mars-band.is-mint .mars-eq {
  background: var(--paper);
  border: 1px solid var(--rule);
  border-left: 4px solid var(--gold);
}

/* The law itself, one step up in size and kept on one line — an equation
   broken mid-expression is worse than one the container scrolls. .mars-eq is
   already overflow-x: auto, so the page body never scrolls sideways. */
.mars-eq__law {
  display: block;
  font-size: clamp(1.0625rem, 2.4vw, 1.375rem);
  white-space: nowrap;
}

/* --------------------------------------------------------------------------
   STAGE 02 COMPONENTS
   Four new patterns, all needed by the six content bands and none of them
   expressible with what stage 01 shipped. Nothing here paints a NEW mint
   surface, so the MINT SURFACES list at the top of this file is unchanged —
   every one of these inherits its ground from the band it sits in, and the
   audit's pass 3 checks an unpinned rule against BOTH paper and mint.
   -------------------------------------------------------------------------- */

/* 1. Sub-blocks — the METHOD / RESULTS pairs in Theory and Simulator
   (guide 4.7-4.8). The section's own <h2> stays the top level, so a sub-block
   heading is one step down; inheriting .mars-section__title's size would make
   the hierarchy read flat. */

.mars-subsection { margin-top: 2rem; }
.mars-subsection + .mars-subsection { margin-top: 2.75rem; }

.mars-subhead {
  font-size: clamp(1.1875rem, 2.2vw, 1.5rem);
  margin: 0 0 0.75rem;
}

/* 2. Two figures side by side — the covariance pair in Theory Method, where
   the two panels are evidence for one point and read better together than
   stacked. Collapses to one column before either gets too small to read. */

.mars-figrow {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.25rem;
}
@media (max-width: 760px) {
  .mars-figrow { grid-template-columns: 1fr; }
}
.mars-figrow > .mars-figure:last-child { margin-bottom: 0; }

/* 3. Result-tile strips — Utility "Visual results". Five 720x720 tiles per row
   (ground truth plus four simulators), one row for reflectivity and one for
   depth. Each tile keeps its own visible label, so the row still reads once it
   has wrapped, and its own alt text, so a screen reader gets a finding per
   tile rather than one caption for ten images. */

.mars-tiles {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 0.6rem;
  margin: 0 0 0.6rem;
}
@media (max-width: 880px) {
  .mars-tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
@media (max-width: 540px) {
  .mars-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

.mars-tile { margin: 0; }
.mars-tile img {
  display: block;
  width: 100%;
  height: auto;
  border: 1px solid var(--rule);
  border-radius: var(--radius);
  background: var(--paper);
}
/* NOT text-transform: uppercase, deliberately. One of these labels is
   "MaRS", and uppercasing it renders "MARS" on screen — which breaks the
   casing convention even though the SOURCE spells it correctly and so passes
   the auditor's grep. Sentence case throughout instead. */
.mars-tile__label {
  display: block;
  margin: 0 0 0.3rem;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 0.8125rem;
  letter-spacing: 0.02em;
  color: var(--grey);            /* GREY on PAPER 6.65:1 / on MINT 6.24:1 */
}

/* 4. A caption under a data table. Deliberately a sibling of
   .mars-table-wrap rather than a <caption> inside the table: the wrapper is
   the horizontal scroller with a 34rem min-width, so a caption inside it
   would be dragged to that width and scroll away with the table. Each table
   still carries a visually-hidden <caption> for its accessible name. */

.mars-figure > .mars-table-wrap { margin-bottom: 0; }

/* --------------------------------------------------------------------------
   Stage placeholder — removed by stage 02, and audited for in stage 06
   -------------------------------------------------------------------------- */

.mars-todo {
  margin: 0.75rem 0 1.25rem;
  padding: 0.7rem 1rem;
  border: 1.5px dashed var(--grey);
  border-radius: var(--radius);
  color: var(--grey);
  font-style: italic;
  font-size: 0.9375rem;
  background: repeating-linear-gradient(
    45deg, transparent, transparent 10px,
    rgba(90, 90, 90, 0.045) 10px, rgba(90, 90, 90, 0.045) 20px);
}

/* --------------------------------------------------------------------------
   Limitations
   -------------------------------------------------------------------------- */

.mars-limitations__body {
  max-width: 70ch;
  color: var(--dark);
}

/* --------------------------------------------------------------------------
   Closing BibTeX + footer band — INK USE 2 OF 2
   -------------------------------------------------------------------------- */

.mars-closing__title {
  color: var(--ink-accent);      /* GOLD text on INK: 9.36:1 */
  font-size: clamp(1.5rem, 3vw, 1.875rem);
  margin: 0 0 1rem;
}

.mars-code {
  position: relative;
  background: #0d1113;
  border: 1px solid #2a3236;
  border-radius: var(--radius);
  padding: 1.1rem 1.15rem;
  overflow-x: auto;
}
.mars-code pre {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.84375rem;
  line-height: 1.6;
  color: #dce3e1;
  white-space: pre;
}
.mars-code__copy {
  position: absolute;
  top: 0.6rem; right: 0.6rem;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 0.78125rem;
  padding: 0.35rem 0.7rem;
  border-radius: 6px;
  border: 1px solid var(--gold);
  background: transparent;
  color: var(--ink-accent);      /* GOLD text on #0d1113: 9.94:1 */
  cursor: pointer;
}
.mars-code__copy:hover { background: var(--gold); color: var(--ink); }
.mars-code__copy.is-done { background: var(--gold); color: var(--ink); }

.mars-closing__note {
  margin: 0.7rem 0 0;
  font-size: 0.8125rem;
  color: #9aa2a0;
}

.mars-closing__rule {
  border: 0;
  border-top: 1px solid #2a3236;
  margin: 2rem 0 1.25rem;
}

.mars-closing__links {
  text-align: center;
  font-size: 0.9375rem;
  color: #b9c0bd;
  margin: 0 0 1rem;
}
.mars-closing__links a { color: var(--ink-accent); text-decoration: none; }
.mars-closing__links a:hover { color: #e2d3b6; text-decoration: underline; }
/* #4a5256 measured 2.24:1 on ink. Bumped to the same grey the muted
   footer text already uses (4.73:1) — still clearly quieter than the
   links it separates, but no longer a contrast failure. Stage 1.5. */
.mars-closing__links .sep { color: #7d8583; margin: 0 0.5rem; }

.mars-closing__footer {
  text-align: center;
  font-size: 0.8125rem;
  line-height: 1.7;
  color: #9aa2a0;
  margin: 0;
}

/* --------------------------------------------------------------------------
   Video lightbox
   -------------------------------------------------------------------------- */

.mars-lightbox {
  position: fixed;
  inset: 0;
  z-index: 300;
  background: rgba(10, 13, 15, 0.9);
  display: grid;
  place-items: center;
  padding: clamp(1rem, 4vw, 3rem);
}
.mars-lightbox[hidden] { display: none; }

.mars-lightbox__body {
  width: 100%;
  max-width: 1100px;
}
.mars-lightbox__body video,
.mars-lightbox__body iframe {
  width: 100%;
  aspect-ratio: 16 / 9;
  height: auto;
  border: 0;
  border-radius: var(--radius);
  background: #000;
}
.mars-lightbox__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 0.6rem;
  color: #e7eae9;
  font-family: var(--font-head);
  font-size: 0.9375rem;
}
.mars-lightbox__close {
  background: transparent;
  border: 1px solid #4a5256;
  border-radius: 8px;
  color: #e7eae9;
  font-size: 0.9375rem;
  padding: 0.35rem 0.8rem;
  cursor: pointer;
}
.mars-lightbox__close:hover { border: 1px solid var(--gold);
                              color: var(--ink-accent); }
.mars-lightbox__srt { color: var(--ink-accent); font-size: 0.8125rem; }

/* ==========================================================================
   Demo lab (demos/index.html)
   The ink sidebar beside a light content area is the DELIBERATE contrast with
   the article-like main page — "you're in the lab now". Do not "fix" it.
   ========================================================================== */

.mars-lab {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.mars-lab__strip {
  background: var(--paper);
  border-bottom: 1px solid var(--rule);
  padding: 0.65rem clamp(1rem, 3vw, 1.5rem);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
}
.mars-lab__back {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 0.9375rem;
  color: var(--aged-fg);
  text-decoration: none;
}
.mars-lab__back:hover { color: var(--dark); }
.mars-lab__label {
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 0.875rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--grey);
}

.mars-lab__body {
  flex: 1;
  display: flex;
  align-items: stretch;
  min-height: 0;
}

/* INK — the third and only other sanctioned ink surface, on this page only. */
.mars-lab__sidebar {
  flex: 0 0 165px;
  background: var(--ink);
  padding: 1.1rem 0.7rem;
}
.mars-lab__nav {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.mars-lab__item {
  width: 100%;
  display: block;
  text-align: left;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 8px;
  padding: 0.55rem 0.6rem;
  color: #cfd4d2;
  font-family: var(--font-head);
  font-size: 0.8125rem;
  font-weight: 500;
  line-height: 1.3;
  cursor: pointer;
}
.mars-lab__item:hover { background: var(--ink-soft); color: #fff; }
.mars-lab__item[aria-current="true"] {
  background: var(--ink-soft);
  border: 1px solid var(--gold);   /* a border is a FILL role; written as the
                                      shorthand so the fill-only grep in
                                      stage_015 W1 stays exact */
  color: #fff;
}
.mars-lab__tag {
  display: block;
  margin-top: 0.25rem;
  font-family: var(--font-body);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.mars-lab__tag.is-live { color: var(--ink-accent); }
.mars-lab__tag.is-soon { color: #7d8583; font-weight: 400; }

.mars-lab__main {
  flex: 1;
  min-width: 0;
  background: var(--paper);
  padding: clamp(1.25rem, 3vw, 2.25rem);
}
.mars-lab__panel[hidden] { display: none; }
.mars-lab__panel h1 {
  font-size: clamp(1.375rem, 3vw, 1.75rem);
  margin: 0 0 0.35rem;
}

.mars-lab__caveat {
  margin: 0 0 1.25rem;
  padding: 0.7rem 1rem;
  background: var(--mint);
  border-left: 4px solid var(--aged);
  border-radius: 0 var(--radius) var(--radius) 0;
  font-size: 0.9375rem;
  color: var(--dark);
}

.mars-lab__status {
  display: inline-block;
  font-family: var(--font-head);
  font-weight: 600;
  font-size: 0.75rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.22rem 0.6rem;
  border-radius: var(--radius-pill);
  margin-bottom: 0.9rem;
}
.mars-lab__status.is-live { background: var(--gold); color: var(--ink); }
.mars-lab__status.is-soon { background: #e6e8e7; color: var(--grey); }

#playground-root {
  min-height: 320px;
  border: 1.5px dashed #c9b998;
  border-radius: var(--radius);
  background: var(--mint);
  display: grid;
  place-items: center;
  padding: 1.5rem;
  text-align: center;
  color: var(--aged-fg);
  font-family: var(--font-head);
  font-size: 0.875rem;
}

@media (max-width: 700px) {
  .mars-lab__body { flex-direction: column; }
  .mars-lab__sidebar { flex: 0 0 auto; padding: 0.7rem; }
  .mars-lab__nav { flex-direction: row; flex-wrap: wrap; }
  .mars-lab__item { width: auto; }
}

/* --------------------------------------------------------------------------
   Reduced motion — suppress every autoplay and transition
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
