/* ─────────────────────────────────────────────────────────────
   Tokens
   ───────────────────────────────────────────────────────────── */
:root{
  /* Clean white system. The dark globe/orbit compositing that once required a pure
     black ground is gone, so the base is now plain white and colour is carried by a
     single navy-blue accent drawn from the badge logo. Old token NAMES are kept and
     only their VALUES flipped, so the ~970 rules below need no sweeping rename; the
     handful of spots where a name's meaning inverts (text over the dark accordion
     photos, the nav fade, the CTA) are fixed at their own rules. */
  --void:#fff;                /* page ground; also the knockout ink on the accent (skip/selection) */
  --surface:#f5f7fa;          /* elevated: nav dropdown, origin band */
  --float:#eaeef4;           /* floating: dropdown/tile hover */

  --thermal:#1c3f77;          /* primary accent — deep navy-blue from the badge */
  --thermal-dim:#16325f;
  --sensor:#2f6bd0;           /* secondary accent — brighter blue */
  --moon:#1c3f77;             /* CTA now shares the primary accent */

  --paper:#0f1a2b;            /* primary ink on white */
  --muted:#54617a;            /* secondary ink (slate) */
  --hairline:rgba(15,26,43,.14);

  /* Over-image: the initiatives accordion keeps its dark duotone photos, so text and
     accent marks sitting ON those panels stay light regardless of the white page. */
  --on-image:#eef2f8;
  --on-image-muted:rgba(238,242,248,.72);
  --on-image-accent:#8fbcf2;
  --on-image-hair:rgba(238,242,248,.28);

  /* spacing scale */
  --s1:.5rem; --s2:1rem; --s3:1.5rem; --s4:2rem;
  --s5:3rem; --s6:5.5rem; --s7:8.5rem; --s8:11rem;

  --gutter:clamp(1.5rem, 5vw, 6rem);
  /* Outer content width ~1248px. Prose columns are capped far narrower (~64ch) per rule. */
  --measure:78rem;
  /* Height of the fixed nav band; hero and anchor targets clear it. */
  --nav-h:5.5rem;

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

  --font-display:'Archivo', system-ui, sans-serif;
  --font-body:'Inter', system-ui, sans-serif;
  --font-mono:'IBM Plex Mono', ui-monospace, monospace;
}

/* Compress the large spacing steps on narrow screens; the small ones hold. */
@media (max-width:48rem){
  :root{ --s6:3.5rem; --s7:5rem; --s8:6.5rem }
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;
  /* Positioned so the absolutely-placed .nav resolves against body and is
     caught by overflow-x below. Against the viewport it would escape the
     clip and widen the whole document. */
  position:relative;
  background:var(--void);
  color:var(--paper);
  font-family:var(--font-body);
  font-size:clamp(1rem,.95rem + .2vw,1.0625rem);
  line-height:1.7;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
  overflow-wrap:break-word;
  /* Keeps single words off a line of their own in body copy. Headings opt out
     via text-wrap:balance below, which is what they want instead. */
  text-wrap:pretty;
}
img{max-width:100%;display:block}
a{color:inherit}

/* The UA rule for [hidden] is display:none, but ANY author display declaration beats
   it, which once silently un-hid a tab panel and rendered two panels at once. Kept as
   a guard: hidden must always mean hidden, whatever a later rule sets display to. */
[hidden]{display:none !important}

::selection{background:var(--thermal);color:var(--void)}

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

.skip{
  position:absolute; left:var(--s2); top:-4rem; z-index:100;
  background:var(--thermal); color:var(--void);
  padding:.65rem 1rem; border-radius:3px; font-weight:600;
  text-decoration:none;
  transition:transform .3s var(--ease-spring);
}
.skip:focus{transform:translateY(5rem)}

/* ─────────────────────────────────────────────────────────────
   Shared type
   ───────────────────────────────────────────────────────────── */
.eyebrow{
  font-family:var(--font-mono);
  font-size:.6875rem;
  letter-spacing:.18em;
  text-transform:uppercase;
  color:var(--thermal);
  margin:0;
}
.eyebrow--sensor{color:var(--sensor)}

h1,h2,h3{
  font-family:var(--font-display);
  font-weight:800;
  font-stretch:112%;
  letter-spacing:-.03em;
  line-height:1.02;
  margin:0;
  text-wrap:balance;
}

.shell{
  max-width:var(--measure);
  margin-inline:auto;
  padding-inline:var(--gutter);
}

/* ─────────────────────────────────────────────────────────────
   Nav
   ───────────────────────────────────────────────────────────── */
/* Fixed to the viewport so navigation is reachable anywhere. Default is the SOLID state:
   a near-opaque white bar with navy links — the safe fallback, the subpage look, and the
   scrolled look. On the home page a small script (site.js) adds `.is-over-hero` while the
   full-bleed hero fills the top, which turns the bar transparent with white links; it
   flips back to solid once the hero scrolls past. No JS ⇒ the solid bar simply stays. */
.nav{
  position:fixed; top:0; left:0; right:0; z-index:50;
  display:flex; flex-direction:row; align-items:center; justify-content:space-between;
  gap:var(--s3);
  padding:clamp(.85rem,2vw,1.25rem) var(--gutter);
  background:rgba(255,255,255,.9);
  -webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
  border-bottom:1px solid var(--hairline);
  transition:background-color .3s var(--ease-spring),
             border-color .3s var(--ease-spring),
             backdrop-filter .3s var(--ease-spring);
}
/* Transparent state, over the dark hero: no bar, light text, badge kept (it reads on the
   starfield). Added/removed by the scroll-aware IIFE in site.js. */
.nav.is-over-hero{
  background:transparent;
  -webkit-backdrop-filter:none; backdrop-filter:none;
  border-bottom-color:transparent;
}
.nav.is-over-hero .wordmark-text{color:#fff}
.nav.is-over-hero .nav-links a{color:rgba(255,255,255,.82)}
.nav.is-over-hero .nav-links a:hover,
.nav.is-over-hero .nav-links a[aria-current="page"]{color:#fff}
@media (max-width:34rem){
  /* Wordmark plus three links will not fit one row at phone widths. */
  .nav{flex-direction:column; align-items:flex-start; gap:.6rem}
  :root{--nav-h:7rem}   /* the stacked bar is taller */
  /* Four items plus a caret overflow one row at 390px. The wordmark above is already
     a home link on every page, so Home is the one to drop rather than let the bar
     wrap and take --nav-h out of step. */
  .nav-home{display:none}
}

/* Anchor targets must clear the fixed bar. */
#initiatives, #origin, #contact,
.mem-section{scroll-margin-top:calc(var(--nav-h) + 1rem)}
/* The mark is now the badge emblem (portrait shield) beside a text wordmark. The old
   horizontal white-on-black logo could not read on a white nav, and its hand-measured
   label offset belonged to that artwork — both are gone. --logo-h lives here so the
   wordmark text can read it if ever needed; properties inherit down, not sideways. */
.wordmark{
  --logo-h:clamp(1.9rem,1.6rem + .8vw,2.35rem);
  display:flex; align-items:center; gap:.6rem;
  text-decoration:none; min-width:0;
}
.wordmark picture{display:flex}
.wordmark img{
  /* width:auto is REQUIRED, not tidiness: the width/height attributes are
     presentational hints, so setting only the height leaves the width pinned at 600
     and the badge comes out stretched. This exact trap already cost the portraits once. */
  height:var(--logo-h); width:auto; display:block;
}
.wordmark-text{
  font-family:var(--font-display); font-weight:800; font-stretch:112%;
  font-size:clamp(1rem,.9rem + .45vw,1.2rem); letter-spacing:-.01em; line-height:1;
  color:var(--paper); white-space:nowrap;
}
/* align-items:center, not the default stretch: the About trigger is a <button> among
   inline <a>s and sits a few px low without it. */
.nav-links{display:flex; align-items:center; gap:clamp(1.25rem,2.5vw,2.25rem)}
.nav-links a{
  font-family:var(--font-mono);
  font-size:.6875rem; letter-spacing:.16em; text-transform:uppercase;
  color:var(--muted); text-decoration:none;
  transition:color .25s var(--ease-spring);
}
.nav-links a:hover{color:var(--paper)}
.nav-links a:active{color:var(--thermal)}
.nav-links a[aria-current="page"]{color:var(--paper)}

/* About disclosure. The panel is absolutely positioned so opening it can never change
   the nav's height — --nav-h drives the globe's top offset and every anchor's
   scroll-margin-top, so a bar that grew would desync all of them at once. */
.nav-menu{position:relative; display:flex; align-items:center}
.nav-trigger{
  display:inline-flex; align-items:center; gap:.4rem;
  background:none; border:0; padding:0; cursor:pointer;
  font-family:var(--font-mono);
  font-size:.6875rem; letter-spacing:.16em; text-transform:uppercase;
  color:var(--muted);
  transition:color .25s var(--ease-spring);
}
.nav-trigger:hover,
.nav-trigger[aria-expanded="true"]{color:var(--paper)}
.nav-caret{transition:rotate .25s var(--ease-spring)}
.nav-trigger[aria-expanded="true"] .nav-caret{rotate:180deg}

.nav-drop{
  /* Anchored by its RIGHT edge, not its left. "Alliance members" makes the panel ~166px
     wide, and About is the second-to-last item in the bar — left-anchored it ran past the
     page gutter at 1440 and was clipped by body's overflow-x:hidden between ~34 and 48rem.
     Growing leftward it always has the whole bar behind it. */
  position:absolute; top:100%; right:0; z-index:60;
  /* No gap between trigger and panel: any margin here lets mouseleave fire while the
     pointer travels down to the first item, closing the menu as you reach for it. The
     visual offset comes from padding-top INSIDE the panel instead. */
  margin:0; padding:.75rem 0 .4rem;
  min-width:9.5rem;
  list-style:none;
  background:var(--surface);
  border:1px solid var(--hairline); border-radius:4px;
  box-shadow:0 12px 28px -8px rgba(15,26,43,.18);
}
/* nowrap is load-bearing. The panel is absolutely positioned inside the narrow
   .nav-menu, so shrink-to-fit caps its width at the longest WORD — "ALLIANCE MEMBERS"
   at .6875rem mono with .16em tracking runs ~163px against the 152px min-width and
   breaks onto two lines without this. */
.nav-drop a{
  display:block; padding:.5rem .9rem; white-space:nowrap;
  font-family:var(--font-mono);
  font-size:.6875rem; letter-spacing:.16em; text-transform:uppercase;
  color:var(--muted); text-decoration:none;
  transition:background-color .2s var(--ease-spring), color .2s var(--ease-spring);
}
.nav-drop a:hover{background:var(--float); color:var(--paper)}

/* ─────────────────────────────────────────────────────────────
   Hero — clean typographic hero on white. The night-Earth globe and the
   scroll-driven orbit sequence are gone; the badge emblem anchors the fold.
   ───────────────────────────────────────────────────────────── */
/* Full-bleed, near-full-height hero: the dark starfield fills the first screen edge to
   edge (no card), with the fixed nav overlaid transparent on top. The image + overlay
   live here now; the overlay is centre-weighted since the copy is centred, and dark
   enough to hold AA over the near-black photo. */
/* Full-viewport starfield hero. The only thing on it is the brand as a monumental
   headline, anchored to the LOWER-middle (justify-content:flex-end + bottom padding),
   Coutumes-style. The mission statement + CTA live in the white .intro block below. */
.hero{
  position:relative;
  min-height:100svh;
  display:flex; flex-direction:column; align-items:center; justify-content:flex-end;
  text-align:center; color:#fff;
  padding-block:calc(var(--nav-h) + var(--s4)) clamp(3.5rem,11vh,8rem);
  padding-inline:var(--gutter);
  background-color:#05080f;
  /* Plain fallback first; the @supports block upgrades to WebP where available. A gentle
     bottom-weighted darken floors the contrast under the lower-anchored headline. */
  background-image:
    linear-gradient(180deg, rgba(5,8,15,.3) 0%, rgba(5,8,15,.28) 42%, rgba(5,8,15,.66) 100%),
    url("assets/space.jpg");
  background-size:cover; background-position:center;
}
@supports (background-image:image-set(url("x.webp") type("image/webp"))){
  .hero{
    background-image:
      linear-gradient(180deg, rgba(5,8,15,.3) 0%, rgba(5,8,15,.28) 42%, rgba(5,8,15,.66) 100%),
      image-set(url("assets/space.webp") type("image/webp"), url("assets/space.jpg") type("image/jpeg"));
  }
}
.hero-inner{ position:relative; width:100%; max-width:60rem; }
.hero-title{
  font-weight:800; font-stretch:112%;
  letter-spacing:-.03em; line-height:.92;
  font-size:clamp(3.25rem,1.6rem + 8vw,8rem);
  max-width:14ch; margin:0 auto;
}

/* Statement band under the hero: a compact dark starfield (assets/space2) carrying the
   tagline + mission in white — the reference's "text under the hero" pattern, tied into
   our dark-image system instead of a white gap. Overlay floors the contrast. */
.statement{
  position:relative;
  padding-block:var(--s7);
  color:#fff;
  background-color:#05080f;
  background-image:
    linear-gradient(180deg, rgba(5,8,15,.74) 0%, rgba(5,8,15,.6) 50%, rgba(5,8,15,.82) 100%),
    url("assets/space2.jpg");
  background-size:cover; background-position:center;
}
@supports (background-image:image-set(url("x.webp") type("image/webp"))){
  .statement{
    background-image:
      linear-gradient(180deg, rgba(5,8,15,.74) 0%, rgba(5,8,15,.6) 50%, rgba(5,8,15,.82) 100%),
      image-set(url("assets/space2.webp") type("image/webp"), url("assets/space2.jpg") type("image/jpeg"));
  }
}
/* Compact WHITE band between the dark hero and the dark mission section — a small white
   space holding the centred tagline, the reference's between-sections text pattern. */
.intro{ padding-block:var(--s6); text-align:center; }
.intro h2{
  font-size:clamp(2.4rem,1.6rem + 3.4vw,4.5rem);
  letter-spacing:-.03em; max-width:16ch; margin:0 auto;
}
.intro-lead{
  max-width:58ch; margin:var(--s4) auto 0;
  color:var(--muted);
  font-size:clamp(1.0625rem,1rem + .5vw,1.375rem);
}
.intro .cta{ margin-top:var(--s5); }
/* Light eyebrow + white button so both pop on the dark band. */
.statement .eyebrow{ color:var(--on-image-accent); }
.statement .cta{
  background:#fff; border-color:#fff; color:var(--thermal);
}
.statement .cta:hover{ background:#e7ecf3; border-color:#e7ecf3; color:var(--thermal-dim); }

/* Base button is solid navy (used on light grounds if reused). */
.cta{
  display:inline-flex; align-items:center; gap:.7rem;
  margin-top:var(--s4);
  padding:.9rem 1.6rem;
  border:1px solid var(--thermal); border-radius:3px;
  background:var(--thermal);
  color:#fff; text-decoration:none;
  font-family:var(--font-mono);
  font-size:.75rem; letter-spacing:.14em; text-transform:uppercase;
  transition:background-color .3s var(--ease-spring),
             border-color .3s var(--ease-spring),
             transform .3s var(--ease-spring);
}
.cta:hover{
  background:var(--thermal-dim); border-color:var(--thermal-dim);
  transform:translateY(-2px);
}
.cta:active{transform:translateY(0)}
.cta svg{transition:transform .3s var(--ease-spring)}
.cta:hover svg{transform:translateX(4px)}

/* ─────────────────────────────────────────────────────────────
   Mission
   ───────────────────────────────────────────────────────────── */
/* The only content in the dark starfield section. Left-aligned readable block; light
   text on the starfield (the .statement padding handles the vertical breathing room). */
.mission{ margin-top:0; }
.mission .lead{
  font-family:var(--font-display);
  font-weight:400; font-stretch:105%;
  font-size:clamp(1.5rem,1.1rem + 1.7vw,2.4rem);
  line-height:1.28; letter-spacing:-.02em;
  max-width:26ch; margin:var(--s3) 0 0;
  text-wrap:balance; color:#fff;
}
.mission .sub{
  max-width:64ch; margin:var(--s4) 0 0;
  color:rgba(255,255,255,.74);
}
.chain{
  display:flex; flex-wrap:wrap; align-items:center; gap:.9rem;
  margin:var(--s5) 0 0;
  font-family:var(--font-mono); font-size:.6875rem;
  letter-spacing:.16em; text-transform:uppercase; color:rgba(255,255,255,.72);
}
.chain i{color:var(--on-image-accent); font-style:normal}

/* ─────────────────────────────────────────────────────────────
   Peace–conflict continuum — a short four-stage band (brief v2 §05)
   ───────────────────────────────────────────────────────────── */
/* On white like the rest — no grey panel. A four-stage sequence read as rule-topped
   columns (1px hairline + mono numeral), not a card. */
.continuum{padding-block:var(--s7)}
.continuum h2{font-size:clamp(1.8rem,1.3rem + 2.2vw,2.9rem); max-width:22ch}
.continuum .lead{max-width:64ch; margin:var(--s3) 0 0; color:var(--muted)}
.continuum-grid{
  margin-top:var(--s6); display:grid; gap:var(--s4) var(--s5);
  grid-template-columns:repeat(4,1fr);
}
.stage{border-top:1px solid var(--hairline); padding-top:var(--s3)}
.stage-label{
  font-family:var(--font-mono); font-size:.625rem; letter-spacing:.16em;
  text-transform:uppercase; color:var(--thermal); margin:0;
}
.stage h3{font-size:clamp(1.0625rem,1rem + .4vw,1.3rem); margin:.55rem 0 0}
.stage p{margin:.6rem 0 0; color:var(--muted);
  font-size:clamp(.9rem,.86rem + .2vw,1rem)}
@media (max-width:56rem){ .continuum-grid{grid-template-columns:repeat(2,1fr); gap:var(--s4) var(--s3)} }
@media (max-width:30rem){ .continuum-grid{grid-template-columns:1fr} }

/* ─────────────────────────────────────────────────────────────
   Access — three pathways in rising order of ambition (brief v2 §06)
   ───────────────────────────────────────────────────────────── */
.pathways{padding-block:var(--s7)}
.pathways h2{font-size:clamp(2rem,1.4rem + 2.6vw,3.25rem); max-width:22ch}
.pathways .lead{max-width:64ch; margin:var(--s3) 0 0; color:var(--muted)}
/* Not a grid of columns — a stacked, full-width numbered list: big numeral, big heading,
   description at reading measure, rows separated by 1px hairline rules with generous
   space. Rules + numbers + large type doing the work. */
.pathway-grid{margin-top:var(--s6)}
.pathway{
  display:grid; grid-template-columns:minmax(0,7rem) 1fr;
  column-gap:var(--s5); row-gap:var(--s3); align-items:baseline;
  padding-block:var(--s5); border-top:1px solid var(--hairline);
}
.pathway:last-child{border-bottom:1px solid var(--hairline)}
/* Numeral in the left column; heading and description both in the right column so the
   copy never falls into the narrow numeral track. */
.pathway-num{
  grid-column:1; grid-row:1;
  font-family:var(--font-mono); font-weight:500; letter-spacing:0;
  font-size:clamp(1.5rem,1.1rem + 1.2vw,2.25rem); line-height:1;
  color:var(--thermal); margin:0;
}
.pathway h3{grid-column:2; font-size:clamp(1.5rem,1.15rem + 1.5vw,2.35rem); letter-spacing:-.02em; margin:0}
.pathway p{grid-column:2; margin:0; color:var(--muted); max-width:64ch;
  font-size:clamp(1rem,.95rem + .25vw,1.1875rem)}
@media (max-width:56rem){
  .pathway{grid-template-columns:1fr; row-gap:var(--s2); padding-block:var(--s4)}
  .pathway-num{grid-column:1} .pathway h3,.pathway p{grid-column:1}
}

/* ─────────────────────────────────────────────────────────────
   Initiatives
   ───────────────────────────────────────────────────────────── */
/* Back on the 64rem page spine. The section was widened to 84rem only to fit an image
   column beside the copy; with the panels text-only, 13rem rail + gap + panel fits the
   shell and the heading lines up with origin and contact again. */
/* Wider than the 64rem page spine: the accordion is image-led, and at 64rem the four
   collapsed panels fall to ~88px each — too narrow for a rotated title. The heading
   moves left with it, matching how .plate breaks out in the origin section.
   NOTE: this element also carries .shell, whose max-width is var(--measure). Equal
   specificity, so this only wins by coming later in the stylesheet. Do not reorder. */
.initiatives{padding-block:var(--s6) var(--s7); max-width:80rem}
.initiatives-head{
  display:flex; flex-wrap:wrap; align-items:baseline; justify-content:space-between;
  gap:var(--s2); padding-bottom:var(--s4);
}
.initiatives h2{font-size:clamp(2rem,1.4rem + 2.6vw,3.25rem)}
.initiatives-lead{max-width:66ch; margin:0 0 var(--s2); color:var(--muted)}

/* ─────────────────────────────────────────────────────────────
   Initiatives — horizontal image accordion
   ───────────────────────────────────────────────────────────── */
/* One panel open at a time, click-driven. ONLY flex-grow and opacity are animated:
   grow 6 against 1 on the other four is 6/(6+4) = exactly the 60% the open panel
   wants, and it avoids animating width or height, which would relayout every frame
   and cannot be composited. */
.acc-wrap{position:relative; margin-top:var(--s4)}
.acc{
  display:flex;
  /* Fixed, with NO svh cap. A viewport cap was worse than useless here: on a short
     desktop window it clipped the longest panel by 27px. A content section is allowed
     to be taller than a small window and make the page scroll; it is not allowed to cut
     sentences in half.
     39rem, raised from 36rem when the panels gained a lead sentence and three named
     commitments. Height is the LAST lever, not the first — measured, this copy needed
     46.4rem on height alone, 41.2rem once the open panel widened to 69%, and 37.5rem
     with the tighter leading below. 39rem leaves 24px of headroom over the measured
     600px worst case (Policy at 960 wide); 38rem left only 8px, which is too thin given
     Inter arrives with display=swap and can shift metrics after first paint. */
  height:39rem;
  border-radius:6px;
  overflow:hidden;                 /* radius on the container only, never per panel */
}
/* Single grain pass over the whole accordion, inline feTurbulence — no image request. */
.acc-wrap::after{
  content:''; position:absolute; inset:0; pointer-events:none;
  border-radius:6px;
  opacity:.12; mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

.acc-panel{
  position:relative;
  flex:1 1 0; min-width:0;         /* min-width:0 or flex items refuse to shrink below content */
  overflow:hidden;
  transition:flex-grow .5s cubic-bezier(.25,1,.5,1);
}
/* 9 against 1 on the other four is 9/13 = 69%, raised from 6 (60%) when the copy grew.
   This is the highest-value lever for fitting text: a wider open panel means a wider
   measure, which removes lines everywhere, and the only cost is the four collapsed
   panels sharing 31% instead of 40% — ample for a rotated vertical title, which needs
   height rather than width. */
.acc-panel[data-open]{flex-grow:9}

/* Duotone: greyscale plate, hue laid over it with mix-blend-mode:color, then a scrim
   so the copy has something to sit on. Images are full opacity, not faded back. */
.acc-panel picture,
.acc-panel img{position:absolute; inset:0; width:100%; height:100%}
.acc-panel img{object-fit:cover; filter:grayscale(1) contrast(1.15)}
.acc-tint{position:absolute; inset:0; background:var(--hue); mix-blend-mode:color}
/* General grounding only. The heavy lifting for text contrast is on .acc-body, which
   is sized to the copy — see there. Keeping this light means more of the image
   survives on the panels whose copy is short. */
.acc-scrim{
  position:absolute; inset:0;
  background:linear-gradient(to bottom,
    transparent 30%, rgba(0,0,0,.42) 70%, rgba(0,0,0,.58) 100%);
}

/* The whole collapsed panel is the hit target. */
.acc-hit{
  position:absolute; inset:0; z-index:2;
  display:grid; place-items:center;
  background:none; border:0; padding:0;
  font:inherit; color:inherit; cursor:pointer;
}
.acc-hit:focus-visible{outline:2px solid var(--on-image-accent); outline-offset:-4px}
.acc-vtitle{
  rotate:-90deg; white-space:nowrap;
  font-family:var(--font-display); font-weight:800; font-stretch:112%;
  font-size:1.0625rem; letter-spacing:.06em; text-transform:uppercase;
  color:var(--on-image);
  transition:opacity .5s cubic-bezier(.25,1,.5,1);
}
.acc-panel[data-open] .acc-vtitle{opacity:0}

/* Detail markers. --cross staggers the crosshair per panel so the five do not line up. */
.acc-cross,
.acc-num{
  position:absolute; top:var(--cross); z-index:3;
  pointer-events:none;
  transition:opacity .5s cubic-bezier(.25,1,.5,1);
}
.acc-cross{
  left:1.25rem;
  font-size:14px; line-height:1; font-weight:300;
  color:var(--on-image); opacity:.6;
}
.acc-num{
  right:1.25rem;
  font-family:var(--font-mono); font-size:.75rem; font-weight:500;
  color:var(--on-image); opacity:0;
}
.acc-panel[data-open] .acc-num{opacity:.6}

/* The backing is ON THE BODY, not the panel, and that is the point: the body is
   bottom-anchored and sized to its own copy, so the dark area always covers exactly
   the text however tall the block grows. A panel-wide gradient has to be retuned every
   time copy changes — it was retuned three times, and Capacity then Impact each fell
   below AA as their blocks grew and pushed the headline up into clear sky. This
   version cannot drift. The 3rem padding-top IS the fade-in zone above the headline. */
.acc-body{
  position:absolute; inset:auto 0 0 0; z-index:3;
  color:var(--on-image);
  /* 2.25rem top, trimmed from 3rem: this padding IS the gradient's fade-in zone above
     the headline, and it was the cheapest 12px to recover when the copy grew. */
  padding:2.25rem clamp(1.5rem,2.6vw,2.75rem) clamp(1.5rem,2.6vw,2.75rem);
  background:linear-gradient(to bottom,
    transparent 0, rgba(0,0,0,.78) 3rem, rgba(0,0,0,.90) 100%);
  opacity:0; pointer-events:none;
  transition:opacity .5s cubic-bezier(.25,1,.5,1);
}
.acc-panel[data-open] .acc-body{
  opacity:1; pointer-events:auto;
  transition-delay:.1s;            /* copy arrives just after the panel has opened */
}
.acc-body h3{
  font-size:clamp(1.75rem,1.2rem + 1.9vw,2.75rem);
  letter-spacing:-.02em; line-height:1;
}
.acc-sub{
  margin:.6rem 0 0;
  font-size:40%;                   /* of the headline, per spec */
  font-size:clamp(.75rem,.62rem + .5vw,1.1rem);
  opacity:.75;
}
.acc-copy{
  margin:var(--s3) 0 0; max-width:62ch;
  color:var(--on-image); opacity:.82;
  font-size:clamp(.875rem,.82rem + .25vw,1rem);
}

/* The panel copy: a lead sentence, three named commitments, and a link out.
   ─────────────────────────────────────────────────────────────
   line-height 1.55 rather than the body's 1.7 throughout. At this density the looser
   leading is precisely what pushed every panel past the fixed height — measured, it was
   worth ~4rem of panel — and tighter leading is right for reference copy anyway.
   70ch rather than the 62ch used elsewhere, because the open panel is now 69% wide and
   the extra measure is what keeps the commitment paragraphs to three lines. */
.acc-lead{
  margin:1.1rem 0 0; max-width:70ch;
  color:var(--on-image); font-weight:600; line-height:1.55;
  font-size:clamp(.9375rem,.86rem + .3vw,1.0625rem);
}
/* A description list, not a <ul>: these are label/description pairs, and the label sits
   on its own line rather than running into the text as the old panels' <b>Label</b>: did. */
.acc-defs{
  margin:1.1rem 0 0; max-width:70ch;
  display:grid; gap:.7rem;
  font-size:clamp(.875rem,.82rem + .25vw,1rem); line-height:1.55;
  counter-reset:acc;
}
.acc-defs dt{color:var(--on-image); font-weight:600; counter-increment:acc}
/* Numeral inline on the label line, NOT a hanging indent. A hanging indent would take
   ~24px off the measure for every description line too, and at 960 wide the tightest
   panel has only 24px of headroom — one extra wrapped line would clip it. Inline, the
   numeral only lengthens the label, which is nowhere near a wrap. Mono/thermal at
   .6875rem is the same numeral idiom as the 01–05 panel markers. */
.acc-defs dt::before{
  content:counter(acc) ". ";
  font-family:var(--font-mono); font-size:.6875rem; font-weight:500;
  color:var(--on-image-accent);
}
.acc-defs dd{margin:.1rem 0 0; color:var(--on-image); opacity:.82}
/* Sits above .acc-hit (z-index 2) because .acc-body is z-index 3, so it is clickable
   even though the whole collapsed panel is otherwise one big button. Collapsed bodies
   carry `inert`, so these links stay out of the tab order until their panel opens. */
.acc-more{
  display:inline-block; margin-top:1.1rem;
  color:var(--on-image-accent); text-decoration:none;
  font-family:var(--font-mono); font-size:.6875rem;
  letter-spacing:.14em; text-transform:uppercase;
  border-bottom:1px solid var(--on-image-hair);
  transition:color .25s var(--ease-spring), border-color .25s var(--ease-spring);
}
.acc-more:hover{color:var(--on-image); border-bottom-color:var(--on-image)}

/* The three strands of Access. A real <ul>, so it is announced as a list of three —
   but no glyph bullet: each item already opens with a term and an em dash, and a dot
   on top of that reads as clutter. A short thermal rule marks the item instead, which
   is the same vocabulary as the numerals and eyebrows elsewhere. */
.acc-list{
  margin:var(--s3) 0 0; padding:0; max-width:62ch;
  list-style:none;
  display:grid; gap:.6rem;
  color:var(--on-image);
  font-size:clamp(.875rem,.82rem + .25vw,1rem);
}
.acc-list li{
  position:relative;
  padding-left:1.5rem;
  opacity:.82;
}
.acc-list li::before{
  content:''; position:absolute;
  left:0; top:.72em;                 /* em-relative so it tracks the first line's baseline */
  width:.7rem; height:1px;
  background:var(--on-image-accent);
}
.acc-list b{color:var(--on-image); font-weight:600; opacity:1}

/* Capacity's three are a sequence, not a set, so that one is an <ol> and shows real
   numerals in place of the dash. Kept small and mono so they read as list markers and
   never compete with the panel's own 01–05. */
.acc-list--num{counter-reset:acc}
.acc-list--num li{counter-increment:acc}
.acc-list--num li::before{
  content:counter(acc);
  width:auto; height:auto; background:none;
  /* .5em of the LIST ITEM's font-size, with line-height:1, so the numeral centres on
     the first line rather than hanging above it — the marker's own line box is much
     shorter than the item's, so top:0 reads as superscript. */
  top:.5em; left:.1rem;
  font-family:var(--font-mono); font-size:.6875rem; line-height:1;
  color:var(--on-image-accent);
}

.acc-badge{
  position:absolute; top:1rem; right:1rem; z-index:4;
  margin:0; padding:.3rem .7rem;
  border:1px solid var(--on-image-hair); border-radius:999px;
  font-family:var(--font-mono); font-size:.625rem; letter-spacing:.16em;
  text-transform:uppercase; color:var(--on-image-muted);
}

@media (max-width:56.25rem){
  /* Stacked, the open panel is a slice of a fixed container height — and the longest
     copy (Access, 505px at 390 wide) does not fit in the ~466px that leaves, on any
     phone. Measured: clipped by 39px on a tall handset, 213px at 320. So below this
     breakpoint the accordion stops distributing a fixed height and simply lets the
     open panel be as tall as its content. That is still "expanding downward", it just
     cannot clip, and nothing animates height — the open panel has no transition. */
  .acc{flex-direction:column; height:auto}
  .acc-panel{flex:none; min-height:4.5rem}
  .acc-vtitle{rotate:none; font-size:.9375rem}
  .acc-hit{place-items:center start; padding-left:clamp(1.5rem,4vw,2.75rem)}
  .acc-cross{top:auto; bottom:.75rem}
  .acc-num{top:auto; bottom:.75rem}

  /* Collapsed bodies leave the flow entirely, or every panel would grow to its copy.
     They are already inert, so this removes nothing that was reachable. */
  .acc-panel:not([data-open]) .acc-body{display:none}
  /* relative + z-index, never static: a non-positioned body paints underneath the
     absolutely-positioned tint, scrim and hit layers and the headline disappears
     wherever the image behind it is bright. */
  .acc-panel[data-open] .acc-body{
    position:relative; z-index:3; inset:auto;
    opacity:1;
    padding-top:clamp(4.5rem,14vw,6rem);
  }

  /* Stacked, the badge lands on top of the open panel's subtitle. It is decorative
     and already aria-hidden, so drop it rather than fight for the corner. */
  .acc-badge{display:none}
}
}

/* ─────────────────────────────────────────────────────────────
   Origin + contact
   ───────────────────────────────────────────────────────────── */
.origin{
  padding-block:var(--s6);
  border-top:1px solid var(--hairline);
  background:
    radial-gradient(90% 140% at 12% 0%, rgba(47,107,208,.06), transparent 62%),
    var(--surface);
}
.origin .body{
  max-width:64ch; margin:var(--s3) 0 0; color:var(--muted);
  font-size:clamp(1.0625rem,1rem + .35vw,1.25rem);
}
.origin strong{color:var(--paper); font-weight:500}

/* The founding photograph. It runs wider than the 64rem text shell so the faces stay
   legible, and sits on a hard edge with no scrim or filter — this is the one warm,
   daylit object on the page and softening it would only make it look degraded. */
.plate{
  margin:var(--s5) auto 0;
  max-width:90rem;
  padding-inline:var(--gutter);
}
.plate img{
  display:block; width:100%; height:auto;
  /* Sharpen the seam against the section's near-black: without it the photo's own
     pale edges dissolve into the background rather than reading as a plate. */
  outline:1px solid var(--hairline); outline-offset:-1px;
}
.plate figcaption{
  margin-top:var(--s2);
  font-family:var(--font-mono);
  font-size:.6875rem; letter-spacing:.08em;
  color:var(--muted);
}

@media (max-width:48rem){
  /* Sixty faces at phone width need every pixel — go edge to edge and put the
     caption back inside the gutter on its own. */
  .plate{padding-inline:0}
  .plate img{outline:0}
  .plate figcaption{padding-inline:var(--gutter)}
}

/* Extra bottom padding gives the address room to scroll up into the highlight
   completion zone (see the .scroll-hl handler in site.js). */
.contact{padding-block:var(--s7) calc(var(--s7) + 12vh)}
/* No eyebrow here, deliberately: "Get in touch with us!" now sits directly on the
   address, and a mono GET IN TOUCH three lines above it said the same thing twice.
   The h2's margin-top went with the eyebrow — the heading is the top of the section. */
.contact h2{font-size:clamp(2.2rem,1.4rem + 3.2vw,4rem); max-width:18ch}

/* Scroll-linked highlighter (reusable). A navy block sweeps left→right behind any
   .scroll-hl element and its text turns white, drawing the eye down the contact section.
   ::before is a copy of the text (via data-text) laid exactly over the element — white on
   a navy ground — revealed left-to-right by clip-path as --fill (set per element by
   site.js) runs 0→1. width:fit-content so the highlight hugs the text, not its column.
   With no JS, --fill stays 0, the overlay is clipped away, and the text is plain ink. */
.scroll-hl{ position:relative; width:fit-content; }
.scroll-hl::before{
  content:attr(data-text);
  position:absolute; inset:0; z-index:1; pointer-events:none;
  color:#fff; background:var(--thermal);
  clip-path:inset(0 calc((1 - var(--fill,0)) * 100%) 0 0);
}
.contact-lede{
  margin:var(--s3) 0 0; max-width:34ch; color:var(--paper);
  font-size:clamp(1.125rem,1rem + .6vw,1.5rem);
}
.contact .body{max-width:64ch; color:var(--muted); margin:var(--s2) 0 0}

/* The wide gap above the address is doing the work in this layout: it is what makes
   the address read as a destination rather than as one more sentence in the pitch.
   Flex-wrap rather than a fixed column count so a second address needs no CSS. */
.contact-ways{
  margin-top:var(--s6);
  display:flex; flex-wrap:wrap; gap:var(--s5) var(--s7);
}
.contact-label{margin:0 0 var(--s2); color:var(--paper); font-size:1.0625rem}

.mail{
  /* Spacing comes from .contact-label's margin-bottom — this sits directly under it. */
  display:inline-block; margin-top:0;
  font-family:var(--font-display); font-weight:800; font-stretch:112%;
  /* The outer min() only binds below ~390px, where the 27-character address would
     otherwise run past the gutter and get clipped by body's overflow-x:hidden.
     Shrinking is the right answer rather than wrapping: the underline is a
     background gradient on the inline-block, so a second line would leave the
     first line un-underlined. Keep this address on one line. */
  /* Ceiling lowered from 2.1rem: with the heading no longer competing for attention
     against a near-equal address, the h2 has to be the biggest thing in the section
     for the hierarchy to read. Below ~390px this is unchanged — 5.3vw binds there. */
  font-size:min(clamp(1.125rem,.95rem + .8vw,1.625rem), 5.3vw);
  letter-spacing:-.025em; color:var(--paper); text-decoration:none;
  background-image:linear-gradient(var(--thermal),var(--thermal));
  background-size:100% 2px; background-repeat:no-repeat; background-position:0 100%;
  transition:background-size .4s var(--ease-spring), color .25s var(--ease-spring);
}
.mail:hover{color:var(--thermal); background-size:100% 3px}

.foot{
  border-top:1px solid var(--hairline);
  padding:var(--s4) 0 var(--s5);
  display:flex; flex-wrap:wrap; gap:var(--s2) var(--s4);
  justify-content:space-between; align-items:center;
  font-family:var(--font-mono); font-size:.6875rem;
  letter-spacing:.12em; text-transform:uppercase; color:var(--muted);
}
.foot a{text-decoration:none; transition:color .25s var(--ease-spring)}
.foot a:hover{color:var(--thermal)}

/* ─────────────────────────────────────────────────────────────
   Reveal on scroll
   ───────────────────────────────────────────────────────────── */
.reveal{opacity:0; transform:translateY(18px)}
.reveal.is-in{
  opacity:1; transform:none;
  transition:opacity .7s var(--ease-spring), transform .7s var(--ease-spring);
}

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

/* ─────────────────────────────────────────────────────────────
   Subpages — /origin/ and /about/
   ───────────────────────────────────────────────────────────── */
/* Clears the fixed nav; the home page gets this from the hero's own height. */
.page{padding-block:calc(var(--nav-h) + var(--s6)) var(--s7)}
.page h1{
  font-size:clamp(2.7rem,1.7rem + 3.8vw,4.6rem);
  margin-bottom:var(--s2);
}
.page .body{
  max-width:64ch; margin:var(--s3) 0 0; color:var(--muted);
  font-size:clamp(1.0625rem,1rem + .35vw,1.25rem);
}
.page strong{color:var(--paper); font-weight:500}

.people{
  list-style:none; margin:var(--s6) 0 0; padding:0;
  display:grid; gap:var(--s5);
  grid-template-columns:repeat(auto-fit,minmax(15rem,1fr));
}
.person h2{font-size:clamp(1.25rem,1.1rem + .6vw,1.625rem); margin-top:var(--s3)}
.person-role{
  margin:.55rem 0 0;
  font-family:var(--font-mono); font-size:.625rem;
  letter-spacing:.16em; text-transform:uppercase; color:var(--sensor);
}
.person p:last-child{margin:var(--s2) 0 0; color:var(--muted)}
/* Capped at 12.5rem on purpose. The source headshots are 400x400, so anything wider
   than 200px CSS would upscale on a retina screen — the site's standing rule is that
   the source must exceed 2x the displayed size. Raise this only with bigger sources. */
.portrait{
  /* height:auto is required, not tidiness. The width/height HTML attributes act as
     presentational hints, so without it height stays pinned at the attribute's 400px,
     both dimensions are definite, and aspect-ratio is ignored — the portrait renders
     200x400 with the face stretched. Same reason .plate img sets it. */
  aspect-ratio:1; width:100%; height:auto; max-width:12.5rem;
  object-fit:cover;
  background:var(--float);
  border:1px solid var(--hairline);
}

@media (max-width:48rem){
  /* One column at phone width, so three square portraits would push the copy a long
     way down. */
  .people{gap:var(--s4)}
  .portrait{max-width:10rem}
}

/* ─────────────────────────────────────────────────────────────
   Alliance members — /members/
   ───────────────────────────────────────────────────────────── */
/* Matches the reference layout: a sticky numbered index rail beside a tight
   three-column grid of tiles, captioned bottom-left. Measured off the reference at
   1512 CSS px — tile 313x190 (5:3), 7px gutters between tiles, ~1263px of content.
   Widens past the 64rem shell for the same reason .initiatives does: three columns
   plus a 17rem rail do not fit the text measure. */
.members{max-width:80rem}

.mem-layout{
  margin-top:var(--s6);
  display:grid;
  grid-template-columns:minmax(0,17rem) 1fr;
  gap:clamp(2rem,5vw,6rem);
  align-items:start;
}

/* Sticky, so the index stays legible while you scroll five sections past it. Offset by
   the fixed nav plus a little air; --nav-h is the single source for that clearance. */
.mem-rail{position:sticky; top:calc(var(--nav-h) + var(--s3))}
/* line-height 1.3 rather than the body's 1.7, and no bottom margin: measured off the
   reference, "Index" sits ~32px above the first row's centre while the rows themselves
   are ~44px apart — the title is tighter to the list than the list is to itself. */
.mem-rail-title{margin:0; line-height:1.3; color:var(--muted); font-size:1.0625rem}
.mem-rail-list{list-style:none; margin:0; padding:0}
/* Three aligned columns — dot, numeral, label — so the labels form a clean edge
   however long the numeral column's text is. Column widths and the .4rem gap are
   measured: 6px dot, ~9px to the numeral, ~78px from numeral to label. */
.mem-rail-list a{
  display:grid; grid-template-columns:6px 4.5rem 1fr; align-items:center;
  gap:.4rem; padding:.65rem 0;
  text-decoration:none; color:rgba(15,26,43,.42);
  transition:color .25s var(--ease-spring);
}
.mem-dot{
  width:6px; height:6px; border-radius:50%;
  background:rgba(15,26,43,.25);
  transition:background-color .25s var(--ease-spring);
}
/* .75rem, not the nav's .6875rem: in the reference the numeral and its label read at the
   same size, and the site's mono label size is too small to hold that against 14px Inter. */
.mem-num{
  font-family:var(--font-mono); font-size:.75rem;
  letter-spacing:.18em; text-transform:uppercase;
}
.mem-label{font-size:.875rem}
.mem-rail-list a:hover{color:var(--paper)}
.mem-rail-list a:hover .mem-dot{background:rgba(15,26,43,.55)}
.mem-rail-list a:active{color:var(--thermal)}
.mem-rail-list a[data-current]{color:var(--paper)}
.mem-rail-list a[data-current] .mem-dot{background:var(--thermal)}

.mem-section + .mem-section{margin-top:var(--s6)}
/* Hidden, not absent: while the rail sits alongside it already names every section, and
   the reference shows no heading over the grid. It returns at 56.25rem, where the rail
   has become a row far above. clip-path rather than display:none so it stays in the
   accessibility tree for aria-labelledby. */
.mem-heading{
  position:absolute; width:1px; height:1px;
  margin:-1px; padding:0; overflow:hidden;
  clip-path:inset(50%); white-space:nowrap;
}
.mem-grid{
  list-style:none; margin:0; padding:0;
  display:grid; grid-template-columns:repeat(3,1fr); gap:.5rem;
}
.mem-tile{
  position:relative; aspect-ratio:5/3; overflow:hidden;
  background:var(--float);
  border:1px solid var(--hairline);
}
/* The empty placeholder rectangle. Portraits drop in here later; the gradient is
   already in place so a caption over a bright frame stays legible — a short bottom
   edge band, which is the only kind of scrim this site allows. */
.mem-thumb{
  position:absolute; inset:0;
  /* A light bottom edge-band so a caption stays legible in dark ink over the empty
     tile now, and over a portrait once real ones drop in. */
  background:linear-gradient(to top, rgba(255,255,255,.7) 0%, rgba(255,255,255,0) 40%);
}
.mem-cap{
  position:absolute; left:.7rem; right:.7rem; bottom:.6rem;
  display:flex; flex-direction:column;
  font-size:.8125rem; line-height:1.35;
}
.mem-name{color:var(--paper)}
.mem-org{color:var(--muted)}

@media (max-width:56.25rem){
  /* Stacked: the rail becomes a wrapped row of links above the grid, so sticky buys
     nothing and would only float a strip over the tiles. */
  .mem-layout{grid-template-columns:1fr; gap:var(--s4); margin-top:var(--s5)}
  .mem-rail{position:static}
  .mem-rail-title{margin-bottom:var(--s2)}
  .mem-rail-list{display:flex; flex-wrap:wrap; gap:0 var(--s4)}
  .mem-rail-list a{grid-template-columns:6px auto; gap:.6rem}
  .mem-num{display:none}
  /* Un-hides — the rail is no longer beside the grid to label it. */
  .mem-heading{
    position:static; width:auto; height:auto; margin:0 0 var(--s2);
    overflow:visible; clip-path:none;
    font-size:clamp(1.125rem,1rem + .5vw,1.375rem);
  }
  .mem-grid{grid-template-columns:repeat(2,1fr)}
}

@media (max-width:34rem){
  /* Still two columns, not one. Five categories stacked single-file run to ~6700px of
     scroll at 390px, and a full-width 5:3 tile reads as a banner rather than as part of
     a grid — which is the whole shape of this layout. The caption steps down instead. */
  .mem-grid{gap:.4rem}
  .mem-cap{left:.55rem; right:.55rem; bottom:.5rem; font-size:.75rem}
  .mem-rail-list{gap:0 var(--s3)}
}