:root {
  --c-ink: #14171A;
  --c-ink-muted: #4E555B;
  --c-surface: #F0F1F0;
  --c-surface-alt: #DDE3E5;
  --c-surface-deep: #191D21;
  --c-surface-deep-ink: #E9ECEB;
  --c-accent: #F0C000;
  --c-accent-ink: #14171A;
  --c-accent-soft: #FBEFC2;
  --c-line: #9AA2A5;
  --c-accent-2: #1F5C7A;
  --c-accent-text-dark: #F0C000;
  --font-display: 'Big Shoulders Display', 'Arial Narrow', Arial, sans-serif;
  --font-body: Archivo, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --display-weight: 800;
  --display-transform: uppercase;
  --display-tracking: 0.005em;
  --scale-ratio: 1.25;
  --section-rhythm: 6rem;
  --radius: 0;
  --border-weight: 2px;
}

/* ==========================================================================
   THE FRAME — component layer for the feeder network.

   Theme packs supply only tokens (build.py emits them as :root custom
   properties above this file). Everything below is shared, reviewed once, and
   identical across all sites — so a theme change can restyle a site but can
   never break its layout.

   Hard constraints, all deliberate:
     - Zero JavaScript. AI crawlers execute none, so nothing may depend on it.
     - Zero external requests. Fonts are self-hosted WOFF2.
     - No animation that hides content at rest; screenshots and crawlers must
       see the finished page.
     - text-transform: capitalize is never used. It mangled prose in 2025.
   ========================================================================== */

/* --- Self-hosted variable fonts (SIL OFL 1.1) ---------------------------- */

@font-face {
  font-family: 'Big Shoulders Display';
  src: url('../fonts/BigShouldersDisplay-latin.woff2') format('woff2');
  font-weight: 100 900;
  font-display: swap;
  font-style: normal;
}

@font-face {
  font-family: 'Archivo';
  src: url('../fonts/Archivo-latin.woff2') format('woff2');
  font-weight: 100 900;
  font-display: swap;
  font-style: normal;
}

/* --- Derived scale ------------------------------------------------------- */

:root {
  --bay-1: 0.5rem;
  --bay-2: 1rem;
  --bay-3: 1.5rem;
  --bay-4: 2.5rem;
  --bay-5: 4rem;
  --bay-6: 6rem;
  --bay-7: 8rem;

  --measure: 68ch;
  --container: 75rem;
  --gutter: var(--bay-3);

  /* One descending ramp. Every size on the page comes from this list — an
     ad-hoc literal is how forty sibling sites drift out of alignment. */
  --step-nano: 0.6875rem;   /* title-block cell labels, brand subtitle */
  --step-label: 0.75rem;    /* all labels, buttons, table headers, nav */
  --step-small: 0.875rem;   /* methodology, disclosure, notes, citations */
  --step-caption: 0.9375rem;/* figure captions, title-block values */
  --step-0: 1.0625rem;      /* body */
  --step-1: 1.1875rem;      /* title */
  --step-2: 1.4375rem;      /* lede, answer capsule */
  --step-brand: 1.5rem;     /* wordmark */
  --step-num: 2rem;         /* process step numerals */
  --step-3: clamp(1.75rem, 3.4vw, 2.9rem);  /* headline */
  --step-4: clamp(2.75rem, 7vw, 6rem);      /* display */

  /* Third-party marks are supplied on white and contain white; see .credplate. */
  --c-plate-white: #ffffff;

  --rule-beam: 3px;
  --rule-hair: 1px;
  --rule-load: 6px;

  --ease: cubic-bezier(0.16, 0.84, 0.44, 1);
}

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

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

* {
  margin: 0;
}

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

body {
  background: var(--c-surface);
  color: var(--c-ink);
  font-family: var(--font-body);
  font-size: var(--step-0);
  font-weight: 400;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

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

table {
  border-collapse: collapse;
  width: 100%;
}

/* --- Typography roles --------------------------------------------------- */

.t-display,
.t-headline {
  font-family: var(--font-display);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  text-wrap: balance;
}

.t-display {
  font-size: var(--step-4);
  line-height: 0.92;
  text-transform: var(--display-transform);
}

.t-headline {
  font-size: var(--step-3);
  line-height: 1;
}

.t-title {
  font-family: var(--font-body);
  font-size: var(--step-1);
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.005em;
  text-wrap: balance;
}

.t-label {
  font-family: var(--font-body);
  font-size: var(--step-label);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* Every numeral a reader might compare against another numeral. */
.t-figure,
.dim__value,
.ptable td,
.ptable th,
.spec__value,
.spec td {
  font-variant-numeric: tabular-nums slashed-zero;
  font-feature-settings: 'tnum' 1, 'zero' 1;
}

.prose {
  max-width: var(--measure);
}

.prose > * + * {
  margin-top: var(--bay-2);
}

.lede {
  font-size: var(--step-2);
  line-height: 1.45;
  max-width: 60ch;
}

/* Secondary text is surface-aware. On a dark ground it is tinted from the
   surface's own foreground, never left as the light-ground grey (which renders
   at roughly 1.5:1 on mill scale — effectively invisible). */
.muted {
  color: var(--muted-ink, var(--c-ink-muted));
}

/* De-emphasis derived from the inherited text colour rather than from a fixed
   token. Correct on any ground — including inside a dark table header, where a
   light-ground muted grey fails contrast outright. */
.note-inline {
  color: color-mix(in srgb, currentColor 72%, transparent);
  font-weight: 400;
}

.band--mill,
.masthead,
.hero,
.titleblock {
  --muted-ink: color-mix(in srgb, var(--c-surface-deep-ink) 74%, var(--c-surface-deep));
}

/* Link colour is inherited through a variable so a dark region can override it
   for every descendant at once. Chalk-line blue reads 6.5:1 on slab but only
   2.3:1 on mill scale, so dark surfaces switch to chalk. */
a {
  color: var(--link, var(--c-accent-2, var(--c-ink)));
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}

.band--mill,
.masthead,
.hero,
.titleblock {
  --link: var(--c-surface-deep-ink);
}

a:hover {
  text-decoration-thickness: 2px;
}

:where(a, button, summary, [tabindex]):focus-visible {
  outline: var(--rule-beam) solid var(--link, var(--c-accent-2, var(--c-ink)));
  outline-offset: 2px;
}

/* --- Layout ------------------------------------------------------------- */

.wrap {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.band {
  padding-block: var(--section-rhythm);
  border-top: var(--rule-beam) solid var(--c-surface-deep);
}

/* The hero owns the top of the page; no rule above it. */
.band--hero {
  border-top: 0;
  padding-block: 0;
}

.band--slab {
  background: var(--c-surface);
}

.band--zinc {
  background: var(--c-surface-alt);
}

.band--mill {
  background: var(--c-surface-deep);
  color: var(--c-surface-deep-ink);
}

.band__head {
  max-width: 46rem;
}

.band__head > * + * {
  margin-top: var(--bay-2);
}

/* More space above a heading than below it, everywhere. */
.band__body {
  margin-top: var(--bay-5);
}

.band__body > * + * {
  margin-top: var(--bay-4);
}

/* Prose beside a supporting figure. */
.split {
  display: grid;
  grid-template-columns: minmax(0, 1.45fr) minmax(0, 1fr);
  gap: var(--bay-5);
  align-items: start;
}

.split > * + * {
  margin-top: 0;
}

.figure {
  margin: 0;
  border: var(--rule-hair) solid var(--c-line);
  border-top: var(--rule-beam) solid var(--c-surface-deep);
}

.figure img {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}

.figure__caption {
  padding: var(--bay-2);
  font-size: var(--step-small);
  color: var(--muted-ink, var(--c-ink-muted));
}

.bullets {
  max-width: var(--measure);
  padding-left: var(--bay-3);
}

.bullets > li + li {
  margin-top: var(--bay-1);
}

.grid {
  display: grid;
  gap: var(--bay-3);
}

/* Semantic lists that carry no bullet in presentation. */
.plain,
.gallery,
.grid.plain {
  list-style: none;
  padding-left: 0;
}

.grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid--4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

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

.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--bay-1);
  padding: 1.125rem 2rem;
  border: var(--border-weight) solid transparent;
  border-radius: var(--radius);
  font-family: var(--font-body);
  font-size: var(--step-label);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 0.18s var(--ease), color 0.18s var(--ease),
              border-color 0.18s var(--ease);
}

/* The one action colour. If a second element wants it, the first wasn't the action. */
.btn--primary {
  background: var(--c-accent);
  border-color: var(--c-accent);
  color: var(--c-accent-ink);
}

/* Hover text resolves through --c-accent-text-dark: the accent itself where it
   passes AA as text on a dark field, deep ink where it does not (a primer-red
   accent reads ~3.4:1 on near-black — a legal mark, illegible small text). The
   token is derived at build time; see build.py accent_text_dark(). */
.btn--primary:hover {
  background: var(--c-ink);
  border-color: var(--c-ink);
  color: var(--c-accent-text-dark, var(--c-accent));
}

.btn--secondary {
  background: transparent;
  border-color: currentColor;
  color: inherit;
}

.btn--secondary:hover {
  background: var(--c-ink);
  border-color: var(--c-ink);
  color: var(--c-surface);
}

.band--mill .btn--secondary:hover {
  background: var(--c-surface-deep-ink);
  border-color: var(--c-surface-deep-ink);
  color: var(--c-surface-deep);
}

.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--bay-2);
}

.actions__note {
  font-size: var(--step-small);
  color: var(--muted-ink, var(--c-ink-muted));
}

/* --- Dimension string (signature) --------------------------------------- */
/* A shop-drawing annotation: tick, extension line, measurement, line, tick. */

.dim {
  display: flex;
  align-items: center;
  width: 100%;
  color: currentColor;
}

.dim__tick {
  flex: 0 0 auto;
  width: 1px;
  height: 0.875rem;
  background: currentColor;
}

.dim__line {
  flex: 1 1 auto;
  height: 1px;
  background: currentColor;
}

.dim__value {
  flex: 0 1 auto;
  min-width: 0;
  padding-inline: var(--bay-2);
  font-size: var(--step-label);
  font-weight: 600;
  letter-spacing: 0.08em;
}

/* A short measurement stays on one line; a longer note wraps rather than
   running off the edge of a 390px screen. */
.dim--measure .dim__value {
  white-space: nowrap;
}

/* --- Credential strip --------------------------------------------------- */
/* One data plate bolted into the title block, not three stickers on it.
   Separate plates made three objects where the design needs one set, and
   content-sized plates guaranteed unequal widths, which is what wrecked the
   phone-width stack. A single white field with ruled cells is the metaphor the
   title block already commits to.

   Marks are optically normalised at BUILD TIME (see build.py OPTICAL_AREA_K),
   so every mark arrives on an identical canvas and the CSS here needs no
   per-logo values — a fourth credential normalises itself. */

.creds {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  background: var(--c-plate-white);
  border: 0;
  border-radius: 0;
  padding: 0;
  margin: 0;
  list-style: none;

  /* A light island inside a dark region. Both surface-aware tokens must be
     re-resolved here or the captions inherit the footer's chalk values and ship
     at roughly 1.5:1 on white. */
  --muted-ink: var(--c-ink-muted);
  --link: var(--c-accent-2);
  color: var(--c-ink);
}

.creds > li {
  display: flex;
}

.creds > li + li {
  border-left: var(--rule-hair) solid var(--c-line);
}

/* The cell padding IS the clear-space guarantee: roughly 40px between
   neighbouring marks, comfortably over each organisation's published minimum. */
.credplate {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--bay-1);
  padding: var(--bay-2) var(--bay-3) var(--bay-3);
  border: 0;
  background: transparent;
  text-decoration: none;
  transition: background-color 0.18s var(--ease);
}

/* Hover is the wayfinding colour, not safety yellow. These are verify links —
   something you follow, not the action you take. */
.credplate:hover,
.credplate:focus-visible {
  background: color-mix(in srgb, var(--c-accent-2) 8%, transparent);
}

/* 7rem is the CANVAS height, not the mark height. Each canvas is 176x112 at 1x
   with the mark optically sized inside it, so this renders the marks at their
   intended 44-65px while the clear space comes along for free. Setting this to
   the old 3.5rem scaled the whole canvas down and made every mark half-size. */
.credplate img {
  width: auto;
  max-width: 100%;
  height: 12rem;
  object-fit: contain;
}

/* The credential's actual payload. Without it the footer emitted no credential
   text at all, leaving the member ID legible only to sighted users with good
   eyes — not to a screen reader user browsing visually, and not to a retrieval
   system, which is a named consumer of this markup. */
.credplate__caption {
  font-size: var(--step-nano);
  font-weight: 600;
  letter-spacing: 0.1em;
  line-height: 1.35;
  text-transform: uppercase;
  text-align: center;
  font-variant-numeric: tabular-nums;
  color: var(--muted-ink);
  transition: color 0.18s var(--ease);
}

.credplate:hover .credplate__caption,
.credplate:focus-visible .credplate__caption {
  color: var(--link);
}

/* Text-only fallback for a credential whose mark we do not hold. */
.creds .credlink {
  display: inline-flex;
  align-items: baseline;
  gap: 0.4em;
  font-size: var(--step-label);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  border-bottom: 1px solid currentColor;
  padding-bottom: 2px;
}

.creds .credlink::after {
  content: '\2197';
  font-size: var(--step-nano);
  opacity: 0.7;
}

.creds .credlink:hover {
  border-bottom-width: var(--border-weight);
}

/* Same apparatus rotated 90 degrees at phone width — the move the Restacked
   Table signature already established, so the footer inherits a committed
   pattern instead of inventing one. */
@media (max-width: 720px) {
  .creds {
    grid-template-columns: minmax(0, 1fr);
  }

  .creds > li + li {
    border-left: 0;
    border-top: var(--rule-hair) solid var(--c-line);
  }

  .credplate {
    padding: var(--bay-3) var(--bay-2);
  }

  .credplate img {
    height: auto;
    width: min(74vw, 300px);
    max-width: 100%;
  }
}

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

.hero {
  position: relative;
  background: var(--c-surface-deep);
  color: var(--c-surface-deep-ink);
}

.hero__media {
  position: absolute;
  inset: 0;
  overflow: hidden;
}

.hero__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* A genuine scrim. Text over photography needs a real gradient, not a wash. */
.hero__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to right,
    color-mix(in srgb, var(--c-surface-deep) 92%, transparent) 0%,
    color-mix(in srgb, var(--c-surface-deep) 82%, transparent) 45%,
    color-mix(in srgb, var(--c-surface-deep) 40%, transparent) 100%
  );
}

.hero__inner {
  position: relative;
  padding-block: var(--bay-7) var(--bay-6);
}

.hero__content {
  max-width: 40rem;
}

.hero__content > * + * {
  margin-top: var(--bay-3);
}

/* The eyebrow and dimension string are wayfinding text, not the action, so
   they no longer spend the accent at all. The accent's sanctioned uses are
   the primary button, the load rule and the active nav marker ("Nothing
   else" — DESIGN.md); an accent eyebrow beside an accent dim beside an
   accent button was three spends in one viewport, found on the derrick
   heroes by the 2026-07-30 review. */
.hero__eyebrow {
  color: var(--muted-ink, var(--c-ink-muted));
}

.hero__sub {
  font-size: var(--step-2);
  line-height: 1.45;
  color: color-mix(in srgb, var(--c-surface-deep-ink) 88%, var(--c-surface-deep));
}

.hero__dim {
  max-width: 30rem;
  margin-top: var(--bay-4);
  color: var(--c-surface-deep-ink);
}

.hero__creds {
  margin-top: var(--bay-4);
  padding-top: var(--bay-3);
  border-top: 1px solid color-mix(in srgb, var(--c-surface-deep-ink) 30%, transparent);
}

/* The credential row, in text.
   `.credline` had markup and no rule at all, so it shipped as a browser-default
   <ul>: three disc bullets and a 40px indent, over the hero photography, on
   every page of every site. The marks themselves live in the title block; what
   this row is for is the member ID as readable text — the one thing on the page
   a reader can go and check, and a string a retrieval system can lift.
   Separators are drawn from currentColor so the row works on any ground. */
.credline {
  display: flex;
  flex-wrap: wrap;
  list-style: none;
  padding: 0;
  margin: 0;
}

.credline > li {
  display: flex;
  align-items: center;
}

.credline > li + li::before {
  content: "";
  align-self: stretch;
  width: 1px;
  margin-inline: var(--bay-2);
  background: color-mix(in srgb, currentColor 32%, transparent);
}

.credline a {
  font-size: var(--step-label);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, currentColor 45%, transparent);
  padding-bottom: 2px;
}

.credline a:hover,
.credline a:focus-visible { border-bottom-color: var(--c-accent); }

/* Stacked on a phone: three of these do not fit on one line, and a wrapped flex
   row puts a separator rule at the start of the second line. */
@media (max-width: 560px) {
  .credline {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--bay-1);
  }
  .credline > li + li::before { content: none; }
}

/* --- Answer capsule ----------------------------------------------------- */
/* The GEO workhorse: a self-contained answer, first thing under the heading. */

.capsule {
  font-size: var(--step-2);
  line-height: 1.5;
  font-weight: 500;
  max-width: 58ch;
  padding-left: var(--bay-3);
  /* Mill scale on light grounds: safety yellow is only 1.5:1 against slab and
     1.3:1 against zinc, well under the 3:1 non-text minimum. Yellow returns on
     the dark bands, where it reads at 9.9:1. */
  border-left: var(--rule-load) solid var(--c-surface-deep);
}

.band--mill .capsule {
  border-left-color: var(--c-accent);
}

/* --- Callout ------------------------------------------------------------ */

.callout {
  background: var(--c-accent-soft);
  color: var(--c-ink);
  padding: var(--bay-3);
  border-radius: var(--radius);
  max-width: 46rem;
}

.callout__label {
  display: block;
  margin-bottom: var(--bay-1);
  color: var(--muted-ink, var(--c-ink-muted));
}

.callout__cite {
  display: block;
  margin-top: var(--bay-2);
  font-size: var(--step-small);
  color: var(--muted-ink, var(--c-ink-muted));
}

/* --- Cards -------------------------------------------------------------- */
/* A row of these should read as a bolted assembly, not as floating tiles. */

.card {
  background: var(--c-surface);
  border: var(--rule-hair) solid var(--c-line);
  border-top: var(--rule-beam) solid var(--c-surface-deep);
  border-radius: var(--radius);
  padding: var(--bay-3);
}

.band--slab .card {
  background: var(--c-surface-alt);
}

.card > * + * {
  margin-top: var(--bay-2);
}

.card__icon {
  display: block;
  width: 2.25rem;
  height: 2.25rem;
  color: var(--c-surface-deep);
  margin-bottom: var(--bay-1);
}

/* A hairline under the card title, so a row of cards reads as plate with a
   stamped label rather than as text floating in a box. */
.card .t-title {
  padding-bottom: var(--bay-1);
  border-bottom: var(--rule-hair) solid var(--c-line);
}

/* --- Value props: ruled list variant ------------------------------------ */

.vlist {
  list-style: none;
  padding: 0;
  margin: 0;
  border-top: var(--rule-hair) solid var(--c-line);
}

.vlist > li {
  display: grid;
  grid-template-columns: 3rem 1fr;
  gap: var(--bay-3);
  padding-block: var(--bay-3);
  border-bottom: var(--rule-hair) solid var(--c-line);
}

.vlist__mark {
  color: var(--c-surface-deep);
}

.vlist__body > * + * {
  margin-top: var(--bay-1);
}

/* --- Process ------------------------------------------------------------ */
/* Numbered because the sequence itself is the information. */

.steps {
  list-style: none;
  counter-reset: step;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--bay-1);
}

.steps > li {
  counter-increment: step;
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  gap: var(--bay-3);
  padding: var(--bay-3) 0;
  border-top: var(--rule-hair) solid var(--c-line);
}

.steps > li::before {
  content: counter(step, decimal-leading-zero);
  font-family: var(--font-display);
  font-size: var(--step-num);
  font-weight: var(--display-weight);
  line-height: 1;
  color: var(--c-surface-deep);
  font-variant-numeric: tabular-nums;
}

/* Bounded measure: the step column is 1fr of the full wrap, which ran the
   descriptions to roughly 130 characters a line at 1440. */
.steps__body {
  max-width: var(--measure);
}

.steps__body > * + * {
  margin-top: var(--bay-1);
}

/* --- Data tables (signature) -------------------------------------------- */

.tablewrap {
  overflow-x: auto;
  border: var(--rule-hair) solid var(--c-line);
  background: var(--c-surface);
}

.ptable caption,
.spec caption {
  text-align: left;
  padding: var(--bay-3) var(--bay-3) var(--bay-2);
  color: var(--muted-ink, var(--c-ink-muted));
  font-size: var(--step-small);
}

.ptable thead th,
.spec thead th {
  background: var(--c-surface-deep);
  color: var(--c-surface-deep-ink);
  font-family: var(--font-body);
  font-size: var(--step-label);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-align: left;
  padding: 0.875rem var(--bay-2);
  white-space: nowrap;
}

.ptable td,
.spec td {
  padding: 0.875rem var(--bay-2);
  border-top: var(--rule-hair) solid var(--c-line);
  vertical-align: top;
}

.ptable tbody tr:nth-child(even),
.spec tbody tr:nth-child(even) {
  background: color-mix(in srgb, var(--c-surface-alt) 55%, var(--c-surface));
}

.num {
  text-align: right;
  white-space: nowrap;
  font-weight: 500;
}

.ptable .num--price {
  font-weight: 600;
}

.spec__group th {
  background: var(--c-surface-alt);
  color: var(--c-ink);
  font-family: var(--font-body);
  font-size: var(--step-label);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-align: left;
  padding: 0.75rem var(--bay-2);
  border-top: var(--rule-beam) solid var(--c-surface-deep);
}

/* A price table always shows its date and methodology. A number without both
   is a claim, not data. */
.datastamp {
  display: flex;
  flex-wrap: wrap;
  gap: var(--bay-1) var(--bay-3);
  align-items: baseline;
  margin-bottom: var(--bay-3);
  padding-bottom: var(--bay-2);
  border-bottom: var(--rule-load) solid var(--c-surface-deep);
}

.datastamp__date {
  font-size: var(--step-label);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.method {
  margin-top: var(--bay-3);
  max-width: 60ch;
  font-size: var(--step-small);
  color: var(--muted-ink, var(--c-ink-muted));
}

/* The method/inclusions block under a full-width table ran as a 60ch strip
   beside a dead field at 1440. Two columns read as the drawing-notes block
   the apparatus is imitating. Applies to the dl only; a single source-note
   paragraph keeps its measure. */
@media (min-width: 1080px) {
  dl.method {
    max-width: none;
    column-count: 2;
    column-gap: var(--bay-5);
  }

  dl.method dt {
    break-after: avoid;
  }

  dl.method dd {
    break-inside: avoid;
  }
}

.method dt {
  font-size: var(--step-label);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--c-ink);
  margin-top: var(--bay-2);
}

.method dd {
  margin: 0.25rem 0 0;
}

.provisional {
  margin-top: var(--bay-3);
  padding: var(--bay-2) var(--bay-3);
  background: var(--c-accent-soft);
  border-left: var(--rule-load) solid var(--c-surface-deep);
  font-size: var(--step-small);
  color: var(--c-ink);
}

/* --- Comparison --------------------------------------------------------- */

/* Fixed layout so the three systems get equal width. Auto layout sized columns
   by content, which squeezed the tube column to four-line wraps and made the
   emphasised column look wide because it was favoured rather than because it
   matters more. */
.cmp {
  table-layout: fixed;
}

.cmp th:first-child {
  width: 15%;
}

.cmp th[scope='col'] {
  background: var(--c-surface-deep);
  color: var(--c-surface-deep-ink);
  font-size: var(--step-label);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-align: left;
  padding: 0.875rem var(--bay-2);
}

/* Our column is marked, not painted.
   A full safety-yellow field here broke the rule that yellow means "act here"
   — and it cost more than a rule. This page's persuasive power is that it says
   plainly where cold-formed and tube are the right call; a highlighter on our
   own column makes the table read as a sales sheet and undercuts the sentence
   at the bottom that admits the other systems are fine. The 6px yellow edge is
   the system's declared load-bearing marker and says the same thing quietly. */
.cmp th[scope='col'].is-emphasis {
  box-shadow: inset 0 -6px 0 var(--c-accent);
}

.cmp th[scope='row'] {
  text-align: left;
  font-weight: 600;
  padding: 0.875rem var(--bay-2);
  border-top: var(--rule-hair) solid var(--c-line);
  vertical-align: top;
}

.cmp td {
  padding: 0.875rem var(--bay-2);
  border-top: var(--rule-hair) solid var(--c-line);
  vertical-align: top;
}

/* Suitability rating in a comparison matrix.

   Deliberately NOT green ticks and red crosses. That grid is the category
   default, it would fight this page's own fairness note (which tells readers
   when the cheaper system is the right buy), and two states cannot express the
   conditional that most of these rows actually resolve to. The mark is a filled,
   half-filled or open circle in mill scale; the adjacent word carries the
   meaning, so nothing depends on colour.

   Circles, despite the square-corner rule: these are Harvey balls, the standard
   notation for a graded rating in a spec table, and a drawing set already uses
   circles for callout balloons and grid bubbles. The rule governs SURFACES —
   cards, buttons, plates — not notation marks. See DESIGN.md → Shapes. */

.suit {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  margin-bottom: 0.35rem;
}

.suit__mark {
  flex: 0 0 auto;
  width: 0.8rem;
  height: 0.8rem;
  border: 2px solid var(--c-surface-deep);
  border-radius: 50%;
  background: transparent;
  /* Keeps the half-fill gradient inside the circle rather than the border box. */
  overflow: hidden;
}

.suit--suited .suit__mark {
  background: var(--c-surface-deep);
}

.suit--conditional .suit__mark {
  background: linear-gradient(
    to right,
    var(--c-surface-deep) 0 50%,
    transparent 50% 100%
  );
}

.suit__label {
  font-size: var(--step-nano);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.suit--not_suited .suit__label {
  color: var(--muted-ink, var(--c-ink-muted));
}

.suit__text {
  display: block;
}

/* On the emphasised column the mark sits on safety yellow, where mill scale
   still reads at 9.9:1. */
.cmp th[scope='col'].is-emphasis + td .suit__mark {
  border-color: var(--c-surface-deep);
}

.checklist {
  list-style: none;
  padding: 0;
  margin: 0;
  border-top: var(--rule-hair) solid var(--c-line);
}

.checklist > li {
  padding-block: var(--bay-3);
  border-bottom: var(--rule-hair) solid var(--c-line);
}

.checklist__ask {
  font-family: var(--font-body);
  font-size: var(--step-1);
  font-weight: 600;
  line-height: 1.35;
}

.checklist__why {
  margin-top: var(--bay-1);
  max-width: var(--measure);
}

/* Bounded to the same right edge as the `why` above it. Unbounded, the answer
   ran to about 120 characters a line while the question it answers held 68, so
   the two blocks in one entry were set to two different measures. */
.checklist__ours {
  margin-top: var(--bay-2);
  padding-left: var(--bay-3);
  max-width: calc(var(--measure) + var(--bay-3));
  border-left: var(--rule-beam) solid var(--c-surface-deep);
}

.checklist__ours .t-label {
  display: block;
  color: var(--muted-ink, var(--c-ink-muted));
  margin-bottom: 0.25rem;
}

/* The rule belongs to the block; the measure belongs to the prose. Setting both
   on one element sized the beam to the text, so a 3px structural rule stopped
   two thirds of the way across under a full-width comparison table. */
.fairness {
  margin-top: var(--bay-4);
  padding-top: var(--bay-3);
  border-top: var(--rule-beam) solid var(--c-surface-deep);
}

.fairness > p {
  max-width: var(--measure);
  color: var(--muted-ink, var(--c-ink-muted));
}

/* --- Gallery ------------------------------------------------------------ */

.gallery {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--bay-3);
}

/* Tiles stretch so a caption that wraps to two lines does not leave its row
   with a ragged bottom edge. The images are a fixed ratio, so the extra height
   lands in the caption plate, where it reads as a deliberate band. */
.gallery > li {
  display: flex;
}

.gallery figure {
  margin: 0;
  display: flex;
  flex: 1;
  flex-direction: column;
  border: var(--rule-hair) solid var(--c-line);
  background: var(--c-surface);
}

.band--mill .gallery figure {
  border-color: color-mix(in srgb, var(--c-surface-deep-ink) 24%, transparent);
  background: color-mix(in srgb, var(--c-surface-deep-ink) 6%, transparent);
}

.gallery img {
  aspect-ratio: 4 / 3;
  object-fit: cover;
  width: 100%;
}

.gallery figcaption {
  padding: var(--bay-2);
  font-size: var(--step-caption);
}

.gallery__meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.25rem var(--bay-2);
  margin-top: var(--bay-1);
  font-size: var(--step-label);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  color: var(--muted-ink, var(--c-ink-muted));
}

/* --- Example gallery ---------------------------------------------------- */
/* Configuration renders from the design corpus. The renders already carry
   dimension annotations in the same drawing grammar as the rest of this system,
   so they are shown on a light plate that lets that read, not scrimmed. */

.jumpnav {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--bay-1) var(--bay-2);
  padding-bottom: var(--bay-2);
  border-bottom: var(--rule-beam) solid var(--c-surface-deep);
}

.jumpnav__label {
  color: var(--muted-ink, var(--c-ink-muted));
}

.jumpnav ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--bay-1) var(--bay-2);
  list-style: none;
  padding: 0;
  margin: 0;
}

.jumpnav a {
  font-size: var(--step-label);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  border-bottom: 1px solid color-mix(in srgb, currentColor 45%, transparent);
  padding-bottom: 2px;
}

.jumpnav a:hover { border-bottom-color: var(--c-accent); }

/* `scroll-margin-top` so a jump link does not tuck the card under the top of
   the viewport. The anchor sits on the first card of each use-type run. */
.excard[id] { scroll-margin-top: var(--bay-4); }

/* Four up at 1440, three at tablet, one on a phone. The narrower track is what
   the flattened grid buys: 23 cards land in six rows instead of sixteen. */
.exgrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15.5rem, 1fr));
  gap: var(--bay-3);
}

.excard {
  display: flex;
  flex-direction: column;
  background: var(--c-surface);
  border: var(--rule-hair) solid var(--c-line);
  border-top: var(--rule-beam) solid var(--c-surface-deep);
  border-radius: var(--radius);
}

.band--slab .excard { background: var(--c-surface-alt); }

.excard__render {
  width: 100%;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  background: var(--c-surface);
  border-bottom: var(--rule-hair) solid var(--c-line);
}

.excard__body {
  padding: var(--bay-3);
  display: flex;
  flex-direction: column;
  gap: var(--bay-2);
  flex: 1;
}

/* The use type, which used to be an <h3> heading over a grid of its own. */
.excard__use {
  font-size: var(--step-nano);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-ink, var(--c-ink-muted));
}

/* Sits directly under the use-type label, so the pair reads as one block.
   Two lines reserved: titles run 18–26 characters and wrap at this width, and a
   card whose title happens to fit on one line must not lift its schedule out of
   line with the rest of the row. */
.excard__use + .t-title {
  margin-top: calc(var(--bay-2) * -1 + 0.25rem);
  min-height: calc(2 * 1.3em);
}

/* Same reasoning: three lines reserved so the schedules below start level. */
.excard__blurb {
  font-size: var(--step-small);
  line-height: 1.5;
  min-height: calc(3 * 1.5em);
  color: var(--muted-ink, var(--c-ink-muted));
}

/* Specs as label/value pairs, figures tabular so sizes line up card to card.

   Comparing 40x80x12 against 30x50x14 is the whole reason this section exists,
   and it only works if the schedules sit level across a row. The header block
   above reserves its lines, so the schedule starts at a fixed offset; the auto
   margin BELOW it hands the row's leftover height to the tags instead, which
   keeps them on the card's foot without dragging the schedule down with them. */
.exspec {
  margin: 0;
  margin-bottom: auto;
  padding-top: var(--bay-1);
  border-top: var(--rule-hair) solid var(--c-line);
}

.exspec > div {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--bay-2);
  padding: 0.35rem 0;
  border-bottom: var(--rule-hair) solid var(--c-line);
}

.exspec dt {
  font-size: var(--step-nano);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted-ink, var(--c-ink-muted));
}

.exspec dd {
  margin: 0;
  font-size: var(--step-small);
  font-weight: 500;
  text-align: right;
  font-variant-numeric: tabular-nums slashed-zero;
}

/* The openings count is three facts in one value and is the only row that will
   not sit beside its label at card width — it wrapped with "window" stranded on
   a second line, right-aligned under nothing. Given the full width it fits. */
.exspec > div:last-child {
  flex-direction: column;
  align-items: flex-start;
  gap: 0.1rem;
}

.exspec > div:last-child dd { text-align: left; }

.extags {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
}

.extags > li {
  font-size: var(--step-nano);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  padding: 0.25rem 0.5rem;
  border: 1px solid var(--c-line);
  color: var(--muted-ink, var(--c-ink-muted));
}

.exprovenance {
  font-size: var(--step-small);
  font-weight: 500;
  padding-left: var(--bay-3);
  border-left: var(--rule-beam) solid var(--c-surface-deep);
}

/* Marks the minority case, so it should read as a caveat rather than a boast.
   No `margin-top: auto` — `.exspec` above already owns the slack, and two auto
   margins in one flex column split it instead of pushing the block down. */
.excard__real {
  padding-top: var(--bay-2);
  border-top: var(--rule-beam) solid var(--c-surface-deep);
  font-size: var(--step-nano);
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

@media (max-width: 720px) {
  .exgrid { grid-template-columns: minmax(0, 1fr); }

  /* The reserved header lines come off here: they exist to keep the schedules
     of a ROW level, and at one column there is no row to level against.

     Tried and rejected: laying the card on its side, render beside the
     schedule. It cuts about 180px a card, and it ruins the renders — these are
     wide 16:9 technical drawings, and a 122px-wide portrait column crops them
     to an unreadable slice of wall. The render is how a reader identifies the
     building; it does not get sacrificed to a scroll-length number. The length
     of this section on a phone is a curation question, not a layout one. */
  .excard__use + .t-title,
  .excard__blurb { min-height: 0; }

  .exspec { margin-bottom: 0; }
}

/* --- FAQ ---------------------------------------------------------------- */
/* Plain dl, always open. A JS-free accordion would hide content from crawlers
   and screenshots alike; an accordion with JS would hide it from every AI
   crawler, none of which execute JavaScript. */

.faq {
  margin: 0;
  border-top: var(--rule-hair) solid var(--c-line);
}

.faq > div {
  padding-block: var(--bay-3);
  border-bottom: var(--rule-hair) solid var(--c-line);
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
  gap: var(--bay-3);
}

.faq dt {
  font-family: var(--font-body);
  font-size: var(--step-1);
  font-weight: 600;
  line-height: 1.35;
}

.faq dd {
  margin: 0;
  max-width: var(--measure);
}

/* A single resolved link inside an answer (financing, the e-book). Content names
   a facts key; build.py resolves it, so no URL is authored in copy. */
.faq__link {
  display: inline-block;
  margin-top: var(--bay-1);
  font-size: var(--step-label);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  border-bottom: var(--border-weight) solid currentColor;
  padding-bottom: 2px;
}

/* --- CTA band ----------------------------------------------------------- */

.cta {
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) auto;
  gap: var(--bay-5);
  align-items: end;
}

.cta__body > * + * {
  margin-top: var(--bay-2);
}

/* --- Site chrome -------------------------------------------------------- */

.masthead {
  background: var(--c-surface-deep);
  color: var(--c-surface-deep-ink);
  border-bottom: var(--rule-load) solid var(--c-accent);
}

.masthead__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--bay-2) var(--bay-4);
  padding-block: var(--bay-2);
}

.brand {
  font-family: var(--font-display);
  font-size: var(--step-brand);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  text-transform: uppercase;
  text-decoration: none;
  color: inherit;
  line-height: 1;
}

.brand__sub {
  display: block;
  font-family: var(--font-body);
  font-size: var(--step-nano);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  margin-top: 0.35rem;
  color: color-mix(in srgb, var(--c-surface-deep-ink) 70%, var(--c-surface-deep));
}

/* No hamburger: a JS-free disclosure widget is worse than five visible links. */
.nav {
  display: flex;
  flex-wrap: wrap;
  gap: var(--bay-3);
  list-style: none;
  padding: 0;
  margin: 0;
}

.nav a {
  display: block;
  padding-block: 0.35rem;
  font-size: var(--step-label);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  color: inherit;
  border-bottom: var(--rule-beam) solid transparent;
  transition: border-color 0.18s var(--ease);
}

.nav a:hover,
.nav a[aria-current='page'] {
  border-bottom-color: var(--c-accent);
}

/* --- Title block (signature) -------------------------------------------- */
/* The footer is a drawing title block. Rendering the required operator
   disclosure as engineering apparatus makes it read as rigor, not fine print. */

.titleblock {
  background: var(--c-surface-deep);
  color: var(--c-surface-deep-ink);
  border-top: var(--rule-load) solid var(--c-accent);
}

.titleblock__inner {
  padding-block: var(--bay-5);
}

.titleblock__grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  border: 1px solid color-mix(in srgb, var(--c-surface-deep-ink) 34%, transparent);
}

.tbcell {
  padding: var(--bay-2);
  border-right: 1px solid color-mix(in srgb, var(--c-surface-deep-ink) 34%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--c-surface-deep-ink) 34%, transparent);
}

.tbcell:last-child {
  border-right: 0;
}

.tbcell__label {
  display: block;
  font-size: var(--step-nano);
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--c-surface-deep-ink) 62%, var(--c-surface-deep));
  margin-bottom: 0.4rem;
}

.tbcell__value {
  font-size: var(--step-caption);
  font-variant-numeric: tabular-nums;
}

.tbcell--wide {
  grid-column: 1 / -1;
  padding: 0;
}

.titleblock__disclosure {
  margin-top: var(--bay-3);
  max-width: 70ch;
  font-size: var(--step-small);
  color: color-mix(in srgb, var(--c-surface-deep-ink) 82%, var(--c-surface-deep));
}

.titleblock__foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--bay-2);
  margin-top: var(--bay-3);
  font-size: var(--step-small);
  color: color-mix(in srgb, var(--c-surface-deep-ink) 70%, var(--c-surface-deep));
}

/* ==========================================================================
   Variant B structures. Each is a different assembly of the same tokens —
   a recoloured clone would do nothing for the cross-domain similarity number,
   so every variant here changes the DOM shape, not the paint.
   ========================================================================== */

/* --- Hero: split variant (hero.b) ---------------------------------------- */
/* Light-ground opening: the photograph is mounted as a framed plate beside
   the content, not laid behind it under a scrim. */

.herosplit {
  background: var(--c-surface);
  border-bottom: var(--rule-beam) solid var(--c-surface-deep);
}

.herosplit__inner {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: var(--bay-5);
  align-items: center;
  padding-block: var(--bay-6);
}

.herosplit__content > * + * {
  margin-top: var(--bay-3);
}

.herosplit__eyebrow {
  color: var(--muted-ink, var(--c-ink-muted));
}

.herosplit__sub {
  font-size: var(--step-2);
  line-height: 1.45;
  max-width: 60ch;
}

.herosplit__creds {
  margin-top: var(--bay-4);
  padding-top: var(--bay-3);
  border-top: var(--rule-hair) solid var(--c-line);
}

/* --- Answer block: rail variant (answer_block.b) -------------------------- */
/* Question and capsule in a left rail, evidence right, photograph full-width
   below. Wide figures hold 16:9 at desktop and revert to 4:3 on phones. */

.abrail {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.5fr);
  gap: var(--bay-5);
  align-items: start;
}

.abrail__head > * + * {
  margin-top: var(--bay-2);
}

.abrail__body > * + * {
  margin-top: var(--bay-4);
}

.abrail__figure {
  margin-top: var(--bay-5);
}

.abrail__figure img {
  aspect-ratio: 16 / 9;
}

/* --- Spec plates (spec_table.b) ------------------------------------------- */
/* Each spec group is a bordered plate with a labelled header band and a
   definition list. The dark header strip is the table-header grammar carried
   over, not a dark card: it labels data, it does not float content. */

.specplates {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr));
  gap: var(--bay-3);
  align-items: start;
}

.specplate {
  background: var(--c-surface);
  border: var(--rule-hair) solid var(--c-line);
}

.band--slab .specplate {
  background: var(--c-surface-alt);
}

.specplate__label {
  display: block;
  margin: 0;
  padding: 0.75rem var(--bay-3);
  background: var(--c-surface-deep);
  color: var(--c-surface-deep-ink);
}

.specplate__list {
  margin: 0;
  padding: var(--bay-1) var(--bay-3) var(--bay-2);
}

.specplate__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr);
  gap: var(--bay-2);
  padding-block: 0.6rem;
  border-bottom: var(--rule-hair) solid var(--c-line);
}

.specplate__row:last-child {
  border-bottom: 0;
}

.specplate__row dt {
  font-size: var(--step-small);
  font-weight: 600;
  padding-top: 0.1rem;
}

.specplate__row dd {
  margin: 0;
}

.specplate__value {
  display: block;
  font-weight: 500;
  font-variant-numeric: tabular-nums slashed-zero;
  font-feature-settings: 'tnum' 1, 'zero' 1;
}

.specplate__note {
  display: block;
  margin-top: 0.15rem;
  font-size: var(--step-small);
}

/* --- FAQ register (faq.b) -------------------------------------------------- */
/* A numbered single-column register sharing the process section's counter
   grammar. The number is presentation; the question is a real heading. */

.faqreg {
  list-style: none;
  counter-reset: q;
  margin: 0;
  padding: 0;
  max-width: 54rem;
  border-top: var(--rule-hair) solid var(--c-line);
}

.faqreg > li {
  counter-increment: q;
  display: grid;
  grid-template-columns: 4.5rem minmax(0, 1fr);
  gap: var(--bay-3);
  padding-block: var(--bay-3);
  border-bottom: var(--rule-hair) solid var(--c-line);
}

.faqreg > li::before {
  content: counter(q, decimal-leading-zero);
  font-family: var(--font-display);
  font-size: var(--step-num);
  font-weight: var(--display-weight);
  line-height: 1;
  color: var(--c-surface-deep);
  font-variant-numeric: tabular-nums;
}

.faqreg__q {
  font-family: var(--font-body);
  font-size: var(--step-1);
  font-weight: 600;
  line-height: 1.35;
}

.faqreg__a {
  margin-top: var(--bay-1);
  max-width: var(--measure);
}

/* --- CTA title-block row (cta_band.b) -------------------------------------- */
/* The closing action as one ruled plate of labelled cells, echoing the footer
   title block. Lives on the mill ground like every closing CTA. */

.ctablock {
  display: grid;
  /* The body cell needs the wider track: it holds prose, and at 1.2/1.0 it
     rendered at roughly 18 characters a line, which reads as an accident. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.3fr) auto;
  border: 1px solid color-mix(in srgb, var(--c-surface-deep-ink) 34%, transparent);
}

.ctablock--two {
  grid-template-columns: minmax(0, 1.6fr) auto;
}

.ctablock__cell {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: var(--bay-2);
  padding: var(--bay-4);
  border-right: 1px solid color-mix(in srgb, var(--c-surface-deep-ink) 34%, transparent);
}

.ctablock__cell:last-child {
  border-right: 0;
}

.ctablock__cell--actions {
  justify-content: center;
}

.skiplink {
  position: absolute;
  left: -9999px;
}

.skiplink:focus {
  left: var(--gutter);
  top: var(--bay-1);
  z-index: 10;
  padding: var(--bay-1) var(--bay-2);
  background: var(--c-accent);
  color: var(--c-accent-ink);
  font-weight: 600;
}

/* ==========================================================================
   Responsive — verified at 390 / 768 / 1440
   ========================================================================== */

@media (max-width: 1080px) {
  .grid--4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cta { grid-template-columns: minmax(0, 1fr); gap: var(--bay-4); }
  .faq > div { grid-template-columns: minmax(0, 1fr); gap: var(--bay-1); }

  /* Variant B structures collapse with their A-variant counterparts. */
  .abrail { grid-template-columns: minmax(0, 1fr); gap: var(--bay-4); }
  .ctablock,
  .ctablock--two { grid-template-columns: minmax(0, 1fr); }
  .ctablock__cell {
    border-right: 0;
    border-bottom: 1px solid color-mix(in srgb, var(--c-surface-deep-ink) 34%, transparent);
  }
  .ctablock__cell:last-child { border-bottom: 0; }
  .titleblock__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .tbcell:nth-child(2n) { border-right: 0; }
  .tbcell--wide { border-right: 0; }

  /* Three cells in two columns leaves the fourth slot blank, and an empty cell
     defeats the whole title-block metaphor. The last cell spans instead. */
  .titleblock__grid > .tbcell:nth-last-child(2) {
    grid-column: 1 / -1;
    border-right: 0;
  }
}

@media (max-width: 720px) {
  :root {
    --gutter: var(--bay-2);
    --section-rhythm: 3.5rem;
  }

  .grid--2,
  .grid--3,
  .grid--4 { grid-template-columns: minmax(0, 1fr); }

  .card { padding: var(--bay-3); }

  .hero__inner { padding-block: var(--bay-5) var(--bay-4); }

  /* Capped below the desktop scrim's darkest stop: at 84/94% the photo
     disappeared entirely and the hero read as a flat dark slab on a phone —
     dark as atmosphere, which this system does not allow. The photo must
     survive its own scrim. */
  .hero__scrim {
    background: linear-gradient(
      to bottom,
      color-mix(in srgb, var(--c-surface-deep) 72%, transparent) 0%,
      color-mix(in srgb, var(--c-surface-deep) 88%, transparent) 100%
    );
  }

  /* The subheading at 23px ran to six lines and out-shouted the action. */
  .hero__sub {
    font-size: var(--step-1);
  }

  /* A table switched to display:block leaves its caption computing width
     against nothing, collapsing it to a one-word column. */
  .ptable caption,
  .spec caption {
    display: block;
    padding-inline: 0;
  }

  .steps > li { grid-template-columns: 3rem 1fr; gap: var(--bay-2); }
  .steps > li::before { font-size: var(--step-brand); }

  .vlist > li { grid-template-columns: 2rem 1fr; gap: var(--bay-2); }

  .herosplit__inner {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--bay-4);
    padding-block: var(--bay-4);
  }

  .faqreg > li { grid-template-columns: 3rem minmax(0, 1fr); gap: var(--bay-2); }
  .faqreg > li::before { font-size: var(--step-brand); }

  .specplate__row { grid-template-columns: minmax(0, 1fr); gap: 0.15rem; }

  /* Full-bleed photography: 16:9 at desktop, 4:3 on phones (DESIGN.md). */
  .abrail__figure img { aspect-ratio: 4 / 3; }

  .actions { width: 100%; }
  .actions .btn { flex: 1 1 auto; justify-content: center; }

  /* Tables restack as labeled definition rows. A horizontally scrolling table
     with an invisible right edge is how spec data gets lost on a phone. */
  .tablewrap { border: 0; overflow-x: visible; }

  .ptable,
  .spec,
  .cmp { display: block; }

  .ptable thead,
  .spec thead,
  .cmp thead { display: none; }

  .ptable tbody,
  .spec tbody,
  .cmp tbody { display: block; }

  .ptable tbody tr,
  .cmp tbody tr {
    display: block;
    background: var(--c-surface);
    border: var(--rule-hair) solid var(--c-line);
    border-top: var(--rule-beam) solid var(--c-surface-deep);
    margin-bottom: var(--bay-2);
  }

  .band--zinc .ptable tbody tr,
  .band--zinc .cmp tbody tr { background: var(--c-surface); }

  .ptable tbody tr:nth-child(even),
  .cmp tbody tr:nth-child(even) { background: var(--c-surface); }

  .ptable tbody td,
  .cmp tbody td,
  .cmp tbody th[scope='row'] {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--bay-2);
    padding: 0.6rem var(--bay-2);
    border-top: var(--rule-hair) solid var(--c-line);
    text-align: left;
  }

  .ptable tbody tr > td:first-child,
  .cmp tbody tr > th[scope='row'] {
    border-top: 0;
    background: var(--c-surface-alt);
    font-weight: 600;
  }

  .ptable tbody td::before,
  .cmp tbody td::before {
    content: attr(data-label);
    flex: 0 0 auto;
    font-size: var(--step-nano);
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--muted-ink, var(--c-ink-muted));
  }

  .ptable .num { text-align: right; }

  /* The price table holds short values, so label-left / value-right works there.
     Comparison cells hold prose — sharing a row with the label squeezed them to
     two words per line — so they stack and read left-aligned at full width. */
  .cmp tbody td {
    display: block;
    text-align: left;
  }

  .cmp tbody td::before {
    display: block;
    margin-bottom: 0.4rem;
  }

  .cmp tbody th[scope='row'] {
    display: block;
    text-align: left;
  }

  /* The 15% criterion column is a desktop measure. Left applied once the table
     becomes a block it resolves against the phone width and wraps the row header
     one word per line. */
  .cmp,
  .cmp th:first-child {
    table-layout: auto;
    width: auto;
  }

  .spec tbody tr { display: block; border-top: var(--rule-hair) solid var(--c-line); }
  .spec tbody tr.spec__group { border-top: var(--rule-beam) solid var(--c-surface-deep); }
  .spec tbody td { display: block; padding: 0.35rem var(--bay-2); border-top: 0; }
  .spec tbody td:first-child { font-weight: 600; padding-top: 0.7rem; }
  .spec tbody td:last-child { padding-bottom: 0.7rem; }
  .spec__group th { display: block; }
}

/* Print is a different material, so it gets its own two documented values
   (DESIGN.md → Colors → Print). Paper is true white and ink is true black:
   slab grey (#F0F1F0) prints as a flat wash of toner across the whole sheet, and
   mill scale (#191D21) is near-black anyway. A buyer printing a spec table to take
   to a contractor should get a clean sheet. */
@media print {
  :root {
    --c-print-paper: #ffffff;
    --c-print-ink: #000000;
  }

  .masthead,
  .nav,
  .btn { display: none; }

  body {
    background: var(--c-print-paper);
    color: var(--c-print-ink);
  }
}
