/* ============================================================================
   GREEN PACIFIC — SYSTEM
   Base · layout · components · responsive · reduced motion.
   Authoritative source: design-system.md. Section refs (§) are to that file.

   No hex literals here — every colour is a token from tokens.css (§8.4 rule 8).
   No `outline: none` anywhere (§4.0, §8.4 rule 7). No border-radius anywhere.
   ============================================================================ */

/* ── FONT FACES — SELF-HOSTED (D-11) ──────────────────────────────────────
   UNBOUND. The .woff2 files below DO NOT EXIST in this repository yet, and
   no font may be used in a client-facing build until OP signs off the licence
   (§5.7, CV-1). Until the files land, the metric-different system fallback
   stack in --sans / --mono renders. See README "What is not bound".

   Do NOT replace these with the Google Fonts CDN: it is a third-party request
   on a client site AND it silently drops weight 450, which would render every
   lede and standfirst at 400 without erroring (§1.4, D-11, §12 item 7).

   size-adjust / ascent-override for the fallback face are deliberately NOT
   written here. They are per-project values and must be MEASURED at build
   (§1.4, §12 item 6). Copying numbers from another project is prohibited.
   ------------------------------------------------------------------------ */
@font-face{
  font-family:"IBM Plex Sans"; font-style:normal; font-weight:400;
  font-display:swap; src:url("../fonts/ibm-plex/IBMPlexSans-Regular.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0100-024F,U+2000-206F,U+20A0-20BF,U+2122,U+2190-21BB;
}
@font-face{
  font-family:"IBM Plex Sans"; font-style:normal; font-weight:450;
  font-display:swap; src:url("../fonts/ibm-plex/IBMPlexSans-Text.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0100-024F,U+2000-206F,U+20A0-20BF,U+2122,U+2190-21BB;
}
@font-face{
  font-family:"IBM Plex Sans"; font-style:normal; font-weight:600;
  font-display:swap; src:url("../fonts/ibm-plex/IBMPlexSans-SemiBold.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0100-024F,U+2000-206F,U+20A0-20BF,U+2122,U+2190-21BB;
}
/* Mono 500 only. Mono 450 is requested by the prototype, used nowhere, and is
   dropped from the font request (D-1). */
@font-face{
  font-family:"IBM Plex Mono"; font-style:normal; font-weight:500;
  font-display:swap; src:url("../fonts/ibm-plex/IBMPlexMono-Medium.woff2") format("woff2");
  unicode-range:U+0000-00FF,U+0100-024F,U+2000-206F,U+20A0-20BF,U+2122,U+2190-21BB;
}


/* ══ 1. BASE ═══════════════════════════════════════════════════════════════ */

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

html{
  scroll-behavior:smooth;
  scroll-padding-top:calc(var(--spine-h) + var(--s-6));
  -webkit-text-size-adjust:100%;
}

body{
  margin:0;
  background:var(--paper);
  color:var(--ink);
  font-family:var(--sans);
  font-size:var(--fs-b);
  font-weight:var(--w-body);
  line-height:var(--lh-b);
  font-synthesis:none;            /* §1.1 — a synthesised bold is a failure, not a fallback */
  -webkit-font-smoothing:antialiased;
  -moz-osx-font-smoothing:grayscale;
  text-rendering:optimizeLegibility;
}

img,svg,video{ max-width:100%; height:auto; display:block; }
a{ color:inherit; }
button{ font:inherit; }

h1,h2,h3,h4,h5,h6{ font-weight:var(--w-display); margin:0; }
p{ margin:0; }
ul,ol{ margin:0; }

/* Nothing in this system is rounded. */
a,button,input,select,textarea,figure,table,th,td,.slot,.btn{ border-radius:0; }

/* ── Focus — universal (§4.0). `outline: none` appears nowhere. ─────────── */
:where(a,button,input,select,textarea,summary,[tabindex]):focus-visible{
  outline:2px solid var(--focus);
  outline-offset:2px;
}
.on-dark :where(a,button,input,select,textarea,summary,[tabindex]):focus-visible{
  outline-color:var(--focus-rev);
}

/* ── Skip link — first focusable element (§10) ──────────────────────────── */
.skip{
  position:absolute; left:var(--s-4); top:calc(-1 * var(--s-15));
  z-index:200;
  background:transparent; color:var(--blue);
  border:1px solid var(--blue);
  padding:var(--s-3) var(--s-5);
  font-size:var(--fs-ui); font-weight:var(--w-display);
  text-decoration:none;
}
.skip:focus{ top:var(--s-4); background:var(--paper); }

.u-visually-hidden{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip-path:inset(50%); white-space:nowrap; border:0;
}

.container{
  max-width:var(--container);
  margin-inline:auto;
  padding-inline:var(--pad-x);
}


/* ══ 2. TYPE ROLES (§1.2) ══════════════════════════════════════════════════ */

.t-d1{ font-size:var(--fs-d1); line-height:var(--lh-d1); letter-spacing:var(--tr-d1); font-weight:var(--w-display); }
.t-d2{ font-size:var(--fs-d2); line-height:var(--lh-d2); letter-spacing:var(--tr-d2); font-weight:var(--w-display); }
.t-d3{ font-size:var(--fs-d3); line-height:var(--lh-d3); letter-spacing:var(--tr-d3); font-weight:var(--w-display); }
.t-d3r{ font-size:var(--fs-d3); line-height:var(--lh-d3r); letter-spacing:var(--tr-d3r); font-weight:var(--w-display); }
.t-d4{ font-size:var(--fs-d4); line-height:var(--lh-d4); letter-spacing:var(--tr-d4); font-weight:var(--w-display); }
.t-h5{ font-size:var(--fs-h5); line-height:var(--lh-h5); letter-spacing:var(--tr-h5); font-weight:var(--w-display); }

.t-lede{
  font-size:var(--fs-lede); line-height:var(--lh-lede); letter-spacing:var(--tr-lede);
  font-weight:var(--w-read); color:var(--ink-2); max-width:var(--measure-lede);
}
.t-lg{
  font-size:var(--fs-lg); line-height:var(--lh-lg);
  font-weight:var(--w-read); color:var(--ink-2); max-width:var(--measure-lg);
}
.t-b{ font-size:var(--fs-b); line-height:var(--lh-b); max-width:var(--measure-b); }
.t-ui{ font-size:var(--fs-ui); line-height:var(--lh-ui); }
.t-sm{ font-size:var(--fs-sm); line-height:var(--lh-sm); }

.t-b + .t-b{ margin-top:var(--s-5); }   /* paragraph → paragraph (§3.2) */

/* Bracketed, unsupplied GP fact. Typographic, not decorative: it must be
   impossible to mistake a placeholder for a supplied fact (CL-G10, B-2). */
.gp-pending{
  font-family:var(--mono); font-weight:var(--w-mono);
  font-size:0.9em; letter-spacing:0.02em; color:var(--ink-3);
}
.on-dark .gp-pending{ color:var(--ink-rev-3); }


/* ══ 3. LABEL — the atom (§4.1) ════════════════════════════════════════════ */

.label{
  font-family:var(--mono); font-weight:var(--w-mono);
  text-transform:uppercase; display:block;
}
.label--rail{
  font-size:var(--fs-m-lg); letter-spacing:var(--tr-m-lg); line-height:var(--lh-mono);
  color:var(--blue);
  border-top:var(--rail-rule-w) solid var(--blue);   /* R3, full 168px */
  padding-top:var(--s-3);
}
.label--eyebrow{
  font-size:var(--fs-m-lg); letter-spacing:var(--tr-m-lg); line-height:var(--lh-mono);
  color:var(--blue);
  border-top:1px solid var(--rule);                  /* R1 */
  padding-top:var(--s-3);
}
.label--step{
  font-size:var(--fs-m); letter-spacing:var(--tr-m); line-height:var(--lh-mono);
  color:var(--blue); margin-bottom:var(--s-2);
}
.label--meta{
  font-size:var(--fs-m); letter-spacing:var(--tr-m); line-height:var(--lh-mono);
  color:var(--ink-3);
}
.label--head{
  font-size:var(--fs-m); letter-spacing:var(--tr-head); line-height:var(--lh-mono);
  color:var(--white);
}

/* On dark: labels take --ink-rev-3 (6.53:1); the rail rule follows. (§4.1) */
.on-dark .label--rail{ color:var(--ink-rev-3); border-top-color:var(--ink-rev-3); }
.on-dark .label--eyebrow{ color:var(--ink-rev-3); border-top-color:var(--rule-dark); }
.on-dark .label--step{ color:var(--ink-rev-3); }
.on-dark .label--meta{ color:var(--ink-rev-2); }

/* Below 900px the rail collapses: label above the heading, R3 rule shortened
   to a 48px lead rule. It never becomes a full-width bar. (§3.4) */
@media (max-width:899px){
  .label--rail{ border-top:0; padding-top:var(--s-3); position:relative; }
  .label--rail::before{
    content:""; position:absolute; top:0; left:0;
    width:48px; height:var(--rail-rule-w); background:var(--blue);
  }
  .on-dark .label--rail::before{ background:var(--ink-rev-3); }
}


/* ══ 4. RULE LADDER (§4.2) — R1 R2 R3 R4. There is no R5. ═════════════════ */
.r1{ border-top:1px solid var(--rule); }
.r2{ border-top:1px solid var(--rule-strong); }
.r3{ border-top:2px solid var(--blue); }
.r4{ border-top:3px solid var(--blue); }
.on-dark .r1,.on-dark .r2{ border-top-color:var(--rule-dark); }
.on-dark .r3,.on-dark .r4{ border-top-color:var(--ink-rev-3); }


/* ══ 5. CTA (§4.5) ═════════════════════════════════════════════════════════ */

.btn{
  display:inline-block;
  background:var(--blue); color:var(--white);
  border:1px solid var(--blue);
  text-decoration:none; text-align:center;
  padding:var(--s-3) var(--s-5);
  font-family:var(--sans); font-size:var(--fs-ui); font-weight:var(--w-display);
  line-height:var(--lh-ui);
  white-space:nowrap; cursor:pointer;
  transition:background var(--dur-1) var(--ease-standard),
             border-color var(--dur-1) var(--ease-standard),
             color var(--dur-1) var(--ease-standard);
}
.btn:hover{ background:var(--blue-deep); border-color:var(--blue-deep); }
.btn:active{ transform:translateY(1px); }

.btn--ghost{
  background:transparent; color:var(--blue);
  border:1px solid var(--blue);        /* D-4: never --rule-strong (2.26:1) */
}
.btn--ghost:hover{ background:transparent; color:var(--blue-deep); border-color:var(--blue-deep); }

.btn--inline{
  display:inline; background:none; border:0; padding:0;
  color:var(--blue); text-decoration:none;
  border-bottom:1px solid transparent;
  white-space:normal;
}
.btn--inline:hover{ border-bottom-color:var(--blue); }

/* On dark panels the primary CTA is --paper/--ink. --blue on --blue-deep is
   1.81:1 and would disappear. Mantis is NEVER a CTA fill (D-3). */
.on-dark .btn{ background:var(--paper); color:var(--ink); border-color:var(--paper); }
.on-dark .btn:hover{ background:var(--white); border-color:var(--white); }
.on-dark .btn--ghost{ background:transparent; color:var(--ink-rev); border-color:var(--ink-rev); }
.on-dark .btn--ghost:hover{ background:transparent; color:var(--white); border-color:var(--white); }
.on-dark .btn--inline{ color:var(--ink-rev-3); border-bottom-color:transparent; }
.on-dark .btn--inline:hover{ border-bottom-color:var(--ink-rev-3); }

.btn[aria-disabled="true"]{
  background:var(--rule); border-color:var(--rule); color:var(--ink-3);
  cursor:not-allowed;   /* 3.78:1 — WCAG exempts disabled controls. Recorded, not hidden (§4.5) */
}

@media (max-width:899px){
  .btn{ padding:14px var(--s-5); font-size:1rem; min-height:44px; }
}

.acts{ display:flex; gap:var(--s-3); flex-wrap:wrap; align-items:center; }


/* ══ 6. SPINE — persistent commercial layer (§4.11) ════════════════════════ */

.spine{
  position:sticky; top:0; z-index:100;
  background:var(--paper);                       /* opaque fallback first */
  border-bottom:1px solid var(--rule);
}
@supports (backdrop-filter: blur(10px)) or (-webkit-backdrop-filter: blur(10px)){
  .spine{
    background:color-mix(in srgb, var(--paper) 94%, transparent);
    -webkit-backdrop-filter:saturate(180%) blur(10px);
    backdrop-filter:saturate(180%) blur(10px);
  }
}
/* MEASURE AT BUILD (§12 item 3): nav text over the translucent spine sitting
   above a --blue-deep section must stay >= 4.5:1 in the worst composite. */

.spine__in{
  max-width:var(--container); margin-inline:auto; padding-inline:var(--pad-x);
  height:var(--spine-h);
  display:flex; align-items:center; gap:var(--s-7);
}
/* The spine never disappears and never inverts, including over --blue-deep. */

.lockup{ display:flex; align-items:center; gap:var(--s-3); flex-shrink:0; text-decoration:none; }
.lockup__img{ height:28px; width:auto; }   /* L1 digital minimum: 28px mark height (§5.4) */
.lockup--footer .lockup__img{ height:20px; }  /* L2/L3 minimum: 20px (§5.4) */

/* UNBOUND BRAND SLOT. Deliberately NOT a wordmark: the GREEN PACIFIC wordmark
   may never be re-set, retyped or reconstructed in a live font (§5.6;
   brand-guidelines §1.4; CL-P17), so it is not set in HTML text either, and
   the prototype's placeholder mark redraw is not reproduced (D-7). This is an
   empty labelled slot, and an empty labelled slot is the correct state. */
.lockup__slot{
  display:inline-block;
  min-height:28px; line-height:28px;
  padding-inline:var(--s-2);
  border:1px dashed var(--ink-3);
  font-family:var(--mono); font-weight:var(--w-mono);
  font-size:var(--fs-m-sm); letter-spacing:var(--tr-m); text-transform:uppercase;
  color:var(--ink-3);
}

.nav{
  display:flex; gap:var(--s-6); margin-left:auto;
  font-size:var(--fs-ui); line-height:var(--lh-ui);
}
.nav a{
  text-decoration:none; padding:var(--s-1) 0;
  border-bottom:1px solid transparent;
  transition:color var(--dur-1) var(--ease-standard),
             border-color var(--dur-1) var(--ease-standard);
}
.nav a:hover{ color:var(--blue); border-bottom-color:var(--blue); }
.nav a[aria-current="page"]{ color:var(--blue); border-bottom-color:var(--blue); }

@media (max-width:899px){
  .nav{ display:none; }                    /* replaced by .nav-mobile in <main> flow */
  .spine__in{ gap:var(--s-4); }
  .spine .btn{ padding:var(--s-3) var(--s-4); font-size:var(--fs-sm); min-height:0; }
}

/* Mobile navigation: a real, keyboard-operable disclosure. No hamburger
   overlay, no focus trap, no JS dependency for the links to be reachable. */
.nav-mobile{ display:none; }
@media (max-width:899px){
  .nav-mobile{ display:block; border-bottom:1px solid var(--rule); }
  .nav-mobile__summary{
    list-style:none; cursor:pointer;
    display:flex; align-items:center; gap:var(--s-2);
    min-height:44px; padding:var(--s-3) var(--pad-x);
    font-family:var(--mono); font-weight:var(--w-mono);
    font-size:var(--fs-m); letter-spacing:var(--tr-m); text-transform:uppercase;
    color:var(--blue);
  }
  .nav-mobile__summary::-webkit-details-marker{ display:none; }
  .nav-mobile__list{
    list-style:none; margin:0; padding:0 var(--pad-x) var(--s-4);
    display:flex; flex-direction:column;
  }
  .nav-mobile__list a{
    display:block; min-height:44px; padding:var(--s-3) 0;
    text-decoration:none; font-size:var(--fs-ui);
    border-top:1px solid var(--rule);
  }
}


/* ══ 7. HERO — SPEED 1. First viewport, no scroll, no animation (§2, §3) ═══
   Nothing here carries .rise. Nothing here waits on script. This block is
   readable before any JS runs, and it must stay that way. */

.hero{
  max-width:var(--container); margin-inline:auto;
  padding:var(--hero-y-top) var(--pad-x) 0;
  display:grid; grid-template-columns:1fr 1fr; gap:var(--gap-major);
  align-items:center;
}
.hero__statement{ margin:var(--s-6) 0 0; }        /* D1 — one per page, never two */
.hero .t-lede{ margin-top:var(--s-3); }
.hero .acts{ margin-top:var(--s-7); }

.proofline{
  margin-top:var(--s-8); padding-top:var(--s-4);
  border-top:1px solid var(--rule);
  list-style:none; padding-left:0;
  display:flex; gap:var(--s-5); flex-wrap:wrap;
  font-family:var(--mono); font-weight:var(--w-mono);
  font-size:var(--fs-m); letter-spacing:var(--tr-m-sm); line-height:var(--lh-mono);
  text-transform:uppercase; color:var(--ink-2);
}
.proofline li{ display:flex; align-items:center; gap:var(--s-2); }
/* The verification marker (§2.6 permitted use 1): 8x8 Mantis square. The TEXT
   is the information; the square is punctuation. Remove the colour and the
   line still states the fact. */
.marker{
  width:8px; height:8px; flex-shrink:0;
  background:var(--mantis); display:inline-block;
}

@media (max-width:899px){
  .hero{ grid-template-columns:1fr; gap:var(--gap-major); }
}


/* ══ 8. MEDIA SLOT (§4.9) ══════════════════════════════════════════════════
   Every image, video and generated frame goes in a slot. There is no bare
   <img>. In THIS build every slot is EMPTY and LABELLED — no stock, no
   generated imagery, no placeholder photography of any kind. */

.slot{
  position:relative; margin:0;
  background:var(--white);
  border:1px solid var(--rule);           /* R1 */
  overflow:hidden;
}
.on-dark .slot{ background:var(--panel-deep); border-color:var(--rule-dark); }

.slot__frame{
  aspect-ratio:3 / 2;
  display:flex; align-items:center; justify-content:center;
  text-align:left; padding:var(--s-6);
}
.slot--portrait .slot__frame{ aspect-ratio:4 / 5; }
.slot--wide .slot__frame{ aspect-ratio:16 / 9; }

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

/* The empty-slot shot brief. §4.9 marks the "empty (spec text)" state as
   review-only; this build is a review build (see README). */
.slot__brief{
  font-family:var(--mono); font-weight:var(--w-mono);
  font-size:var(--fs-m-sm); letter-spacing:var(--tr-m-sm);
  line-height:var(--lh-mono-sm); text-transform:uppercase;
  color:var(--ink-3); max-width:40ch;
}
.on-dark .slot__brief{ color:var(--ink-rev-3); }
.slot__brief b{ font-weight:var(--w-mono); color:var(--ink-2); }
.on-dark .slot__brief b{ color:var(--ink-rev); }

/* Below 560px slots go full-bleed and lose the R1 border (§4.9). */
@media (max-width:559px){
  .slot{ margin-inline:calc(-1 * var(--pad-x)); border-left:0; border-right:0; }
  .slot + .cap{ padding-inline:0; }
}


/* ══ 9. CAPTION DEVICE (§4.4) ══════════════════════════════════════════════
   Presence of the FACTUAL form means the asset beside it is factual.
   Two mutually exclusive forms. A .cap--factual may not exist inside a
   figure whose data-media-class is 2 or 3, or whose data-media-meaning is
   "altered" (§4.4, §8.4 rules 1-2). Enforced at build, not by discipline. */

.cap{
  font-size:var(--fs-cap); line-height:var(--lh-cap);
  margin-top:var(--s-3); max-width:var(--measure-b);
}
@media (max-width:899px){ .cap{ max-width:42ch; } }

.cap--factual{
  border-left:3px solid var(--blue);      /* R4. D-8: BLUE, not Mantis */
  padding-left:var(--s-3);
  color:var(--ink-2);                     /* 8.77:1 */
}
.on-dark .cap--factual{ border-left-color:var(--ink-rev-3); color:var(--ink-rev-2); }
.cap__mark{                                /* 8x8 Mantis marker — decoration only (D-8) */
  width:8px; height:8px; display:inline-block;
  background:var(--mantis); margin-right:var(--s-2);
  position:relative; top:0;
}

.cap--observational{
  border:0; padding-left:0;
  color:var(--ink-3);                     /* 5.33:1 */
}
.on-dark .cap--observational{ color:var(--ink-rev-2); }


/* ══ 10. PROGRESS RAIL — fixed (§4.8) ══════════════════════════════════════ */

.rail{
  position:fixed; left:22px; top:50%; transform:translateY(-50%); z-index:90;
  display:flex; flex-direction:column; gap:var(--s-4);
}
.rail a{
  display:flex; align-items:center; gap:var(--s-2);
  text-decoration:none;
  font-family:var(--mono); font-weight:var(--w-mono);
  font-size:var(--fs-m);                  /* D-2: 11px, lifted from the prototype's 9.5px */
  letter-spacing:var(--tr-m); text-transform:uppercase;
  color:var(--ink-3);                     /* D-4: 5.33:1, lifted from --rule-strong's 2.26:1 */
  transition:color var(--dur-3) var(--ease-standard);
}
.rail i{
  width:20px; height:1px; background:currentColor; flex-shrink:0;
  transition:width var(--dur-3) var(--ease-standard), height var(--dur-3) var(--ease-standard);
}
.rail a:hover{ color:var(--blue); }
.rail a:hover i{ width:28px; }
/* Active state is carried by RULE LENGTH as well as colour — it survives
   greyscale and it survives reduced motion. */
.rail a[aria-current="true"]{ color:var(--blue); }
.rail a[aria-current="true"] i{ width:38px; height:2px; }

.rail--on-dark a{ color:var(--ink-rev-2); }
/* MEASURE AT BUILD (§12 item 5): the dark idle state. */
.rail--on-dark a:hover,
.rail--on-dark a[aria-current="true"]{ color:var(--ink-rev); }

@media (max-width:1179px){ .rail{ display:none; } }  /* §4.8: hidden below 1180px, not replaced */


/* ══ 11. SECTIONS AND THE LABEL RAIL HEAD (§3.4, §3.5) ═════════════════════ */

.sect{ padding-block:var(--sect-y-commercial); border-top:1px solid var(--rule); }
.sect--narrative{ padding-block:var(--sect-y-narrative); }
/* Inverted sections carry no top rule — the ground change is the division. */
.sect--inverted{
  background:var(--blue-deep); color:var(--ink-rev); border-top:0;
}
.sect--raised{ background:var(--white); }

.rail-head{
  display:grid; grid-template-columns:var(--rail-w) 1fr; gap:var(--rail-gap);
  margin-bottom:var(--s-11);
}
.rail-head h2{ margin:0; max-width:20ch; }
.rail-head .t-lg{ margin-top:var(--s-3); }
.on-dark .t-lg,.on-dark .t-lede{ color:var(--ink-rev-2); }
.on-dark .t-b{ color:var(--ink-rev-2); }

@media (max-width:899px){
  .rail-head{ grid-template-columns:1fr; gap:var(--s-3); margin-bottom:var(--s-8); }
}

.block + .block{ margin-top:var(--s-9); }


/* ══ 12. MOVEMENT PANEL — the sticky sequence (§4.7) ═══════════════════════ */

.seq{ display:grid; grid-template-columns:1fr 1fr; gap:var(--gap-major); align-items:start; }
.seq__sticky{ position:sticky; top:var(--sticky-top); }

.step{
  padding:var(--s-6) 0 var(--s-6) var(--s-6);
  border-left:1px solid var(--rule-strong);          /* R2 */
  transition:opacity var(--dur-3) var(--ease-standard),
             border-color var(--dur-3) var(--ease-standard),
             border-width var(--dur-3) var(--ease-standard);
  position:relative;
}
/* Dimming belongs ONLY to an observed sequence. A static step list — the
   operating model on services.html — is never dimmed, because there is no
   active row to be dim in contrast to. */
.js [data-sequence] .step{ opacity:.42; }
.on-dark .step{ border-left-color:var(--rule-dark); }
.step h3{ margin:0 0 var(--s-2); }
.step p{ margin:0; color:var(--ink-2); font-size:var(--fs-b); line-height:var(--lh-b); }
.on-dark .step p{ color:var(--ink-rev-2); }
.on-dark .step h3{ color:var(--ink-rev); }

.js [data-sequence] .step.is-active{ opacity:1; }
.step.is-active{
  border-left:3px solid var(--blue);                 /* R4 */
  padding-left:calc(var(--s-6) - 2px);               /* absorbs the 2px growth — no reflow */
}
.on-dark .step.is-active{ border-left-color:var(--ink-rev-3); }
/* Mantis marker at the spine top — reinforcement only. Remove the colour and
   the state is still carried by opacity and rule weight (§2.6 use 2). */
.step.is-active::before{
  content:""; position:absolute; left:-3px; top:0;
  width:8px; height:8px; background:var(--mantis);
}

@media (max-width:899px){
  .seq{ grid-template-columns:1fr; gap:var(--s-7); }
  .seq__sticky{ position:static; }
  /* A step you cannot scroll past independently must not be dimmed (§4.7). */
  .js [data-sequence] .step,.step{ opacity:1; }
}


/* ── Portrait grid — Movement III (§3.3 --gap-cell) ────────────────────── */
.people{ display:grid; grid-template-columns:repeat(3,1fr); gap:var(--gap-cell); }
@media (max-width:899px){ .people{ grid-template-columns:1fr; gap:var(--s-9); } }


/* ══ 13. SCOPE TABLE (§4.3) ════════════════════════════════════════════════ */

.scope{ margin:0; }
.scope table{ width:100%; border-collapse:collapse; font-size:var(--fs-ui); }
.scope caption{ text-align:left; }
.scope th{
  background:var(--blue-deep); color:var(--white);   /* 13.57:1 */
  font-family:var(--mono); font-weight:var(--w-mono);
  font-size:var(--fs-m); letter-spacing:var(--tr-head); text-transform:uppercase;
  text-align:left; padding:var(--s-3) var(--s-4);
}
.scope td{
  padding:var(--s-3) var(--s-4);
  border-bottom:1px solid var(--rule);               /* R1 does the separating */
  background:var(--white); color:var(--ink);
  line-height:var(--lh-ui);
}
.scope tbody tr:nth-child(even) td{ background:var(--paper); }  /* zebra: atmosphere, not structure */
.scope td.num,.scope td.freq{
  font-family:var(--mono); font-weight:var(--w-mono);
  font-size:var(--fs-sm); font-variant-numeric:tabular-nums;
}
.scope__note{
  font-family:var(--mono); font-weight:var(--w-mono);
  font-size:var(--fs-m-sm); letter-spacing:var(--tr-m-sm);
  line-height:var(--lh-mono-sm); text-transform:uppercase;
  color:var(--ink-3); margin-top:var(--s-3);
}

/* Below 900px the table RESTRUCTURES — it does not scroll horizontally.
   The <th> text becomes the per-cell mono label. (§4.3) */
@media (max-width:899px){
  .scope thead{ position:absolute; width:1px; height:1px; overflow:hidden; clip-path:inset(50%); }
  .scope table,.scope tbody,.scope tr,.scope td{ display:block; width:100%; }
  .scope tr{ border-bottom:1px solid var(--rule); padding-block:var(--s-5); }
  .scope tbody tr:nth-child(even) td,.scope td{ background:transparent; border-bottom:0; }
  .scope td{ padding:0 0 var(--s-3); display:grid; grid-template-columns:var(--s-15) 1fr; gap:var(--s-4); }
  .scope td::before{
    content:attr(data-label);
    font-family:var(--mono); font-weight:var(--w-mono);
    font-size:var(--fs-m); letter-spacing:var(--tr-m); text-transform:uppercase;
    color:var(--blue);
  }
}
@media (max-width:559px){
  .scope td{ grid-template-columns:1fr; gap:var(--s-1); }
}


/* ══ 14. SECTOR CELL (§4.10) ═══════════════════════════════════════════════ */

.sectors{
  display:grid; grid-template-columns:repeat(5,1fr);
  gap:1px; background:var(--rule); border:1px solid var(--rule);
}
.sector{
  background:var(--paper); padding:var(--s-6) var(--s-5);
  text-decoration:none; display:block;
  border-top:2px solid transparent;                  /* R3 drawn inside existing padding */
  transition:background var(--dur-2) var(--ease-standard),
             border-color var(--dur-2) var(--ease-standard);
}
.sector b{ display:block; font-size:var(--fs-lg); font-weight:var(--w-display); margin-bottom:var(--s-1); }
.sector span{ display:block; font-size:var(--fs-sm); line-height:var(--lh-sm); color:var(--ink-2); }
.sector:hover,.sector:focus-visible{ background:var(--white); border-top-color:var(--blue); }
.sector[aria-current="page"]{ background:var(--white); border-top-color:var(--blue); }
/* No icons. No illustrations. No arrows. The list is the design. */

@media (max-width:1179px){ .sectors{ grid-template-columns:repeat(3,1fr); } }  /* D-6 */
@media (max-width:899px){ .sectors{ grid-template-columns:repeat(2,1fr); } }
@media (max-width:559px){ .sectors{ grid-template-columns:1fr; } }


/* ══ 15. SITE WALK + FORM (§4.6) ═══════════════════════════════════════════ */

.walk__in{ display:grid; grid-template-columns:1fr 1fr; gap:var(--gap-major); align-items:start; }
.walk h2{ max-width:16ch; }
.walk ol{ padding-left:var(--s-5); margin-top:var(--s-6); color:var(--ink-rev-2); font-size:var(--fs-b); }
.walk li{ margin-bottom:var(--s-2); }
@media (max-width:899px){ .walk__in{ grid-template-columns:1fr; gap:var(--s-7); } }

.form{
  background:var(--panel-deep); border:1px solid var(--rule-dark);
  padding:var(--s-7);
}
.field{ margin-bottom:var(--s-5); }
.field > .label{ margin-bottom:var(--s-2); }
.on-dark .field > .label{ color:var(--ink-rev-3); }   /* 7.44:1 on --panel-deep */

.field input,.field select,.field textarea{
  width:100%;
  background:var(--field-deep); border:1px solid var(--rule-dark);
  color:var(--ink-rev);                                /* 10.71:1 */
  font-family:var(--sans); font-weight:var(--w-body);
  font-size:1rem;                                      /* 16px min — below it iOS zooms on focus */
  line-height:var(--lh-ui);
  padding:var(--s-3);
  transition:border-color var(--dur-1) var(--ease-standard);
}
.field input::placeholder,.field textarea::placeholder{ color:var(--ink-rev-2); opacity:.7; }
/* MEASURE AT BUILD (§12 item 4). Placeholders carry no information in this
   system, so a marginal ratio is tolerable — it is not an excuse. */
.field input:hover,.field select:hover,.field textarea:hover{ border-color:var(--ink-rev-3); }
.field input:focus-visible,.field select:focus-visible,.field textarea:focus-visible{ border-color:var(--focus-rev); }

.field__help{
  margin-top:var(--s-2); font-size:var(--fs-sm); line-height:var(--lh-sm);
  color:var(--ink-rev-2);
}
.field__error{
  margin-top:var(--s-2); font-size:var(--fs-sm); line-height:var(--lh-sm);
  color:var(--ink-rev); font-weight:var(--w-read);
}
.field__error:empty{ display:none; }
/* Error is never signalled by colour alone: the "Error — " text prefix and
   aria-invalid are mandatory (§4.6). */
.field [aria-invalid="true"]{ border:2px solid var(--alert); }

.form .btn{ width:100%; }

/* Light-ground form fields (contact.html). --rule-strong at 2.26:1 is
   PROHIBITED as a control boundary here; --ink-3 at 5.33:1 passes (D-4). */
.form--light{ background:var(--white); border-color:var(--rule); }
.form--light .field > .label{ color:var(--ink-3); }
.form--light .field input,
.form--light .field select,
.form--light .field textarea{
  background:var(--white); border:1px solid var(--ink-3); color:var(--ink);
}
.form--light .field input::placeholder,
.form--light .field textarea::placeholder{ color:var(--ink-3); opacity:1; }
.form--light .field input:hover,
.form--light .field select:hover,
.form--light .field textarea:hover{ border-color:var(--blue); }
.form--light .field__help{ color:var(--ink-3); }
.form--light .field__error{ color:var(--alert); }


/* ══ 16. FOOTER + MOBILE CTA BAR (§4.11) ═══════════════════════════════════ */

footer.site{
  padding:var(--s-10) 0 88px;                 /* bottom pad clears the mobile CTA bar */
  border-top:1px solid var(--rule);
  font-size:var(--fs-ui); line-height:var(--lh-ui); color:var(--ink-2);
}
footer.site .container{
  display:flex; gap:var(--s-8); flex-wrap:wrap; justify-content:space-between;
}
.footer__mono{
  font-family:var(--mono); font-weight:var(--w-mono);
  font-size:var(--fs-m); letter-spacing:var(--tr-m-sm);
  line-height:var(--lh-mono); text-transform:uppercase;
}
.footer__nav{ list-style:none; padding:0; margin:var(--s-3) 0 0; }
.footer__nav li{ margin-bottom:var(--s-2); }
.footer__nav a{ text-decoration:none; border-bottom:1px solid transparent; }
.footer__nav a:hover{ color:var(--blue); border-bottom-color:var(--blue); }
/* No social icon row. No newsletter. No badge wall. */

.mcta{ display:none; }
@media (max-width:899px){
  .mcta{
    display:flex; position:fixed; left:0; right:0; bottom:0; z-index:150;
    border-top:1px solid var(--rule);
    background:var(--paper);
    padding:var(--s-3) var(--s-4); gap:var(--s-3);
  }
  .mcta .btn{ flex:1; min-height:44px; }
  body{ padding-bottom:calc(var(--spine-h) + var(--s-4)); }
}


/* ══ 17. MOTION (§6.3) ═════════════════════════════════════════════════════
   Opacity and position only. Distance capped at 22px. One-way: entrance runs
   once and unobserves. Nothing here blocks first paint — .rise is applied by
   script AFTER load, so with JS off or slow, everything is simply visible. */

.js .rise{
  opacity:0; transform:translateY(var(--rise-distance));
  transition:opacity var(--dur-4) var(--ease-out-soft),
             transform var(--dur-4) var(--ease-out-soft);
}
.js .rise.is-in{ opacity:1; transform:none; }
.js .rise--delay{ transition-delay:80ms; }   /* the label arrives just before what it names */


/* ══ 18. REDUCED MOTION — a first-class state, not a degradation (§6.4) ════
   The test: with animation disabled the page must read as a well-composed
   static editorial layout. Reduced motion never removes information, never
   removes a control, and never removes navigation. */

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

  /* Every step readable, none dimmed. The anchor step keeps its R4 blue
     spine, set instantly — the sequence still reads as a sequence. */
  .step{ opacity:1; }

  /* The sticky panel becomes a linear sequence: each media slot renders
     above the steps it illustrates. */
  .seq{ grid-template-columns:1fr; gap:var(--s-7); }
  .seq__sticky{ position:static; }

  /* The rail remains functional navigation; its active state is carried by
     rule length and colour, set instantly. */
  .rail i{ transition:none; }

  video[autoplay]{ display:none; }   /* the poster frame renders in its place */
}
