@charset "UTF-8";
/* ============================================================================
   PRICELESS FINANCIAL SERVICES — the design system
   Direction: "The Blind Spot". See _rebuild/BRIEF.md §1 and §2.

   ONE stylesheet. Nothing on this site loads a second design system, and nothing
   hard-codes a value a token already names. The previous build failed partly
   because three stylesheets argued over .section, .container and .btn on every
   request; that is not repeated here.

   Order:  0 tokens · 1 reset · 2 type · 3 layout · 4 bands · 5 rules & marks
           6 buttons · 7 art frames · 8 the beat · 9 figures · 10 header
           11 hero · 12 components · 13 forms · 14 footer · 15 motion
           16 utilities · 17 responsive
   ========================================================================= */

/* ---------------------------------------------------------------- 0 TOKENS */
:root {
  /* Ground — the ink the persuade surfaces are printed on */
  --ink-950: #070B14;
  --ink-900: #0A1020;
  --ink-850: #0D1526;
  --ink-800: #111A2E;
  --ink-700: #1A2740;
  --line:    #22314F;
  --line-soft: rgba(143, 178, 255, .14);

  /* Brand blue — taken from the swans in the client's own logo */
  --swan-300: #B9CEFF;
  --swan-400: #8FB2FF;
  --swan-500: #6090FC;
  --swan-600: #3E6FE0;

  /* Brand orange — taken from the beaks. Rationed to one job per screen. */
  /* Four steps, because the accent has to work against two grounds with two
     different label colours and one value cannot do both. Measured, not guessed:
       #FF7A2B on ink #0A1020   7.28:1   hover on a dark ground, ink label
       #FC6000 on ink #0A1020   6.15:1   the action on a dark ground, ink label
       #B84200 with #FFFFFF     5.50:1   the action on paper, white label
       #9E3800 with #FFFFFF     6.95:1   hover on paper, white label
     The value this replaced, #D94E00, carried a white label at 4.17:1, which is
     below AA for a 16px semibold button and was the only contrast failure on the
     site. Hover now goes lighter on ink rather than darker, so the label stays
     ink and the ratio goes up rather than down. */
  --beak-400: #FF7A2B;
  --beak-500: #FC6000;
  --beak-600: #B84200;
  --beak-700: #9E3800;

  /* Paper — the ground the reading surfaces are printed on */
  --paper:    #F7F6F3;
  --paper-2:  #EDEBE6;
  --paper-3:  #E2DFD8;
  --graphite: #14161A;
  --slate:    #5A6473;
  --slate-2:  #7C8697;

  /* Sentiment */
  --pos: #1F9D6B;
  /* Two red steps, for the same reason the orange has four: one value cannot
     serve both text and non-text on every ground. --neg (4.35:1 on the page
     ground, 3.98:1 on a raised band) is fine for 2px borders, rules and large
     figures, which sit at the 3:1 non-text floor — and it FAILS the 4.5:1 text
     floor everywhere except the deepest ground, which is exactly where error
     messages were being set. --neg-400 is the measured text step: 5.31:1 on the
     worst ground it lands on (--ink-800). */
  --neg:     #D24B3E;
  --neg-400: #E06B5C;

  /* Semantic — dark ground (default) */
  --bg:        var(--ink-900);
  --bg-raised: var(--ink-800);
  --fg:        #E8EDF7;
  --fg-dim:    #A8B6CE;
  /* Measured against every ground this text actually lands on, not just the page
     ground. #6F8099 cleared 4.71:1 on --ink-900 and was signed off on that — but
     .fine, .note and .plate__l all appear inside raised bands too, and on
     --ink-800 the same colour is 4.31:1, under AA. A token that passes on the
     ground it was tested against and fails on the one beside it is the easiest
     accessibility bug on any site to miss. Worst case is now 5.06:1. */
  --fg-faint:  #7A8CA6;
  --rule:      var(--line);
  --link:      var(--swan-400);
  --act:       var(--beak-500);
  --act-fg:    #0A1020;

  /* Type */
  --serif: "Newsreader", Georgia, "Times New Roman", serif;
  --sans:  "Instrument Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, system-ui, sans-serif;

  --t-hero:     clamp(2.55rem, 1.10rem + 5.30vw, 5.30rem);
  --t-question: clamp(1.85rem, 1.05rem + 2.75vw, 3.30rem);
  --t-h3:       clamp(1.30rem, 1.05rem + 0.85vw, 1.80rem);
  --t-lead:     clamp(1.10rem, 1.00rem + 0.45vw, 1.38rem);
  --t-body:     1.0625rem;
  --t-small:    0.9125rem;
  --t-note:     0.72rem;
  --t-plate:    clamp(2.60rem, 1.40rem + 4.20vw, 4.60rem);

  --lh-tight: 1.06;
  --lh-head:  1.14;
  --lh-body:  1.65;
  --lh-read:  1.72;

  --measure:      68ch;
  --measure-read: 66ch;
  --measure-tight: 46ch;

  /* Space */
  --s1: .25rem;  --s2: .5rem;   --s3: .75rem;  --s4: 1rem;
  --s5: 1.5rem;  --s6: 2rem;    --s7: 3rem;    --s8: 4rem;
  --s9: 6rem;    --s10: 8rem;   --s11: 10rem;
  --band-y: clamp(4.5rem, 2.5rem + 7vw, 10rem);
  --gutter: clamp(1.25rem, .6rem + 2.6vw, 3.5rem);
  --max:    1320px;
  --max-read: 760px;

  /* Motion */
  --ease: cubic-bezier(.16, 1, .3, 1);
  --ease-in-out: cubic-bezier(.65, 0, .35, 1);
  --dur-1: 180ms;
  --dur-2: 320ms;
  --dur-3: 700ms;

  --radius: 0px;          /* squared everywhere; the softness comes from the photography */
  --radius-art: 2px;

  --hdr-h: 76px;
}

/* Reading surfaces used to flip to a pale stock. They no longer do.
   The client looked at the site and said the insights page did not match the
   rest of it, and they were right: a reader moving from an argument on ink to an
   article on paper reads it as two websites, and the seam is more expensive than
   the readability the pale ground bought.
   So the ground is now the same everywhere and reading surfaces differ in
   ERGONOMICS instead of in colour: more leading, a longer measure, and a body
   colour pulled back from white. Pure white on near-black at nineteen pixels is
   what actually makes long-form on a dark ground tiring, not the darkness. */
.mode-read,
.mode-operate {
  --fg-dim:  #C3CEE2;
  --lh-body: 1.70;
}

/* ----------------------------------------------------------------- 1 RESET */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--sans);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-variant-numeric: tabular-nums;
  overflow-x: hidden;
}

img, svg, video { display: block; max-width: 100%; height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
h1, h2, h3, h4, p, figure, blockquote, ul, ol, dl { margin: 0; }
ul, ol { padding: 0; list-style: none; }
a { color: var(--link); text-decoration: none; }
hr { border: 0; border-top: 1px solid var(--rule); margin: 0; }
table { border-collapse: collapse; width: 100%; }

:focus-visible {
  outline: 2px solid var(--swan-500);
  outline-offset: 3px;
}
.mode-read :focus-visible, .mode-operate :focus-visible { outline-color: var(--swan-400); }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--act); color: var(--act-fg);
  padding: var(--s3) var(--s5); font-weight: 600;
}
.skip:focus { left: var(--s4); top: var(--s4); }

::selection { background: var(--swan-500); color: #06090F; }

/* ------------------------------------------------------------------ 2 TYPE */
.serif { font-family: var(--serif); font-weight: 400; font-optical-sizing: auto; }

h1, h2, h3, .q, .plate-n {
  font-family: var(--serif);
  font-weight: 400;
  font-optical-sizing: auto;
  letter-spacing: -.014em;
  text-wrap: balance;
}

h1, .h1 { font-size: var(--t-hero); line-height: var(--lh-tight); letter-spacing: -.028em; }
h2, .q  { font-size: var(--t-question); line-height: var(--lh-head); letter-spacing: -.02em; }
h3, .h3 { font-size: var(--t-h3); line-height: 1.22; }

/* The one emphasised word. Italic serif, brand blue. Never more than one per headline. */
h1 em, h2 em, .q em, .lead em {
  font-style: italic;
  color: var(--swan-400);
  font-weight: 400;
}
.mode-read h1 em, .mode-read h2 em, .mode-read .q em { color: var(--swan-400); }

.lead {
  font-size: var(--t-lead);
  line-height: 1.52;
  color: var(--fg-dim);
  max-width: var(--measure);
  font-weight: 400;
}

.body   { max-width: var(--measure); color: var(--fg-dim); }
.body p + p { margin-top: var(--s4); }
.body strong { color: var(--fg); font-weight: 600; }

/* The annotation layer. Small caps, letterspaced, brand blue. No monospace on this
   site — monospace was the rejected build's signature and it reads as a spreadsheet. */
.note, .eyebrow {
  font-size: var(--t-note);
  line-height: 1.45;
  text-transform: uppercase;
  letter-spacing: .145em;
  font-weight: 600;
  color: var(--swan-400);
}
.mode-read .note, .mode-read .eyebrow { color: var(--swan-400); }
.note--quiet { color: var(--fg-faint); font-weight: 500; letter-spacing: .12em; }

.fine {
  font-size: var(--t-small);
  line-height: 1.55;
  color: var(--fg-faint);
  max-width: 78ch;
}

.tnum { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }

/* ---------------------------------------------------------------- 3 LAYOUT */
.wrap {
  width: 100%;
  max-width: var(--max);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.wrap--read { max-width: calc(var(--max-read) + var(--gutter) * 2); }

/* The asymmetric rail. A narrow annotation column against a wide content column.
   Collapses to one column under 900px, with the rail becoming a label above. */
.rail {
  display: grid;
  grid-template-columns: minmax(0, 15rem) minmax(0, 1fr);
  gap: clamp(1.5rem, .5rem + 3vw, 5rem);
  align-items: start;
}
.rail__side { position: sticky; top: calc(var(--hdr-h) + var(--s6)); }
.rail--flat .rail__side { position: static; }

.cols-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--s7); }
.cols-3 { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s6); }
.cols-4 { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: var(--s5); }

.stack > * + * { margin-top: var(--s4); }
.stack-5 > * + * { margin-top: var(--s5); }
.stack-6 > * + * { margin-top: var(--s6); }
.stack-7 > * + * { margin-top: var(--s7); }

/* ----------------------------------------------------------------- 4 BANDS */
.band { padding-block: var(--band-y); position: relative; }
.band--tight  { padding-block: calc(var(--band-y) * .6); }
.band--raised { background: var(--bg-raised); }
.band--deep   { background: var(--ink-950); }
.band--paper  { background: var(--ink-850); }  /* kept for template compatibility; no longer pale */
.band--edge   { border-top: 1px solid var(--rule); }

/* Depth without images: two slow radial glows and a grain overlay. This is what
   keeps a dark page from reading as flat black paint, and it costs nothing. */
.band--lit::before,
.band--lit::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 0;
}
.band--lit::before {
  background:
    radial-gradient(58rem 34rem at 12% -10%, rgba(96, 144, 252, .13), transparent 62%),
    radial-gradient(46rem 30rem at 92% 108%, rgba(252, 96, 0, .07), transparent 60%);
}
.band--lit::after {
  opacity: .035;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}
.band > .wrap { position: relative; z-index: 1; }

/* --------------------------------------------------------- 5 RULES & MARKS */
.rule-hair { border-top: 1px solid var(--rule); }
.rule-lead { border-top: 2px solid var(--swan-500); width: 3.5rem; }
.rule-act  { border-top: 2px solid var(--act); width: 3.5rem; }

.mark-n {
  font-family: var(--serif);
  font-size: var(--t-note);
  letter-spacing: .16em;
  color: var(--swan-500);
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------- 6 BUTTONS */
.btn {
  --btn-bg: transparent; --btn-fg: var(--fg); --btn-bd: var(--rule);
  display: inline-flex; align-items: center; gap: .6em;
  min-height: 52px; padding: .85rem 1.6rem;
  background: var(--btn-bg); color: var(--btn-fg);
  border: 1px solid var(--btn-bd); border-radius: var(--radius);
  font-family: var(--sans); font-size: 1rem; font-weight: 600;
  letter-spacing: .005em; cursor: pointer; text-align: left;
  transition: background var(--dur-1) var(--ease-in-out),
              color var(--dur-1) var(--ease-in-out),
              border-color var(--dur-1) var(--ease-in-out),
              transform var(--dur-1) var(--ease-in-out);
}
.btn svg { flex: none; transition: transform var(--dur-2) var(--ease); }
.btn:hover svg { transform: translateX(4px); }
.btn:active { transform: translateY(1px); }

/* The action. Orange ground, ink text — white on this orange fails contrast. */
/* The action. On ink the label is ink, not white — white on this orange fails AA.
   Hover therefore goes lighter, which is the opposite of the reflex and the only
   direction that keeps the label legible. */
.btn--act { --btn-bg: var(--act); --btn-fg: var(--act-fg); --btn-bd: var(--act); }
.btn--act:hover { --btn-bg: var(--beak-400); --btn-bd: var(--beak-400); }
/* One action hover, because there is one ground. */

.btn--ghost { --btn-bd: var(--swan-500); --btn-fg: var(--swan-400); }
.btn--ghost:hover { --btn-bg: rgba(96, 144, 252, .12); --btn-fg: var(--swan-300); }


.btn--quiet { --btn-bd: var(--rule); --btn-fg: var(--fg-dim); }
.btn--quiet:hover { --btn-fg: var(--fg); --btn-bd: var(--fg-faint); }

.btn--wide { width: 100%; justify-content: center; text-align: center; }

/* A text link that behaves like a rule being drawn. */
.tlink {
  display: inline-flex; align-items: center; gap: .5em;
  font-weight: 600; color: var(--link);
  padding-block: .3em; position: relative;
}
.tlink::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  border-bottom: 1px solid currentColor;
  transform: scaleX(0); transform-origin: left;
  transition: transform var(--dur-2) var(--ease);
}
.tlink:hover::after { transform: scaleX(1); }
.tlink svg { transition: transform var(--dur-2) var(--ease); }
.tlink:hover svg { transform: translateX(4px); }

.cta-note {
  display: block; margin-top: var(--s3);
  font-size: var(--t-small); color: var(--fg-faint);
}

.actions { display: flex; flex-wrap: wrap; gap: var(--s4); align-items: center; }

/* ------------------------------------------------------------ 7 ART FRAMES */
/* Every photograph on this site sits in a frame that reserves its own space, so
   nothing shifts while an image decodes. The frame is also the placeholder: until
   a real file lands the frame states what belongs there rather than pretending. */
.art {
  position: relative;
  display: block;
  overflow: hidden;
  background: linear-gradient(152deg, var(--ink-800) 0%, var(--ink-950) 62%, #060A12 100%);
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-art);
  aspect-ratio: var(--ar, 3 / 2);
}
.art > picture { display: contents; }
.art > img,
.art > picture > img {
  width: 100%; height: 100%; object-fit: cover;
  filter: saturate(.86) contrast(1.04);
}
/* The ink wash that makes photography and page one surface. */
.art::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    linear-gradient(to top, rgba(10, 16, 32, .82) 0%, rgba(10, 16, 32, .18) 42%, rgba(10, 16, 32, 0) 72%),
    radial-gradient(120% 90% at 50% 45%, transparent 42%, rgba(7, 11, 20, .55) 100%);
}
.art--flat::after { background: linear-gradient(to top, rgba(10,16,32,.55), rgba(10,16,32,0) 55%); }

.art--ar-wide  { --ar: 16 / 9; }
.art--ar-cine  { --ar: 21 / 9; }
.art--ar-3-2   { --ar: 3 / 2; }
.art--ar-4-5   { --ar: 4 / 5; }
.art--ar-1-1   { --ar: 1 / 1; }

/* Placeholder state. Deliberately reads as a specification, never as a design. */
.art[data-art]:not(.is-loaded) { display: grid; place-items: center; }
.art[data-art]:not(.is-loaded)::before {
  content: attr(data-art-label);
  position: relative; z-index: 2;
  max-width: 30ch; padding: var(--s5);
  font-size: var(--t-note); text-transform: uppercase; letter-spacing: .16em;
  font-weight: 600; line-height: 1.7; text-align: center;
  color: rgba(143, 178, 255, .42);
}
.art[data-art]:not(.is-loaded):not(.art--bg)::after {
  background:
    repeating-linear-gradient(135deg, rgba(96,144,252,.05) 0 1px, transparent 1px 14px),
    radial-gradient(90% 70% at 50% 40%, rgba(96,144,252,.09), transparent 70%);
}

/* A frame used as a page ground rather than as a picture in the flow: the hero
   photographs. It keeps its gradient and its own wash, and it never prints the
   placeholder label — a specification set behind a headline is a defect, not a
   placeholder. Declared AFTER the base placeholder rules on purpose; the two have
   equal specificity, so order is what decides this. */
.art--bg[data-art]:not(.is-loaded) { display: block; }
.art--bg[data-art]:not(.is-loaded)::before { content: none; display: none; }

.art-cap {
  margin-top: var(--s3);
  font-size: var(--t-small); color: var(--fg-faint);
  max-width: 52ch;
}

/* Full-bleed cinematic band between arguments. */
.art-band { position: relative; }
.art-band .art { --ar: 21 / 9; border: 0; border-radius: 0; }
.art-band__text {
  position: absolute; inset-inline: 0; bottom: 0; z-index: 2;
  padding: var(--band-y) 0 clamp(2rem, 1rem + 3vw, 4.5rem);
}

/* ------------------------------------------------------------- 8 THE BEAT */
/* The load-bearing pattern. Question → recognition → proof. Every persuade block
   on the site is one of these, and a block that cannot fill all three does not ship. */
.beat { display: grid; gap: var(--s5); }
.beat__q {
  font-family: var(--serif);
  font-size: var(--t-question);
  line-height: var(--lh-head);
  letter-spacing: -.02em;
  max-width: 22ch;
  text-wrap: balance;
}
.beat__r { max-width: var(--measure); color: var(--fg-dim); }
.beat__r p + p { margin-top: var(--s4); }
.beat__p {
  padding-top: var(--s5);
  border-top: 1px solid var(--rule);
  display: grid; gap: var(--s2);
}

/* ---------------------------------------------------------------- 9 FIGURES */
/* One hard number, set large. This is the payload of a beat. */
.plate { display: grid; gap: var(--s2); }
.plate__n {
  font-family: var(--serif);
  font-size: var(--t-plate);
  line-height: .96;
  letter-spacing: -.035em;
  font-variant-numeric: tabular-nums;
  color: var(--fg);
}
.plate__n--act  { color: var(--act); }
.plate__n--blue { color: var(--swan-400); }
.mode-read .plate__n--blue { color: var(--swan-400); }
.plate__n--pos  { color: var(--pos); }
.plate__n--neg  { color: var(--neg); }
.plate__l {
  font-size: var(--t-note); text-transform: uppercase;
  letter-spacing: .145em; font-weight: 600; color: var(--fg-faint);
  max-width: 30ch;
}
.plate__c { font-size: var(--t-small); color: var(--fg-dim); max-width: 44ch; }

/* The credential strip under the hero. Flat, no adjectives.
   Flex, not a fixed four-column grid. The strip carries two figures now rather
   than four, and repeat(4, 1fr) would have left them both crushed into the first
   quarter of the width with two empty tracks beside them. Flex lets the strip
   hold however many cells it is given without the stylesheet having to know the
   count — which is the same fault, at the layout level, as counting things in
   the copy. */
.strip {
  display: flex; flex-wrap: wrap;
  gap: 0 clamp(2.5rem, 1rem + 4vw, 6rem);
  border-top: 1px solid var(--rule);
}
.strip__cell { flex: 0 1 auto; min-width: 11rem; max-width: 24rem; padding: var(--s5) 0 0; }
.strip__f {
  font-family: var(--serif); font-size: clamp(1.7rem, 1.2rem + 1.6vw, 2.5rem);
  line-height: 1; letter-spacing: -.03em; font-variant-numeric: tabular-nums;
}
.strip__l {
  margin-top: var(--s2);
  font-size: var(--t-note); text-transform: uppercase; letter-spacing: .14em;
  font-weight: 600; color: var(--fg-faint); line-height: 1.5;
}

/* Callouts inside long-form argument. */
.callout {
  border-left: 2px solid var(--swan-500);
  padding: var(--s4) 0 var(--s4) var(--s5);
  max-width: var(--measure);
}
.callout--act { border-left-color: var(--act); }
.callout--warn { border-left-color: var(--neg); }
.callout__f {
  font-family: var(--serif); font-size: clamp(1.8rem, 1.3rem + 1.6vw, 2.6rem);
  line-height: 1; letter-spacing: -.03em; font-variant-numeric: tabular-nums;
}
.callout__l { margin-top: var(--s2); }
.callout__b { margin-top: var(--s3); color: var(--fg-dim); }

/* --------------------------------------------------------------- 10 HEADER */
.hdr {
  position: fixed; inset-inline: 0; top: 0; z-index: 80;
  height: var(--hdr-h);
  display: flex; align-items: center;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background var(--dur-2) var(--ease-in-out),
              border-color var(--dur-2) var(--ease-in-out),
              backdrop-filter var(--dur-2);
}
.hdr.is-stuck {
  background: rgba(10, 16, 32, .82);
  backdrop-filter: saturate(140%) blur(14px);
  -webkit-backdrop-filter: saturate(140%) blur(14px);
  border-bottom-color: var(--line);
}
/* There used to be a pale .mode-read variant of the stuck bar and an inverted
   logo to go with it, from when the reading surfaces printed on paper stock.
   The ground is the same ink everywhere now (see inc/setup.php), so both rules
   were painting a white bar and a dark logo over a dark page on /insights/ and
   /contact/. Removed rather than carried. */

.hdr__in { display: flex; align-items: center; gap: var(--s5); width: 100%; min-width: 0; }
.hdr__logo { display: block; flex: none; }
.hdr__logo img { height: 34px; width: auto; }
.hdr__tel { margin-left: auto; gap: .5em; }

/* --- the site menu ------------------------------------------------------- */
/* Seven items and an action on a 1320px measure is a tight bar, so the gap and
   the label size are declared once as custom properties and stepped down at the
   two widths where it actually gets close — 1280 and 1160. Nothing here wraps
   and nothing collides with the logo; the bar gets quieter instead. */
.nav {
  --nav-gap: 1.35rem;
  --nav-size: .95rem;
  margin-left: auto;
  display: flex; align-items: center; gap: var(--nav-gap);
  min-width: 0;
}
.nav__list { display: flex; align-items: center; gap: var(--nav-gap); }
.nav__item { position: relative; display: flex; align-items: center; }

.nav__a {
  position: relative;
  display: inline-flex; align-items: center;
  min-height: 44px;
  color: var(--fg-dim);
  font-size: var(--nav-size, .95rem); font-weight: 500;
  white-space: nowrap;
  transition: color var(--dur-1) var(--ease-in-out);
}
.nav__a:hover, .nav__a[aria-current] { color: var(--fg); }
.nav__a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: .6rem;
  border-bottom: 1px solid var(--swan-500);
  transform: scaleX(0); transform-origin: left;
  transition: transform var(--dur-2) var(--ease);
}
.nav__a:hover::after, .nav__a[aria-current]::after { transform: scaleX(1); }

.nav__cta { min-height: 44px; padding: .55rem 1.05rem; font-size: calc(var(--nav-size, .95rem) - .03rem); white-space: nowrap; }

/* The dropdown control. A separate button beside the link, never the link
   itself: /blind-spots/ carries all seven and has to stay reachable.

   It is a full 44x44 target at every width the bar exists at. The width is
   bought back with negative margins that eat the label's own trailing padding
   on one side and the bar's gap on the other, so a 44px hit box costs about two
   pixels of bar and still does not overlap either neighbour. */
.nav__item--sub > .nav__a { padding-right: .4rem; }
.nav__item--sub > .nav__a::after { right: .4rem; }
.nav__tog {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; min-height: 44px;
  margin-left: -.4rem; margin-right: -.45rem;
  padding: 0; background: none; border: 0;
  color: var(--fg-dim); cursor: pointer;
  transition: color var(--dur-1) var(--ease-in-out);
}
.nav__tog:hover { color: var(--fg); }
.nav__tog svg { transition: transform var(--dur-2) var(--ease); }
.nav__item.is-open .nav__tog, .nav__tog[aria-expanded="true"] { color: var(--fg); }
.nav__item.is-open .nav__tog svg, .nav__tog[aria-expanded="true"] svg { transform: rotate(180deg); }

/* The panel. Its top padding is transparent and deliberate: it bridges the gap
   between the bar and the card so a pointer travelling down does not cross a
   dead strip and close the thing it is reaching for. */
.nav__panel {
  position: absolute; top: 100%; left: -1rem; z-index: 5;
  padding-top: .95rem;
  opacity: 0; visibility: hidden; transform: translateY(-6px);
  transition: opacity var(--dur-1) var(--ease-in-out),
              transform var(--dur-2) var(--ease),
              visibility var(--dur-2);
}
.nav__panel-in {
  min-width: 18.5rem;
  padding-block: var(--s2);
  background: var(--bg-raised);
  border: 1px solid var(--rule);
  box-shadow: 0 20px 44px rgba(7, 11, 20, .55);
}
.nav__panel a {
  display: flex; align-items: center; gap: var(--s3);
  min-height: 44px; padding: .3rem var(--s5);
  color: var(--fg-dim); font-size: .9rem; font-weight: 500; line-height: 1.3;
  transition: background var(--dur-1) var(--ease-in-out), color var(--dur-1) var(--ease-in-out);
}
.nav__panel a:hover { background: var(--ink-700); color: var(--fg); }
.nav__panel a[aria-current] { color: var(--swan-400); }
.nav__all { margin-top: var(--s2); padding-top: var(--s2); border-top: 1px solid var(--rule); }
.nav__all a { color: var(--swan-400); font-weight: 600; }
.nav__all svg { transition: transform var(--dur-2) var(--ease); }
.nav__all a:hover svg { transform: translateX(4px); }

/* Open state, in two layers on purpose.
   Layer one is the stylesheet on its own: hover and focus-within. It is what a
   visitor gets if assets/js/priceless.js never runs, and it means the seven are
   still reachable from the bar with a keyboard when there is no script at all.
   Layer two takes over the moment the menu block boots and puts pf-menu-js on
   <html>. From then on `.is-open` is the only thing that opens a panel, which
   is what lets a click CLOSE a panel the pointer is still resting on and keeps
   aria-expanded honest about what is on the screen. */
.nav__item:hover > .nav__panel,
.nav__item:focus-within > .nav__panel { opacity: 1; visibility: visible; transform: none; }

html.pf-menu-js .nav__item:hover > .nav__panel,
html.pf-menu-js .nav__item:focus-within > .nav__panel { opacity: 0; visibility: hidden; transform: translateY(-6px); }
html.pf-menu-js .nav__item.is-open > .nav__panel { opacity: 1; visibility: visible; transform: none; }

@media (max-width: 1280px) {
  .nav { --nav-gap: 1rem; --nav-size: .9rem; }
  .nav__cta { padding-inline: .95rem; }
  .nav__panel-in { min-width: 17.5rem; }
}
@media (max-width: 1160px) {
  .nav { --nav-gap: .7rem; --nav-size: .855rem; }
  .nav__cta { padding-inline: .8rem; gap: .45em; }
  .hdr__in { gap: var(--s4); }
  .hdr__logo img { height: 30px; }
}

.burger {
  display: none; margin-left: auto;
  width: 46px; height: 46px; padding: 0;
  background: none; border: 1px solid var(--rule); cursor: pointer;
}
.burger span { display: block; width: 20px; height: 1.5px; background: var(--fg); margin: 4px auto; transition: transform var(--dur-2) var(--ease), opacity var(--dur-1); }
.burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(5.5px) rotate(45deg); }
.burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-5.5px) rotate(-45deg); }

/* --- the drawer ---------------------------------------------------------- */
/* Under 960 the whole menu comes in here. The seven are an indented sub-list
   under What We Solve rather than a second dropdown — a menu inside a menu on a
   phone is one tap too many, and the list is only seven lines long. */
.drawer {
  position: fixed; inset: 0; z-index: 79;
  background: var(--ink-950);
  padding: calc(var(--hdr-h) + var(--s5)) var(--gutter) calc(var(--s7) + env(safe-area-inset-bottom));
  opacity: 0; visibility: hidden; transform: translateY(-8px);
  transition: opacity var(--dur-2) var(--ease-in-out), transform var(--dur-2) var(--ease), visibility var(--dur-2);
  overflow-y: auto; -webkit-overflow-scrolling: touch;
}
.drawer.is-open { opacity: 1; visibility: visible; transform: none; }
.drawer__list > li + li { border-top: 1px solid var(--line); }
.drawer__a {
  display: flex; align-items: center; min-height: 52px;
  padding-block: var(--s2);
  font-family: var(--serif); font-size: 1.45rem; line-height: 1.15;
  color: var(--fg);
}
.drawer__a[aria-current] { color: var(--swan-400); }
.drawer__sub {
  margin: 0 0 var(--s3) var(--s2);
  padding-left: var(--s5);
  border-left: 1px solid var(--line);
}
.drawer__sub a {
  display: flex; align-items: center; min-height: 44px;
  font-family: var(--sans); font-size: .95rem; font-weight: 500;
  color: var(--fg-dim);
}
.drawer__sub a[aria-current] { color: var(--swan-400); }
.drawer__cta { margin-top: var(--s6); }

/* Scroll progress hairline. */
.progress {
  position: fixed; top: 0; left: 0; z-index: 90;
  height: 2px; width: 100%; transform-origin: left; transform: scaleX(0);
  background: linear-gradient(90deg, var(--swan-500), var(--beak-500));
  pointer-events: none;
}

/* Sticky mobile action, past the first screen. */
.sticky-cta {
  position: fixed; inset-inline: 0; bottom: 0; z-index: 70;
  padding: var(--s3) var(--gutter) calc(var(--s3) + env(safe-area-inset-bottom));
  background: rgba(7, 11, 20, .94);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  border-top: 1px solid var(--line);
  transform: translateY(110%);
  transition: transform var(--dur-2) var(--ease);
  display: none;
}
.sticky-cta.is-on { transform: none; }

/* ----------------------------------------------------------------- 11 HERO */
.hero {
  position: relative;
  min-height: min(92svh, 900px);
  display: flex; align-items: flex-end;
  padding-top: calc(var(--hdr-h) + var(--s8));
  padding-bottom: var(--s8);
  overflow: hidden;
}
.hero__art { position: absolute; inset: 0; z-index: 0; }
.hero__art .art { width: 100%; height: 100%; aspect-ratio: auto; border: 0; border-radius: 0; }
.hero__art .art::after {
  background:
    linear-gradient(to right, rgba(10,16,32,.96) 0%, rgba(10,16,32,.86) 38%, rgba(10,16,32,.42) 72%, rgba(10,16,32,.62) 100%),
    linear-gradient(to top, rgba(7,11,20,.9), rgba(7,11,20,0) 55%);
}
.hero__in { position: relative; z-index: 2; width: 100%; }
.hero__h { max-width: 17ch; margin-top: var(--s4); }
.hero__sub { margin-top: var(--s5); max-width: 54ch; }
.hero__actions { margin-top: var(--s6); }
.hero .strip { margin-top: var(--s8); }

/* Page head for interior surfaces — smaller, no image behind the text. */
.phead { padding-top: calc(var(--hdr-h) + var(--s8)); padding-bottom: var(--s7); }
.phead__h { max-width: 20ch; margin-top: var(--s4); font-size: clamp(2.1rem, 1.2rem + 3.4vw, 3.9rem); }
.phead__s { margin-top: var(--s5); }

/* THE MASTHEAD, above 1080px.
   Every page head was a headline capped at 20ch and a standfirst capped at 68ch,
   stacked at the left of a 1320px container. Both caps are correct — a 1300px
   line of body copy is unreadable and the fix for "it only fills half the page"
   is never to make the lines longer. The fault was that nothing used the other
   half, so a correctly-measured column read as a box stranded on the left.
   So the head becomes two columns and the standfirst moves up beside the
   headline, where it also does its actual job better: it is read as the second
   half of the title rather than as the first paragraph of the page.
   Placement only — no template on this site had to change to get it.

   GUARDED, 2026-09-02. The grid assumes the wrap's DIRECT children are the
   eyebrow, the headline and the standfirst. Two templates do not fit that shape
   and were being broken by it:
     404.php nests the whole head inside a .rail, so the rail — the only child —
     was thrown into the narrow right-hand column and the left half of the band
     sat empty, with the headline wrapping at ten characters.
     page.php prints into .wrap--read, a 760px reading column, which the grid
     split into two ~370px columns and floated the "last updated" line beside
     the title instead of under it.
   The grid therefore engages only on a full-width wrap that actually holds a
   .phead__h directly. Everything else keeps the stack it was designed as. */
@media (min-width: 1080px) {
  .phead > .wrap:not(.wrap--read):has(> .phead__h) {
    display: grid;
    grid-template-columns: minmax(0, 1.08fr) minmax(0, 0.92fr);
    column-gap: clamp(2.5rem, 1rem + 4vw, 5.5rem);
    align-items: start;
  }
  .phead > .wrap:not(.wrap--read):has(> .phead__h) > .eyebrow { grid-column: 1 / -1; grid-row: 1; }
  .phead > .wrap:not(.wrap--read):has(> .phead__h) > .phead__h {
    grid-column: 1;
    grid-row: 2 / span 12;   /* holds the left column for however many rows the right needs */
    max-width: none;         /* the column is the measure now */
    align-self: start;
  }
  /* The standfirst and anything after it stack down the right-hand column. */
  .phead > .wrap:not(.wrap--read):has(> .phead__h) > *:not(.eyebrow):not(.phead__h) { grid-column: 2; }
  .phead > .wrap:not(.wrap--read):has(> .phead__h) > .phead__s {
    grid-row: 2;
    margin-top: .45rem;      /* drops the first line onto the headline's first baseline */
    max-width: 46ch;
  }
}

/* ----------------------------------------------------------- 12 COMPONENTS */

/* Blind-spot card. A question, a recognition line, a figure, a rule that draws on hover. */
.spot {
  position: relative; display: grid; gap: var(--s4);
  padding: var(--s6) 0 var(--s6);
  border-top: 1px solid var(--rule);
}
.spot__n { color: var(--swan-500); }
.spot__q {
  font-family: var(--serif); font-size: clamp(1.35rem, 1.05rem + 1.05vw, 1.95rem);
  line-height: 1.2; letter-spacing: -.018em; max-width: 24ch;
  transition: color var(--dur-1) var(--ease-in-out);
}
.spot__r { color: var(--fg-dim); font-size: var(--t-small); max-width: 46ch; }
.spot__f { margin-top: var(--s2); }
.spot:hover .spot__q { color: var(--swan-300); }
.mode-read .spot:hover .spot__q { color: var(--swan-400); }
.spot__link { color: inherit; }  /* was an inline style in front-page.php; see .card__link */
.spot__link::after { content: ""; position: absolute; inset: 0; }

.spot-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 var(--s7); }

/* The house analogy — five trades, broken links between them. */
.trades { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 0; margin-block: var(--s6); }
.trades__t {
  position: relative; padding: var(--s4) var(--s3);
  border: 1px solid var(--rule); border-right: 0;
  font-size: var(--t-note); text-transform: uppercase; letter-spacing: .13em;
  font-weight: 600; color: var(--fg-dim); text-align: center;
}
.trades__t:last-child { border-right: 1px solid var(--rule); }
.trades__t::after {
  content: ""; position: absolute; top: 50%; right: -5px; width: 10px;
  border-top: 1px dashed var(--neg); opacity: .7;
}
.trades__t:last-child::after { display: none; }

/* Four-step method. */
.steps { counter-reset: step; display: grid; gap: 0; }
.step {
  display: grid; grid-template-columns: 4.5rem minmax(0, 1fr);
  gap: var(--s5); padding: var(--s6) 0;
  border-top: 1px solid var(--rule);
}
.step__n { font-family: var(--serif); font-size: 1.5rem; color: var(--swan-500); font-variant-numeric: tabular-nums; }
.step__t { font-family: var(--serif); font-size: var(--t-h3); line-height: 1.25; }
.step__b { margin-top: var(--s3); color: var(--fg-dim); max-width: 56ch; }
/* A step with no title. The margin above belongs to a body that follows a
   .step__t in the same cell; where the body sits directly beside the ordinal —
   the running order on /masterclass/, the checklist on the blind-spot pages —
   it was pushing the text 12px below the number's line and the two columns
   read as misaligned. One of those templates was already correcting it with an
   inline margin-top:0; this is that correction, owned by the component. */
.step__n + .step__b { margin-top: 0; }

/* Tabs — used by proof exhibits and the audience selector.
   REBUILT. The first version was an underline strip: bare text with a 2px bar
   under the selected one. The client looked at it and said the tabs were not
   identifiable, and they were right, for three reasons that compound. Bare text
   at --fg-faint reads as disabled labels, not controls. Nothing encloses the
   strip, so it reads as a heading row rather than a switch. And with seven tabs
   the strip wrapped, orphaning the seventh on a second row with nothing under it.
   The site already has a language for "cells you can press" — the calculator
   routes, the quiz answers, the estate rungs: a bordered tile, background lift
   on hover, and an inset orange bar when active. Tabs now speak it too. A ragged
   last row of tiles reads as intentional in a way an orphaned underline never
   did, because each tile carries its own box. Borders are collapsed with
   negative margins rather than the 1px-gap background trick, because that trick
   paints a grey ghost cell wherever the count does not fill the row. */
/* A GRID OF EQUAL COLUMNS, not a flex row. The flex version sized each tile to
   its label, so no two tiles matched, and when the strip wrapped the leftover
   tile stretched across the entire second row with its label floating in the
   middle of nothing. auto-fit with an equal fraction gives every tile the same
   width, collapses unused tracks (so four tabs fill the row exactly), and when
   wrapping does happen the second row lands on the same column grid as the
   first. At full width all seven exhibits now fit on one row. Labels are
   allowed to wrap to two lines rather than forcing the row wider — the grid
   stretches every tile in the row to the same height, so one two-line label
   costs a taller row, never a ragged one. */
.tabs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
  padding: 1px 0 0 1px;             /* room for the collapsed borders below */
}
.tab {
  appearance: none; cursor: pointer;
  margin: -1px 0 0 -1px;            /* neighbouring tiles share one hairline */
  border: 1px solid var(--rule);
  background: var(--bg);
  padding: var(--s3) var(--s4);
  min-height: 52px;
  display: flex; align-items: center; justify-content: center;
  color: var(--fg-dim); font-weight: 600; font-size: .95rem;
  text-align: center; line-height: 1.3;
  transition: color var(--dur-1) var(--ease-in-out), background var(--dur-1) var(--ease-in-out);
}
.tab:hover { background: var(--bg-raised); color: var(--fg); }
/* The active bar is the tile's own bottom border plus a 1px inset — 2px of
   orange flush inside the cell's edge. The old inset-only shadow drew on top of
   a still-dark border and started a pixel left of the visible hairline, which
   read as the bar leaking out of its tile. */
.tab[aria-selected="true"] {
  background: var(--bg-raised);
  color: var(--fg);
  border-bottom-color: var(--act);
  box-shadow: inset 0 -1px 0 var(--act);
}
/* The keyboard ring has to beat the neighbouring tiles' borders. */
.tab:focus-visible { position: relative; z-index: 1; }
.tabpanel { padding-top: var(--s7); }
.tabpanel[hidden] { display: none; }

/* Accordion — FAQ. */
.acc { border-top: 1px solid var(--rule); }
.acc__q {
  width: 100%; appearance: none; background: none; border: 0; cursor: pointer;
  display: flex; align-items: flex-start; gap: var(--s4);
  padding: var(--s5) 0; text-align: left;
  font-family: var(--serif); font-size: var(--t-h3); line-height: 1.28; color: var(--fg);
  transition: color var(--dur-1) var(--ease-in-out);
}
/* Hover feedback. The question rows are buttons, and they were the only
   pressable rows on the site that gave nothing back under the pointer — the
   cursor changed and the row did not. They now answer the way every other
   whole-row control here answers: the serif line lifts to the light blue the
   cards and the diagnosis rows already use. */
.acc__q:hover { color: var(--swan-300); }
.acc__q .sign { flex: none; width: 16px; height: 16px; margin-top: .45em; position: relative; }
.acc__q .sign::before, .acc__q .sign::after {
  content: ""; position: absolute; background: var(--swan-500);
  transition: transform var(--dur-2) var(--ease), opacity var(--dur-1);
}
.acc__q .sign::before { inset: 7px 0 auto; height: 1.5px; }
.acc__q .sign::after  { inset: 0 7px auto; width: 1.5px; height: 16px; }
.acc__q[aria-expanded="true"] .sign::after { transform: rotate(90deg); opacity: 0; }
.acc__a { overflow: hidden; height: 0; transition: height var(--dur-2) var(--ease-in-out); }
.acc__a > div { padding-bottom: var(--s6); color: var(--fg-dim); max-width: var(--measure); }
.acc__a p + p { margin-top: var(--s4); }
.acc__item { border-bottom: 1px solid var(--rule); }

/* Data table. Figures right, tabular, summed under a rule. */
.tbl { font-size: var(--t-small); }
.tbl caption { text-align: left; padding-bottom: var(--s4); color: var(--fg-faint); font-size: var(--t-note); text-transform: uppercase; letter-spacing: .14em; font-weight: 600; }
.tbl th, .tbl td { padding: var(--s3) var(--s4); border-bottom: 1px solid var(--rule); text-align: left; vertical-align: baseline; }
.tbl th { font-weight: 600; color: var(--fg-faint); font-size: var(--t-note); text-transform: uppercase; letter-spacing: .12em; }
.tbl td:last-child, .tbl th:last-child { text-align: right; font-variant-numeric: tabular-nums; }
.tbl tbody tr:hover { background: rgba(96, 144, 252, .05); }
.tbl tfoot td { border-top: 2px solid var(--rule); border-bottom: 0; font-weight: 600; color: var(--fg); }
.tbl-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* Slider — the corporation calculator. */
.slider { display: grid; gap: var(--s3); }
.slider__row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s4); }
.slider__v { font-family: var(--serif); font-size: 1.9rem; line-height: 1; font-variant-numeric: tabular-nums; }
input[type="range"] {
  -webkit-appearance: none; appearance: none;
  width: 100%; height: 2px; background: var(--rule); cursor: pointer; margin: var(--s4) 0;
}
input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; width: 22px; height: 22px; border-radius: 50%;
  background: var(--act); border: 0; box-shadow: 0 0 0 6px rgba(252, 96, 0, .16);
  transition: box-shadow var(--dur-1) var(--ease-in-out);
}
input[type="range"]:hover::-webkit-slider-thumb { box-shadow: 0 0 0 10px rgba(252, 96, 0, .2); }
input[type="range"]::-moz-range-thumb {
  width: 22px; height: 22px; border-radius: 50%; background: var(--act); border: 0;
  box-shadow: 0 0 0 6px rgba(252, 96, 0, .16);
}

/* Route chips — the four doors out of a corporation. */
.routes { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 1px; background: var(--rule); border: 1px solid var(--rule); }
/* False affordance, corrected. This cell is used two ways: as a pressable
   <button> where clicking between the four doors is the lesson, and as an inert
   <div> on the homepage calculator, where all four figures compute at once and
   there is nothing to press. The base rule used to put cursor:pointer and a
   hover lift on both, which promised a click the homepage cells could not
   honour — a visitor clicks, nothing happens, and the page reads as broken.
   Pointer and hover now belong to the button form only. */
.route {
  appearance: none; border: 0; text-align: left;
  background: var(--bg); padding: var(--s4);
  display: grid; gap: var(--s2);
  transition: background var(--dur-1) var(--ease-in-out);
}
button.route { cursor: pointer; }
button.route:hover { background: var(--bg-raised); }
.route[aria-pressed="true"] { background: var(--bg-raised); box-shadow: inset 0 -2px 0 var(--act); }
.route__l { font-size: var(--t-note); text-transform: uppercase; letter-spacing: .13em; font-weight: 600; color: var(--fg-faint); }
.route__r { font-family: var(--serif); font-size: 1.5rem; line-height: 1; font-variant-numeric: tabular-nums; }

/* Ladder — the estate rungs. */
.ladder { display: grid; gap: 1px; background: var(--rule); border: 1px solid var(--rule); }
.rung {
  appearance: none; border: 0; cursor: pointer; text-align: left; background: var(--bg);
  padding: var(--s5); display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--s4); align-items: baseline;
  transition: background var(--dur-1) var(--ease-in-out);
}
.rung:hover, .rung[aria-pressed="true"] { background: var(--bg-raised); }
.rung[aria-pressed="true"] { box-shadow: inset 2px 0 0 var(--act); }

/* Article cards. */
.cards { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s6); }
.card { position: relative; display: grid; gap: var(--s3); padding-top: var(--s5); border-top: 1px solid var(--rule); }
.card__t { font-family: var(--serif); font-size: var(--t-h3); line-height: 1.24; transition: color var(--dur-1); }
.card:hover .card__t { color: var(--swan-300); }
.mode-read .card:hover .card__t { color: var(--swan-400); }
.card__x { color: var(--fg-dim); font-size: var(--t-small); }
/* The title's own anchor. Without this the global link colour painted every
   card title on /insights/ the same blue — nine titles reading as one undated
   link pile, no hierarchy against the eyebrow, and the hover shift above was
   invisible because the anchor's colour beat the wrapper's. The stretched-link
   pattern is used three times on this site (.card, .spot, .dx) and the other
   two were patched per-template with an inline color:inherit; each now carries
   this rule in its own block instead, and the inline patches are gone. */
.card__link { color: inherit; }
.card__link::after { content: ""; position: absolute; inset: 0; }

/* Lanes — who owns what, shared with accountants and lawyers. */
.lanes { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1px; background: var(--rule); border: 1px solid var(--rule); }
.lane { background: var(--bg); padding: var(--s6); display: grid; gap: var(--s4); align-content: start; }
.lane--ours { background: var(--bg-raised); box-shadow: inset 0 -3px 0 var(--act); }
.lane__h { font-family: var(--serif); font-size: var(--t-h3); }
.lane li { padding: var(--s2) 0; border-bottom: 1px solid var(--rule); color: var(--fg-dim); font-size: var(--t-small); }
.lane li:last-child { border-bottom: 0; }

/* Long-form article body, on paper. */
/* Long-form on ink. Slightly larger than the paper setting, more leading, and a
   body colour a few steps back from white: #C9D4E6 on the page ground measures
   about 11:1, which is comfortable rather than glaring over two thousand words. */
.prose { font-size: 1.175rem; line-height: 1.8; color: #C9D4E6; max-width: var(--measure-read); }
.prose > * + * { margin-top: var(--s5); }
.prose h2 { font-size: clamp(1.6rem, 1.2rem + 1.5vw, 2.2rem); margin-top: var(--s8); }
.prose h3 { margin-top: var(--s7); }
.prose strong { font-weight: 600; }
.prose em { font-style: italic; }
.prose ul { list-style: none; }
.prose ul li { position: relative; padding-left: 1.4em; }
.prose ul li::before { content: ""; position: absolute; left: 0; top: .72em; width: .6em; border-top: 1px solid var(--swan-500); }
.prose ul li + li { margin-top: var(--s3); }
.prose blockquote {
  border-left: 2px solid var(--swan-500); padding-left: var(--s5);
  font-family: var(--serif); font-size: 1.35rem; line-height: 1.45; color: var(--fg);
}

/* The sources-and-cautions block. Attached to every article, never optional. */
.sources {
  margin-top: var(--s9); padding: var(--s6);
  border: 1px solid var(--line); background: var(--ink-850);
  font-size: .9rem; line-height: 1.65; color: var(--fg-dim);
  max-width: var(--measure-read);
}
.sources h2 {
  font-family: var(--sans); font-size: var(--t-note); text-transform: uppercase;
  /* --swan-600 here was correct while this block sat on the pale stock. On the
     ink ground it measures 3.95:1, under AA for an 11.5px semibold heading, and
     it was the last paper-era colour left in the stylesheet. --swan-400 is 8.66:1
     and is what every comparable heading already uses. */
  letter-spacing: .14em; font-weight: 600; color: var(--swan-400); margin: 0 0 var(--s3);
}

/* Flags carried through from the client's own material. */
.flag {
  display: inline-flex; align-items: center; gap: .4em;
  font-size: var(--t-note); text-transform: uppercase; letter-spacing: .12em;
  font-weight: 600; color: var(--beak-500);
  padding: .2em .55em; border: 1px solid rgba(252, 96, 0, .38);
}

/* ---------------------------------------------------------------- 13 FORMS */
.form { display: grid; gap: var(--s4); }
.field { display: grid; gap: var(--s2); }
.field label { font-size: var(--t-small); font-weight: 600; color: var(--fg); }
.field .hint { font-size: var(--t-note); color: var(--fg-faint); text-transform: none; letter-spacing: 0; font-weight: 400; }
.field input[type="text"], .field input[type="email"], .field input[type="tel"], .field input[type="search"], .field textarea, .field select {
  width: 100%; min-height: 52px; padding: .8rem 1rem;
  background: rgba(255, 255, 255, .04);
  border: 1px solid var(--rule); border-radius: var(--radius);
  color: var(--fg); font-size: 1rem;
  transition: border-color var(--dur-1), background var(--dur-1);
  -webkit-user-select: text; user-select: text;
}
/* Form fields take the dark treatment everywhere. */
.field input:focus, .field textarea:focus { border-color: var(--swan-500); background: rgba(96, 144, 252, .06); }
.field input::placeholder, .field textarea::placeholder { color: var(--fg-faint); }
.field textarea { min-height: 132px; resize: vertical; }
.field.is-bad input, .field.is-bad textarea { border-color: var(--neg); }
.field .err { font-size: var(--t-small); color: var(--neg-400); }
.field .err:empty { display: none; }

.check { display: grid; grid-template-columns: 20px 1fr; gap: var(--s3); align-items: start; }
.check input { width: 20px; height: 20px; margin: 2px 0 0; accent-color: var(--beak-500); }
.check label { font-size: var(--t-small); font-weight: 400; color: var(--fg-dim); line-height: 1.5; }

.hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

.form__msg { padding: var(--s4); border: 1px solid var(--rule); font-size: var(--t-small); }
.form__msg--ok  { border-color: var(--pos); color: var(--pos); }
/* Border stays --neg (non-text, 3:1 floor); the words take the text step. */
.form__msg--bad { border-color: var(--neg); color: var(--neg-400); }

/* --------------------------------------------------------------- 14 FOOTER */
/* Four columns and a legal band. The second and third columns are real
   navigation — the same seven the header carries, and the seven problems — so
   the footer is a second way through the site rather than a list of leftovers. */
.ftr { background: var(--ink-950); color: #97A6C0; padding-block: var(--s9) var(--s7); border-top: 1px solid var(--line); }
.ftr a { color: #B9C6DC; }
.ftr a:hover { color: #fff; }
.ftr__top { display: grid; grid-template-columns: 1.5fr 1fr 1.15fr 1.2fr; gap: var(--s7) var(--s6); }
.ftr__logo img { height: 40px; width: auto; }
.ftr__cred { max-width: 34ch; }
.ftr__carriers { max-width: 38ch; }
.ftr h3 { font-family: var(--sans); font-size: var(--t-note); text-transform: uppercase; letter-spacing: .14em; font-weight: 600; color: var(--swan-400); }
.ftr li { font-size: var(--t-small); }
/* Footer links are a touch target as much as a link — 44px tall, so a thumb on a
   phone lands on the row it aimed at rather than the one above it. */
.ftr__col a {
  display: flex; align-items: center; gap: .55em;
  min-height: 44px; line-height: 1.3;
}
.ftr__col a svg { flex: none; color: var(--swan-500); }
.ftr__col a[aria-current] { color: #fff; }
.ftr__addr { padding: .4rem 0 var(--s2); line-height: 1.55; }

/* The legal band runs the full width of the footer, like the columns above it.
   It was capped at 92ch, which left it stopping 244px short of them — one footer
   with two different right edges, which is what made it read as a box rather
   than as part of the page. Full width here, and the measure is kept where it
   belongs: on the individual paragraphs inside. */
.ftr__legal { margin-top: var(--s8); padding-top: var(--s6); border-top: 1px solid var(--line); font-size: .8125rem; line-height: 1.65; color: var(--fg-faint); }
.ftr__legal p + p { margin-top: var(--s3); }

/* The two standing paragraphs, side by side. Two 62ch columns beats one 160ch
   line, which is what full width without columns would have produced. */
.ftr__fine {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s4) clamp(2rem, 1rem + 3vw, 4.5rem);
  margin-bottom: var(--s5);
}
.ftr__fine p { max-width: 64ch; }
.ftr__fine p + p { margin-top: 0; }

/* THE DISCLOSURE. The only place on the site that carries it, so it is set
   brighter than the rest of the fine print and given a frame of its own.

   TWO CELLS, NOT TWO STACKED PARAGRAPHS. An accounting credential from one
   country and a set of life licences from another, neither qualifying the other.
   Stacked paragraphs let a reader run the two together, which is the exact
   misreading the whole compliance regime exists to prevent, and the previous
   version had to spend a third paragraph saying "these are two separate things"
   to stop it. Two labelled cells with a rule between them say that structurally,
   in no words at all. */
.ftr__disclosure {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s5);
  margin-bottom: var(--s6);
  padding: var(--s5);
  border: 1px solid var(--line);
  border-left: 2px solid var(--swan-500);
}
.ftr__claim { display: grid; gap: var(--s2); align-content: start; }
.ftr__claim + .ftr__claim {
  padding-left: var(--s5);
  border-left: 1px solid var(--line);
}
.ftr__claim-k {
  font-size: var(--t-note); text-transform: uppercase; letter-spacing: .14em;
  font-weight: 600; color: var(--swan-400);
}
.ftr__claim p { color: var(--fg-dim); font-size: .875rem; line-height: 1.6; max-width: 54ch; }

.ftr__meta { display: flex; flex-wrap: wrap; align-items: center; gap: 0 var(--s5); margin-top: var(--s4); }
.ftr__meta a { display: inline-flex; align-items: center; min-height: 44px; }

/* The build credit. The two halves of the studio's name go to two different
   domains, so they are two anchors — but they have to read as one name, which
   means the space between them is drawn here rather than sitting in the markup
   where it would become a third, unlinked node between two links. */
.ftr__credit { margin-left: auto; color: var(--fg-faint); }
/* nowrap so the studio's name never breaks across two lines. The space between
   the two halves is a real space in the markup — see pf_credit() in
   inc/helpers.php for why the two cleverer versions were both worse. */
.ftr__credit-n { white-space: nowrap; }
.ftr__credit a { color: var(--fg-dim); text-decoration: underline; text-decoration-color: var(--line); text-underline-offset: 3px; }
.ftr__credit a:hover { color: #fff; text-decoration-color: currentColor; }
.ftr__legal--bare { margin-top: 0; border-top: 0; padding-top: 0; }

/* ---------------------------------------------------------------- 15 MOTION */
/* Reveals fail SAFE. The default state is visible, and the hidden start state is
   applied only under .pf-js, which an inline script in the head adds before the
   first paint. So if the stylesheet loads and the script does not — blocked, a
   CSP, a proxy that mangles it, a browser that chokes on it — the page reads
   normally rather than being a column of invisible boxes. That failure mode is
   not hypothetical here: the previous build shipped it. */
.pf-js .rv { opacity: 0; transform: translateY(20px); }
.pf-js .rv.is-in {
  opacity: 1; transform: none;
  transition: opacity var(--dur-3) var(--ease), transform var(--dur-3) var(--ease);
  transition-delay: var(--rv-d, 0ms);
}
.art > img, .art > picture > img { transform: scale(1.06); transition: transform 1200ms var(--ease), opacity 600ms var(--ease); }
.is-in .art > img, .art.is-in > img,
.is-in .art > picture > img, .art.is-in > picture > img { transform: scale(1); }

@media (prefers-reduced-motion: reduce) {
  .pf-js .rv, .rv { opacity: 1; transform: none; transition: none; }
  .art > img, .art > picture > img { transform: none; transition: none; }
  .btn, .tlink, .nav__a, .acc__a, .drawer, .sticky-cta { transition: none !important; }
  .progress { display: none; }
  *, *::before, *::after { animation-duration: .001ms !important; animation-iteration-count: 1 !important; }
}

/* ------------------------------------------------------------- 16 UTILITIES */
.vh { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0; }
.mt-4 { margin-top: var(--s4); } .mt-5 { margin-top: var(--s5); }
.mt-6 { margin-top: var(--s6); } .mt-7 { margin-top: var(--s7); }
.mt-8 { margin-top: var(--s8); } .mt-9 { margin-top: var(--s9); }
.dim { color: var(--fg-dim); } .faint { color: var(--fg-faint); }
.act { color: var(--act); } .blue { color: var(--swan-400); }
.mode-read .blue { color: var(--swan-400); }
.center { text-align: center; margin-inline: auto; }
.narrow { max-width: var(--measure-tight); }
.nowrap { white-space: nowrap; }

/* ------------------------------------------------------------ 17 RESPONSIVE */
@media (max-width: 1100px) {
  .ftr__top { grid-template-columns: 1fr 1fr; gap: var(--s6); }
  .cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 960px) {
  :root { --hdr-h: 68px; }
  .nav { display: none; }
  .burger { display: block; }
  .sticky-cta { display: block; }
  .rail { grid-template-columns: minmax(0, 1fr); gap: var(--s5); }
  .rail__side { position: static; }
  .lanes { grid-template-columns: minmax(0, 1fr); }
  .routes { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .spot-grid { grid-template-columns: minmax(0, 1fr); gap: 0; }
  .cols-3, .cols-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .hero { min-height: auto; padding-bottom: var(--s7); }
  .hero__art .art::after {
    background:
      linear-gradient(to top, rgba(10,16,32,.97) 12%, rgba(10,16,32,.78) 52%, rgba(10,16,32,.5) 100%);
  }
}

@media (max-width: 720px) {
  /* The strip is flex now, so the old grid-template and the nth-child(n+3)
     divider are both dead: there is no third cell to divide. Cells wrap on
     their own and each keeps a readable minimum. */
  .strip { gap: 0 var(--s7); }
  .strip__cell { padding-top: var(--s4); min-width: 9rem; }
  .cols-2, .cols-3, .cols-4, .cards { grid-template-columns: minmax(0, 1fr); }
  .trades { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .trades__t { border: 1px solid var(--rule); }
  .trades__t::after { display: none; }
  .step { grid-template-columns: minmax(0, 1fr); gap: var(--s3); }
  .rung { grid-template-columns: minmax(0, 1fr); }
  .rung > :last-child { grid-column: 1 / -1; }
  .art-band .art { --ar: 4 / 5; }
  /* Tabs used to become a hidden-scrollbar horizontal scroller here, which put
     five of the seven exhibits off-screen with nothing saying so. Two equal
     columns instead: every tab visible and tappable, rows aligned to the same
     grid, and an odd count leaves one honest empty cell rather than a tile
     stretched across the row. */
  .tabs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 420px) {
  :root { --t-body: 1rem; }
  .routes { grid-template-columns: minmax(0, 1fr); }
}

/* Printing is disabled site-wide — see guard.css. This block only keeps the
   fallback legible if the guard script fails to load. */
@media print {
  .hdr, .ftr, .sticky-cta, .progress, .drawer { display: none !important; }
}

/* --- proof + numbers (added by template work) -------------------------------
   Components that page-proof.php, page-numbers.php and page-who.php need and
   that the system above did not already carry. Nothing here invents a colour:
   every value is a token declared in section 0. Everything composes with
   .tabs / .ladder / .tbl / .plate / .callout rather than replacing them, and
   every element the JS toggles with [hidden] carries an explicit display guard
   so a display rule below can never defeat the attribute.
   ------------------------------------------------------------------------- */

/* Tables ------------------------------------------------------------------ */
/* A table wider than its column scrolls inside .tbl-scroll instead of pushing
   the page sideways. The minimum is set per table from its own column count,
   so a three-column table is not forced to the width of a six-column one. */
.tbl-scroll > .tbl { min-width: var(--tbl-min, 0); }

/* Figure tables: the first column labels the row, everything after it is a
   number, right aligned and tabular. Row headers stay sentence case — the
   uppercase small-caps treatment in section 12 is for column heads only. */
.tbl--fig td { text-align: right; font-variant-numeric: tabular-nums; }
.tbl--fig th:not(:first-child) { text-align: right; }
.tbl--fig tbody th,
.tbl--ref tbody th {
  font-size: var(--t-small); text-transform: none; letter-spacing: 0;
  color: var(--fg); font-weight: 600;
}
.tbl tbody tr.is-hi td,
.tbl tbody tr.is-hi th { color: var(--fg); font-weight: 600; }
.tbl tbody tr.is-hi th:first-child { box-shadow: inset 2px 0 0 var(--act); }

/* The reference table on the 2026 numbers page: label, figure, caveat. The
   figure is the middle column, so the section 12 last-child rule is undone. */
.tbl--ref th:last-child, .tbl--ref td:last-child { text-align: left; }
.tbl--ref .v {
  text-align: right; font-variant-numeric: tabular-nums;
  white-space: nowrap; color: var(--fg); font-weight: 600;
}
.tbl--ref tbody th { width: 22%; }
.tbl--ref .n { color: var(--fg-dim); width: 50%; }

/* The federal / provincial separation banner. Two halves, one rule between
   them, the BC half marked so the distinction survives a glance. */
.split {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px; background: var(--rule); border: 1px solid var(--rule);
}
.split__half { background: var(--bg); padding: var(--s6); display: grid; align-content: start; gap: var(--s3); }
.split__half--bc { background: var(--bg-raised); box-shadow: inset 0 -3px 0 var(--act); }
.split__t { font-family: var(--serif); font-size: var(--t-h3); line-height: 1.22; letter-spacing: -.014em; color: var(--fg); }
.split__b { color: var(--fg-dim); font-size: var(--t-small); max-width: 48ch; }

/* The quiz ---------------------------------------------------------------- */
/* Four answers, all of them correct. State is boot('quiz') in priceless.js;
   this is only the surface that subsystem operates on. */
.quiz__opts {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 1px; background: var(--rule); border: 1px solid var(--rule);
}
.quiz__opt {
  appearance: none; border: 0; cursor: pointer; text-align: left;
  background: var(--bg); padding: var(--s5);
  display: grid; gap: var(--s2); align-content: start;
  transition: background var(--dur-1) var(--ease-in-out);
}
.quiz__opt:hover { background: var(--bg-raised); }
.quiz__opt[aria-pressed="true"] { background: var(--bg-raised); box-shadow: inset 0 -2px 0 var(--act); }
.quiz__k { font-size: var(--t-note); text-transform: uppercase; letter-spacing: .145em; font-weight: 600; color: var(--swan-400); }
.mode-read .quiz__k { color: var(--swan-400); }
.quiz__a {
  font-family: var(--serif); font-size: clamp(1.45rem, 1.1rem + 1.25vw, 2.05rem);
  line-height: 1; letter-spacing: -.03em; font-variant-numeric: tabular-nums; color: var(--fg);
}
/* The action line inside a quiz cell. It used to sit in the faint grey the
   fine print uses, which is the colour this site gives to things you cannot do
   anything about — so the one line telling the visitor to click read as a
   caption. It is set as a link now, with the arrow the site's other actions
   carry, because it is one. */
.quiz__go {
  font-size: var(--t-small); font-weight: 600; color: var(--link);
  display: inline-flex; align-items: center; gap: .4em;
}
.quiz__go::after { content: "→"; font-size: .9em; transition: transform var(--dur-2) var(--ease); }
.quiz__opt:hover .quiz__go::after { transform: translateX(3px); }
.quiz__opt[aria-pressed="true"] .quiz__go { color: var(--fg-faint); }
.quiz__opt[aria-pressed="true"] .quiz__go::after { content: none; }

/* The counter. Nobody quits at two if the page is visibly keeping score. */
.quiz__count {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s3) var(--s5);
  border-top: 1px solid var(--rule); padding-top: var(--s5);
}
.quiz__count .fine { flex: 1 1 26ch; margin: 0; }
.dots { display: flex; gap: var(--s2); align-items: center; }
.dot {
  width: 10px; height: 10px; border-radius: 50%;
  /* --rule at 10px was nearly invisible — the score-keeper the quiz depends on
     read as dust on the screen. The unfilled state now uses the same blue the
     annotation layer uses, at a weight that survives a laptop at arm's length. */
  border: 1.5px solid var(--fg-faint); background: transparent;
  transition: background var(--dur-1) var(--ease-in-out), border-color var(--dur-1) var(--ease-in-out);
}
.dot.is-on { background: var(--act); border-color: var(--act); }

.working {
  margin-top: var(--s6);
  border-left: 2px solid var(--swan-500);
  padding: var(--s4) 0 var(--s4) var(--s5);
  max-width: var(--measure);
}
.mode-read .working { border-left-color: var(--swan-400); }
.working__l { margin-top: var(--s3); color: var(--fg-dim); }
.working[hidden] { display: none; }
.reveal { margin-top: var(--s7); }
.reveal[hidden] { display: none; }

/* Comparison -------------------------------------------------------------- */
/* Two outcomes side by side. auto-fit rather than a fixed pair, because the
   estate ladder reuses this for a rung that carries a single figure. */
.cmp {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
  gap: 1px; background: var(--rule); border: 1px solid var(--rule);
}
.cmp__side { background: var(--bg); padding: var(--s6); display: grid; align-content: start; }
.cmp__both { margin-top: var(--s6); border-top: 2px solid var(--rule); padding-top: var(--s6); max-width: var(--measure); }

/* The estate ladder ------------------------------------------------------- */
/* .ladder / .rung already exist. These are the three cells inside a rung, plus
   the panel each rung reveals through the pressgroup contract. */
.rung__t { display: grid; gap: var(--s1); }
.rung__step { font-size: var(--t-note); text-transform: uppercase; letter-spacing: .145em; font-weight: 600; color: var(--fg-faint); }
.rung__ttl { font-family: var(--serif); font-size: var(--t-h3); line-height: 1.22; letter-spacing: -.014em; color: var(--fg); }
.rung__state { font-size: var(--t-small); color: var(--swan-400); text-align: right; }
.mode-read .rung__state { color: var(--swan-400); }
/* The press affordance. The four rungs are buttons in a pressgroup, and they
   read as a static table: serif titles, small-caps ordinals, a finding on the
   right — every part of them speaks the site's DATA vocabulary and nothing
   speaks its ACTION vocabulary. The quiz solved the identical problem with an
   arrow on the line that answers a press, so the rung's state line — already
   set in the link blue — now carries the same arrow, moves the same way on
   hover, and hands over to the orange bar once pressed. */
.rung__state::after {
  content: "→"; display: inline-block; margin-left: .4em; font-size: .9em;
  transition: transform var(--dur-2) var(--ease);
}
.rung:hover .rung__state::after { transform: translateX(3px); }
.rung[aria-pressed="true"] .rung__state { color: var(--act); }
.rung[aria-pressed="true"] .rung__state::after { content: none; }
.rung-panel[hidden] { display: none; }

/* Rungs two and three carry no dollar figure and that is the finding, not a
   gap. A dashed rule reads as a decision; an empty slot reads as an omission. */
.nofig { border: 1px dashed var(--rule); padding: var(--s5); max-width: var(--measure); }
.nofig__b { margin-top: var(--s3); color: var(--fg-dim); }

/* Sourcing ---------------------------------------------------------------- */
/* Deliberately not small print. On the proof page the assumptions block is the
   reason the page works, so it is set at reading size under a brand rule. */
.src { border-top: 2px solid var(--swan-500); padding-top: var(--s5); max-width: var(--measure); }
.mode-read .src { border-top-color: var(--swan-400); }
.src__b { margin-top: var(--s4); color: var(--fg-dim); }
.src .flag { margin-left: var(--s3); }

/* Self-identification ----------------------------------------------------- */
/* A ruled list. Rules, not boxes: this site does not put cards round things. */
.ruled { max-width: var(--measure); border-top: 1px solid var(--rule); }
.ruled__i {
  display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--s4);
  padding: var(--s4) 0; border-bottom: 1px solid var(--rule); color: var(--fg-dim);
}
.ruled__m { line-height: 1.6; }

/* The analogy. Drawn from the reader's own working world, and the sharpest
   line in each profile, so it is set as a pull quote and not a paragraph. */
.pull { border-left: 2px solid var(--swan-500); padding: var(--s2) 0 var(--s2) var(--s6); }
.mode-read .pull { border-left-color: var(--swan-400); }
.pull__q {
  font-family: var(--serif); font-size: clamp(1.3rem, 1.02rem + 1.1vw, 1.9rem);
  line-height: 1.28; letter-spacing: -.018em; color: var(--fg); text-wrap: balance;
}

/* The two doors out of a profile. */
.doors {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px; background: var(--rule); border: 1px solid var(--rule);
}
.door {
  background: var(--bg); padding: var(--s6); color: var(--fg);
  display: grid; gap: var(--s3); align-content: start;
  transition: background var(--dur-1) var(--ease-in-out);
}
.door:hover { background: var(--bg-raised); }
.door__t {
  font-family: var(--serif); font-size: var(--t-h3); line-height: 1.22;
  letter-spacing: -.014em; max-width: 26ch;
  transition: color var(--dur-1) var(--ease-in-out);
}
.door:hover .door__t { color: var(--swan-300); }
.mode-read .door:hover .door__t { color: var(--swan-400); }
.door__go { display: inline-flex; align-items: center; gap: .5em; font-size: var(--t-small); font-weight: 600; color: var(--link); }
.door__go svg { transition: transform var(--dur-2) var(--ease); }
.door:hover .door__go svg { transform: translateX(4px); }

/* Responsive -------------------------------------------------------------- */
@media (max-width: 960px) {
  .quiz__opts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .split, .doors { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 720px) {
  .quiz__opts { grid-template-columns: minmax(0, 1fr); }
  .rung__state { text-align: left; }
  .pull { padding-left: var(--s5); }
  .cmp__side, .split__half, .door { padding: var(--s5); }
  .tbl--ref tbody th, .tbl--ref .n { width: auto; }
}

@media (prefers-reduced-motion: reduce) {
  .quiz__opt, .dot, .door, .door__go svg, .cmp__side,
  .quiz__go::after, .rung__state::after { transition: none; }
}

/* --- about + contact (added by template work) --- */
/* Everything below is additive. No token is redefined, no existing rule is
   rewritten, and no hex value appears that the token layer did not already name.
   These are the components used by page-about.php, page-contact.php,
   page-faq.php and page.php that the original sheet had no reason to carry. */

/* ---- /about/ : the biography column and the one photograph -------------- */
.bio {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 21rem);
  gap: clamp(2rem, 1rem + 4vw, 5rem);
  align-items: start;
}
.bio__say { min-width: 0; }

/* The only photograph of a real person on this site, and there is never a second
   one. No team shots, no office shots, no stock people. See BRIEF 0.9. The ratio
   is pinned to the file's own 4:5 so the space is reserved before it decodes. */
.portrait { margin: 0; max-width: 21rem; }
.portrait img {
  width: 100%; height: auto;
  aspect-ratio: 4 / 5; object-fit: cover;
  border: 1px solid var(--line-soft);
  border-radius: var(--radius-art);
  filter: saturate(.9) contrast(1.03);
}
.portrait__cap { display: grid; gap: var(--s1); margin-top: var(--s4); }
.portrait__n { font-family: var(--serif); font-size: var(--t-h3); line-height: 1.2; color: var(--fg); }
.portrait__c { font-size: var(--t-small); line-height: 1.5; color: var(--fg-faint); }

/* The name story. The one anecdote on the page, set apart rather than buried as a
   fourth paragraph. It reuses the .pull / .pull__q pull-quote already defined
   above rather than adding a second one; only the placement and the attribution
   line are new, and the placement is scoped so it cannot reach any other .pull. */
.bio .pull { margin-top: var(--s7); max-width: 54ch; }
.pull__by {
  margin-top: var(--s4);
  font-size: var(--t-note); text-transform: uppercase; letter-spacing: .145em;
  font-weight: 600; color: var(--swan-400);
}
.mode-read .pull__by, .mode-operate .pull__by { color: var(--swan-400); }

/* ---- /about/ : the credentials, as four separate claims ----------------- */
/* A ruled definition list and never a paragraph. The designation is Indian, the
   licences are Canadian, and a reader must not be able to run the two together.
   See BRIEF 0.2 and inc/brand.php. */
.creds { border-top: 1px solid var(--rule); max-width: var(--measure); }
.creds__row {
  display: grid;
  grid-template-columns: minmax(0, 11rem) minmax(0, 1fr);
  gap: var(--s2) var(--s5);
  padding: var(--s5) 0;
  border-bottom: 1px solid var(--rule);
}
.creds__k {
  font-size: var(--t-note); text-transform: uppercase; letter-spacing: .145em;
  font-weight: 600; color: var(--swan-400); padding-top: .25em;
}
.mode-read .creds__k, .mode-operate .creds__k { color: var(--swan-400); }
.creds__v { margin: 0; color: var(--fg); }

/* ---- /about/ : the boundary line --------------------------------------- */
.boundary { border-top: 2px solid var(--rule); padding-top: var(--s5); max-width: 62ch; }
.boundary__t { margin-top: var(--s4); font-size: var(--t-lead); line-height: 1.5; color: var(--fg); }

/* ---- refs : the referral cards on /about/, the two exits on /faq/ ------- */
/* Deliberately NOT the .door component defined above. That one is a whole-card
   link with a hover state and an inline arrow. These carry an audience label, a
   body and a real 52px button, and two components fighting over one class name is
   how the previous build ended up with three stylesheets arguing about .btn. */
.refs {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px; background: var(--rule); border: 1px solid var(--rule);
}
.ref { background: var(--bg-raised); padding: var(--s6); display: grid; gap: var(--s3); align-content: start; }
.ref--wide { grid-column: 1 / -1; background: var(--bg); }
.ref__aud {
  font-size: var(--t-note); text-transform: uppercase; letter-spacing: .145em;
  font-weight: 600; color: var(--swan-400);
}
.mode-read .ref__aud, .mode-operate .ref__aud { color: var(--swan-400); }
.ref__h { font-family: var(--serif); font-size: var(--t-h3); line-height: 1.22; }
.ref__b { color: var(--fg-dim); font-size: var(--t-small); max-width: 54ch; }
.ref__go { margin-top: var(--s3); }

/* ---- /contact/ : three ways in, given equal weight --------------------- */
.ways {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px; background: var(--rule); border: 1px solid var(--rule);
}
.way { background: var(--bg); padding: var(--s6); display: grid; gap: var(--s3); align-content: start; }
.way__i { display: block; color: var(--swan-500); }
.mode-read .way__i, .mode-operate .way__i { color: var(--swan-400); }
.way__l {
  font-size: var(--t-note); text-transform: uppercase; letter-spacing: .145em;
  font-weight: 600; color: var(--fg-faint);
}
/* The email address is thirty characters and has to survive a 300px column, so
   this is capped well below --t-h3 and allowed to break. */
.way__v {
  font-family: var(--serif);
  font-size: clamp(1.05rem, .95rem + .5vw, 1.35rem);
  line-height: 1.25; color: var(--fg);
  overflow-wrap: anywhere;
}
/* The number and the address are tap targets as well as text, so they carry the
   full 44px even though each card also has a 52px button under it. */
.way__v a { color: inherit; display: inline-flex; align-items: center; min-height: 44px; }
.way__v a:hover { color: var(--link); }
.way__b { color: var(--fg-dim); font-size: var(--t-small); }
.way__go { margin-top: var(--s4); }

/* ---- /contact/ : office, hours, what actually comes back --------------- */
.office { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: var(--s7); }
.office__cell { border-top: 2px solid var(--rule); padding-top: var(--s5); }
.office__addr {
  margin: 0; font-style: normal;
  font-family: var(--serif); font-size: var(--t-h3); line-height: 1.35; color: var(--fg);
}
.office__b { color: var(--fg-dim); }

/* ---- forms ------------------------------------------------------------- */
.form__go { display: grid; gap: var(--s3); justify-items: start; margin-top: var(--s3); }
/* .form__msg draws a bordered box. Without this rule an empty one is a stray
   rectangle sitting under every form on the site before anything is submitted. */
.form__msg:empty { display: none; padding: 0; border: 0; }
/* A 20px checkbox is under the 44px floor. The label is a target as well, so this
   raises the box and pads the row rather than resizing the shared component. */
.form--enquiry .check { grid-template-columns: 24px minmax(0, 1fr); min-height: 44px; }
.form--enquiry .check input { width: 24px; height: 24px; }
.form--enquiry .check label { padding-block: var(--s1); }

/* ---- accordion : the heading wrapper ----------------------------------- */
/* The button is wrapped in an h3 so the two question groups have a real document
   outline. The wrapper carries no type of its own; .acc__q already has all of it. */
.acc__h { margin: 0; font-size: inherit; line-height: inherit; letter-spacing: inherit; }
.acc__t { display: block; min-width: 0; }

/* ---- page.php : arbitrary editor content ------------------------------- */
/* .prose was written for article bodies, where the markup is ours. On the generic
   template it has to survive whatever the client types, so ordered lists, tables,
   fourth-level headings, captions and the alignment classes all get a definition. */
.prose h4 { font-family: var(--serif); font-size: 1.15rem; line-height: 1.3; margin-top: var(--s6); }
.prose a { color: var(--link); text-decoration: underline; text-underline-offset: .18em; }
.prose a:hover { color: var(--fg); }
.prose ol { list-style: decimal; padding-left: 1.5em; }
.prose ol li + li { margin-top: var(--s3); }
.prose ol li::marker { color: var(--fg-faint); font-variant-numeric: tabular-nums; }
.prose li > ul, .prose li > ol { margin-top: var(--s3); }
.prose hr { border-top: 1px solid var(--rule); margin-block: var(--s7); }
.prose figure { margin: 0; }
.prose figcaption { margin-top: var(--s3); font-size: var(--t-small); color: var(--fg-faint); }
.prose img { border-radius: var(--radius-art); }
.prose blockquote p + p { margin-top: var(--s4); }
.prose blockquote cite {
  display: block; margin-top: var(--s3);
  font-family: var(--sans); font-size: var(--t-small); font-style: normal; color: var(--fg-faint);
}

/* A wide table scrolls inside its own box rather than pushing the page sideways
   at 375px. Block-editor tables arrive wrapped in a figure; a table pasted
   straight into the editor does not, so both shapes are covered. */
.prose figure.wp-block-table { overflow-x: auto; -webkit-overflow-scrolling: touch; }
.prose > table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.prose table { font-size: var(--t-small); }
.prose caption {
  text-align: left; padding-bottom: var(--s3);
  font-size: var(--t-note); text-transform: uppercase; letter-spacing: .14em;
  font-weight: 600; color: var(--fg-faint);
}
.prose th, .prose td {
  padding: var(--s3) var(--s4); border-bottom: 1px solid var(--rule);
  text-align: left; vertical-align: baseline;
}
.prose th {
  font-family: var(--sans); font-size: var(--t-note);
  text-transform: uppercase; letter-spacing: .12em; font-weight: 600; color: var(--fg-faint);
}

.prose .alignleft  { float: left;  margin: 0 var(--s5) var(--s4) 0; max-width: 50%; }
.prose .alignright { float: right; margin: 0 0 var(--s4) var(--s5); max-width: 50%; }
.prose .aligncenter { margin-inline: auto; }
.prose .wp-caption { max-width: 100%; }
.prose .wp-caption-text { margin-top: var(--s3); font-size: var(--t-small); color: var(--fg-faint); }
.prose .screen-reader-text {
  position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%);
}

.pagelinks { display: flex; flex-wrap: wrap; gap: var(--s3); margin-top: var(--s7); }
.pagelinks a, .pagelinks > span {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 44px; min-height: 44px; padding: 0 var(--s3);
  border: 1px solid var(--rule);
}

/* Standalone text links on these four surfaces are navigation rather than
   in-sentence links, so they carry a full 44px target. */
.surface-about .tlink,
.surface-contact .tlink,
.surface-faq .tlink,
.page-doc .tlink { min-height: 44px; }

/* ---- responsive -------------------------------------------------------- */
@media (max-width: 1100px) {
  .ways, .office { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .office { gap: var(--s6); }
}

@media (max-width: 960px) {
  .bio { grid-template-columns: minmax(0, 1fr); }
  .portrait { max-width: 19rem; }
  .refs { grid-template-columns: minmax(0, 1fr); }
  .creds__row { grid-template-columns: minmax(0, 1fr); gap: var(--s2); }
  .creds__k { padding-top: 0; }
}

@media (max-width: 720px) {
  .ways, .office { grid-template-columns: minmax(0, 1fr); }
  .way, .ref { padding: var(--s5); }
  .bio .pull { margin-top: var(--s6); }
  .prose .alignleft, .prose .alignright { float: none; margin: 0; max-width: 100%; }
}

/* --- blind spots (added by template work) ---------------------------------
   Three components the system did not have yet, used by page-blind-spots.php and
   page-blind-spot.php. No new colour is introduced here and no value is
   hard-coded: everything below is built out of the tokens in section 0.

     .dxlist / .dx   the diagnosis index on the hub. A list, not a card grid.
     .honest         the pull quote that says when a problem is not a problem.
     .sources--ink   the existing sources block, re-grounded for an ink surface.
     .tbl--wide      a table with more than two columns, on a phone.
   ------------------------------------------------------------------------- */

/* The diagnosis index. Seven rows separated by hairlines, the figure held out to
   the right so the eye can compare seven of them down one column. Cards would make
   seven problems look like seven products and would force the comparison sideways,
   which is the wrong axis for this. */
.dxlist { border-top: 1px solid var(--rule); }

.dx {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 17rem);
  gap: var(--s5) clamp(1.5rem, .5rem + 2.4vw, 3.5rem);
  align-items: start;
  padding: var(--s7) var(--s4);
  margin-inline: calc(var(--s4) * -1);
  border-bottom: 1px solid var(--rule);
  transition: background var(--dur-1) var(--ease-in-out);
}
.dx:hover { background: rgba(96, 144, 252, .05); }

.dx__cat { margin-bottom: var(--s3); }

.dx__q {
  font-family: var(--serif);
  font-size: clamp(1.35rem, 1.02rem + 1.15vw, 2.05rem);
  line-height: 1.18;
  letter-spacing: -.018em;
  max-width: 26ch;
  transition: color var(--dur-1) var(--ease-in-out);
}
.dx:hover .dx__q { color: var(--swan-300); }
.mode-read .dx:hover .dx__q { color: var(--swan-400); }

.dx__s {
  margin-top: var(--s4);
  color: var(--fg-dim);
  font-size: var(--t-small);
  max-width: 54ch;
}

/* The row is the link, so this reads as an affordance rather than being one. The
   rule under it is drawn by hovering anywhere on the row. */
.dx__go { margin-top: var(--s5); }
.dx:hover .dx__go::after { transform: scaleX(1); }
.dx:hover .dx__go svg { transform: translateX(4px); }

.dx__link { color: inherit; }  /* was an inline style in page-blind-spots.php; see .card__link */
.dx__link::after { content: ""; position: absolute; inset: 0; }

.dx__f { text-align: right; }
.dx__f .plate { justify-items: end; }
.dx__f .plate__n { font-size: clamp(1.7rem, 1.15rem + 1.9vw, 2.6rem); }
.dx__f .plate__l { max-width: 34ch; }

@media (max-width: 1000px) {
  /* The figure drops under the text rather than being squeezed into a column too
     narrow for a small-caps label to survive in. */
  .dx { grid-template-columns: minmax(0, 1fr); }
  .dx__f { grid-column: 1 / -1; text-align: left; }
  .dx__f .plate { justify-items: start; }
}

@media (max-width: 720px) {
  .dx {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--s4);
    padding: var(--s6) var(--s4);
  }
  .dx__f { grid-column: 1 / -1; margin-top: var(--s2); }
}

/* The honest paragraph. Every one of the seven pages carries one, and it argues
   against its own page. It is set at pull-quote size for the same reason the
   sources block is never collapsed: the moment either of them is shrunk, the page
   stops being the thing it claims to be. Blue rule, not orange — the orange on
   these pages is spent on the cost figure and the action. */
.honest {
  max-width: 58ch;
  border-left: 2px solid var(--swan-500);
  padding-left: clamp(1.25rem, .6rem + 2vw, 2.5rem);
}
.mode-read .honest { border-left-color: var(--swan-400); }
.honest__p {
  font-family: var(--serif);
  font-size: clamp(1.15rem, 1.00rem + .85vw, 1.6rem);
  line-height: 1.5;
  letter-spacing: -.012em;
  color: var(--fg);
}

/* The sources-and-cautions block, on an ink ground. Same component, same rules,
   same never-trimmed contract as the article version — only the ground changes,
   because these seven print on ink and the paper card would read as a foreign
   object dropped onto the page. */
.sources--ink {
  background: var(--ink-850);
  border-color: var(--line);
  color: var(--fg-dim);
}
.sources--ink h2 { color: var(--swan-400); }

/* A table with more than two columns cannot squash onto a phone and stay
   readable, so it keeps a minimum width and scrolls inside .tbl-scroll instead.
   Only one of the seven blind spots needs this; the two-column ones fit any width.
   The first line feeds the --tbl-min hook that the proof block's
   `.tbl-scroll > .tbl` rule already reads, which is the intended way in. The
   second is the same declaration written directly, because that hook is owned by
   another surface and a five-column table squashed into three hundred pixels is
   not a failure this page is allowed to inherit. */
.tbl-scroll--wide { --tbl-min: 44rem; }
.tbl-scroll--wide > .tbl { min-width: 44rem; }

/* --- navigation rebuild ------------------------------------------------------
   Appended at the end on purpose. Everything in here has to win over §17
   RESPONSIVE, which was written for the five-item bar and the old footer, and
   the only honest way to do that without editing somebody else's section is to
   come after it. Nothing here invents a colour: every value is a token from §0.

   1. The bar. Below 960 the menu is the drawer, so the seven-item bar only has
      to survive 961–1320. The step-downs live in §10 with the rest of the menu;
      what is left here is the guard against a long label ever pushing the bar
      into the logo.
   2. The footer. §17 takes the four columns to two at 1100, which is right; it
      never took them to one, which left a two-column grid at 375 where the
      seven problems and the office block were both about eleven characters
      wide. That is fixed below.
   -------------------------------------------------------------------------- */

/* The logo never gives ground and the menu never wraps. If a label were ever
   long enough to overflow, the bar scrolls rather than folding onto a second
   line inside a fixed 76px header — a wrapped nav in a fixed bar disappears
   under the page. */
@media (min-width: 961px) {
  .hdr__logo { flex: 0 0 auto; }
  .nav { flex: 0 1 auto; overflow: visible; }
  .nav__list { flex-wrap: nowrap; }
}

/* Below the breakpoint the bar is gone and the drawer is the menu. Belt and
   braces on top of §17: the panel must never be reachable there, because the
   seven are already in the drawer as a sub-list. */
@media (max-width: 960px) {
  .nav__panel { display: none; }
}

/* The footer, at the two widths §17 did not cover. Two columns stay two all the
   way down to 560 — brand beside Menu, the seven beside Office — because
   spanning the brand across the top leaves the fourth column sitting next to a
   hole, and a hole in a four-block footer reads as a missing block. */
@media (max-width: 860px) {
  .ftr__top { grid-template-columns: 1fr 1fr; gap: var(--s6) var(--s5); }
}
@media (max-width: 560px) {
  .ftr { padding-block: var(--s8) var(--s7); }
  .ftr__top { grid-template-columns: minmax(0, 1fr); gap: var(--s6); }
  .ftr__legal { margin-top: var(--s7); }
  /* One column on a phone. The two claims keep their labels and gain a rule
     between them, so the separation survives the stack. */
  .ftr__disclosure { grid-template-columns: minmax(0, 1fr); padding: var(--s4); gap: var(--s4); }
  .ftr__claim + .ftr__claim {
    padding-left: 0; border-left: 0;
    padding-top: var(--s4); border-top: 1px solid var(--line);
  }
  .ftr__meta { gap: 0 var(--s4); }
  /* One column for the standing paragraphs on a phone. */
  .ftr__fine { grid-template-columns: minmax(0, 1fr); gap: var(--s3); }
  /* The credit stops being pushed to the end of a wrapped row and gets its own. */
  .ftr__credit { margin-left: 0; flex-basis: 100%; margin-top: var(--s3); }
}

/* The sticky action sits over the bottom of the page on the surfaces that carry
   it, and the legal band is the last thing on the page. Clear it. */
@media (max-width: 960px) {
  .ftr { padding-bottom: calc(var(--s7) + 4.5rem); }
}

/* Reduced motion. The dropdown and the drawer both still work, they just arrive
   rather than animate. The open/closed state is never carried by motion alone. */
@media (prefers-reduced-motion: reduce) {
  .nav__panel, .nav__tog svg, .nav__panel a, .nav__all svg { transition: none !important; }
  .nav__panel { transform: none !important; }
}

/* --- spacing and alignment pass, 26 Aug 2026 ------------------------------
   The client's note was that some sections only fill half the page and read as
   text in a box. They were right, and the cause was the same everywhere: a
   correctly-measured column of prose left-aligned in a 1320px container with
   nothing beside it. The answer is never to lengthen the lines — a 1300px line
   of body copy is unreadable — it is to use the other half of the band.
   ------------------------------------------------------------------------- */

/* The recognition opening on a blind-spot page. First paragraph larger on the
   left, the rest beside it. */
.recog {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  column-gap: clamp(2.5rem, 1rem + 4vw, 5.5rem);
  align-items: start;
  /* Each row is only as tall as its own content. Without this the first row is
     sized by the tall serif paragraph on the left, and the second paragraph in
     the right-hand column starts 200px below the first one with nothing in
     between — which looked like a bug, because it was one. */
  grid-auto-rows: min-content;
}
.recog > p {
  color: var(--fg);
  font-size: var(--t-lead);
  line-height: 1.5;
  max-width: 44ch;
}
.recog > p:first-child {
  grid-column: 1;
  grid-row: 1 / span 20;   /* holds the left column for however many the right needs */
  font-family: var(--serif);
  font-size: clamp(1.35rem, 1.05rem + 1.15vw, 1.95rem);
  line-height: 1.34;
  letter-spacing: -.012em;
  max-width: 20ch;
}
.recog > p:not(:first-child) { grid-column: 2; }
.recog > p:not(:first-child) + p { margin-top: var(--s5); }

/* The headline figure, set horizontally. */
.hfig {
  display: grid;
  grid-template-columns: minmax(0, auto) minmax(0, 1fr);
  column-gap: clamp(2rem, 1rem + 3.5vw, 5rem);
  align-items: baseline;
}
.hfig__n {
  font-family: var(--serif);
  font-size: clamp(2.8rem, 1.4rem + 5vw, 5.6rem);
  line-height: .94;
  letter-spacing: -.035em;
  color: var(--act);
  white-space: nowrap;
}
.hfig__t { max-width: 52ch; }
.hfig__l {
  font-size: var(--t-note); text-transform: uppercase; letter-spacing: .145em;
  font-weight: 600; color: var(--fg-faint);
}
.hfig__c { margin-top: var(--s4); color: var(--fg-dim); font-size: var(--t-small); line-height: 1.62; }

@media (max-width: 900px) {
  /* grid-row has to be reset too, not just grid-column. Resetting only the column
     left the first paragraph still spanning twenty rows, which on a phone put a
     350px hole between it and the next one. Found at 520px, and it is the reason
     this block is now written as a single-column default with the two-column
     layout added above the breakpoint rather than taken away below it. */
  .recog { display: block; }
  .recog > p { max-width: 52ch; }
  /* The 20ch cap is a display measure for a two-column layout. Left on a phone it
     wraps the opening paragraph at about half the width of the ones under it,
     which reads as ragged rather than as emphasis. It keeps the larger size; it
     gives up the narrow measure. */
  .recog > p:first-child { max-width: 34ch; }
  .recog > p + p { margin-top: var(--s5); }
  .hfig { display: block; }
  .hfig__t { margin-top: var(--s5); }
  .hfig__n { white-space: normal; }
}

/* THE SECTION MASTHEAD.
   The same fault as .phead had, repeated at section level all over the site: an
   eyebrow, a question and a paragraph or two, wrapped in a div capped at the
   reading measure and left-aligned in a 1320px band. The measure is right. What
   was missing was anything in the other half of the band.
   Add .sect-head to that wrapper and the question moves left, the body moves up
   beside it, and the band gets used. Below 1080px it falls back to the stack it
   already was, which is correct on a narrow screen. */
@media (min-width: 1080px) {
  .sect-head {
    display: grid;
    grid-template-columns: minmax(0, 1.02fr) minmax(0, 0.98fr);
    column-gap: clamp(2.5rem, 1rem + 4vw, 5.5rem);
    align-items: start;
    grid-auto-rows: min-content;
    max-width: none;          /* overrides the inline cap this replaces */
  }
  .sect-head > .eyebrow { grid-column: 1 / -1; grid-row: 1; }
  .sect-head > h2,
  .sect-head > .beat__q {
    grid-column: 1;
    grid-row: 2 / span 20;    /* holds the left column for however many rows the right needs */
    max-width: none;
    align-self: start;
  }
  .sect-head > *:not(.eyebrow):not(h2):not(.beat__q) { grid-column: 2; }
  .sect-head > .body,
  .sect-head > .lead,
  .sect-head > p:not(.eyebrow) {
    grid-row: 2;
    margin-top: .45rem;       /* drops the first line onto the heading's first baseline */
    max-width: 48ch;
  }
  /* Anything after the body — a note, a fine line, an action — stacks under it. */
  .sect-head > *:nth-child(n+4):not(.eyebrow):not(h2):not(.beat__q) {
    grid-row: auto;
    margin-top: var(--s5);
  }
}

/* .sect-head with no eyebrow: hold grid row 1 open.
   The component reserves row 1 for the eyebrow and starts the heading and the
   body together on row 2. Where a block has no eyebrow, row 1 stays empty in the
   right-hand column, and a trailing action block — the one placed with
   grid-row: auto so it stacks under the body — was falling into that hole
   instead. On five of the closing bands that put the buttons and their note
   ABOVE the question they answer, which is the wrong reading order and reads as
   a broken grid, because it is one.
   An empty grid item pinned across row 1 closes the hole, so auto-placement
   starts below the body where the reading order needs it. It is zero height, and
   where an eyebrow does exist it shares that cell and the eyebrow sets the row
   height, so nothing moves on the blocks that were already correct. */
@media (min-width: 1080px) {
  .sect-head::before {
    content: "";
    grid-column: 1 / -1;
    grid-row: 1;
    block-size: 0;
  }
}

/* --- .steps--bare (added by the numeric-ornament pass) ---------------------
   The .step component reserves a 4.5rem first column for an ordinal badge, and
   on the two blocks below that badge was counting furniture rather than a
   sequence:

     page-proof.php   the four tests inside "the average lie". Each test already
                      carries its own name — Growth, Safety, Diversification,
                      Guarantees — and a name in that slot says more than 01.
     page-blind-spot.php  the three things to go and check this week. They are a
                      set, not a process; the copy itself says none of them needs
                      us, and nothing about them has to happen in order.

   The badge column is collapsed rather than left standing empty, so the text
   starts where the paragraphs above it start instead of sitting in a 4.5rem
   indent with nothing to its left. gap goes to 0 because the children carry
   their own margins, exactly as they did when they were nested in a wrapper.

   Opt-in only. The four-step method on front-page.php and page-consultation.php
   is a chronological process where the order is the point, and it keeps 01-04.
   ------------------------------------------------------------------------- */
.steps--bare .step {
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
}
/* A bare step whose body is its first child has nothing above it to stand off
   from; the shared margin was 12px of dead air under the rule, and the template
   was cancelling it inline. Owned here now. */
.steps--bare .step__b:first-child { margin-top: 0; }
