/* ==========================================================================
   MCPA — Mine Clearance Planning Agency
   Design system, 2026. One file, one set of tokens.

   This replaces main.css, field-atlas.css, narrative-overhaul.css,
   alethia-mcpa.css, motion-layer.css and redesign.css. Those were six
   successive "overhaul" layers that each redefined the SAME token names with
   different values — `--blue` was #1E5C8C in one and #6b7c5c (a green) in
   another — so no rule could be reasoned about without knowing load order.
   Nothing here is an override of anything. If a value is wrong, it is wrong
   in exactly one place.

   Direction: the organisation's real asset is thirty-six years of documented
   evidence, so the page is built like an institutional record — warm paper,
   a serif that can carry a number, hairline rules, and photography given room.

   1  Tokens
   2  Reset and base
   3  Typography
   4  Layout primitives
   5  Buttons
   6  Header and navigation
   7  Hero and credentials band
   8  Problem
   9  Figures strip
   10 Services
   11 Land release
   12 Risk education
   13 Scene band
   14 Outcomes
   15 The record (map, charts)
   16 Donor assurance
   17 Partners
   18 About, timeline, gallery, lightbox
   19 Field notes and news
   20 Contact, forms, vacancies
   21 Grievance
   22 Footer
   23 Chrome (cookie, to-top)
   24 Motion and reduced motion
   25 Responsive
   ========================================================================== */

/* ---------- 1. Tokens ---------- */
/* ONE ground. The previous pass had --paper, --paper-2, --paper-3, two forest
   bands and white cards all in play, which is why the page read as three
   different sites stitched together. There are now exactly three surfaces:
   the page (--paper), a barely-raised band (--paper-2) and a card (--white).
   The names are historical; the values are dark. Keeping the names means every
   component inherits the new scheme without being touched. */
:root {
  --paper:        #0A0E0D;   /* page ground */
  --paper-2:      #101615;   /* raised band */
  --paper-3:      #101615;   /* deliberately identical - the third ground is gone */
  --white:        #151D1B;   /* card surface */

  --ink:          #E9EFEC;   /* primary text */
  --ink-soft:     #C2CCC8;   /* secondary text */
  --muted:        #8D9B96;   /* captions, supporting copy */
  --forest:       #101615;   /* dark band == raised band, so bands stop fighting */
  --forest-deep:  #070A09;   /* header ground */

  /* Green is the brand accent: it is the outcome MCPA delivers. Red is kept,
     but demoted to a hazard-only token used by the field HUD and the 3D plot,
     so the one red thing on the page is always the thing being removed.
     The token is still called --clay because every component references it. */
  --clay:         #34CE8A;   /* primary action, rules, active states */
  --clay-deep:    #6FE3A0;   /* lighter, for small accent text on dark */
  --clay-wash:    rgba(52, 206, 138, .13);
  --hazard:       #FF5F3A;   /* explosive hazard, and nothing else */
  --hazard-wash:  rgba(255, 95, 58, .14);

  --sand:         #E3B872;
  --sand-wash:    rgba(227, 184, 114, .12);
  --sage:         #6FE3A0;   /* cleared / safe */
  --sage-wash:    rgba(111, 227, 160, .12);

  --line:         rgba(255,255,255,.085);
  --line-strong:  rgba(255,255,255,.19);
  --line-dark:    rgba(255,255,255,.11);

  /* Type */
  --f-display: 'Albert Sans', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --f-sans:    Lato, system-ui, -apple-system, 'Segoe UI', sans-serif;
  --f-mono:    'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace;

  /* Measure */
  --shell:      1240px;
  --shell-wide: 1440px;
  --gutter: clamp(20px, 4vw, 56px);
  --sec-y:  clamp(64px, 8vw, 132px);

  /* The logo artwork, inlined.

     It was a url() to assets/mcpa-logo-96.png, and it kept vanishing outside
     the dev server. The element's box was still there — the wordmark was
     indented by it — so masking was working fine and the mask IMAGE was not
     arriving, and a mask that cannot load hides everything it is masking.
     Rather than keep guessing at why the request failed (query string, file://
     origin rules, a copy served without its assets), there is now no request:
     the 13KB PNG is base64 in the stylesheet, which is already versioned and
     already has to load for the page to look like anything.

     Declared once and used twice — as the mask, and as the no-mask fallback
     background — so the bytes appear in the file a single time. */
  --logo-src: url("data:image/png;base64,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");

  /* The header's height, stated once. It is the brand mark plus the nav's
     16px of padding top and bottom — nothing else in the bar is taller — and
     both the hero's negative margin and the field readout's top offset are
     measured from it. They were two separate hardcoded 74s, which had already
     drifted 16px behind the mark's real size. */
  --header-h: 98px;

  --radius: 3px;
  --radius-lg: 6px;
  --shadow: 0 1px 2px rgba(18,33,28,.05), 0 12px 32px -18px rgba(18,33,28,.28);
  --shadow-lg: 0 2px 4px rgba(18,33,28,.06), 0 40px 80px -40px rgba(18,33,28,.4);

  --ease: cubic-bezier(.22,.61,.36,1);
}

/* ---------- 2. Reset and base ---------- */
*, *::before, *::after { box-sizing: border-box; }

/* clip, not hidden: overflow-x:hidden makes this a scroll container, which
   silently disables position:sticky on every descendant (it is what stopped
   the land-release illustration tracking its steps). clip contains the
   overflow without that side effect. */
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; overflow-x: clip; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--f-sans);
  font-size: 17px;
  line-height: 1.62;
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}

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

a { color: inherit; text-decoration-color: color-mix(in srgb, currentColor 35%, transparent); text-underline-offset: 3px; }
a:hover { text-decoration-color: currentColor; }

button, input, textarea, select { font: inherit; color: inherit; }
button { cursor: pointer; }

::selection { background: var(--ink); color: var(--paper); }

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

.visually-hidden, .sr-only {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

.skip-link {
  position: fixed; top: 10px; left: 10px; z-index: 200;
  transform: translateY(-160%);
  background: var(--ink); color: var(--paper);
  padding: 12px 20px; border-radius: var(--radius);
  font-weight: 600; text-decoration: none;
  transition: transform .2s var(--ease);
}
.skip-link:focus { transform: none; }

/* ---------- 3. Typography ---------- */
h1, h2, h3, h4 {
  font-family: var(--f-display);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -.02em;
  margin: 0;
  text-wrap: balance;
}

/* Albert Sans is geometric, so it takes tighter tracking than a serif would
   at display sizes without the counters closing up. */
h1 { font-size: clamp(2.6rem, 5.4vw, 4.7rem); line-height: 1; letter-spacing: -.038em; font-weight: 700; }
h2 { font-size: clamp(1.9rem, 3.4vw, 3rem); letter-spacing: -.032em; font-weight: 700; }
h3 { font-size: clamp(1.2rem, 1.5vw, 1.5rem); line-height: 1.2; }
h4 { font-size: 1.05rem; line-height: 1.3; }

p { margin: 0 0 1.05em; text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

strong, b { font-weight: 600; }

/* Labels. Short, non-sentence strings only: mono uppercase is a label voice,
   and running a sentence through it makes the reader decode rather than read. */
.mono, .eyebrow, .chapter-label, .phase, .geo-legend,
.chart-caption, .news-meta, .vacancy-meta, .footer-bottom .mono {
  font-family: var(--f-mono);
  font-size: .715rem;
  letter-spacing: .1em;
  text-transform: uppercase;
  font-weight: 500;
}

/* The section spine. Every section opens with one of these: numbered 01-08 for
   the argument a donor is walked through, unnumbered for the reference
   sections after it. They are paragraphs, so any prose rule scoped to a
   container they sit in — `.problem-copy p`, `.contact-info > p` — will
   outrank this on specificity and quietly set them as body copy. Those rules
   carry a :not() for exactly that reason; a new one needs the same. */
.eyebrow, .chapter-label {
  display: inline-flex; align-items: center; gap: 10px;
  color: var(--clay-deep);
  margin: 0 0 20px;
}
.eyebrow::before, .chapter-label::before {
  content: ""; width: 26px; height: 2px; background: var(--clay); flex: none;
}
.chapter-label span { color: var(--muted); }

/* ---------- 4. Layout primitives ---------- */
.shell {
  width: min(100% - (var(--gutter) * 2), var(--shell));
  margin-inline: auto;
}

main > section { padding-block: var(--sec-y); position: relative; }

/* Every section sits on the page ground. Rhythm comes from the content — rules,
   cards, the field canvas — not from swapping the background every other
   section, which is what made the old page look like several different sites. */
.impact-strip, .dashboard, .site-footer, .credbar { background: var(--paper-2); }

.sec-head { max-width: 62ch; margin-bottom: clamp(36px, 4vw, 64px); }
/* The standfirst only. The chapter and reference labels are paragraphs too and
   they sit in here as well, so without the exclusion this rule outranks the
   label styling on specificity and sets them as muted body copy. */
.sec-head p:not(.eyebrow):not(.chapter-label) {
  color: var(--muted); font-size: 1.12rem; margin-top: 18px;
}
.sec-head > p:last-child { margin-bottom: 0; }

/* Dark-field variants */
.impact-strip .sec-head p:not(.chapter-label):not(.eyebrow),
.dashboard .sec-head p:not(.chapter-label):not(.eyebrow) { color: var(--muted); }
.impact-strip .eyebrow, .dashboard .eyebrow { color: var(--sand); }
.impact-strip .eyebrow::before, .dashboard .eyebrow::before { background: var(--sand); }

/* A panel's standfirst is a sentence, not a label — it was being set in mono
   caps and read as machine output rather than as an explanation. */
.panel-note {
  display: block; margin: 6px 0 22px;
  font-size: .95rem; line-height: 1.55; color: var(--muted);
}

/* ---------- 5. Buttons ---------- */
.btn {
  --btn-bg: var(--ink);
  --btn-fg: var(--paper);
  --btn-bd: var(--ink);
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  padding: 15px 26px;
  background: var(--btn-bg); color: var(--btn-fg);
  border: 1.5px solid var(--btn-bd); border-radius: var(--radius);
  font-family: var(--f-sans); font-size: .92rem; font-weight: 600;
  letter-spacing: .005em; text-decoration: none; text-align: center;
  transition: background .22s var(--ease), color .22s var(--ease),
              border-color .22s var(--ease), transform .22s var(--ease);
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: none; }

.btn-primary { --btn-bg: var(--clay); --btn-bd: var(--clay); --btn-fg: #fff; }
.btn-primary:hover { --btn-bg: var(--clay-deep); --btn-bd: var(--clay-deep); }

.btn-secondary { --btn-bg: var(--ink); --btn-bd: var(--ink); --btn-fg: var(--paper); }
.btn-secondary:hover { --btn-bg: var(--forest); --btn-bd: var(--forest); }

.btn-ghost, .btn-quiet {
  --btn-bg: transparent; --btn-fg: var(--ink); --btn-bd: var(--line-strong);
}
.btn-ghost:hover, .btn-quiet:hover { --btn-bd: var(--ink); --btn-bg: transparent; }

.btn-onphoto {
  --btn-bg: rgba(255,255,255,.1); --btn-fg: #fff; --btn-bd: rgba(255,255,255,.5);
  backdrop-filter: blur(6px);
}
.btn-onphoto:hover { --btn-bg: rgba(255,255,255,.2); --btn-bd: #fff; }

.btn-sm { padding: 10px 18px; font-size: .84rem; }

/* ---------- 6. Header and navigation ---------- */
.site-header {
  position: sticky; top: 0; z-index: 90;
  background: transparent;
  transition: background .3s var(--ease), box-shadow .3s var(--ease);
}
.site-header::after {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: var(--forest-deep);
  opacity: 0;
  transition: opacity .3s var(--ease);
}
.site-header.is-condensed::after { opacity: 1; }
.site-header.is-condensed { box-shadow: 0 1px 0 var(--line-dark); }

/* Before condensing, the bar floats on the hero photograph and needs its own
   legibility gradient rather than a solid fill. */
.site-header::before {
  content: ""; position: absolute; inset: 0 0 auto; height: 190%; z-index: -2;
  background: linear-gradient(to bottom, rgba(9,20,15,.72), rgba(9,20,15,0));
  pointer-events: none;
  transition: opacity .3s var(--ease);
}
.site-header.is-condensed::before { opacity: 0; }

.nav {
  display: flex; align-items: center; gap: clamp(16px, 2.4vw, 40px);
  padding-block: 16px;
  color: #fff;
}

.brand { display: flex; align-items: center; gap: 12px; text-decoration: none; flex: none; }
/* The mark, painted rather than displayed. The supplied file is single-colour
   line art in the brand's dark green (#003000) on transparency, and that green
   measures about 1.3:1 against the page ground — unreadable on it, and the
   reason earlier builds either knocked it out to white or sat it on a pale
   plate. Using the file as a mask and filling it with a token keeps the mark
   green and lets it sit straight on the dark ground with no plate at all.
   A filter chain could not land on an exact token; a mask can. */
/* Fallback first: the logo file itself, painted normally. If the mask never
   applies — because the browser does not support masking, or because the mask
   image failed to load — the element is left with nothing but a background
   COLOUR, and a mask that cannot load masks everything out. Either way the
   mark disappears completely rather than degrading. This way the worst case is
   the logo in its own dark green rather than no logo at all. */
.brand-mark, .footer-mark {
  display: block; flex: none;
  background: var(--logo-src) center / contain no-repeat;
}
@supports ((-webkit-mask-image: url("")) or (mask-image: url(""))) {
  .brand-mark, .footer-mark {
    /* The brand's primary green, not the mint: a step up in brightness from the
       file's own #003000 rather than a jump to near-white. 8.9:1 on the header,
       which the thin line work needs. */
    background: var(--clay);
    -webkit-mask: var(--logo-src) center / contain no-repeat;
            mask: var(--logo-src) center / contain no-repeat;
  }
}
/* The mark is what sets the header's height: 16px of nav padding above and
   below it and nothing else in the bar is taller. Growing it grows the bar,
   which is why the field readout's top offset is stated against the same
   number. */
/* The logo file is 149x96 — the full lockup, not a round emblem — so a square
   box let `contain` letterbox it: at 66x66 the artwork actually drew at
   66x42.5 with 12px of dead space above and below. Giving the box the file's
   own 149:96 proportion makes the mark 55% taller at the same box height, so
   the header does not change size. */
.brand-mark { width: 102px; height: 66px; }
.brand-name {
  display: flex; flex-direction: column; line-height: 1;
  font-family: var(--f-display); font-weight: 700; font-size: 1.5rem; letter-spacing: .01em;
}
.brand-sub {
  font-family: var(--f-mono); font-weight: 400;
  font-size: .555rem; letter-spacing: .17em; text-transform: uppercase;
  margin-top: 6px; opacity: .8;
}

.nav-links { display: flex; align-items: center; gap: clamp(14px, 1.8vw, 30px); margin-right: auto; }
/* The navigation is a set of labels, so it takes the label style the rest of
   the page uses for eyebrows, chapter marks and captions — mono, uppercase,
   letterspaced. Set in sentence-case body type it was the one piece of
   chrome speaking a different language from everything under it. */
.nav-links a {
  position: relative;
  font-family: var(--f-mono);
  font-size: .68rem; font-weight: 500;
  text-transform: uppercase; letter-spacing: .11em;
  text-decoration: none; padding: 6px 0; white-space: nowrap;
  opacity: .88;
  transition: opacity .2s var(--ease);
}
.nav-links a:hover { opacity: 1; }
.nav-links a::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0;
  height: 2px; background: var(--clay);
  transform: scaleX(0); transform-origin: left;
  transition: transform .26s var(--ease);
}
.nav-links a:hover::after, .nav-links a.is-active::after { transform: scaleX(1); }
.nav-close { display: none; }

.nav-utility { display: flex; align-items: center; gap: 12px; flex: none; }

.site-search { position: relative; display: flex; align-items: center; }
.site-search input {
  width: 132px; padding: 9px 34px 9px 13px;
  background: rgba(255,255,255,.1); color: #fff;
  border: 1px solid rgba(255,255,255,.24); border-radius: var(--radius);
  font-size: .82rem;
  transition: width .28s var(--ease), background .2s var(--ease);
}
.site-search input::placeholder { color: rgba(255,255,255,.6); }
.site-search input:focus { width: 190px; background: rgba(255,255,255,.16); outline-offset: 1px; }
.site-search button {
  position: absolute; right: 4px;
  display: grid; place-items: center;
  width: 26px; height: 26px; padding: 0;
  background: none; border: 0; color: rgba(255,255,255,.75); border-radius: 2px;
}
.site-search button:hover { color: #fff; }
.site-search-status { position: absolute; top: 100%; left: 0; font-size: .7rem; white-space: nowrap; padding-top: 4px; }

.language-switcher { display: flex; gap: 2px; padding: 3px; background: rgba(255,255,255,.1); border-radius: var(--radius); }
.language-switcher button {
  padding: 6px 10px; background: none; border: 0; border-radius: 2px;
  font-family: var(--f-mono); font-size: .68rem; letter-spacing: .06em;
  color: rgba(255,255,255,.7);
  transition: background .2s var(--ease), color .2s var(--ease);
}
.language-switcher button:hover { color: #fff; }
/* --ink is light on this scheme, so the selected chip needs the dark value
   for its label or it renders white text on a white pill. */
.language-switcher button[aria-pressed="true"] { background: var(--ink); color: var(--paper); font-weight: 700; }

.nav-cta { --btn-fg: #fff; }
.nav-toggle { display: none; }
.translate-engine { position: absolute; width: 0; height: 0; overflow: hidden; }

/* Google Translate injects a banner that shoves the page down. */
.goog-te-banner-frame, .skiptranslate { display: none !important; }
body { top: 0 !important; }

/* ---------- 7. Hero and credentials band ---------- */
.hero {
  position: relative;
  /* Shortened. The headline used to run to three lines; at one line the block
     lost about 130px and all of it turned into dead air under the header,
     because the copy is bottom-aligned and only the box above it grew. */
  min-height: min(88vh, 820px);
  display: flex; align-items: flex-end;
  /* The copy is bottom-aligned, so the lower padding is what lifts it. */
  padding-block: clamp(112px, 16vh, 190px) clamp(96px, 11vw, 164px);
  margin-top: calc(-1 * var(--header-h));   /* header floats over the photograph */
  background: var(--forest-deep);
  overflow: hidden;
}
/* The interactive plot fills the hero. Pointer events stay on the stage so the
   ground can be swept, while the copy above it re-enables them for itself. */
.field-stage { position: absolute; inset: 0; z-index: 0; }
.field-stage canvas { width: 100%; height: 100%; display: block; }
/* Set by the field script once WebGL is actually running, so the crosshair
   never appears over the fallback photograph. */
.field-stage.is-live canvas { cursor: crosshair; }
.field-stage.is-static canvas { display: none; }

.hero-media { position: absolute; inset: 0; }
.hero-media img { width: 100%; height: 100%; object-fit: cover; object-position: center 42%; }

/* Legibility scrim, weighted to the left where the headline sits.

   Much lighter than it was, and ramped over five stops instead of three. The
   scene is now staged with the sun low on the right, so the left of the frame
   is already in shade and the scrim only has to finish the job rather than do
   all of it. The old two-stop version was dense enough to black out the
   village and hard-edged enough that the ramp itself was visible as a diagonal
   band across the picture. */
.hero::after {
  content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background:
    linear-gradient(102deg,
      rgba(8,12,11,.86) 0%,
      rgba(8,12,11,.70) 14%,
      rgba(8,12,11,.42) 30%,
      rgba(8,12,11,.16) 45%,
      rgba(8,12,11,0) 60%),
    linear-gradient(to top,
      var(--paper) 0%,
      rgba(10,14,13,.72) 13%,
      rgba(10,14,13,0) 36%);
}
.hero-shell { position: relative; z-index: 2; pointer-events: none; }
.hero-shell a, .hero-shell button { pointer-events: auto; }

/* ---- detector readout ---- */
/* Hung from the header rule at the right gutter, not floated in the middle of
   the picture. Vertically centred it sat directly over the half of the plot the
   sweep actually happens in, so the instrument was covering the thing it reads.
   Up here it is over sky at every desktop width: the tiles begin well below it,
   and the sweep has the whole grid back.

   The top offset is the header height plus a band, which is a fixed distance at
   every viewport height — so the panel keeps one alignment instead of drifting
   with the flex-end copy. Its right edge is the same --gutter every other
   element on the page ends on. */
.field-hud {
  position: absolute; z-index: 2;
  right: var(--gutter); top: calc(var(--header-h) + clamp(22px, 3.4vh, 44px));
  width: min(272px, calc(100vw - var(--gutter) * 2));
  padding: 18px 20px 20px;
  background: rgba(10,14,13,.58);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg);
  backdrop-filter: blur(14px);
}
/* A 2px stub of the accent, the same mark the hero kicker carries on the far
   side of the frame. It is what ties the panel back to the copy column. */
.field-hud::before {
  content: ""; position: absolute; left: 20px; top: -1px;
  width: 34px; height: 2px; background: var(--clay);
}
.field-hint {
  margin: 0 0 16px; padding-left: 18px; position: relative;
  font-family: var(--f-mono); font-size: .66rem; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink-soft); line-height: 1.5;
}
.field-hint::before {
  content: ""; position: absolute; left: 0; top: .42em;
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--hazard); box-shadow: 0 0 0 0 var(--hazard-wash);
  animation: field-ping 2.2s var(--ease) infinite;
}
@keyframes field-ping {
  0%   { box-shadow: 0 0 0 0 rgba(255,95,58,.55); }
  70%  { box-shadow: 0 0 0 9px rgba(255,95,58,0); }
  100% { box-shadow: 0 0 0 0 rgba(255,95,58,0); }
}
.field-readout { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; margin: 0 0 16px; }
.field-readout dt {
  font-family: var(--f-mono); font-size: .56rem; letter-spacing: .09em;
  text-transform: uppercase; color: var(--muted); margin-bottom: 6px; line-height: 1.3;
}
.field-readout dd {
  margin: 0; font-family: var(--f-display); font-weight: 700;
  font-size: 1.15rem; letter-spacing: -.02em; font-variant-numeric: tabular-nums;
}
.field-assist {
  width: 100%; padding: 10px 14px;
  background: transparent; color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  font-family: var(--f-mono); font-size: .64rem; letter-spacing: .08em; text-transform: uppercase;
  transition: border-color .2s var(--ease), background .2s var(--ease);
}
.field-assist:hover { border-color: var(--clay); background: var(--clay-wash); }

.hero-kicker {
  font-family: var(--f-mono); font-size: .74rem; letter-spacing: .17em;
  text-transform: uppercase; color: var(--sand);
  display: flex; align-items: center; gap: 12px; margin-bottom: 26px;
}
.hero-kicker::before { content: ""; width: 34px; height: 2px; background: var(--clay); }

/* Sized to hold the headline on one line at desktop and wrap on its own below
   that. Slightly under the global h1 ceiling: a short line set at the maximum
   reads as type that only just fits, where a touch smaller reads as chosen. */
.hero h1 {
  max-width: none; color: #fff;
  font-size: clamp(2.5rem, 4.6vw, 4.1rem);
  text-shadow: 0 2px 30px rgba(0,0,0,.3);
}

.hero-lede {
  max-width: 56ch; margin-top: 26px;
  font-size: clamp(1.05rem, 1.35vw, 1.24rem);
  line-height: 1.58;
  color: rgba(255,255,255,.86);
}

.hero-actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 36px; }

/* The four headline figures. They are stated here and nowhere else on the
   page: repeating them in a band lower down said the same thing twice and
   made the record look thinner than it is. */
.hero-proof {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(18px, 2.2vw, 40px);
  margin: clamp(44px, 6vw, 72px) 0 0;
  padding-top: 30px;
  border-top: 1px solid rgba(255,255,255,.24);
  max-width: 1000px;
}
.hero-proof div { min-width: 0; }
.hero-proof dt {
  font-family: var(--f-mono); font-size: .68rem; letter-spacing: .11em;
  text-transform: uppercase; color: rgba(255,255,255,.66);
  margin-bottom: 10px;
}
.hero-proof dd {
  margin: 0;
  font-family: var(--f-display); font-weight: 600;
  font-size: clamp(1.7rem, 2.5vw, 2.5rem); line-height: 1;
  letter-spacing: -.02em; font-variant-numeric: tabular-nums;
}
.hero-proof abbr { text-decoration: none; font-size: .5em; opacity: .75; }

.credbar { padding-block: 0; background: var(--forest-deep); }
/* No outer border. It added a pixel of inset, and with the edge cells now run
   flush to the measure there is no edge left for it to cap. */
.credbar-inner {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 1px; background: var(--line-dark);
}
.credbar p {
  margin: 0; padding: 22px 24px;
  background: var(--forest-deep); color: var(--ink);
  display: flex; flex-direction: column; gap: 5px;
}
/* The cells at each end of a row drop their outer padding so the first label
   starts on the same left edge as the headline above it and the last ends on
   the same right edge. Even padding all round put this band's text 25px inside
   the column every other element on the page aligns to — the one real
   misalignment in the layout. The counts follow the column count, which
   changes at 1024 and again at 760. */
.credbar p:nth-child(4n+1) { padding-left: 0; }
.credbar p:nth-child(4n)   { padding-right: 0; }
.credbar strong { font-size: .95rem; font-weight: 600; }
.credbar span {
  font-family: var(--f-mono); font-size: .66rem; letter-spacing: .08em;
  text-transform: uppercase; color: rgba(255,255,255,.55);
}

/* ---------- 8. Problem ---------- */
.problem-chapter .problem-layout { display: grid; grid-template-columns: 1.35fr .95fr; gap: clamp(32px, 5vw, 84px); align-items: start; }
.problem-copy h2 { margin-bottom: 22px; }
.problem-copy p:not(.chapter-label):not(.eyebrow) { color: var(--muted); font-size: 1.12rem; max-width: 52ch; }

.problem-evidence {
  padding: 32px 34px;
  background: var(--white); border: 1px solid var(--line);
  border-top: 3px solid var(--clay);
  border-radius: var(--radius); box-shadow: var(--shadow);
}
.evidence-label { font-family: var(--f-mono); font-size: .7rem; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); margin-bottom: 14px; }
.evidence-figure { display: flex; align-items: baseline; gap: 16px; margin-bottom: 16px; }
.evidence-figure strong {
  font-family: var(--f-display); font-size: clamp(3.4rem, 6vw, 5rem);
  line-height: .85; font-weight: 700; color: var(--clay); letter-spacing: -.03em;
}
.evidence-figure span { font-size: .95rem; line-height: 1.4; color: var(--ink-soft); }
.evidence-note { font-size: .92rem; color: var(--muted); padding-top: 16px; border-top: 1px solid var(--line); }

.problem-route { grid-column: 1 / -1; width: 100%; height: auto; margin-top: 12px; color: var(--clay); }
.problem-route .route-line { fill: none; stroke: var(--ink); stroke-width: 2.5; stroke-dasharray: 9 8; opacity: .5; }
.problem-route .route-diversion { fill: none; stroke: var(--clay); stroke-width: 2.5; }
.problem-route .route-arrow { fill: var(--clay); stroke: none; }
.problem-route .route-marker circle { fill: var(--clay-wash); stroke: var(--clay); stroke-width: 2; }
.problem-route .route-marker path { fill: var(--clay); stroke: none; }
.problem-route .route-marker path:last-child { stroke: var(--white); stroke-width: 1.6; fill: none; }
.problem-route text { font-family: var(--f-mono); font-size: 15px; letter-spacing: .1em; fill: var(--muted); text-transform: uppercase; }

.chapter-cue {
  grid-column: 1 / -1;
  display: inline-flex; align-items: center; gap: 12px;
  font-size: .9rem; font-weight: 500; text-decoration: none; color: var(--ink);
  padding-top: 22px; border-top: 1px solid var(--line); margin-top: 8px;
}
.chapter-cue span { font-family: var(--f-mono); font-size: .68rem; letter-spacing: .12em; text-transform: uppercase; color: var(--clay-deep); }
.chapter-cue i { font-style: normal; transition: transform .25s var(--ease); }
.chapter-cue:hover i { transform: translateY(3px); }

/* ---------- 9. Figures strip ---------- */
.impact-strip .strip-lead {
  max-width: 68ch; font-size: 1.15rem; line-height: 1.6;
  color: var(--muted);
  margin-bottom: clamp(40px, 5vw, 64px);
}
.strip-grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 1px; background: var(--line-dark);
  border-block: 1px solid var(--line-dark);
}
.strip-grid .stat { background: var(--forest); padding: 34px 28px 30px; }
.strip-grid .num {
  display: flex; align-items: baseline; gap: 6px;
  font-family: var(--f-display); font-weight: 600;
  font-size: clamp(2.3rem, 4.2vw, 3.5rem); line-height: 1;
  letter-spacing: -.028em; font-variant-numeric: tabular-nums;
  color: #fff;
}
.strip-grid .num small { font-size: .34em; font-weight: 500; opacity: .7; letter-spacing: 0; }
.strip-grid .label {
  display: block; margin-top: 16px;
  font-family: var(--f-mono); font-size: .68rem; letter-spacing: .1em;
  text-transform: uppercase; color: rgba(255,255,255,.58); line-height: 1.5;
}

/* ---------- 10. Services ---------- */
.svc-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.svc-card {
  display: flex; flex-direction: column; gap: 12px;
  padding: 30px 28px 26px;
  background: var(--white); border: 1px solid var(--line);
  border-radius: var(--radius);
  transition: border-color .25s var(--ease), transform .25s var(--ease), box-shadow .25s var(--ease);
}
.svc-card:hover { border-color: var(--line-strong); transform: translateY(-3px); box-shadow: var(--shadow); }
.svc-wide { grid-column: span 2; }
/* The glyphs stroke with currentColor, and currentColor was --forest: #101615,
   a near-black held over from the light theme. Every one of these was a black
   line drawing on a dark card — present in the DOM, invisible on the page. */
.svc-card .icon {
  display: grid; place-items: center; width: 44px; height: 44px;
  background: var(--clay-wash); color: var(--clay-deep);
  border: 1px solid color-mix(in srgb, var(--clay) 24%, transparent);
  border-radius: var(--radius);
  transition: background .25s var(--ease), color .25s var(--ease),
              border-color .25s var(--ease);
}
.svc-card:hover .icon {
  background: color-mix(in srgb, var(--clay) 22%, transparent);
  border-color: color-mix(in srgb, var(--clay) 52%, transparent);
  color: #fff;
}
.svc-card h3 { margin-top: 4px; }
.svc-card p { color: var(--muted); font-size: .97rem; margin: 0; }
.svc-tag {
  margin-top: auto; padding-top: 16px;
  font-family: var(--f-mono); font-size: .66rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--clay-deep);
}

/* ---------- 11. Land release ---------- */
/* Document order is stage-then-steps, so the illustration takes the wide column
   and sticks while the five stages scroll past it. explainers.js marks the
   current step .active and cross-fades the matching .scene in the stage. */
.landrelease .lr-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 400px);
  gap: clamp(28px, 4vw, 64px);
  align-items: start;
}
.lr-stage-wrap { position: sticky; top: 92px; }

.lr-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.lr-step {
  position: relative;
  padding: 24px 0 24px 54px;
  border-top: 1px solid var(--line);
  opacity: .42;
  transition: opacity .35s var(--ease);
}
.lr-step:last-child { border-bottom: 1px solid var(--line); }
.lr-step.active { opacity: 1; }
.lr-node {
  position: absolute; left: 0; top: 22px;
  display: grid; place-items: center;
  width: 32px; height: 32px;
  border: 1.5px solid var(--line-strong); border-radius: 50%;
  font-family: var(--f-mono); font-size: .72rem; color: var(--muted);
  transition: background .3s var(--ease), color .3s var(--ease), border-color .3s var(--ease);
}
.lr-step.active .lr-node { background: var(--clay); border-color: var(--clay); color: #fff; }
.lr-step h3 { margin-bottom: 10px; }
.lr-step h3 span { font-family: var(--f-mono); font-size: .62em; color: var(--muted); letter-spacing: .06em; }
.lr-step > p { font-size: .96rem; color: var(--muted); margin: 0; }
.lr-step ul { list-style: none; margin: 14px 0 0; padding: 0; display: flex; flex-direction: column; gap: 9px; }
.lr-step li {
  display: grid; grid-template-columns: 16px 1fr; gap: 10px; align-items: start;
  font-size: .89rem; color: var(--ink-soft);
}
.lr-step li svg { color: var(--clay); margin-top: 5px; }

.lr-rail { position: relative; height: 3px; background: var(--line-strong); margin-bottom: 26px; }
.lr-rail-fill { position: absolute; inset: 0 auto 0 0; width: 0; background: var(--clay); transition: width .4s var(--ease); }

.lr-stage {
  position: relative; width: 100%; aspect-ratio: 16 / 10;
  background: var(--white); border: 1px solid var(--line);
  border-radius: var(--radius-lg); overflow: hidden;
}
.lr-stage svg { width: 100%; height: 100%; display: block; }
.lr-stage .scene { opacity: 0; transition: opacity .5s var(--ease); }
.lr-stage .scene.on { opacity: 1; }
.lr-stage-cap {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 12px;
  margin-top: 18px; font-size: .95rem; color: var(--muted);
}
.lr-count { font-family: var(--f-mono); font-size: .7rem; letter-spacing: .12em; text-transform: uppercase; color: var(--clay-deep); }
.lr-note { font-size: .88rem; color: var(--muted); margin-top: 10px; }

/* ---------- 12. Risk education ---------- */
.eore-head { margin-bottom: clamp(32px, 4vw, 56px); }
.eore-track-wrap { position: relative; }
.eore-track {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px;
  overflow: visible;
}
.eore-panel {
  display: flex; flex-direction: column; gap: 12px;
  padding: 28px 24px;
  background: var(--white); border: 1px solid var(--line);
  border-top: 3px solid var(--sage);
  border-radius: var(--radius);
}
.eore-panel .phase { color: var(--clay-deep); margin: 0; }
.eore-panel h3 { margin: 0; }
.eore-panel > p { font-size: .95rem; color: var(--muted); margin: 0; }
.eore-panel ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.eore-panel li { display: grid; grid-template-columns: auto 1fr; gap: 10px; align-items: start; font-size: .88rem; color: var(--ink-soft); }
.eore-panel li svg { color: var(--clay); margin-top: 4px; }
.eore-fig { margin-top: auto; padding-top: 8px; }
.eore-fig svg { width: 100%; height: auto; display: block; border-radius: var(--radius); }
.eore-progress { display: none; }

/* Field photographs that show what a session actually looks like. Capped at
   tile width: the source frames are 577–684px, so anything larger softens. */
.eore-evidence { margin-top: clamp(40px, 5vw, 64px); }
.eore-evidence h3 { margin-bottom: 8px; }
.eore-evidence > p { color: var(--muted); max-width: 60ch; margin-bottom: 28px; }
/* ---- the field board ----
   These six were six loose cards on the page ground, at two different heights
   because each grid row sized itself to its own longest caption, and with six
   different image proportions because the source files are 578-684px wide and
   308-431px tall. Read as a set they looked like an upload rather than a
   record.

   They are now one board with six plates pinned to it: a recessed panel, a
   mount round each photograph, a fixing at the head of it and a stamped index.
   The depth is surface steps and hairlines, the same way everything else on
   this page gets its depth — no cork, no shadows thrown at an angle, no
   tilted frames. It reads as a board because it is built like one, not
   because it is drawn to look like one. */
.field-grid {
  list-style: none; margin: 0;
  display: grid; grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 1fr;                     /* every plate the same height */
  gap: clamp(14px, 1.6vw, 22px);
  padding: clamp(16px, 2vw, 28px);
  background: var(--paper-2);
  border: 1px solid var(--line-dark);
  border-radius: var(--radius-lg);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.05);
  counter-reset: plate;
}
.field-item {
  counter-increment: plate;
  position: relative;
  display: flex; flex-direction: column;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  /* The mount: 8px of card visible round the photograph, and a deeper strip
     at the head for the fixing and the index to sit in. */
  padding: 24px 8px 0;
  transition: transform .25s var(--ease), border-color .25s var(--ease);
}
.field-item::before {
  content: ""; position: absolute; left: 50%; top: 9px;
  width: 7px; height: 7px; margin-left: -3.5px; border-radius: 50%;
  background: var(--clay);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--clay) 16%, transparent);
}
/* Numbered, in the same mono the chapter spine uses, so a caption can refer to
   a plate by number. */
.field-item::after {
  content: counter(plate, decimal-leading-zero);
  position: absolute; top: 8px; right: 11px;
  font-family: var(--f-mono); font-size: .56rem; letter-spacing: .12em;
  color: var(--muted);
}
.field-item:hover, .field-item:focus-within {
  transform: translateY(-3px);
  border-color: color-mix(in srgb, var(--clay) 42%, transparent);
}
/* One proportion for all six. Cover crops rather than letterboxes, so no
   plate carries a band of empty ground. */
.field-item img {
  width: 100%; height: auto; aspect-ratio: 3 / 2;
  object-fit: cover; display: block; border-radius: 2px;
}
.field-cap {
  flex: 1;
  padding: 12px 6px 14px; margin: 0;
  font-size: .82rem; color: var(--muted); line-height: 1.45;
}
.field-cap strong { display: block; color: var(--ink); font-weight: 600; margin-bottom: 4px; font-size: .9rem; }

/* ---------- 13. Scene band ---------- */
.scene-band .hero-story {
  width: min(100% - 32px, var(--shell-wide)); margin-inline: auto;
  /* The walker rig is a nested <svg overflow="visible">, so parts of the scene
     paint outside the viewBox and would widen the document. Clip at the frame. */
  overflow: hidden;
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--paper-2);
}
.scene-band .hero-scene { width: 100%; height: auto; display: block; overflow: hidden; }
.scene-caption {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 20px;
  margin-top: 22px;
}
.scene-phase { margin: 0; font-family: var(--f-mono); font-size: .7rem; letter-spacing: .12em; text-transform: uppercase; color: var(--clay-deep); }
.scene-phase-text { margin: 0; color: var(--muted); font-size: .95rem; margin-right: auto; }

/* ---------- 14. Outcomes ---------- */
.impact-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 18px; }
.impact-card {
  display: flex; flex-direction: column;
  background: var(--white); border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden;
  transition: transform .25s var(--ease), box-shadow .25s var(--ease);
}
.impact-card:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
.impact-feature { grid-column: span 2; grid-row: span 2; }
.impact-card .icon {
  display: grid; place-items: center; width: 40px; height: 40px;
  margin: 24px 26px 0;
  background: var(--clay-wash); color: var(--clay-deep); border-radius: var(--radius);
}
.impact-card h3 { margin: 16px 26px 0; }
.impact-card .figure {
  display: block; margin: 14px 26px 0;
  font-family: var(--f-display); font-weight: 600;
  font-size: clamp(1.5rem, 2.4vw, 2.1rem); line-height: 1;
  letter-spacing: -.02em; color: var(--clay);
}
.impact-card p { margin: 14px 26px 26px; font-size: .95rem; color: var(--muted); }
/* Who the sessions are built around. The feature card spans two grid rows, so
   under a single paragraph it left half a column of empty ground beneath the
   most human photograph on the page. */
.reach-list { list-style: none; margin: 4px 26px 0; padding: 0; }
.reach-list li { padding: 16px 0; border-top: 1px solid var(--line); }
.reach-list li:first-child { border-top: 0; padding-top: 4px; }
.reach-list h4 {
  margin: 0 0 6px;
  font-family: var(--f-mono); font-size: .7rem; font-weight: 500;
  letter-spacing: .11em; text-transform: uppercase; color: var(--clay-deep);
}
.impact-card .reach-list p { margin: 0; font-size: .92rem; line-height: 1.6; }
.impact-card .reach-close {
  margin: 20px 26px 26px; padding-top: 18px;
  border-top: 1px solid var(--line);
  color: var(--ink-soft); font-size: .95rem;
}

@media (min-width: 981px) {
  /* Two columns of groups once there is width for it, so the card fills its
     span instead of running as one long ribbon. */
  .reach-list { display: grid; grid-template-columns: 1fr 1fr; column-gap: 30px; }
  .reach-list li:nth-child(2) { border-top: 0; padding-top: 4px; }
}

.impact-illustration, .impact-sketch img { width: 100%; height: 190px; object-fit: cover; order: -1; }
.impact-sketch { margin: 20px 0 0; }
.impact-feature .impact-sketch img { height: 300px; }

/* ---------- 15. The record (map, charts) ---------- */
.dashboard .geo-panel, .dashboard .dash-panel {
  background: color-mix(in srgb, #fff 7%, transparent);
  border: 1px solid var(--line-dark);
  border-radius: var(--radius-lg);
  padding: clamp(22px, 2.6vw, 34px);
}
.geo-panel { margin-bottom: 20px; }
.geo-head { display: grid; grid-template-columns: 1fr auto; gap: 24px; align-items: start; margin-bottom: 26px; }
.geo-head h3 { color: #fff; }
.dashboard .panel-note { color: rgba(255,255,255,.62); }
.geo-chips { display: flex; flex-wrap: wrap; gap: 6px; max-width: 460px; }
.geo-chips button, .chip {
  padding: 7px 14px;
  background: transparent; color: rgba(255,255,255,.8);
  border: 1px solid var(--line-dark); border-radius: 100px;
  font-family: var(--f-mono); font-size: .66rem; letter-spacing: .08em; text-transform: uppercase;
  transition: background .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease);
}
.geo-chips button:hover { border-color: rgba(255,255,255,.5); color: #fff; }
.geo-chips button[aria-pressed="true"] { background: var(--clay); border-color: var(--clay); color: #fff; }

.geo-body { display: grid; grid-template-columns: 1.5fr 1fr; gap: clamp(20px, 3vw, 40px); align-items: start; }
.dash-map-wrap { position: relative; }
.dash-map-wrap svg { width: 100%; height: auto; display: block; overflow: visible; }

/* ---- the coverage map ----
   Three tiers of line, which is the whole reason the map reads as a map now:
   a hairline between provinces, a heavier line where two mine-action regions
   meet, and the national border on top of both. Everything below the border
   is clipped to it, so no cell can spill over the frontier. */
.afg-ground { fill: rgba(255,255,255,.045); }
.afg-outline {
  fill: none; stroke: rgba(255,255,255,.55); stroke-width: 1.6;
  stroke-linejoin: round; pointer-events: none;
}
.prov-cell {
  fill: rgba(52,206,138,.07);
  stroke: rgba(255,255,255,.15); stroke-width: .7;
  cursor: pointer;
  transition: fill .22s var(--ease), stroke .22s var(--ease);
}
.prov-cell:focus { outline: none; }
.prov-cell.lit    { fill: rgba(52,206,138,.20); }
.prov-cell.hover  { fill: rgba(52,206,138,.30); stroke: rgba(255,255,255,.55); }
.prov-cell.active { fill: rgba(52,206,138,.42); stroke: #fff; stroke-width: 1.3; }
.prov-cell:focus-visible { stroke: #fff; stroke-width: 1.6; }
.prov-frontier {
  fill: none; stroke: rgba(255,255,255,.34); stroke-width: 1.5;
  stroke-linecap: round; pointer-events: none;
}
.prov-markers { pointer-events: none; }

/* The tooltip is positioned by percentage of the map box, so it tracks the
   marker at every width without a resize listener. */
.geo-tip {
  position: absolute; z-index: 3; pointer-events: none;
  transform: translate(-50%, calc(-100% - 14px));
  padding: 8px 11px; min-width: 0; white-space: nowrap;
  background: rgba(8,12,11,.94);
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  box-shadow: 0 8px 26px rgba(0,0,0,.45);
}
.geo-tip[hidden] { display: none; }
.geo-tip b { display: block; font-size: .86rem; color: #fff; font-weight: 600; }
.geo-tip i {
  display: block; font-style: normal;
  font-family: var(--f-mono); font-size: .58rem; letter-spacing: .1em;
  text-transform: uppercase; color: var(--sand); margin-top: 3px;
}
.geo-tip span {
  display: block; font-family: var(--f-mono); font-size: .6rem;
  letter-spacing: .06em; color: var(--muted); margin-top: 4px;
}
.geo-legend { color: rgba(255,255,255,.5); margin-top: 12px; text-align: center; letter-spacing: .08em; }
.geo-detail { border-left: 2px solid var(--clay); padding-left: 22px; min-height: 160px; }
.geo-detail h4 { font-size: 1.25rem; color: #fff; margin-bottom: 12px; }
.geo-detail p { color: rgba(255,255,255,.7); font-size: .93rem; }
.prov-stat { display: flex; justify-content: space-between; gap: 16px; padding: 9px 0; border-bottom: 1px solid var(--line-dark); font-size: .88rem; }
.prov-stat span:first-child { color: rgba(255,255,255,.62); }
.prov-stat span:last-child { font-family: var(--f-mono); font-variant-numeric: tabular-nums; color: #fff; }

.dash-grid { display: grid; gap: 20px; }
.dash-grid-3 { grid-template-columns: repeat(3, 1fr); }
.dash-panel h3 { color: #fff; font-size: 1.15rem; }
.chart-box { position: relative; margin: 16px 0; min-height: 180px; }
.chart-caption { font-family: var(--f-sans); font-size: .85rem; letter-spacing: 0; text-transform: none; color: rgba(255,255,255,.6); line-height: 1.55; }

/* ---------- 16. Donor assurance ---------- */
.assurance-feature {
  background: var(--white); border: 1px solid var(--line);
  border-radius: var(--radius-lg); overflow: hidden;
  box-shadow: var(--shadow);
}
.assurance-feature-head { padding: clamp(32px, 4vw, 54px); border-bottom: 1px solid var(--line); }
.assurance-kicker {
  font-family: var(--f-mono); font-size: .7rem; letter-spacing: .14em;
  text-transform: uppercase; color: var(--clay-deep); margin-bottom: 16px;
}
.assurance-feature-head h3 { font-size: clamp(1.8rem, 3vw, 2.6rem); letter-spacing: -.022em; }
.assurance-intro { max-width: 68ch; margin-top: 18px; color: var(--muted); font-size: 1.05rem; }
.assurance-areas { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 24px; }
.assurance-areas span {
  /* --forest is a near-black left from the light theme, so these pills were
     dark text on a dark translucent green — barely legible. */
  padding: 7px 15px;
  background: var(--clay-wash); color: var(--clay-deep);
  border: 1px solid color-mix(in srgb, var(--clay) 34%, transparent);
  border-radius: 100px;
  font-family: var(--f-mono); font-size: .66rem; letter-spacing: .1em; text-transform: uppercase;
}

.assurance-tabs {
  display: grid; grid-template-columns: repeat(5, 1fr);
  background: var(--paper-2); border-bottom: 1px solid var(--line);
}
.assurance-tabs button {
  display: flex; flex-direction: column; gap: 8px; align-items: flex-start;
  padding: 20px 22px; background: none; border: 0;
  border-bottom: 3px solid transparent;
  font-size: .92rem; font-weight: 600; text-align: left; color: var(--muted);
  transition: background .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease);
}
.assurance-tabs button + button { border-left: 1px solid var(--line); }
.assurance-tabs button span { font-family: var(--f-mono); font-size: .66rem; letter-spacing: .1em; color: var(--line-strong); }
.assurance-tabs button:hover { background: var(--white); color: var(--ink); }
.assurance-tabs button[aria-selected="true"] {
  background: var(--white); color: var(--ink); border-bottom-color: var(--clay);
}
.assurance-tabs button[aria-selected="true"] span { color: var(--clay); }

.assurance-body { display: grid; grid-template-columns: 1.4fr 1fr; }
.assurance-panels { padding: clamp(30px, 3.5vw, 48px); }
.assurance-panel[hidden] { display: none; }
.assurance-panel-label { font-family: var(--f-mono); font-size: .68rem; letter-spacing: .12em; text-transform: uppercase; color: var(--clay-deep); margin-bottom: 14px; }
.assurance-panel h4 { font-size: clamp(1.3rem, 2vw, 1.75rem); margin-bottom: 14px; }
.assurance-panel p { color: var(--muted); max-width: 56ch; margin: 0; }

.assurance-reports {
  padding: clamp(30px, 3.5vw, 48px);
  background: var(--paper-2); border-left: 1px solid var(--line);
}
.assurance-reports h4 { margin-bottom: 18px; }
.assurance-reports ul { list-style: none; margin: 0 0 20px; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.assurance-reports li { position: relative; padding-left: 20px; font-size: .92rem; color: var(--ink-soft); }
.assurance-reports li::before { content: ""; position: absolute; left: 0; top: .62em; width: 8px; height: 1.5px; background: var(--clay); }
.assurance-reports p { font-size: .88rem; color: var(--muted); padding-top: 18px; border-top: 1px solid var(--line); }

/* ---------- 17. Partners ---------- */
.partner-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px; background: var(--line); border: 1px solid var(--line); }
/* The grid draws its rules by showing its own background through a 1px gap, so
   any cell left over at the end of the last row showed up as an empty ruled
   box. Eleven partners plus this filler is twelve, which divides evenly by the
   four, three and two column counts the grid actually uses. */
.partner-grid::after { content: ""; background: var(--white); }
.partner-card {
  position: relative;
  display: flex; flex-direction: column; gap: 8px;
  padding: 26px 24px; min-height: 168px;
  background: var(--white);
  transition: background .22s var(--ease);
}
/* Hover used --paper-2, which is darker than the card's own surface: the card
   receded on approach. It now lifts, and takes a brand rule down its leading
   edge so pointer and keyboard resolve to the same signal. */
.partner-card::before {
  content: ""; position: absolute; inset: 0 auto 0 0; width: 2px;
  background: var(--clay);
  transform: scaleY(0); transform-origin: 50% 0;
  transition: transform .28s var(--ease);
}
.partner-card:hover, .partner-card:focus-visible {
  background: color-mix(in srgb, var(--white) 88%, var(--ink) 12%);
}
.partner-card:hover::before, .partner-card:focus-visible::before { transform: scaleY(1); }
.partner-mark {
  font-family: var(--f-mono); font-size: .8rem; font-weight: 500;
  letter-spacing: .06em; color: var(--clay-deep);
}
.partner-card strong { font-family: var(--f-display); font-size: 1.1rem; font-weight: 600; }
.partner-detail { font-size: .87rem; color: var(--muted); line-height: 1.5; }

/* ---------- 18. About, timeline, gallery, lightbox ---------- */
.purpose-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px; margin-bottom: clamp(40px, 5vw, 72px); }
.purpose-statement {
  padding: 34px 32px;
  background: var(--forest); color: var(--ink);
  border-radius: var(--radius-lg);
}
.purpose-statement:last-child { background: var(--white); color: var(--ink); border: 1px solid var(--line); }
.purpose-statement h3 { font-size: 1.4rem; margin-bottom: 14px; }
.purpose-statement p { font-size: 1.02rem; opacity: .88; margin: 0; }
.purpose-statement:last-child p { color: var(--muted); opacity: 1; }

.about-layout { display: grid; grid-template-columns: 1.15fr .85fr; gap: clamp(32px, 5vw, 72px); align-items: start; }
.about-body p { color: var(--muted); font-size: 1.02rem; }

.cred-list { list-style: none; margin: 32px 0 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.cred-list li {
  display: grid; grid-template-columns: auto 1fr; gap: 16px; align-items: start;
  padding: 18px 0; border-top: 1px solid var(--line);
}
.cred-list svg { color: var(--clay); margin-top: 3px; }
.cred-list strong { display: block; font-weight: 600; margin-bottom: 3px; }
.cred-list span { font-size: .9rem; color: var(--muted); }

.timeline { list-style: none; margin: 0; padding: 0 0 0 30px; position: relative; }
.timeline::before { content: ""; position: absolute; left: 5px; top: 8px; bottom: 8px; width: 1.5px; background: var(--line-strong); }
.timeline li { position: relative; padding-bottom: 30px; }
.timeline li::before {
  content: ""; position: absolute; left: -30px; top: 6px;
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--paper); border: 2px solid var(--clay);
}
.timeline .year {
  display: block; font-family: var(--f-mono); font-size: .68rem;
  letter-spacing: .1em; text-transform: uppercase; color: var(--clay-deep); margin-bottom: 6px;
}
.timeline strong { display: block; font-family: var(--f-display); font-size: 1.15rem; font-weight: 600; margin-bottom: 6px; }
.timeline p { font-size: .92rem; color: var(--muted); margin: 0; }

.gallery { margin-top: clamp(48px, 6vw, 80px); }
.gallery h3 { margin-bottom: 24px; }
.gallery-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; }
.gallery-item {
  position: relative; display: block; padding: 0;
  background: var(--white); border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden; text-align: left;
  transition: transform .25s var(--ease), box-shadow .25s var(--ease);
}
.gallery-item:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
.gallery-item img { width: 100%; height: 230px; object-fit: cover; }
.gallery-cap { display: block; padding: 14px 16px; font-size: .87rem; color: var(--muted); }
.gallery-nav { display: flex; gap: 10px; margin-top: 18px; }
.gallery-nav-button {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 10px 18px; background: none;
  border: 1.5px solid var(--line-strong); border-radius: var(--radius);
  font-size: .85rem; font-weight: 600;
}
.gallery-nav-button:hover { border-color: var(--ink); }

.lightbox { border: 0; padding: 0; background: transparent; max-width: 100vw; max-height: 100vh; }
.lightbox::backdrop { background: rgba(9,20,15,.9); }
.lightbox-inner { display: flex; align-items: center; gap: 12px; padding: 20px; }
.lightbox-inner img { max-width: min(90vw, 1200px); max-height: 82vh; object-fit: contain; border-radius: var(--radius); }
.lightbox-cap { color: var(--ink); font-size: .9rem; text-align: center; margin-top: 14px; }
.lightbox-btn {
  display: grid; place-items: center; width: 44px; height: 44px; flex: none;
  background: rgba(255,255,255,.12); color: #fff;
  border: 1px solid rgba(255,255,255,.25); border-radius: 50%;
}
.lightbox-btn:hover { background: rgba(255,255,255,.25); }
.lightbox-close { position: absolute; top: 20px; right: 20px; }

/* ---------- 19. Field notes and news ---------- */
.story-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 18px; }
.story-card {
  display: flex; flex-direction: column; gap: 12px;
  padding: 32px 30px;
  background: var(--white); border: 1px solid var(--line);
  border-left: 3px solid var(--clay); border-radius: var(--radius);
  transition: transform .25s var(--ease), box-shadow .25s var(--ease);
}
.story-card:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
.story-card h3 { margin: 0; }
.story-card p { color: var(--muted); font-size: .96rem; margin: 0; }

.story-dialog {
  width: min(720px, calc(100vw - 40px)); padding: 0;
  background: var(--paper); color: var(--ink);
  border: 1px solid var(--line-strong); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
}
.story-dialog::backdrop { background: rgba(9,20,15,.72); }
.story-dialog > * { padding-inline: clamp(24px, 4vw, 44px); }
.story-dialog > *:first-child { padding-top: 36px; }
.story-dialog > *:last-child { padding-bottom: 36px; }

.news-filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 28px; }
.news-filters .chip { color: var(--muted); border-color: var(--line-strong); background: transparent; }
.news-filters .chip:hover { border-color: var(--ink); color: var(--ink); }
.news-filters .chip[aria-pressed="true"] { background: var(--ink); border-color: var(--ink); color: var(--paper); }

.news-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; }
.news-card {
  display: flex; flex-direction: column;
  background: var(--white); border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden;
  transition: transform .25s var(--ease), box-shadow .25s var(--ease);
}
.news-card:hover { transform: translateY(-3px); box-shadow: var(--shadow); }
.news-card img { width: 100%; height: 172px; object-fit: cover; }
.news-body { padding: 22px 22px 26px; display: flex; flex-direction: column; gap: 10px; }
.news-meta { display: flex; align-items: center; gap: 10px; color: var(--muted); }
.news-meta .cat { color: var(--clay-deep); }
.news-card h3 { font-size: 1.08rem; }
.news-card p { font-size: .9rem; color: var(--muted); margin: 0; }

/* ---------- 20. Contact, forms, vacancies ---------- */
.contact-card {
  display: grid; grid-template-columns: 1fr 1fr;
  background: var(--white); border: 1px solid var(--line);
  border-radius: var(--radius-lg); overflow: hidden;
}
.contact-info { padding: clamp(32px, 4vw, 54px); background: var(--forest); color: var(--ink); }
.contact-info h2 { color: #fff; margin-bottom: 16px; }
.contact-info > p:not(.chapter-label):not(.eyebrow) { color: rgba(255,255,255,.78); margin-bottom: 28px; }
.c-row { display: grid; grid-template-columns: auto 1fr; gap: 14px; padding: 16px 0; border-top: 1px solid var(--line-dark); }
.c-row .icon { color: var(--sand); margin-top: 3px; }
.c-row strong { display: block; font-family: var(--f-mono); font-size: .66rem; letter-spacing: .1em; text-transform: uppercase; color: rgba(255,255,255,.6); margin-bottom: 5px; font-weight: 500; }
.c-row span { font-size: .95rem; }
.c-row a { color: #fff; }
.contact-map { margin-top: 24px; opacity: .75; }
.contact-map svg { width: 100%; height: auto; }
.contact-socials { display: flex; gap: 8px; margin-top: 24px; }
.contact-socials a {
  display: grid; place-items: center; width: 38px; height: 38px;
  border: 1px solid var(--line-dark); border-radius: 50%; color: rgba(255,255,255,.5);
}
.contact-socials a[aria-disabled="true"] { opacity: .4; cursor: default; }

.contact-form, .grv-form { padding: clamp(32px, 4vw, 54px); display: flex; flex-direction: column; gap: 18px; }
/* The submit sizes to its label rather than stretching the full column width,
   which is what a flex column would otherwise do to it. */
.contact-form .btn, .grv-form .btn { align-self: flex-start; margin-top: 6px; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
.field { display: flex; flex-direction: column; gap: 7px; }
.field label { font-family: var(--f-mono); font-size: .68rem; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); }
.field .optional { text-transform: none; letter-spacing: 0; opacity: .7; }
/* Fields were set on --paper, the page ground, which is DARKER than the card
   they sit in — so each one was a hole in the panel rather than a surface to
   type on, and at a .19 border on a dark card the edge was barely there. They
   now sit fractionally above the card and carry their own edge. */
.field input, .field textarea {
  padding: 13px 15px;
  background: rgba(255,255,255,.045);
  border: 1px solid rgba(255,255,255,.17);
  border-radius: var(--radius); font-size: .95rem;
  transition: border-color .2s var(--ease), background .2s var(--ease),
              box-shadow .2s var(--ease);
}
.field input::placeholder, .field textarea::placeholder { color: var(--muted); opacity: 1; }
.field input:hover, .field textarea:hover { border-color: rgba(255,255,255,.30); }
/* A ring, not just a border swap: on a dark panel a 1px colour change is not
   enough to find the focused field at a glance. */
.field input:focus, .field textarea:focus {
  outline: none;
  background: rgba(255,255,255,.07);
  border-color: var(--clay);
  box-shadow: 0 0 0 3px var(--clay-wash);
}
.field textarea { min-height: 132px; resize: vertical; }

/* Validation is amber, not green and not red. Green is the outcome this
   organisation delivers and reads as success on a field that just failed;
   red is reserved for explosive hazard and nothing else, which is a promise
   worth keeping on a mine action site. Amber is the remaining honest signal. */
.field .error { display: none; font-size: .82rem; color: var(--sand); }
.field.invalid .error { display: block; }
.field.invalid input, .field.invalid textarea { border-color: var(--sand); }
.field.invalid input:focus, .field.invalid textarea:focus { box-shadow: 0 0 0 3px var(--sand-wash); }

/* --forest is #101615, a near-black held over from the light theme: this was
   near-black text on a dark green wash. */
.form-status {
  display: none; font-size: .88rem; color: var(--clay-deep);
  padding: 12px 16px; background: var(--sage-wash);
  border: 1px solid color-mix(in srgb, var(--clay) 30%, transparent);
  border-radius: var(--radius);
}
.form-status.show { display: block; }

.vacancies-panel {
  margin-top: 20px; padding: clamp(28px, 3.5vw, 44px);
  background: var(--white); border: 1px solid var(--line); border-radius: var(--radius-lg);
}
.vacancies-heading h2 { font-size: clamp(1.5rem, 2.4vw, 2rem); margin-bottom: 20px; }
.vacancy-empty h3 { margin-bottom: 8px; }
.vacancy-empty p, .vacancy-item p { color: var(--muted); font-size: .95rem; }
.vacancy-item { display: grid; grid-template-columns: 1fr auto; gap: 20px; align-items: center; padding: 22px 0; border-top: 1px solid var(--line); }
.vacancy-meta { display: flex; flex-wrap: wrap; gap: 14px; color: var(--muted); margin: 6px 0 8px; }

/* ---------- 21. Grievance ---------- */
.grv-card {
  display: grid; grid-template-columns: .9fr 1.1fr;
  background: var(--white); border: 1px solid var(--line);
  border-radius: var(--radius-lg); overflow: hidden;
}
.grv-info { padding: clamp(32px, 4vw, 54px); background: var(--paper-2); border-right: 1px solid var(--line); }
.grv-steps { list-style: none; margin: 0 0 24px; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.grv-steps li { display: grid; grid-template-columns: auto 1fr; gap: 16px; padding: 16px 0; border-top: 1px solid var(--line); }
.grv-steps li:first-child { border-top: 0; }
.grv-num {
  display: grid; place-items: center; width: 28px; height: 28px;
  background: var(--clay); color: #fff; border-radius: 50%;
  font-family: var(--f-mono); font-size: .74rem;
}
.grv-steps strong { display: block; margin-bottom: 4px; }
.grv-steps span { font-size: .9rem; color: var(--muted); }
.grv-note { font-size: .88rem; color: var(--muted); padding-top: 18px; border-top: 1px solid var(--line); }

/* ---------- 22. Footer ---------- */
.site-footer { padding-block: clamp(56px, 7vw, 96px) 32px; color: var(--ink); }
.footer-grid { display: grid; grid-template-columns: 1.6fr 1fr 1fr 1.2fr; gap: clamp(28px, 4vw, 60px); }
.footer-brand { display: flex; align-items: center; gap: 14px; margin-bottom: 18px; }
.footer-mark { width: 106px; height: 68px; }   /* the file's own 149:96 */
.footer-brand span { font-family: var(--f-display); font-size: 1.18rem; font-weight: 600; line-height: 1.2; }
.site-footer .tagline { color: rgba(255,255,255,.66); font-size: .93rem; max-width: 42ch; }
.footer-accred { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 18px; }
.footer-accred span {
  padding: 6px 13px; border: 1px solid var(--line-dark); border-radius: 100px;
  font-family: var(--f-mono); font-size: .62rem; letter-spacing: .1em;
  text-transform: uppercase; color: rgba(255,255,255,.7);
}
.site-footer h4 {
  font-family: var(--f-mono); font-size: .68rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--sand); margin-bottom: 16px; font-weight: 500;
}
.site-footer ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
.site-footer li, .site-footer a { font-size: .92rem; color: rgba(255,255,255,.72); text-decoration: none; }
.site-footer a:hover { color: #fff; text-decoration: underline; }
.footer-bottom {
  display: flex; flex-wrap: wrap; justify-content: space-between; gap: 12px;
  margin-top: clamp(40px, 5vw, 68px); padding-top: 26px;
  border-top: 1px solid var(--line-dark);
  font-size: .8rem; color: rgba(255,255,255,.5);
}
.footer-bottom .mono { letter-spacing: .1em; }

/* ---------- 23. Chrome ---------- */
.cookie-banner {
  position: fixed; left: 20px; bottom: 20px; z-index: 120;
  width: min(380px, calc(100vw - 40px));
  padding: 22px 24px;
  background: var(--white); border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  transform: translateY(160%); transition: transform .4s var(--ease);
}
.cookie-banner.show { transform: none; }
.cookie-banner p { font-size: .88rem; color: var(--muted); margin-bottom: 16px; }
.cookie-banner .row { display: flex; gap: 10px; }
.cookie-banner .btn { padding: 10px 20px; font-size: .85rem; }

.to-top {
  position: fixed; right: 20px; bottom: 20px; z-index: 110;
  display: grid; place-items: center; width: 46px; height: 46px;
  background: var(--ink); color: var(--paper);
  border: 0; border-radius: 50%; box-shadow: var(--shadow);
  opacity: 0; pointer-events: none;
  transition: opacity .3s var(--ease), transform .3s var(--ease);
}
.to-top.show { opacity: 1; pointer-events: auto; }
.to-top:hover { transform: translateY(-3px); }

/* ---------- 24. Motion ---------- */
/* Authored visible-first: if the observer in main.js never runs, everything
   is still on screen. Only browsers that accept motion get the hidden start. */
@media (prefers-reduced-motion: no-preference) {
  .reveal { opacity: 0; transform: translateY(16px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
  .reveal.in { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important;
    transition-duration: .001ms !important; scroll-behavior: auto !important;
  }
  .reveal { opacity: 1; transform: none; }
}

/* ---------- 25. Responsive ---------- */
/* The utility cluster is the first thing to run out of room; shed it in stages
   so the primary links survive as long as possible before the hamburger. */
@media (max-width: 1320px) { .site-search { display: none; } }
/* Uppercase mono links are wider than the sentence-case type they replaced, so
   the header CTA has to stand down earlier or the six links start squeezing
   their gaps shut around 1200. */
@media (max-width: 1240px) { .nav-cta { display: none; } }

@media (max-width: 1180px) {
  .svc-grid, .impact-grid { grid-template-columns: repeat(2, 1fr); }
  .svc-wide, .impact-feature { grid-column: span 2; }
  .impact-feature { grid-row: auto; }
  .news-grid { grid-template-columns: repeat(2, 1fr); }
  /* Three plates across a tablet leaves each one too small to read a face in. */
  .field-grid { grid-template-columns: repeat(2, 1fr); }
  .partner-grid { grid-template-columns: repeat(3, 1fr); }
  .dash-grid-3 { grid-template-columns: 1fr; }
  .eore-track { grid-template-columns: repeat(2, 1fr); }
  .assurance-tabs { grid-template-columns: repeat(3, 1fr); }
  .assurance-tabs button:nth-child(3n) { border-right: 0; }
}

@media (max-width: 1024px) {
  /* Below this there is no right-hand band to dock into: the panel becomes a
     bar across the foot of the plot, and the hero opens up underneath the
     figures to give it a place to stand rather than a thing to cover. */
  /* Measured, not guessed: the bar runs to 191px once the hint wraps to two
     lines at 375px, and it is offset 18px from the foot. */
  .hero { padding-bottom: clamp(238px, 30vw, 280px); }
  .field-hud {
    top: auto; transform: none;
    bottom: clamp(18px, 3vw, 32px);
    left: var(--gutter); right: var(--gutter); width: auto;
  }

  .nav-links {
    position: fixed; inset: 0 0 0 auto; z-index: 100;
    width: min(340px, 84vw);
    flex-direction: column; align-items: stretch; justify-content: flex-start; gap: 0;
    padding: 84px 28px 28px;
    background: var(--forest-deep);
    /* Parked off-screen. It is position:fixed, so body's overflow-x:hidden
       cannot clip it and the translated box would otherwise widen the
       document to ~535px on a 375px screen. visibility keeps it out of the
       overflow calculation and out of the tab order while closed. */
    visibility: hidden;
    transform: translateX(100%);
    /* visibility must flip instantly on open and only after the slide on
       close, so it is stepped with a delay rather than transitioned. */
    transition: transform .34s var(--ease), visibility 0s linear .34s;
    overflow-y: auto;
  }
  .nav-links.open, .nav.open .nav-links {
    visibility: visible; transform: none;
    transition: transform .34s var(--ease), visibility 0s linear 0s;
  }
  .nav-links a { padding: 16px 0; border-bottom: 1px solid var(--line-dark); font-size: 1rem; }
  .nav-links a::after { display: none; }
  .nav-close {
    display: block; position: absolute; top: 22px; right: 24px;
    padding: 8px 14px; background: none; color: #fff;
    border: 1px solid var(--line-dark); border-radius: var(--radius); font-size: .8rem;
  }
  .nav-toggle {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 9px 14px; background: rgba(255,255,255,.1); color: #fff;
    border: 1px solid rgba(255,255,255,.24); border-radius: var(--radius);
    font-size: .78rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  }
  .site-search, .nav-cta { display: none; }

  .problem-chapter .problem-layout,
  .geo-body, .about-layout, .contact-card, .grv-card,
  .assurance-body, .landrelease .lr-layout { grid-template-columns: 1fr; }
  .assurance-reports, .grv-info { border-left: 0; border-right: 0; border-top: 1px solid var(--line); }
  .footer-grid { grid-template-columns: repeat(2, 1fr); }
  .credbar-inner { grid-template-columns: repeat(2, 1fr); }
  /* Two columns, so the flush cells are every other one, not every fourth. */
  .credbar p:nth-child(4n+1), .credbar p:nth-child(4n) { padding-inline: 24px; }
  .credbar p:nth-child(2n+1) { padding-left: 0; }
  .credbar p:nth-child(2n)   { padding-right: 0; }
  .hero-proof { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 26px 32px; }
}

@media (max-width: 760px) {
  body { font-size: 16px; }
  .strip-grid { grid-template-columns: repeat(2, 1fr); }
  /* Portrait needs its own scrim. The desktop ramp runs across the frame at
     102deg, which on a tall narrow viewport is very nearly top-to-bottom — so
     it landed its dense end on the sky and left nothing of the picture above
     the copy. Here the bands are placed deliberately instead: sky at the top,
     a dark band only where the copy actually sits, the plot open below it,
     then down to the page. */
  .hero::after {
    background: linear-gradient(to bottom,
      rgba(8,12,11,.22) 0%,
      rgba(8,12,11,.72) 20%,
      rgba(8,12,11,.78) 55%,
      rgba(8,12,11,.34) 74%,
      rgba(10,14,13,.88) 95%,
      var(--paper) 100%);
  }
  .hero-proof { grid-template-columns: 1fr; gap: 0; }
  .hero-proof div {
    display: flex; align-items: baseline; justify-content: space-between;
    gap: 16px; border-bottom: 1px solid rgba(255,255,255,.14); padding-block: 14px;
  }
  .hero-proof dt { margin-bottom: 0; }
  .svc-grid, .impact-grid, .news-grid, .story-grid,
  .purpose-grid, .gallery-grid, .field-grid,
  .eore-track { grid-template-columns: 1fr; }
  .svc-wide, .impact-feature { grid-column: auto; }
  .partner-grid { grid-template-columns: repeat(2, 1fr); }
  .form-row { grid-template-columns: 1fr; }
  .assurance-tabs { grid-template-columns: 1fr; }
  .assurance-tabs button + button { border-left: 0; border-top: 1px solid var(--line); }
  .footer-grid, .credbar-inner { grid-template-columns: 1fr; }
  /* One column: every cell is both the first and the last in its row. Written
     with the same nth-child specificity as the two- and four-column rules
     above — a plain `.credbar p` here loses to `.credbar p:nth-child(4n)` on
     specificity no matter how late it appears, which left the fourth cell
     indented on phones. */
  .credbar p:nth-child(2n+1), .credbar p:nth-child(2n) { padding-inline: 0; }
  .geo-head { grid-template-columns: 1fr; }
  .cookie-banner { left: 12px; right: 12px; bottom: 12px; width: auto; }
  .hero { min-height: 88vh; }
}

/* Narrow phones: the header must fit brand + language + menu inside 360px.
   The descriptor line and generous chip padding are what push the menu button
   off the edge, where html's overflow clip hides it entirely. */
@media (max-width: 600px) {
  .nav { gap: 10px; }
  .brand-sub { display: none; }
  .brand-mark { width: 78px; height: 50px; }
  /* Must be on a selector: a bare custom property inside a media block is not
     a valid declaration and is dropped. */
  :root { --header-h: 82px; }   /* the smaller mark, plus the same 16px each side */
  .brand-name { font-size: 1.24rem; }
  .nav-utility { gap: 8px; }
  .language-switcher { padding: 2px; }
  .language-switcher button { padding: 6px 7px; font-size: .62rem; }
  .nav-toggle { padding: 8px 10px; }
  .nav-toggle span { display: none; }

  /* The authored line break helps at desktop width but strands "it." on its
     own line at phone width. Let the headline find its own breaks here. */
  .hero h1 { font-size: 2.3rem; max-width: none; }
  .hero h1 br { display: none; }
}

/* ---------- 26. SVG fills orphaned by the stylesheet consolidation ----------
   These shapes carry no fill attribute; their colours lived in the six files
   this system replaced. With no rule they computed to solid black, which is
   why the Afghanistan silhouette and the province markers rendered as
   silhouetted blobs. */

/* Scene-band map */
.map-piece  { fill: var(--paper-2); }
.map-photo  { fill: var(--white); }
.map-tint   { fill: var(--clay-wash); }
.map-stroke { fill: none; stroke: var(--clay); stroke-width: 2.2; stroke-linejoin: round; }

/* Province markers on the coverage map. They are inert now — the cell under
   them is the control — so they carry no cursor and no hover of their own,
   only the state the cell hands them. */
.prov-halo { fill: var(--clay-wash); }
.prov-dot {
  fill: var(--clay);
  transition: fill .2s var(--ease), opacity .2s var(--ease);
}
.prov-dot.prov-zero { fill: rgba(255,255,255,.34); }
.prov-dot.prov-hq { fill: var(--sand); }
.prov-dot.hover, .prov-dot.active { fill: #fff; }

/* The coverage detail list sets label and value in adjacent spans with no
   whitespace between them, so they ran together as "five districtsVTF · 2012". */
.geo-detail li { margin-bottom: 10px; }
.geo-detail li > span + span::before { content: " — "; color: var(--muted); }
