/* ==========================================================================
   Oceans Humanity Project — oceanshumanity.org
   Concept: a working nautical chart. Graticule lines, depth soundings,
   plotted course. Restrained, civic, humane.

   MOBILE-FIRST. The base stylesheet IS the 375px layout. Everything wider is
   layered on with min-width queries, in this ladder:

     480px   two-up statistics, horizontal hero CTAs
     600px   two-up doors + footer columns
     720px   nav bar replaces the drawer, three-up statistics + course
     900px   the two-column editorial layouts (hero, split, story, sidebar)
     1080px  the full five-across card: statistics, course, doors, footer

   The only max-width queries in this file are feature queries — print,
   reduced motion, hover. Never layout.
   ========================================================================== */

/* ---------- Tokens ---------- */
:root{
  --navy-deep:#071A33;
  --navy:#0B2545;
  --navy-mid:#13395F;
  --sea:#2A6F8E;
  --sea-pale:#8FB8CB;

  --paper:#F7F4EF;
  --paper-dim:#EDE7DE;
  --paper-line:#DFD6C9;

  --ink:#16212E;
  --ink-dim:#55636F;
  --ink-faint:#8A96A1;

  --accent:#E8552F;
  --accent-dark:#C4401E;
  --accent-warm:#F2A65A;

  --font-display:'Fraunces',Georgia,'Times New Roman',serif;
  --font-body:'Public Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',Helvetica,sans-serif;

  --w-max:1200px;
  --pad:clamp(1.25rem,5vw,3rem);
  --sec-y:clamp(3.25rem,10vw,8.5rem);

  /* Gutters absorb the notch in landscape. max() keeps the design value on
     every device that reports no inset. */
  --pad-l:max(var(--pad),env(safe-area-inset-left));
  --pad-r:max(var(--pad),env(safe-area-inset-right));

  /* Minimum comfortable hit box. Applied to the BOX, never the type size. */
  --tap:44px;

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

/* ---------- Reset ---------- */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}
/* Final backstop against sideways scroll. clip, not hidden: hidden would
   form a scroll container and silently break .side-card{position:sticky}. */
html,body{overflow-x:clip}
body{
  margin:0;
  font-family:var(--font-body);
  font-size:clamp(1rem,.96rem + .2vw,1.0625rem);
  line-height:1.65;
  color:var(--ink);
  background:var(--paper);
  -webkit-font-smoothing:antialiased;
  overflow-wrap:break-word;
}
img{max-width:100%;height:auto;display:block}
a{color:inherit}
h1,h2,h3,h4{margin:0;font-family:var(--font-display);font-weight:600;line-height:1.08;letter-spacing:-.015em}
/* Long clinical words — "credentialing", "ophthalmology" — are the realistic
   overflow risk at 375px, not layout. */
h1,h2,h3,h4,.pullquote,.brand-name,.stat-num{overflow-wrap:anywhere}
p{margin:0 0 1.1em}
p:last-child{margin-bottom:0}
/* ol is reset alongside ul: the browser default padding-inline-start:40px
   silently indented .course-steps (an <ol>) out of alignment with the
   section heading above it. .prose ol restores real numbering below. */
ul,ol{margin:0;padding:0;list-style:none}
:focus-visible{outline:3px solid var(--accent);outline-offset:3px;border-radius:2px}

/* Visually hidden, still announced. Used for the injected drawer control. */
.sr-only{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;
}

/* Keyboard bypass to the main landmark. Off-canvas until focused — it must
   never be display:none, or it is unreachable and therefore pointless. */
.skip-link{
  position:absolute;top:0;left:0;z-index:100;
  display:inline-flex;align-items:center;
  min-height:var(--tap);padding:.7rem 1.2rem;
  background:var(--accent);color:#fff;
  font-family:var(--font-body);font-size:.85rem;font-weight:700;
  letter-spacing:.06em;text-transform:uppercase;text-decoration:none;
  border-radius:0 0 2px 0;
  transform:translateY(-120%);
  transition:transform .2s var(--ease);
}
.skip-link:focus,.skip-link:focus-visible{transform:translateY(0)}

/* ---------- Chart textures ---------- */
/* Graticule: latitude/longitude grid, the base visual language of the site.
   Square size is responsive — 90px cells read as almost no grid on a phone,
   so the base is tighter and the original spacing returns at 1080px. */
.chart-grid{position:relative;isolation:isolate}
.chart-grid::before{
  content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:
    repeating-linear-gradient(to right,currentColor 0 1px,transparent 1px 54px),
    repeating-linear-gradient(to bottom,currentColor 0 1px,transparent 1px 54px);
  opacity:.055;
}
/* Grain — keeps large flat fields from looking like flat digital fields.
   mix-blend-mode across a full-bleed field is a known iOS Safari repaint
   hazard: it forces a compositing layer that re-rasterises on scroll, and
   phones are the primary target. The blend is gone. What remains is a plain
   low-opacity noise wash — the blend was doing most of the visual work, so
   opacity comes down with it or the wash turns milky. */
.grain::after{
  content:'';position:absolute;inset:0;z-index:1;pointer-events:none;opacity:.05;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
}

/* ---------- Layout ---------- */
.wrap{width:100%;max-width:var(--w-max);margin-inline:auto;padding-left:var(--pad-l);padding-right:var(--pad-r)}
.section{padding-block:var(--sec-y);position:relative}
.sec-paper{background:var(--paper);color:var(--ink)}
.sec-navy{background:var(--navy);color:#E8EEF4}
.sec-navy .chart-grid::before,.sec-navy::before{color:#fff}
.sec-deep{background:var(--navy-deep);color:#E8EEF4}

/* Section label — small chart annotation with a tick mark */
.eyebrow{
  font-family:var(--font-body);font-size:.72rem;font-weight:700;
  letter-spacing:.18em;text-transform:uppercase;color:var(--sea);
  display:flex;align-items:center;gap:.7rem;margin:0 0 1.4rem;
}
.eyebrow::before{content:'';width:28px;height:2px;background:var(--accent);flex:none}
.sec-navy .eyebrow,.sec-deep .eyebrow{color:var(--sea-pale)}

.sec-title{font-size:clamp(1.75rem,1.3rem + 2.4vw,3.1rem);max-width:19ch}
.sec-lede{font-size:clamp(1.02rem,1rem + .35vw,1.25rem);color:var(--ink-dim);max-width:62ch;margin-top:1.2rem}
.sec-navy .sec-lede,.sec-deep .sec-lede{color:#A9BDCE}

/* ---------- Buttons ---------- */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.6rem;
  font-family:var(--font-body);font-size:.94rem;font-weight:700;
  letter-spacing:.02em;text-decoration:none;cursor:pointer;
  padding:.95rem 1.6rem;border-radius:2px;border:2px solid transparent;
  min-height:var(--tap);
  transition:background .25s var(--ease),color .25s var(--ease),
             border-color .25s var(--ease),transform .25s var(--ease);
}
.btn:active{transform:translateY(0)}
.btn-primary{background:var(--accent);color:#fff;border-color:var(--accent)}
.btn-ghost{background:transparent;color:#E8EEF4;border-color:rgba(232,238,244,.38)}
.btn-ghost-ink{background:transparent;color:var(--ink);border-color:var(--paper-line)}
.btn .arw{transition:transform .25s var(--ease);flex:none}

/* ---------- Header ---------- */
.site-head{
  position:absolute;top:0;left:0;right:0;z-index:50;
  padding-top:calc(1.1rem + env(safe-area-inset-top));
  padding-bottom:1.1rem;
}
.site-head.is-inner{position:relative;background:var(--navy-deep)}
.head-inner{display:flex;align-items:center;justify-content:space-between;gap:1rem}
.brand{display:flex;align-items:center;gap:.7rem;text-decoration:none;color:#fff;min-height:var(--tap)}
.brand svg{flex:none}
.brand-txt{display:flex;flex-direction:column;line-height:1.05;min-width:0}
.brand-name{font-family:var(--font-display);font-size:1rem;font-weight:600;letter-spacing:-.01em}
.brand-sub{font-size:.58rem;letter-spacing:.17em;text-transform:uppercase;color:var(--sea-pale);font-weight:600}

/* ---------- Nav: drawer on small screens ----------
   visibility:hidden is load-bearing. transform alone leaves every link in the
   tab order while the drawer is closed, so Tab from the toggle walks into
   invisible controls. visibility removes them natively — no inert attribute,
   no JS bookkeeping — and it reverts cleanly at 720px. */
.nav{
  position:fixed;inset:0;z-index:60;
  display:flex;flex-direction:column;align-items:stretch;justify-content:center;
  gap:.25rem;
  background:var(--navy-deep);
  padding:
    calc(4.5rem + env(safe-area-inset-top))
    max(1.5rem,env(safe-area-inset-right))
    calc(2rem + env(safe-area-inset-bottom))
    max(1.5rem,env(safe-area-inset-left));
  overflow-y:auto;overscroll-behavior:contain;
  min-height:100vh;
  min-height:100dvh;
  visibility:hidden;
  transform:translateX(100%);
  transition:transform .35s var(--ease),visibility .35s var(--ease);
}
.nav.is-open{visibility:visible;transform:none}
.nav a{
  display:flex;align-items:center;min-height:var(--tap);
  text-decoration:none;color:#C9D8E4;font-size:1.15rem;font-weight:600;
  letter-spacing:.01em;position:relative;padding-block:.55rem;
  transition:color .2s var(--ease);
}
.nav a::after{
  content:'';position:absolute;left:0;right:0;bottom:0;height:2px;
  background:var(--accent);transform:scaleX(0);transform-origin:left;
  transition:transform .28s var(--ease);
}
.nav a[aria-current='page']::after{transform:scaleX(1)}
.nav a[aria-current='page']{color:#fff}
.nav .btn{margin-top:1rem;justify-content:center}

/* Toggle + close. Both are square 44px minimums; the icon inside stays
   whatever size the HTML author drew it. */
.nav-toggle{
  display:inline-flex;align-items:center;justify-content:center;
  min-width:var(--tap);min-height:var(--tap);
  background:none;border:0;padding:.5rem;cursor:pointer;color:#fff;
  position:relative;z-index:70;flex:none;
}
/* Injected by main.js when the markup does not supply one. */
.nav-close{
  position:absolute;
  top:calc(.75rem + env(safe-area-inset-top));
  right:max(1rem,env(safe-area-inset-right));
  display:inline-flex;align-items:center;justify-content:center;
  min-width:var(--tap);min-height:var(--tap);
  background:none;border:0;padding:.5rem;cursor:pointer;
  color:#C9D8E4;font-size:1.6rem;line-height:1;font-family:var(--font-body);
  transition:color .2s var(--ease);
}

/* The drawer's close button is pinned to the same top-right corner as the
   hamburger, so leaving the toggle visible superimposes an X over three bars.
   Safe to remove from the flow: main.js focuses into the drawer on open, and
   on close it drops .nav-open (restoring the toggle) BEFORE refocusing it. */
body.nav-open .nav-toggle{display:none}

/* Scroll-lock while the drawer is open. Applied by main.js only. */
body.nav-open{overflow:hidden}

/* ---------- Hero ---------- */
.hero{
  position:relative;background:var(--navy-deep);color:#fff;overflow:hidden;
  padding-top:calc(clamp(6.5rem,22vw,10.5rem) + env(safe-area-inset-top));
  padding-bottom:clamp(3rem,8vw,6.5rem);
}
.hero::before{
  content:'';position:absolute;inset:0;color:#fff;pointer-events:none;
  background-image:
    repeating-linear-gradient(to right,currentColor 0 1px,transparent 1px 60px),
    repeating-linear-gradient(to bottom,currentColor 0 1px,transparent 1px 60px);
  opacity:.05;
}
/* Depth-sounding glow, bottom-left — suggests water without a literal wave */
.hero::after{
  content:'';position:absolute;left:-10%;bottom:-40%;width:70%;aspect-ratio:1;
  background:radial-gradient(circle,rgba(42,111,142,.5),transparent 66%);
  pointer-events:none;
}
.hero-grid{
  position:relative;z-index:2;
  display:grid;grid-template-columns:1fr;gap:clamp(2.25rem,5vw,4.5rem);
  align-items:center;
}
.hero-kicker{
  font-size:.68rem;font-weight:700;letter-spacing:.2em;text-transform:uppercase;
  color:var(--sea-pale);display:flex;align-items:center;gap:.75rem;margin-bottom:1.4rem;
}
.hero-kicker::before{content:'';width:28px;height:2px;background:var(--accent);flex:none}
.hero h1{
  font-size:clamp(1.85rem,1.15rem + 3.1vw,3.35rem);
  font-weight:600;letter-spacing:-.022em;line-height:1.11;
  text-wrap:balance;
}
.hero-deck{
  margin-top:1.3rem;font-size:clamp(1rem,.95rem + .35vw,1.16rem);
  color:#A9BDCE;max-width:52ch;line-height:1.62;
}
/* Stacked, full-bleed buttons at phone width: a two-up row of 44px targets
   does not fit inside 375px minus gutters without cramping the labels. */
.hero-cta{display:flex;flex-direction:column;align-items:stretch;gap:.75rem;margin-top:2rem}

/* Photo mounted as a chart plate — corner ticks + caption, sized at/below native */
.plate{position:relative;max-width:100%;margin-left:0}
.plate-img{
  position:relative;border:1px solid rgba(232,238,244,.22);
  box-shadow:0 26px 70px rgba(0,0,0,.5);background:var(--navy);
}
.plate-img img{width:100%;filter:saturate(1.04) contrast(1.03)}
.plate-img::after{
  content:'';position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(to top,rgba(7,26,51,.42),transparent 52%);
}
.plate-tick{position:absolute;width:13px;height:13px;border:2px solid var(--accent);pointer-events:none}
.plate-tick.tl{top:-7px;left:-7px;border-right:0;border-bottom:0}
.plate-tick.tr{top:-7px;right:-7px;border-left:0;border-bottom:0}
.plate-tick.bl{bottom:-7px;left:-7px;border-right:0;border-top:0}
.plate-tick.br{bottom:-7px;right:-7px;border-left:0;border-top:0}
.plate-cap{
  margin-top:.85rem;font-size:.68rem;letter-spacing:.08em;text-transform:uppercase;
  color:var(--sea-pale);display:flex;flex-wrap:wrap;justify-content:space-between;
  gap:.35rem 1rem;font-weight:600;
}
/* The caption colour assumes a navy ground. On paper it needs the ink ramp,
   or the plate is unreadable the moment one is used in a light section. */
.sec-paper .plate-cap{color:var(--ink-dim)}
.sec-paper .plate-img{border-color:var(--paper-line);box-shadow:0 18px 44px rgba(11,37,69,.16)}

/* ---------- Impact numbers ---------- */
/* 1 → 2 → 3 → 5 across the ladder. */
.impact-grid{
  display:grid;grid-template-columns:1fr;
  gap:1.8rem clamp(1.2rem,2.4vw,2.2rem);margin-top:2.4rem;
}
.stat{border-top:2px solid var(--ink);padding-top:1.05rem;min-width:0}
.stat-num{
  font-family:var(--font-display);font-size:clamp(2.1rem,1.4rem + 3vw,3.9rem);
  font-weight:600;line-height:.95;letter-spacing:-.03em;
  font-variant-numeric:tabular-nums;display:block;
}
.stat.is-pending .stat-num{color:var(--ink-faint)}
.stat-lbl{
  margin-top:.7rem;font-size:.74rem;font-weight:700;letter-spacing:.09em;
  text-transform:uppercase;color:var(--ink-dim);line-height:1.4;
}
/* Dark-ground variants. The class vocabulary invites an impact grid inside a
   navy section, and without these it renders dark ink on dark navy. */
.sec-navy .stat,.sec-deep .stat{border-top-color:rgba(232,238,244,.55)}
.sec-navy .stat-lbl,.sec-deep .stat-lbl{color:#A9BDCE}
.sec-navy .stat.is-pending .stat-num,.sec-deep .stat.is-pending .stat-num{color:#6B7F91}

/* Pending-data marker. Deliberately visible: invented figures on a nonprofit
   site are a real hazard if screenshotted mid-build. */
.pending-tag{
  display:inline-flex;align-items:center;gap:.4rem;margin-top:.55rem;
  font-size:.62rem;font-weight:700;letter-spacing:.11em;text-transform:uppercase;
  color:var(--accent-dark);background:rgba(232,85,47,.09);
  border:1px dashed rgba(232,85,47,.42);padding:.2rem .5rem;border-radius:2px;
}
.sec-navy .pending-tag,.sec-deep .pending-tag{
  color:var(--accent-warm);background:rgba(242,166,90,.1);border-color:rgba(242,166,90,.45);
}

.attribution{
  margin-top:2.4rem;padding:1.25rem 1.35rem;background:var(--paper-dim);
  border-left:3px solid var(--sea);max-width:76ch;
  font-size:.98rem;color:var(--ink-dim);
}
.attribution strong{color:var(--ink);font-weight:700}
.sec-navy .attribution,.sec-deep .attribution{
  background:rgba(255,255,255,.05);border-left-color:var(--sea-pale);color:#A9BDCE;
}
.sec-navy .attribution strong,.sec-deep .attribution strong{color:#fff}

/* ---------- Split (credibility / mercy) ---------- */
.split{display:grid;grid-template-columns:1fr;gap:clamp(2.25rem,5vw,5rem);align-items:center}
.split-narrow{grid-template-columns:1fr}

/* ---------- Story ---------- */
.story-card{
  display:grid;grid-template-columns:1fr;gap:clamp(1.6rem,4vw,3.5rem);
  align-items:center;background:var(--paper-dim);padding:clamp(1.35rem,3.2vw,2.8rem);
  border:1px solid var(--paper-line);margin-top:2.4rem;
}
.sec-navy .story-card,.sec-deep .story-card{
  background:rgba(255,255,255,.04);border-color:rgba(232,238,244,.18);
}
.pullquote{
  font-family:var(--font-display);font-size:clamp(1.25rem,1rem + 1.5vw,2rem);
  font-weight:500;font-style:italic;line-height:1.32;letter-spacing:-.015em;
  color:var(--ink);margin:0 0 1.2rem;text-wrap:balance;
}
.sec-navy .pullquote,.sec-deep .pullquote{color:#fff}
.pullquote::before{content:'\201C'}
.pullquote::after{content:'\201D'}

/* Photo slot — a designed hole, not a broken image.
   Landscape by default: a 4/5 portrait slot stacked full-width on a phone is
   nearly a full screen of dashed placeholder. */
.photo-slot{
  position:relative;aspect-ratio:16/10;background:
    repeating-linear-gradient(135deg,var(--paper) 0 11px,var(--paper-dim) 11px 22px);
  border:2px dashed var(--paper-line);
  display:grid;place-items:center;text-align:center;padding:1.25rem;
}
.photo-slot.is-wide{aspect-ratio:16/10}
.sec-navy .photo-slot,.sec-deep .photo-slot{
  background:repeating-linear-gradient(135deg,rgba(255,255,255,.03) 0 11px,rgba(255,255,255,.06) 11px 22px);
  border-color:rgba(232,238,244,.24);
}
.photo-slot-inner{max-width:26ch}
.photo-slot svg{margin:0 auto .8rem;opacity:.4}
.photo-slot-t{
  font-size:.68rem;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  color:var(--ink-dim);margin-bottom:.4rem;
}
.photo-slot-d{font-size:.82rem;color:var(--ink-faint);line-height:1.5}
.sec-navy .photo-slot-t,.sec-deep .photo-slot-t{color:var(--sea-pale)}
.sec-navy .photo-slot-d,.sec-deep .photo-slot-d{color:#7D91A3}

/* ---------- How a mission works: plotted course ---------- */
.course{position:relative;margin-top:2.6rem}
/* The dashed rhumb line only makes sense joining nodes on ONE row, which only
   happens at 1080px. Below that it is hidden, not squashed. top:27px is the
   centre of the 54px node — the original 26px was 1px high. */
.course-line{
  display:none;
  position:absolute;top:27px;left:0;right:0;height:2px;
  background-image:linear-gradient(to right,var(--sea-pale) 0 9px,transparent 9px 18px);
  background-size:18px 2px;background-repeat:repeat-x;
  transform:scaleX(0);transform-origin:left;
  transition:transform 1.5s var(--ease);
}
.course.is-in .course-line{transform:scaleX(1)}
.course-steps{
  display:grid;grid-template-columns:1fr;gap:2rem;
  position:relative;z-index:2;
}
/* Base: node and copy side by side, so the list reads as a route down the
   page rather than five tall stacked blocks. */
.step{
  display:grid;grid-template-columns:54px 1fr;gap:1.1rem;align-items:start;
  opacity:0;transform:translateY(16px);
  transition:opacity .6s var(--ease),transform .6s var(--ease);
}
.course.is-in .step{opacity:1;transform:none}
.course.is-in .step:nth-child(1){transition-delay:.1s}
.course.is-in .step:nth-child(2){transition-delay:.22s}
.course.is-in .step:nth-child(3){transition-delay:.34s}
.course.is-in .step:nth-child(4){transition-delay:.46s}
.course.is-in .step:nth-child(5){transition-delay:.58s}
/* Explicit placement is load-bearing: .step has THREE children (node, h3, p)
   in a two-column grid, so without it the <p> flows onto row 2 and lands in
   the 54px icon column, rendering the copy about one character wide. The node
   spans both rows; both text children are pinned to column 2. */
.step-node{
  grid-column:1;grid-row:1 / span 2;
  width:54px;height:54px;border-radius:50%;background:var(--navy);
  border:2px solid var(--sea);display:grid;place-items:center;
  color:var(--sea-pale);margin-bottom:0;position:relative;flex:none;
}
.step-n{
  position:absolute;top:-7px;right:-7px;width:23px;height:23px;border-radius:50%;
  background:var(--accent);color:#fff;font-size:.7rem;font-weight:800;
  display:grid;place-items:center;font-family:var(--font-body);
}
.step h3{grid-column:2;font-size:1.02rem;font-weight:600;margin-bottom:.4rem;letter-spacing:-.005em}
/* Authored for a navy section; on paper the copy needs the ink ramp. */
.step p{grid-column:2;font-size:.88rem;color:#A9BDCE;line-height:1.55}
.sec-paper .step p{color:var(--ink-dim)}

/* ---------- Map ---------- */
/* The SVG keeps its own aspect ratio; if a viewBox forces it wider than the
   phone, the wrapper scrolls instead of the document. */
.map-wrap{
  margin-top:2.2rem;position:relative;
  overflow-x:auto;-webkit-overflow-scrolling:touch;overscroll-behavior-x:contain;
}
.map-svg{width:100%;min-width:0;height:auto;display:block}
.map-note{
  margin-top:1.2rem;font-size:.78rem;color:#7D91A3;
  display:flex;align-items:flex-start;gap:.55rem;max-width:70ch;line-height:1.55;
}
.map-note svg{flex:none}
.map-legend{display:flex;flex-wrap:wrap;gap:.5rem 1.4rem;margin-top:1.4rem;font-size:.8rem;color:#A9BDCE}
.map-legend span{display:flex;align-items:center;gap:.5rem;min-height:var(--tap)}
.sec-paper .map-legend{color:var(--ink-dim)}
.sec-paper .map-note{color:var(--ink-faint)}
.lg-dot{width:11px;height:11px;border-radius:50%;background:var(--accent);flex:none}
.lg-dot.is-port{background:var(--accent-warm)}

/* ---------- Four doors ---------- */
.doors{display:grid;grid-template-columns:1fr;gap:1rem;margin-top:2.4rem}
.door{
  display:flex;flex-direction:column;text-decoration:none;color:inherit;
  background:var(--paper);border:1px solid var(--paper-line);
  padding:1.5rem 1.35rem 1.35rem;position:relative;overflow:hidden;
  transition:transform .3s var(--ease),box-shadow .3s var(--ease),border-color .3s var(--ease);
}
.door::before{
  content:'';position:absolute;top:0;left:0;right:0;height:3px;
  background:var(--accent);transform:scaleX(0);transform-origin:left;
  transition:transform .35s var(--ease);
}
/* Touch feedback, since the lift is pointer-gated below. */
.door:active{border-color:var(--sea-pale)}
.door:active::before{transform:scaleX(1)}
.door-ico{color:var(--sea);margin-bottom:1rem}
.door h3{font-size:1.15rem;margin-bottom:.55rem}
.door p{font-size:.88rem;color:var(--ink-dim);line-height:1.55;flex:1}
.door-go{
  margin-top:1.15rem;font-size:.76rem;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--accent-dark);
  display:flex;align-items:center;gap:.45rem;min-height:var(--tap);
}
.door-go .arw{transition:transform .25s var(--ease);flex:none}

/* ---------- Footer ---------- */
.site-foot{
  background:var(--navy-deep);color:#8FA3B5;font-size:.88rem;
  padding-top:clamp(2.75rem,7vw,5rem);
  padding-bottom:calc(2rem + env(safe-area-inset-bottom));
}
.foot-top{display:grid;grid-template-columns:1fr;gap:2rem;padding-bottom:2.2rem;border-bottom:1px solid rgba(143,163,181,.18)}
.foot-brand .brand{margin-bottom:1rem}
.foot-brand p{max-width:38ch;line-height:1.6;color:#7D91A3}
.foot-col h4{font-size:.72rem;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:#C9D8E4;margin-bottom:.8rem;font-family:var(--font-body)}
.foot-col li{margin-bottom:0}
.foot-col a{
  display:flex;align-items:center;min-height:var(--tap);
  text-decoration:none;color:#8FA3B5;transition:color .2s var(--ease);
}
.foot-bot{padding-top:1.8rem;display:flex;flex-wrap:wrap;gap:1.2rem 2.5rem;justify-content:space-between;align-items:flex-start}
.foot-legal{max-width:66ch;font-size:.78rem;line-height:1.65;color:#6B7F91}
/* Status is pending — must not read as a granted determination. */
.legal-badge{
  display:inline-block;margin-bottom:.8rem;font-size:.66rem;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;color:var(--accent-warm);
  border:1px solid rgba(242,166,90,.4);padding:.28rem .6rem;border-radius:2px;
}

/* ---------- Inner pages ---------- */
.page-head{
  background:var(--navy-deep);color:#fff;position:relative;overflow:hidden;
  padding-top:clamp(2.25rem,6vw,4.5rem);
  padding-bottom:clamp(2.5rem,7vw,5.5rem);
}
.page-head::before{
  content:'';position:absolute;inset:0;color:#fff;pointer-events:none;
  background-image:
    repeating-linear-gradient(to right,currentColor 0 1px,transparent 1px 60px),
    repeating-linear-gradient(to bottom,currentColor 0 1px,transparent 1px 60px);
  opacity:.05;
}
.page-head .wrap{position:relative;z-index:2}
.page-head h1{font-size:clamp(1.95rem,1.4rem + 2.8vw,3.5rem);max-width:17ch}
.page-head .sec-lede{color:#A9BDCE;margin-top:1.2rem}
.crumb{display:flex;flex-wrap:wrap;align-items:center;gap:.55rem;font-size:.78rem;color:var(--sea-pale);margin-bottom:1.2rem}
.crumb a{display:inline-flex;align-items:center;min-height:var(--tap);text-decoration:none;color:var(--sea-pale)}

.prose{max-width:68ch}
.prose h2{font-size:clamp(1.4rem,1.2rem + 1.2vw,2.1rem);margin:2.4rem 0 .9rem}
.prose h2:first-child{margin-top:0}
.prose h3{font-size:1.15rem;margin:1.9rem 0 .65rem}
.prose ul{list-style:none;margin:0 0 1.2em}
/* Prose keeps genuine ordered-list semantics and markers. */
.prose ol{list-style:decimal;margin:0 0 1.2em;padding-left:1.4rem}
.prose ol li{margin-bottom:.55rem;color:var(--ink-dim)}
.prose ul li{position:relative;padding-left:1.5rem;margin-bottom:.55rem;color:var(--ink-dim)}
.prose ul li::before{content:'';position:absolute;left:0;top:.62em;width:7px;height:7px;background:var(--sea);border-radius:50%}
/* A wide table is the other classic source of sideways scroll on a phone.
   Let the table scroll inside itself; never the page. */
.prose table{display:block;width:100%;max-width:100%;overflow-x:auto;border-collapse:collapse;-webkit-overflow-scrolling:touch}
.prose td,.prose th{padding:.6rem .8rem;border-bottom:1px solid var(--paper-line);text-align:left;vertical-align:top}
.prose pre,.prose code{overflow-wrap:anywhere;white-space:pre-wrap}

/* Placeholder block for content the organization hasn't supplied yet */
.tbd{
  border:2px dashed var(--paper-line);background:var(--paper-dim);
  padding:1.25rem 1.35rem;margin:1.5rem 0;
}
.tbd-t{
  font-size:.68rem;font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--accent-dark);margin-bottom:.6rem;display:flex;align-items:center;gap:.45rem;
}
.tbd p{font-size:.92rem;color:var(--ink-dim);margin:0}

.callout{
  background:var(--navy);color:#E8EEF4;padding:clamp(1.35rem,3.5vw,2.6rem);
  margin:2.2rem 0;border-left:3px solid var(--accent);
}
.callout h3{color:#fff;margin-bottom:.8rem;font-size:1.22rem}
.callout p{color:#A9BDCE;margin-bottom:1.2rem}

.side-grid{display:grid;grid-template-columns:1fr;gap:clamp(2.25rem,5vw,4.5rem);align-items:start}
.side-card{background:var(--paper-dim);border:1px solid var(--paper-line);padding:1.4rem;position:static;top:auto}
.side-card h4{font-size:.72rem;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--ink-dim);margin-bottom:.8rem;font-family:var(--font-body)}
.side-card li{margin-bottom:0;font-size:.9rem}
.side-card a{
  display:flex;align-items:center;min-height:var(--tap);
  color:var(--ink);text-decoration:none;
  border-bottom:1px solid var(--paper-line);transition:border-color .2s var(--ease);
}

/* Inline mailto links ignore min-height (they are inline boxes), so the
   contact address failed the 44px touch minimum everywhere it appeared.
   inline-flex gives the box a real height without disturbing text flow. */
a[href^="mailto:"]{
  display:inline-flex;align-items:center;min-height:44px;
  padding-block:.35rem;
}
@media (min-width:720px){
  a[href^="mailto:"]{min-height:0;padding-block:0}
}

/* ---------- Scroll reveal ----------
   main.js adds .is-in. If the script never loads, or throws, the reveal is
   force-completed there — content must never stay hidden on a JS failure. */
.rv{opacity:0;transform:translateY(22px);transition:opacity .75s var(--ease),transform .75s var(--ease)}
.rv.is-in{opacity:1;transform:none}
.rv-d1{transition-delay:.1s}.rv-d2{transition-delay:.2s}
.rv-d3{transition-delay:.3s}.rv-d4{transition-delay:.4s}

/* ==========================================================================
   Layered layouts — min-width only
   ========================================================================== */

/* --- 480px: the first grid the phone can actually hold --- */
@media (min-width:480px){
  .impact-grid{grid-template-columns:repeat(2,1fr)}
  .hero-cta{flex-direction:row;flex-wrap:wrap;align-items:center;gap:.9rem}
  .hero-cta .btn{flex:0 1 auto}
  .plate-cap{flex-wrap:nowrap}
}

/* --- 600px: two-up cards --- */
@media (min-width:600px){
  .doors{grid-template-columns:repeat(2,1fr);gap:1.2rem}
  .foot-top{grid-template-columns:1fr 1fr;gap:2.2rem}
}

/* --- 720px: the drawer becomes a nav bar --- */
@media (min-width:720px){
  .nav{
    position:static;inset:auto;z-index:auto;
    flex-direction:row;align-items:center;justify-content:flex-end;
    gap:2rem;
    background:none;padding:0;
    overflow:visible;min-height:0;
    visibility:visible;transform:none;transition:none;
  }
  .nav a{display:inline-flex;font-size:.88rem;min-height:0;padding-block:.3rem}
  .nav .btn{margin-top:0;padding:.6rem 1.1rem;font-size:.82rem;min-height:38px}
  .nav-toggle,.nav-close{display:none}
  /* The drawer cannot be open at this width; clear any stale lock. */
  body.nav-open{overflow:visible}

  .site-head{padding-top:calc(1.4rem + env(safe-area-inset-top));padding-bottom:1.4rem}
  .head-inner{gap:1.5rem}
  .brand{gap:.8rem}
  .brand-name{font-size:1.06rem}
  .brand-sub{font-size:.62rem;letter-spacing:.19em}

  .impact-grid{grid-template-columns:repeat(3,1fr);gap:2.4rem clamp(1.2rem,2.4vw,2.2rem)}

  /* Three across: the node returns to sitting above its copy. */
  .course-steps{grid-template-columns:repeat(3,1fr);gap:2.6rem clamp(1rem,2.2vw,2rem)}
  .step{display:block}
  .step-node{margin-bottom:1.35rem}
  .step h3{font-size:1.06rem;margin-bottom:.5rem}

  .attribution{margin-top:3rem;padding:1.5rem 1.7rem;font-size:1.02rem}

  /* Hit boxes relax back to the intended desktop density. */
  .foot-col a,.side-card a{display:inline-flex;min-height:0}
  .crumb a{min-height:0}
  .map-legend span{min-height:0}
  .door-go{min-height:0;margin-top:1.3rem;font-size:.78rem}
  .foot-col li{margin-bottom:.6rem}
  .side-card li{margin-bottom:.7rem}
}

/* --- 900px: the editorial two-column layouts --- */
@media (min-width:900px){
  .hero-grid{grid-template-columns:1.03fr .97fr}
  .split{grid-template-columns:1fr 1fr}
  .split-narrow{grid-template-columns:.95fr 1.05fr}
  .story-card{grid-template-columns:.85fr 1.15fr;margin-top:3rem}
  .side-grid{grid-template-columns:1fr 320px}
  .side-card{position:sticky;top:2rem;padding:1.7rem}

  .plate{max-width:640px;margin-left:auto}
  /* Inside a prose column a right-aligned plate leaves a void beside a photo
     narrower than the box (the source photos are ~400px). Align left and let
     the box shrink to the image. */
  .prose .plate{max-width:100%;margin-left:0;width:fit-content}
  .photo-slot{aspect-ratio:4/5}
  .photo-slot.is-wide{aspect-ratio:16/10}

  .hero-kicker{font-size:.72rem;margin-bottom:1.7rem}
  .hero-kicker::before{width:34px}
  .hero-deck{margin-top:1.6rem}
  .hero-cta{margin-top:2.4rem}
  .sec-lede{margin-top:1.4rem}
  .doors{gap:1.4rem;margin-top:3.2rem}
  .door{padding:1.9rem 1.6rem 1.7rem}
  .door h3{font-size:1.22rem}
  .map-wrap{margin-top:3rem}
  .course{margin-top:3.6rem}
  .impact-grid{margin-top:3.2rem}
  .callout{margin:2.6rem 0}
  .prose h2{margin:3rem 0 1rem}
  .prose h2:first-child{margin-top:0}
  .prose h3{margin:2.2rem 0 .7rem}
  .page-head{padding-top:clamp(3rem,6vw,4.5rem);padding-bottom:clamp(3.5rem,7vw,5.5rem)}
  .crumb{margin-bottom:1.6rem}
  .foot-top{padding-bottom:3rem}
  .foot-bot{padding-top:2rem}
  .tbd{padding:1.5rem 1.7rem;margin:1.6rem 0}
}

/* --- 1080px: the full five-across card --- */
@media (min-width:1080px){
  .impact-grid{grid-template-columns:repeat(5,1fr)}
  .doors{grid-template-columns:repeat(4,1fr)}
  .foot-top{grid-template-columns:1.5fr 1fr 1fr 1fr;gap:2.5rem}
  .course-steps{grid-template-columns:repeat(5,1fr)}
  /* Five nodes on one row — now the rhumb line has something to join. */
  .course-line{display:block}
  .course.is-in .step:nth-child(1){transition-delay:.15s}
  .course.is-in .step:nth-child(2){transition-delay:.38s}
  .course.is-in .step:nth-child(3){transition-delay:.61s}
  .course.is-in .step:nth-child(4){transition-delay:.84s}
  .course.is-in .step:nth-child(5){transition-delay:1.07s}
  /* Original chart spacing returns once there is room to read it. */
  .chart-grid::before,.hero::before,.page-head::before{
    background-image:
      repeating-linear-gradient(to right,currentColor 0 1px,transparent 1px 90px),
      repeating-linear-gradient(to bottom,currentColor 0 1px,transparent 1px 90px);
  }
}

/* ==========================================================================
   Hover — pointer-gated
   A tap on a touch device latches :hover on the element until the next tap
   elsewhere, so every lift, slide and colour shift is scoped to devices that
   actually have a pointer. :active and :focus-visible stay unconditional.
   ========================================================================== */
@media (hover:hover) and (pointer:fine){
  .btn:hover{transform:translateY(-2px)}
  .btn-primary:hover{background:var(--accent-dark);border-color:var(--accent-dark)}
  .btn-ghost:hover{border-color:#E8EEF4;background:rgba(232,238,244,.08)}
  .btn-ghost-ink:hover{border-color:var(--ink);background:rgba(22,33,46,.04)}
  .btn:hover .arw{transform:translateX(4px)}

  .nav a:hover{color:#fff}
  .nav a:hover::after{transform:scaleX(1)}
  .nav-close:hover{color:#fff}

  .door:hover{transform:translateY(-5px);box-shadow:0 20px 44px rgba(11,37,69,.13);border-color:var(--sea-pale)}
  .door:hover::before{transform:scaleX(1)}
  .door:hover .door-go .arw{transform:translateX(4px)}

  .foot-col a:hover{color:#fff}
  .crumb a:hover{color:#fff;text-decoration:underline}
  .side-card a:hover{border-color:var(--accent)}
}

/* ---------- Motion / print ---------- */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;transition-duration:.01ms!important;transition-delay:0ms!important}
  .rv,.step{opacity:1;transform:none}
  .course-line{transform:scaleX(1)}
  .grain::after{display:none}
  /* The drawer still moves — it just moves instantly. */
  .nav{transition:none}
}
@media print{
  .site-head,.nav,.nav-toggle,.nav-close,.skip-link,.hero::after,.grain::after,.door-go{display:none}
  html,body{overflow:visible}
  body{background:#fff;color:#000}
  body.nav-open{overflow:visible}
  .section{padding-block:1.5rem}
  .sec-navy,.sec-deep,.hero,.page-head,.site-foot,.callout{background:#fff!important;color:#000!important}
  .rv,.step{opacity:1!important;transform:none!important}
  .course-line{transform:none!important}
  a[href]::after{content:' (' attr(href) ')';font-size:.8em;color:#555}
}
