/* ==========================================================================
   Great Trek -- components
   ========================================================================== */

/* ---- Header --------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: var(--ink);
  color: var(--bone);
  border-bottom: var(--hair) solid rgb(247 246 243 / 0.14);
}
.site-header__inner {
  max-width: var(--w-wide);
  margin-inline: auto;
  padding: var(--s-3) var(--gutter);
  display: flex;
  align-items: center;
  gap: var(--s-5);
}

/* The wordmark is LOCKED to its descriptor -- the descriptor is part of the
   logo, not a tagline that can be dropped. See views/partials/header.php. */
.wordmark { display: flex; align-items: center; gap: var(--s-3); text-decoration: none; color: inherit; }
.wordmark__mark { flex: none; width: 22px; height: 20px; }
.wordmark__text { display: flex; flex-direction: column; line-height: 1; }
.wordmark__name {
  font-size: 1.05rem;
  font-weight: var(--w-black);
  letter-spacing: 0.02em;
  text-transform: uppercase;
}
.wordmark__desc {
  font-size: 0.58rem;
  font-weight: var(--w-med);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: rgb(247 246 243 / 0.6);
  margin-top: 3px;
}

.site-nav { display: flex; gap: var(--s-5); margin-left: auto; align-items: center; }
.site-nav a {
  color: rgb(247 246 243 / 0.82);
  text-decoration: none;
  font-size: var(--fs-small);
  font-weight: var(--w-med);
  padding-block: var(--s-2);
  border-bottom: 2px solid transparent;
  white-space: nowrap;
  transition: color var(--t), border-color var(--t);
}
.site-nav a:hover, .site-nav a[aria-current="page"] {
  color: var(--bone);
  border-bottom-color: var(--sunrise);
}

.lang-toggle {
  display: flex;
  align-items: center;
  border: var(--hair) solid rgb(247 246 243 / 0.28);
  border-radius: var(--r-2);
  overflow: hidden;
}
.lang-toggle a {
  padding: 0.3rem 0.55rem;
  font-size: var(--fs-micro);
  font-weight: var(--w-bold);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  text-decoration: none;
  color: rgb(247 246 243 / 0.7);
  border: 0;
}
.lang-toggle a[aria-current="true"] { background: var(--bone); color: var(--ink); }

.nav-toggle {
  display: none;
  margin-left: auto;
  background: none;
  border: var(--hair) solid rgb(247 246 243 / 0.3);
  border-radius: var(--r-2);
  color: var(--bone);
  padding: var(--s-2) var(--s-3);
  cursor: pointer;
}

@media (max-width: 60rem) {
  .nav-toggle { display: block; }
  .site-nav {
    display: none;
    position: absolute;
    inset: 100% 0 auto 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--ink);
    padding: var(--s-3) var(--gutter) var(--s-5);
    border-bottom: var(--hair) solid rgb(247 246 243 / 0.14);
  }
  .site-nav.is-open { display: flex; }
  .site-nav a { padding: var(--s-3) 0; border-bottom: var(--hair) solid rgb(247 246 243 / 0.1); }
  .site-nav .btn { margin-top: var(--s-3); text-align: center; }
  .lang-toggle { align-self: flex-start; margin-top: var(--s-3); }
}

/* ---- Buttons: square, never pill ------------------------------------------ */
.btn {
  --btn-bg: var(--sunrise);
  --btn-fg: var(--ink);
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  padding: 0.9rem 1.6rem;
  min-height: 48px;
  border: var(--hair) solid transparent;
  border-radius: var(--r-2);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-size: var(--fs-small);
  font-weight: var(--w-bold);
  letter-spacing: var(--tr-micro);
  text-transform: uppercase;
  text-decoration: none;
  cursor: pointer;
  transition: transform var(--t-fast) var(--ease-out), background-color var(--t), color var(--t);
}
.btn::after {
  content: "";
  position: absolute;
  left: 0; bottom: 0;
  height: 2px; width: 0;
  background: currentColor;
  transition: width var(--t) var(--ease-out);
}
.btn:hover { transform: translateY(-1px); }
.btn:hover::after { width: 100%; }
.btn:active { transform: none; }

.btn--ghost {
  --btn-bg: transparent;
  --btn-fg: var(--on-surface);
  border-color: var(--rule-strong);
}
.btn--ghost:hover { background: var(--surface-2); }

.btn--quiet {
  --btn-bg: transparent;
  --btn-fg: var(--accent-text);
  padding-inline: 0;
  min-height: 0;
}

.btn--lg { padding: 1.1rem 2rem; font-size: var(--fs-body); min-height: 56px; }
.btn--block { display: flex; width: 100%; }
.btn[disabled] { opacity: 0.45; pointer-events: none; }

.btn--danger { --btn-bg: transparent; --btn-fg: var(--sunrise-deep); border-color: currentColor; }
[data-surface="ink"] .btn--danger,
[data-surface="ink-sink"] .btn--danger { --btn-fg: var(--sunrise); }

/* ---- Cards ---------------------------------------------------------------- */
.card {
  background: var(--surface-2);
  border: var(--hair) solid var(--rule);
  border-radius: var(--r-2);
  padding: var(--s-5);
}
.card--link { transition: transform var(--t), box-shadow var(--t); text-decoration: none; color: inherit; display: block; }
.card--link:hover { transform: translateY(-2px); box-shadow: var(--shadow-card); }
.card__n {
  font-size: var(--fs-micro);
  font-weight: var(--w-bold);
  letter-spacing: var(--tr-micro);
  color: var(--accent-text);
}
.card h3 { margin-block: var(--s-3) var(--s-2); }

/* ---- Imagery: always square, with corner registration ticks --------------- */
.figure { position: relative; margin: 0; }
.figure img { width: 100%; border-radius: var(--r-0); }
.figure figcaption {
  margin-top: var(--s-3);
  font-size: var(--fs-small);
  color: var(--on-surface-dim);
}
.figure--ticked::before, .figure--ticked::after {
  content: "";
  position: absolute;
  width: 14px; height: 14px;
  border: 2px solid var(--sunrise);
  pointer-events: none;
}
.figure--ticked::before { top: 0; left: 0; border-right: 0; border-bottom: 0; }
.figure--ticked::after { bottom: 0; right: 0; border-left: 0; border-top: 0; }

/* Every render on this site is labelled. A government reader who works out
   that unlabelled images are synthetic discounts the entire document. */
.concept-label {
  display: inline-block;
  margin-top: var(--s-2);
  font-size: var(--fs-micro);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--on-surface-dim);
}

/* ---- The tally bar -------------------------------------------------------- */
.tally { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); gap: var(--s-6); }
.tally__item { display: grid; gap: var(--s-1); align-content: start; border-top: 3px solid var(--sunrise); padding-top: var(--s-4); }
.tally__n {
  display: block;
  font-size: var(--fs-stat);
  font-weight: var(--w-black);
  line-height: 0.9;
  letter-spacing: var(--tr-display);
  font-variant-numeric: tabular-nums;
  color: var(--on-surface);
}
.tally__label {
  display: block;
  margin-top: var(--s-3);
  font-size: var(--fs-micro);
  font-weight: var(--w-bold);
  letter-spacing: var(--tr-micro);
  text-transform: uppercase;
  color: var(--on-surface-dim);
}
.tally__stamp { margin-top: var(--s-5); font-size: var(--fs-micro); color: var(--on-surface-dim); letter-spacing: 0.04em; }

/* ---- Hero ----------------------------------------------------------------- */
.hero {
  position: relative;
  min-height: min(88vh, 52rem);
  display: grid;
  align-items: end;
  overflow: hidden;
  /* .section supplies vertical padding; the hero manages its own. */
  padding-block: 0;
}
.hero__media { position: absolute; inset: 0; z-index: 0; }
.hero__media img { width: 100%; height: 100%; object-fit: cover; object-position: 65% 55%; }
.hero__media::after {
  content: "";
  position: absolute; inset: 0;
  background:
    /* Dense only at the very bottom, where the lead and the start form sit. */
    linear-gradient(to top,
      rgb(11 15 26 / 0.92) 0%,
      rgb(11 15 26 / 0.72) 22%,
      rgb(11 15 26 / 0.28) 55%,
      rgb(11 15 26 / 0.06) 100%),
    /* A gentle left-hand scrim for the headline; the sunrise stays visible
       on the right, which is the whole reason for the photograph. */
    linear-gradient(to right, rgb(11 15 26 / 0.55) 0%, rgb(11 15 26 / 0.12) 45%, rgb(11 15 26 / 0) 75%);
}
.hero__inner { position: relative; z-index: 1; padding-block: var(--s-8) var(--s-7); }
.hero__title { max-width: min(21ch, 100%); }
.hero__lead { margin-top: var(--s-5); max-width: min(52ch, 100%); color: rgb(247 246 243 / 0.86); }
.hero__actions { margin-top: var(--s-6); }
/* "Already enrolled?" on the enrolment page.
   A family who enrolled months ago and clicks the header button lands on a
   page that only knows how to enrol them again. The duplicate check does catch
   them, but not until they have typed their address into a form they did not
   need -- and being told "you are already enrolled" after starting reads as a
   rejection rather than a signpost.
   So it sits ABOVE the step rail, before any effort is spent, and it is a
   bordered bar rather than a line of small print. It is deliberately not a
   filled button: the one filled button on this page starts the enrolment, and
   two competing primaries is how people pick the wrong one. */
.signpost {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s-2) var(--s-4);
  margin-top: var(--s-6);
  padding: var(--s-4) var(--s-5);
  border: 1px solid rgb(247 246 243 / 0.20);
  background: rgb(247 246 243 / 0.04);
}

.signpost__text { font-size: var(--fs-body); color: rgb(247 246 243 / 0.80); }

.signpost__link {
  font-size: var(--fs-small);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--sunrise);
  text-decoration: none;
  border-bottom: 2px solid var(--sunrise);
  padding-bottom: 2px;
  transition: color 120ms ease, border-color 120ms ease;
}

.signpost__link:hover,
.signpost__link:focus-visible { color: var(--bone); border-bottom-color: var(--bone); }

@media (prefers-reduced-motion: reduce) { .signpost__link { transition: none; } }

.hero__note { margin-top: var(--s-4); font-size: var(--fs-small); color: rgb(247 246 243 / 0.66); max-width: 46ch; }

/* Two-field start form: literally step 1, so a visitor can begin without
   scrolling. Submitting scrolls to the full form with these carried over. */
.quickstart {
  margin-top: var(--s-6);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-3);
  align-items: flex-end;
  max-width: 44rem;
}
.quickstart .field { flex: 1 1 13rem; margin: 0; }

/* ---- Fields: a drafting sheet, not a web form ----------------------------- */
.field { margin-bottom: var(--s-5); }
.field__label {
  display: block;
  font-size: var(--fs-micro);
  font-weight: var(--w-bold);
  letter-spacing: var(--tr-micro);
  text-transform: uppercase;
  color: var(--on-surface-dim);
  margin-bottom: var(--s-2);
}
.field__hint { display: block; margin-top: var(--s-2); font-size: var(--fs-small); color: var(--on-surface-dim); }

.input, .select, .textarea {
  width: 100%;
  min-height: 56px;
  padding: var(--s-3) 0;
  /* 16px+ on mobile or iOS zooms the viewport on focus. */
  font-size: max(1rem, var(--fs-body));
  color: var(--on-surface);
  background: transparent;
  border: 0;
  border-bottom: var(--hair) solid var(--rule-strong);
  border-radius: 0;
  transition: border-color var(--t);
}
.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-bottom: 2px solid var(--sunrise);
}
.textarea { min-height: 8rem; padding-block: var(--s-3); resize: vertical; }
.select {
  appearance: none;
  padding-right: 2rem;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 0.9rem center, right 0.55rem center;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
}
.input::placeholder { color: var(--on-surface-dim); opacity: 0.6; }

/* The only multi-line input on the site. A hairline underline is enough for a
   one-line field; a seven-row box needs an edge, or it reads as a gap in the
   page. Declared after .input deliberately -- same specificity, later wins. */
.input--area {
  padding: var(--s-4);
  min-height: 9rem;
  border: var(--hair) solid var(--rule-strong);
  resize: vertical;
  line-height: 1.6;
  font-family: inherit;
}
.input--area:focus { border-color: var(--sunrise); outline: none; }

.field.is-invalid .input,
.field.is-invalid .select {
  border-bottom-color: var(--sunrise-deep);
  border-left: 2px solid var(--sunrise-deep);
  padding-left: var(--s-3);
}
[data-surface="ink"] .field.is-invalid .input,
[data-surface="ink"] .field.is-invalid .select { border-color: var(--sunrise); }

.field__error {
  display: flex;
  align-items: flex-start;
  gap: var(--s-2);
  margin-top: var(--s-2);
  font-size: var(--fs-small);
  font-weight: var(--w-med);
  color: var(--sunrise-deep);
}
[data-surface="ink"] .field__error, [data-surface="ink-sink"] .field__error { color: var(--sunrise); }
/* Never colour-only: the triangle carries the meaning too. */
.field__error::before { content: "▲"; font-size: 0.7em; line-height: 1.8; flex: none; }

/* Honeypot. Positioned off-screen rather than display:none or type=hidden --
   better bots skip both of those. */
.hp { position: absolute; left: -9999px; top: 0; width: 1px; height: 1px; overflow: hidden; }

/* ---- Segmented radios (pure CSS, no JS) ----------------------------------- */
.segmented { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.segmented input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.segmented label {
  padding: 0.7rem 1.1rem;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  border: var(--hair) solid var(--rule-strong);
  border-radius: var(--r-2);
  font-size: var(--fs-small);
  font-weight: var(--w-med);
  cursor: pointer;
  transition: background-color var(--t), border-color var(--t), color var(--t);
}
.segmented label:hover { border-color: var(--accent-text); }
.segmented input:checked + label {
  background: var(--sunrise);
  border-color: var(--sunrise);
  color: var(--ink);
  font-weight: var(--w-bold);
}
.segmented input:focus-visible + label { outline: 2px solid var(--sunrise); outline-offset: 3px; }
[data-surface="ink"] .segmented input:focus-visible + label,
[data-surface="ink-sink"] .segmented input:focus-visible + label { outline-color: var(--bone); }

/* ==========================================================================
   The From / Toward ledger

   Every push is paired with a pull ON THE SAME ROW, so the reader's eye never
   rests on the grievance. Left column carries checkable facts with named
   sources; right column carries intent. No adjectives -- a cited number is
   more devastating than "rampant" and cannot be quoted back at us.
   ========================================================================== */
.ledger { border-top: var(--hair) solid var(--rule); }
.ledger__row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-6);
  padding-block: var(--s-5);
  border-bottom: var(--hair) solid var(--rule);
  position: relative;
}
.ledger__row::before {
  content: "";
  position: absolute;
  left: 50%; top: var(--s-5);
  width: 1px; height: 14px;
  background: var(--sunrise);
}
.ledger__from { color: var(--on-surface-dim); }
.ledger__to { font-weight: var(--w-semi); }
.ledger__source { display: block; margin-top: var(--s-2); font-size: var(--fs-micro); font-style: italic; opacity: 0.75; }
.ledger__head {
  font-size: var(--fs-micro);
  font-weight: var(--w-bold);
  letter-spacing: var(--tr-micro);
  text-transform: uppercase;
  color: var(--on-surface-dim);
  padding-bottom: var(--s-3);
}
@media (max-width: 42rem) {
  .ledger__row { grid-template-columns: 1fr; gap: var(--s-3); }
  .ledger__row::before { left: 0; top: auto; bottom: 50%; width: 14px; height: 1px; }
  .ledger__to { padding-left: var(--s-5); }
  .ledger__heads { display: none; }
}

/* A quoted card carries the experience the institutional voice should not. */
.quote-card {
  border-left: 3px solid var(--sunrise);
  padding: var(--s-5) var(--s-6);
  background: var(--surface-2);
}
.quote-card blockquote { font-size: var(--fs-lead); font-weight: var(--w-med); line-height: 1.45; }
.quote-card cite { display: block; margin-top: var(--s-4); font-size: var(--fs-small); font-style: normal; color: var(--on-surface-dim); }

/* ==========================================================================
   Statistics

   Architectural rule: every chart is a real <table> or <dl> in the markup,
   styled into a graphic with CSS. No SVG generation, no aria-hidden wrapper,
   no "view as table" toggle. Screen readers get the data, search engines get
   the data, and a government analyst can Ctrl-F it.

   Bar widths come from ONE inline custom property computed in PHP
   (style="--v:62%") -- the only legitimate inline style in this build.
   ========================================================================== */
/* The worked example on /numbers.
   It has to survive being cropped. Somebody will screenshot one chart without
   the heading above it, and at that point the only thing saying "invented" is
   whatever is inside the frame -- so the frame is a dashed plan-line rather
   than a solid panel, the label sits on the border itself, and every bar drops
   to grey. None of the site's real data is ever drawn this way, which is the
   actual signal: it does not look like the charts above it. */
.illus {
  position: relative;
  border: 1px dashed var(--rule-strong, rgb(11 15 26 / 0.28));
  padding: var(--s-7) var(--s-5) var(--s-5);
  background: rgb(11 15 26 / 0.015);
}

.illus__tag {
  position: absolute;
  top: 0;
  left: var(--s-5);
  transform: translateY(-50%);
  padding: 0 var(--s-2);
  background: var(--bone);
  color: var(--sunrise-deep);
  font-size: var(--fs-micro);
  font-weight: var(--w-bold);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* Grey, never INDIGO: indigo means evidence everywhere else on this site. */
.illus .barlist__bar { background: rgb(11 15 26 / 0.45); }
.illus .barlist__row--top .barlist__bar { background: rgb(11 15 26 / 0.55); }

/* Ink, not SUNRISE. Orange is the colour of a live figure everywhere else on
   this site, and an example rendered in it is indistinguishable from a
   measurement at a glance -- which is the one thing this panel must never be.
   Full-strength ink keeps it readable; it simply is not the live colour. */
.illus .stat-panel__n { color: var(--ink); }
.illus .stat-panel { background: transparent; border: 1px solid var(--rule); }

/* SUNRISE fails contrast on BONE, so accent text on a light surface is
   always sunrise-deep. Same rule as every other eyebrow. */
.eyebrow--warn { color: var(--sunrise-deep); }

.barlist { display: grid; gap: var(--s-3); }
.barlist__row {
  display: grid;
  grid-template-columns: minmax(7rem, 14rem) 1fr auto;
  gap: var(--s-4);
  align-items: center;
}
/* Four columns when a row carries a second figure. Without this the extra
   cell falls into an implicit grid row and the number lands above its own
   label, which is how the country chart looked the moment it gained a
   "first choice" column. */
.barlist--two .barlist__row { grid-template-columns: minmax(7rem, 14rem) 1fr auto auto; }

.barlist__label { font-size: var(--fs-small); font-weight: var(--w-med); }
.barlist__track { height: 12px; background: var(--surface-2); border-radius: var(--r-1); overflow: hidden; }
.barlist__bar {
  display: block;
  height: 100%;
  width: var(--v, 0%);
  background: var(--indigo-lift);
  transform-origin: left;
  transition: width var(--t-slow) var(--ease-out);
}
[data-surface="indigo"] .barlist__bar { background: rgb(247 246 243 / 0.55); }
.barlist__row--top .barlist__bar { background: var(--sunrise); }
.barlist__n { font-size: var(--fs-small); font-weight: var(--w-bold); font-variant-numeric: tabular-nums; min-width: 3.5rem; text-align: right; }

/* The second figure is context, not the headline: the bar and the first
   column answer "how many families want this country", and this answers
   "how many put it first". Same size so the columns line up, lighter so the
   eye reads the primary number first. */
.barlist__n--second { font-weight: var(--w-med); opacity: 0.62; }
.js .barlist__bar { width: 0; }
.js .is-in .barlist__bar { width: var(--v, 0%); }

@media (max-width: 36rem) {
  .barlist__row { grid-template-columns: 1fr auto; }
  .barlist__track { grid-column: 1 / -1; order: 3; }
}

/* Category tiles: flex-grow proportional to headcount is a treemap with zero
   JS and zero library. */
.treemap { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.treemap__tile {
  display: grid;
  gap: var(--s-1);
  align-content: start;
  flex-grow: 1;
  flex-shrink: 1;
  flex-basis: 12rem;
  min-width: 11rem;
  padding: var(--s-4);
  background: var(--surface-2);
  border: var(--hair) solid var(--rule);
  border-radius: var(--r-2);
  text-decoration: none;
  color: inherit;
  transition: border-color var(--t), transform var(--t);
}
.treemap__tile:hover { border-color: var(--sunrise); transform: translateY(-2px); }
.treemap__n { font-size: var(--fs-h3); font-weight: var(--w-black); font-variant-numeric: tabular-nums; }
.treemap__name { font-size: var(--fs-small); font-weight: var(--w-semi); margin-top: var(--s-1); }
.treemap__top { font-size: var(--fs-micro); color: var(--on-surface-dim); margin-top: var(--s-2); }

/* The skills wall: sized in FOUR DISCRETE STEPS. Continuous sizing is exactly
   what makes tag clouds look cheap. */
.skillwall { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-5); align-items: baseline; }
.skillwall li { font-weight: var(--w-bold); letter-spacing: var(--tr-head); line-height: 1.15; color: rgb(247 246 243 / 0.5); }
.skillwall li[data-w="1"] { font-size: clamp(0.85rem, 0.8rem + 0.2vw, 1rem); }
.skillwall li[data-w="2"] { font-size: clamp(1.1rem, 1rem + 0.5vw, 1.5rem); color: rgb(247 246 243 / 0.72); }
.skillwall li[data-w="3"] { font-size: clamp(1.6rem, 1.2rem + 1.5vw, 2.6rem); color: var(--bone); }
.skillwall li[data-w="4"] { font-size: clamp(2.2rem, 1.4rem + 3vw, 4rem); color: var(--sunrise); }
.skillwall__n { font-size: 0.45em; font-weight: var(--w-med); opacity: 0.7; margin-left: 0.25em; font-variant-numeric: tabular-nums; }

/* Investment distribution: households per band, never money per band.
   Plotting money invites the "look how rich they are" read from the family
   audience while telling the analyst nothing extra. */
.columns {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  align-items: end;
  gap: var(--s-2);
  min-height: 14rem;
}
.columns__col { display: flex; flex-direction: column; justify-content: flex-end; height: 100%; text-align: center; gap: var(--s-2); }
.columns__bar { display: block; height: var(--v, 0%); min-height: 2px; background: var(--indigo-lift); border-radius: var(--r-1) var(--r-1) 0 0; transition: height var(--t-slow) var(--ease-out); }
.columns__col--peak .columns__bar { background: var(--sunrise); }
.columns__n { font-size: var(--fs-micro); font-weight: var(--w-bold); font-variant-numeric: tabular-nums; }
.columns__label { font-size: 0.6rem; color: var(--on-surface-dim); letter-spacing: 0.02em; }

/* Age pyramid: two-sided bars around a centre axis. */
.pyramid { display: grid; gap: 3px; }
.pyramid__row { display: grid; grid-template-columns: 1fr 4.5rem 1fr; align-items: center; gap: var(--s-2); }
.pyramid__side { height: 14px; display: flex; }
.pyramid__side--l { justify-content: flex-end; }
.pyramid__fill { display: block; width: var(--v, 0%); height: 100%; background: var(--indigo-lift); }
.pyramid__side--r .pyramid__fill { background: var(--sunrise); opacity: 0.75; }
.pyramid__band { font-size: var(--fs-micro); text-align: center; font-variant-numeric: tabular-nums; color: var(--on-surface-dim); }

/* Methodology sits BESIDE the total, never in a footnote. It is why an
   analyst will use our number instead of discounting it. */
.method a {
  color: var(--accent-text);
  font-weight: var(--w-semi);
  text-underline-offset: 3px;
}
/* Marks the link as leaving the site, without an icon font or an image. */
.method a[target="_blank"]::after {
  content: " \2197";
  font-weight: var(--w-bold);
  text-decoration: none;
  display: inline-block;
}

.method {
  margin-top: var(--s-4);
  padding: var(--s-4) var(--s-5);
  border-left: 3px solid var(--rule-strong);
  font-size: var(--fs-small);
  color: var(--on-surface-dim);
  max-width: 60ch;
}

.stat-panels { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 15rem), 1fr)); gap: var(--s-5); }
.stat-panel {
  display: grid;
  gap: var(--s-1);
  align-content: start;
  padding: var(--s-5);
  background: var(--surface-2);
  border-radius: var(--r-2);
}
.stat-panel__n {
  font-size: clamp(2rem, 1.2rem + 3vw, 3.6rem);
  font-weight: var(--w-black);
  line-height: 1;
  letter-spacing: var(--tr-display);
  font-variant-numeric: tabular-nums;
  color: var(--sunrise);
}
.stat-panel__label { margin-top: var(--s-3); font-size: var(--fs-small); font-weight: var(--w-semi); }
.stat-panel__note { margin-top: var(--s-2); font-size: var(--fs-micro); color: var(--on-surface-dim); }

/* Full inventory: never paginated. An analyst wants completeness, and
   pagination reads as concealment. */
.datatable { font-size: var(--fs-small); }
.datatable th, .datatable td { padding: var(--s-3) var(--s-4); text-align: left; border-bottom: var(--hair) solid var(--rule); }
.datatable th { font-size: var(--fs-micro); text-transform: uppercase; letter-spacing: var(--tr-micro); color: var(--on-surface-dim); white-space: nowrap; }
.datatable th button { background: none; border: 0; padding: 0; font: inherit; color: inherit; cursor: pointer; text-transform: inherit; letter-spacing: inherit; }
.datatable tbody tr:nth-child(even) { background: var(--surface-2); }
.datatable td.num, .datatable th.num { text-align: right; font-variant-numeric: tabular-nums; }
.datatable code { font-size: 0.8em; color: var(--on-surface-dim); }

/* ==========================================================================
   The four-stage transformation

   Stepped tabs with a drag-scrub track -- deliberately NOT scroll-driven.
   Scroll-jacking is fragile on mobile, makes page length unpredictable, is
   hostile to reduced-motion users, and is the most-complained-about pattern
   on the web. A bare scrubber is wrong too: four states are too few for
   continuous scrubbing to feel good, and it would not tell you the stages
   have names. So: one control, two input modes.
   ========================================================================== */
.stages { position: relative; }
.stages__stage { position: relative; aspect-ratio: 3 / 2; background: var(--ink-raise); overflow: hidden; }
.stages__stage img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* Because the camera is identical across all four frames, opacity
   interpolation reads as a true time-lapse dissolve, not a slideshow. */
.js .stages__stage img { opacity: 0; transition: opacity var(--t-slow) var(--ease-io); }
.js .stages__stage img.is-shown { opacity: 1; }

.stages__caption {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  padding: var(--s-6) var(--s-5) var(--s-5);
  background: linear-gradient(to top, rgb(11 15 26 / 0.92), rgb(11 15 26 / 0));
  color: var(--bone);
}
.stages__caption h3 { font-size: var(--fs-h3); }
.stages__caption p { margin-top: var(--s-2); font-size: var(--fs-small); color: rgb(247 246 243 / 0.8); max-width: 52ch; }

/* Survey rail -- the same visual device as the form's progress rail. */
.rail { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 0; margin-top: var(--s-5); touch-action: pan-y; }
.rail__node {
  position: relative;
  background: none;
  border: 0;
  border-top: 2px solid var(--rule-strong);
  padding: var(--s-4) var(--s-2) 0;
  text-align: left;
  color: var(--on-surface-dim);
  cursor: pointer;
  font: inherit;
  transition: color var(--t), border-color var(--t);
}
.rail__node::before {
  content: "";
  position: absolute;
  left: 0; top: -2px;
  width: 2px; height: 12px;
  background: var(--rule-strong);
  transition: background-color var(--t), height var(--t);
}
.rail__node[aria-selected="true"] { color: var(--on-surface); border-top-color: var(--sunrise); }
.rail__node[aria-selected="true"]::before { background: var(--sunrise); height: 20px; }
.rail__n { display: block; font-size: var(--fs-micro); font-weight: var(--w-bold); letter-spacing: var(--tr-micro); color: var(--accent-text); }
.rail__name { display: block; margin-top: var(--s-1); font-size: var(--fs-small); font-weight: var(--w-semi); }
@media (max-width: 40rem) { .rail__name { font-size: var(--fs-micro); } }

/* Hotspot pins, positioned by percentage coordinates. */
.pin {
  position: absolute;
  width: 26px; height: 26px;
  transform: translate(-50%, -50%);
  background: none; border: 0; padding: 0; cursor: pointer;
}
.pin::before {
  content: "";
  position: absolute; inset: 0;
  border: 2px solid var(--sunrise);
  background: rgb(255 90 54 / 0.22);
  border-radius: var(--r-1);
}
.pin__tip {
  position: absolute;
  bottom: 140%; left: 50%;
  transform: translateX(-50%);
  width: max-content; max-width: 15rem;
  padding: var(--s-2) var(--s-3);
  background: var(--ink);
  color: var(--bone);
  border: var(--hair) solid var(--sunrise);
  font-size: var(--fs-micro);
  text-align: left;
  opacity: 0; pointer-events: none;
  transition: opacity var(--t);
}
.pin:hover .pin__tip, .pin:focus-visible .pin__tip { opacity: 1; }

/* No-JS fallback: all four figures in document order, 2x2 on desktop.
   Legible, complete, and honestly rather beautiful. */
.stages-fallback { display: grid; gap: var(--s-5); grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); }
.stages-live { display: none; }

/* The swap is gated on the SCRIPT HAVING RUN, not on `.js` being present.
   Gating on `.js` meant a page that rendered this partial without loading
   stages.js hid the working fallback and showed a dead widget -- which is
   exactly what happened on /the-town. */
.stages-root.is-ready .stages-fallback { display: none; }
.stages-root.is-ready .stages-live { display: block; }

/* ---- Masterplan ----------------------------------------------------------- */
.plan { display: grid; gap: var(--s-6); grid-template-columns: minmax(0, 2.2fr) minmax(14rem, 1fr); align-items: start; }
@media (max-width: 55rem) { .plan { grid-template-columns: 1fr; } }
.plan__canvas { position: relative; }
.plan__legend { display: grid; gap: var(--s-2); }
.plan__legend li { display: grid; grid-template-columns: 1.6rem 1fr; gap: var(--s-2); font-size: var(--fs-small); padding: var(--s-2); border-radius: var(--r-1); transition: background-color var(--t); }
.plan__legend li.is-active { background: var(--surface-2); }
.plan__legend b { color: var(--accent-text); font-variant-numeric: tabular-nums; }
.plan__hint { font-size: var(--fs-micro); color: var(--on-surface-dim); margin-top: var(--s-2); }

/* ---- Country cards -------------------------------------------------------- */
.country { display: grid; gap: var(--s-2); align-content: start; padding: var(--s-5); border: var(--hair) solid var(--rule); border-radius: var(--r-2); background: var(--surface-2); }
.country__name { font-size: var(--fs-h3); font-weight: var(--w-black); letter-spacing: var(--tr-head); }
.country__why { font-size: var(--fs-small); color: var(--on-surface-dim); }
.country__count { margin-top: var(--s-2); font-size: var(--fs-micro); font-weight: var(--w-bold); letter-spacing: var(--tr-micro); text-transform: uppercase; color: var(--accent-text); }

/* ---- Timeline ------------------------------------------------------------- */
.timeline { display: grid; gap: 0; border-left: 2px solid var(--rule-strong); padding-left: var(--s-6); }
.timeline__step { position: relative; padding-block: var(--s-5); border-bottom: var(--hair) solid var(--rule); }
.timeline__step:last-child { border-bottom: 0; }
.timeline__step::before {
  content: "";
  position: absolute;
  left: calc(var(--s-6) * -1 - 2px);
  top: calc(var(--s-5) + 0.5em);
  width: 14px; height: 2px;
  background: var(--rule-strong);
}
.timeline__step--now::before { background: var(--sunrise); width: 22px; height: 3px; }
.timeline__status {
  display: inline-block;
  font-size: var(--fs-micro);
  font-weight: var(--w-bold);
  letter-spacing: var(--tr-micro);
  text-transform: uppercase;
  color: var(--on-surface-dim);
  margin-bottom: var(--s-2);
}
.timeline__step--now .timeline__status { color: var(--accent-text); }

/* ---- Accordion (native details, no JS) ------------------------------------ */
.faq { border-top: var(--hair) solid var(--rule); }
.faq details { border-bottom: var(--hair) solid var(--rule); }
.faq summary {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--s-4);
  padding: var(--s-5) 0;
  cursor: pointer;
  font-size: var(--fs-h3);
  font-weight: var(--w-bold);
  letter-spacing: var(--tr-head);
  list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; font-size: 1.4em; font-weight: var(--w-reg); color: var(--accent-text); flex: none; }
.faq details[open] summary::after { content: "–"; }
.faq details > div { padding-bottom: var(--s-5); max-width: var(--w-text); color: var(--on-surface-dim); }
.faq details > div p + p { margin-top: var(--s-4); }

/* ---- Is / Is-not columns -------------------------------------------------- */
.isnot { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr)); gap: var(--s-6); }
.isnot__col h3 { padding-bottom: var(--s-3); border-bottom: 2px solid var(--sunrise); }
.isnot__col--not h3 { border-bottom-color: var(--rule-strong); }
.isnot__col li { padding: var(--s-3) 0; border-bottom: var(--hair) solid var(--rule); font-size: var(--fs-small); }
.isnot__col--not li { color: var(--on-surface-dim); }

/* ---- Footer --------------------------------------------------------------- */
.site-footer { background: var(--ink-sink); color: var(--bone); }
.site-footer__inner { max-width: var(--w-wide); margin-inline: auto; padding: var(--s-9) var(--gutter) var(--s-6); }
.site-footer__grid { display: grid; gap: var(--s-7); grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); }
.site-footer h4 { font-size: var(--fs-micro); font-weight: var(--w-bold); letter-spacing: var(--tr-micro); text-transform: uppercase; color: rgb(247 246 243 / 0.5); margin-bottom: var(--s-3); }
.site-footer a { color: rgb(247 246 243 / 0.82); text-decoration: none; font-size: var(--fs-small); display: block; padding-block: var(--s-2); }
.site-footer a:hover { color: var(--sunrise); }
.site-footer__note { margin-top: var(--s-8); padding-top: var(--s-5); border-top: var(--hair) solid rgb(247 246 243 / 0.12); font-size: var(--fs-small); color: rgb(247 246 243 / 0.62); max-width: 70ch; }
.site-footer__whatif { margin-top: var(--s-6); font-size: var(--fs-small); color: rgb(247 246 243 / 0.72); letter-spacing: 0.01em; }
/* The footer's links are block-level nav items; this one is a word inside a
   sentence and has to stay in the line. */
.site-footer__whatif a { display: inline; padding-block: 0; font-size: inherit; color: inherit; text-decoration: underline; text-underline-offset: 0.22em; text-decoration-thickness: var(--hair); }
.site-footer__whatif a:hover { color: var(--sunrise); text-decoration-color: var(--sunrise); }

.site-footer__legal { margin-top: var(--s-3); font-size: var(--fs-micro); color: rgb(247 246 243 / 0.42); }

/* This line appears on the form and in the footer on every page. Without it,
   the site resembles unregistered migration advice in several of the nine
   jurisdictions we intend to approach. */
.disclaimer { font-size: var(--fs-micro); color: var(--on-surface-dim); max-width: 62ch; }

/* ---- Notices -------------------------------------------------------------- */
/* The family's record card: their number and the day they enrolled, read as
   a pair of facts rather than as more page furniture. */
.record { display: flex; flex-wrap: wrap; gap: var(--s-8); margin-top: var(--s-6); }
.record dt { font-size: var(--fs-micro); font-weight: var(--w-med); letter-spacing: 0.1em; text-transform: uppercase; color: var(--on-surface-dim); }
.record dd { margin: var(--s-2) 0 0; font-size: var(--fs-h3); font-weight: var(--w-bold); letter-spacing: -0.02em; font-variant-numeric: tabular-nums; }
.record__no { color: var(--sunrise); }

/* The dashboard's top rule: the eyebrow on one side, sign out on the other. */
.dash-bar { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: var(--s-4); }
.dash-bar .eyebrow { margin: 0; }

/* A button that has to read as a link: sign out is a real POST (a GET would
   let any image tag on any page sign the family out) but it is not a primary
   action and must not look like one. */
.linkish {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  font-size: var(--fs-small);
  font-weight: var(--w-med);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: underline;
  text-underline-offset: 0.28em;
  text-decoration-thickness: var(--hair);
  cursor: pointer;
  transition: color var(--t);
}
.linkish:hover { color: var(--sunrise); }

/* ---- Focused pages -------------------------------------------------------
   Enrolment, and the code that confirms it. No navigation, no footer columns,
   nothing to wander into: one way forward and one way out. */
.focus-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
  padding: var(--s-5) var(--s-6);
  background: var(--ink);
  /* .wordmark inherits its colour; without this it inherits the body's ink
     and the name renders black on black. The descriptor has its own colour,
     which is why only half the wordmark disappeared. */
  color: var(--bone);
  border-bottom: var(--hair) solid rgb(247 246 243 / 0.12);
}
/* The descriptor is NOT hidden here. docs and the plan are explicit that the
   wordmark is locked to it -- part of the logo, not a droppable tagline --
   and this is the one page where a visitor has no nav to tell them what site
   they are on. */
.focus-header__exit {
  color: rgb(247 246 243 / 0.62);
  font-size: var(--fs-small);
  font-weight: var(--w-med);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-decoration: none;
}
.focus-header__exit:hover { color: var(--sunrise); }

.focus-footer {
  padding: var(--s-7) var(--s-6);
  background: var(--ink);
  color: rgb(247 246 243 / 0.52);
  text-align: center;
}
.focus-footer p { max-width: 60ch; margin-inline: auto; }
.focus-footer a { color: rgb(247 246 243 / 0.72); }

/* ---- Admin ---------------------------------------------------------------
   Deliberately plain: this is a working tool for one person, not a surface
   anyone is being persuaded by. It borrows the site's tokens and adds only
   what a dense table of records actually needs. */
.admin-filters {
  display: grid;
  gap: var(--s-4);
  align-items: end;
  grid-template-columns: minmax(0, 2fr) minmax(0, 1fr) minmax(0, 1fr) auto;
  margin-top: var(--s-6);
}
@media (max-width: 54rem) { .admin-filters { grid-template-columns: 1fr; } }

.pill {
  display: inline-block;
  padding: 0.15rem 0.6rem;
  border: var(--hair) solid var(--rule-strong);
  border-radius: 999px;
  font-size: var(--fs-micro);
  font-weight: var(--w-med);
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.pill--active { border-color: var(--indigo-lift); color: var(--indigo-lift); }
.pill--pending_verification { border-color: var(--on-surface-dim); color: var(--on-surface-dim); }
.pill--paused { border-color: var(--sunrise-deep); color: var(--sunrise-deep); }

.age-note { display: block; margin-top: var(--s-1); font-size: var(--fs-micro); font-weight: var(--w-reg); letter-spacing: 0; white-space: nowrap; }

.notice { padding: var(--s-4) var(--s-5); border-left: 3px solid var(--sunrise); background: var(--surface-2); font-size: var(--fs-small); }
.notice--error { border-left-color: var(--sunrise-deep); }
.notice--ok { border-left-color: var(--indigo-lift); }
[data-surface="ink"] .notice--ok, [data-surface="ink-sink"] .notice--ok { border-left-color: var(--sunrise); }

/* ---- Print: the prospectus must survive being printed to PDF -------------- */
@media print {
  .site-header, .site-footer, .no-print, .rail, .btn { display: none !important; }
  .section { padding-block: 1.5rem; background: #fff !important; color: #000 !important; }
  .section > * { grid-column: content; }
  a[href]::after { content: " (" attr(href) ")"; font-size: 0.7em; color: #555; }
  .stat-panel__n, .tally__n { color: #000 !important; }
  .barlist__bar { background: #333 !important; }
  .page-break { break-before: page; }

  /* The skills inventory runs to dozens of rows and is the part a government
     reader actually circulates. Without these it loses its column headings
     after the first page and splits rows down the middle of a fold. */
  thead { display: table-header-group; }
  tfoot { display: table-footer-group; }
  tr, .stat-panel, .method { break-inside: avoid; }
  h1, h2, h3 { break-after: avoid; }

  /* The panels keep their own indigo fill, so the section's white background
     never reached them: dark text on a heavy ink block. */
  .stat-panel {
    background: #fff !important;
    color: #000 !important;
    border: 1px solid #999;
  }
  .stat-panel__label, .stat-panel__note, .method, .dim { color: #333 !important; }

  /* Printed on paper the reader cannot click, so a relative href is noise.
     Only absolute links are worth spelling out. */
  a[href]::after { content: ""; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.7em; color: #555; }
}

/* ---- Placeholder shown while artwork is still being produced -------------- */
.img-placeholder {
  display: grid;
  place-items: center;
  min-height: 12rem;
  height: 100%;
  padding: var(--s-5);
  background:
    repeating-linear-gradient(135deg,
      rgb(30 42 90 / 0.10) 0 12px,
      rgb(30 42 90 / 0.04) 12px 24px),
    var(--surface-2);
  border: var(--hair) dashed var(--rule-strong);
  color: var(--on-surface-dim);
  text-align: center;
}
.img-placeholder span {
  font-size: var(--fs-micro);
  font-weight: var(--w-bold);
  letter-spacing: var(--tr-micro);
  text-transform: uppercase;
  max-width: 24ch;
}
.hero .img-placeholder { min-height: 100%; border: 0; }
