/* ============================================================================
   Stock the Block — shared design system
   ----------------------------------------------------------------------------
   Every rule in this file is byte-identical across index.html and
   getting-started.html. Rules that differ between the two pages stay inline in
   that page, in a <style> block that loads AFTER this file so the page-specific
   version wins the cascade.

   Custom property names and values are carried over verbatim. Do not rename,
   consolidate or "tidy" them — page CSS and inline SVG both read them by name.
   ============================================================================ */

:root {
  --bg:#F5F5F7; --surface:#FFFFFF; --tint:#EAF2DE; --text:#1D1D1F; --text-secondary:#6C6C70;
  --rule:#DDDDDD; --brand:#2E5A22; --accent:#E8871E; --mascot-fill:#EAF2DE; --mascot-stroke:#2E5A22;
  /* --accent is the brand orange and stays exactly as it was — it paints the
     mascot's mouth and the chart marks. But at 2.31:1 on --tint it cannot
     legally carry text, so accent-coloured TEXT uses --accent-text instead:
     the same hue darkened to the minimum that clears AA on all three light
     grounds. In dark and stock the accent already passes, so there the two
     tokens are the same colour. */
  --accent-text:#9F5D15;
  /* Placeholder text. Measured to clear 4.5:1 on --surface in each theme. */
  --placeholder:#5A5A5E;
  --on-brand:#FFFFFF; --brand-press:#234618;
  --line:rgba(29,29,31,0.12); --line-soft:rgba(29,29,31,0.08);
  --brand-line:rgba(46,90,34,0.25); --brand-line-soft:rgba(46,90,34,0.12); --brand-line-mid:rgba(46,90,34,0.35);
  --nav-bg:rgba(245,245,247,0.72);
  --sensor-shell:#6B4C9A; --sensor-board:#513A75; --sensor-deep:#3D2B5C;
  --paper-shadow:rgba(29,29,31,0.13); --paper-y:8px; --paper-blur:15px; --grain-op:0.05;
  /* Interior of the hero box, revealed as the lid hinges open. A darker
     shade of --mascot-fill; never a new colour and never contents. */
  /* Front / side / interior, lightest to darkest, one light direction.
     Three shades of one colour; never a new hue and never contents. */
  --box-side:#D6E5C4; --box-interior:#C6D9B0;
  /* The specular sweep. White at low alpha so it lifts whatever it crosses. */
  --box-shine:rgba(255,255,255,0.72);
  /* Ice: the what-if ice pack and its frost. A cold blue that reads on each
     theme's ground; the only non-brand hue, and only on the food-safety chart. */
  --ice:#2F6FA8; --ice-soft:rgba(47,111,168,0.10);
}
/* Three modes: light (above, untouched), dark, and stock. The system
   preference decides only when the reader has made no explicit choice — hence
   :not([data-theme]) rather than :not([data-theme="light"]), which would also
   have caught the opt-in stock mode. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) {
    --bg:#14170F; --surface:#1C2016; --tint:#252B1D; --text:#F0F2EC; --text-secondary:#9BA093;
    --rule:#333A28; --brand:#8FBF6F; --accent:#F0A040; --accent-text:#F0A040; --mascot-fill:#252B1D; --mascot-stroke:#8FBF6F;
    --on-brand:#14170F; --brand-press:#A5D186;
    --line:rgba(240,242,236,0.14); --line-soft:rgba(240,242,236,0.08);
    --brand-line:rgba(143,191,111,0.32); --brand-line-soft:rgba(143,191,111,0.15); --brand-line-mid:rgba(143,191,111,0.42);
    --nav-bg:rgba(20,23,15,0.72);
    --sensor-shell:#8C6FC0; --sensor-board:#6B4C9A; --sensor-deep:#513A75;
    --paper-shadow:rgba(0,0,0,0.62); --paper-y:4px; --paper-blur:8px; --grain-op:0.08;
    --box-side:#1D2216; --box-interior:#141810;
    --box-shine:rgba(240,242,236,0.30);
    --placeholder:#9BA093;
    --ice:#BFE0FF; --ice-soft:rgba(190,225,255,0.14);
  }
}
:root[data-theme="dark"] {
  --bg:#14170F; --surface:#1C2016; --tint:#252B1D; --text:#F0F2EC; --text-secondary:#9BA093;
  --rule:#333A28; --brand:#8FBF6F; --accent:#F0A040; --accent-text:#F0A040; --mascot-fill:#252B1D; --mascot-stroke:#8FBF6F;
  --on-brand:#14170F; --brand-press:#A5D186;
  --line:rgba(240,242,236,0.14); --line-soft:rgba(240,242,236,0.08);
  --brand-line:rgba(143,191,111,0.32); --brand-line-soft:rgba(143,191,111,0.15); --brand-line-mid:rgba(143,191,111,0.42);
  --nav-bg:rgba(20,23,15,0.72);
  --sensor-shell:#8C6FC0; --sensor-board:#6B4C9A; --sensor-deep:#513A75;
  --paper-shadow:rgba(0,0,0,0.62); --paper-y:4px; --paper-blur:8px; --grain-op:0.08;
  --box-side:#1D2216; --box-interior:#141810;
  --box-shine:rgba(240,242,236,0.30);
  --placeholder:#9BA093;
  --ice:#BFE0FF; --ice-soft:rgba(190,225,255,0.14);
}
/* Stock — brand mode. Forest-green ground, cream text, orange accent.
   The hues are the site's own two brand colours; nothing new is introduced.

   The exact --brand green (#2E5A22) cannot serve as the text-bearing ground:
   against it the palette's oranges reach only 3.04:1 (#E8871E) and 3.77:1
   (#F0A040), short of the 4.5:1 this mode has to clear. So the ground is the
   palette's own darker forest, --brand-press #234618, over one darker shade of
   the same hue for the page behind it — and the accent is #F0A040, the orange
   the dark theme already uses. Every pair below clears WCAG AA. */
:root[data-theme="stock"] {
  --bg:#1B3511; --surface:#234618; --tint:#234618; --text:#EAF2DE; --text-secondary:#C4C9BC;
  --rule:#3D6B2E; --brand:#8FBF6F; --accent:#F0A040; --accent-text:#F0A040; --mascot-fill:#234618; --mascot-stroke:#8FBF6F;
  --on-brand:#1B3511; --brand-press:#A5D186;
  --line:rgba(234,242,222,0.16); --line-soft:rgba(234,242,222,0.09);
  --brand-line:rgba(143,191,111,0.34); --brand-line-soft:rgba(143,191,111,0.18); --brand-line-mid:rgba(143,191,111,0.46);
  --nav-bg:rgba(27,53,17,0.74);
  --sensor-shell:#8C6FC0; --sensor-board:#6B4C9A; --sensor-deep:#513A75;
  --paper-shadow:rgba(0,0,0,0.55); --paper-y:4px; --paper-blur:8px; --grain-op:0.07;
  --box-side:#1B3612; --box-interior:#132608;
  --box-shine:rgba(234,242,222,0.32);
  --placeholder:#B9BFB0;
  --ice:#BFE0FF; --ice-soft:rgba(190,225,255,0.14);
}
@media (prefers-contrast: more) {
  :root {
    --rule:#55565A; --line:rgba(29,29,31,0.55); --line-soft:rgba(29,29,31,0.32);
    --text-secondary:#4A4A4F; --tint:#FFFFFF;
    --brand-line:rgba(46,90,34,0.75); --brand-line-soft:rgba(46,90,34,0.42); --brand-line-mid:rgba(46,90,34,0.85);
    --paper-shadow:rgba(29,29,31,0.5); --grain-op:0;
  }
  :root[data-theme="dark"] { --rule:#6E7566; --line:rgba(240,242,236,0.5); --line-soft:rgba(240,242,236,0.3); --text-secondary:#C4C9BC; --tint:#14170F; }
  :root[data-theme="stock"] { --rule:#7FA96C; --line:rgba(234,242,222,0.5); --line-soft:rgba(234,242,222,0.3); --text-secondary:#EAF2DE; --brand-line:rgba(143,191,111,0.75); --brand-line-soft:rgba(143,191,111,0.42); --brand-line-mid:rgba(143,191,111,0.85); --grain-op:0; }
}

/* Theme control. A labelled button showing the mode it will switch to next;
   the change itself is announced through a visually hidden live region. */
#themeToggle { display:inline-flex; align-items:center; gap:7px; min-height:36px; padding:0 10px; background:none; border:1px solid var(--line); border-radius:999px; cursor:pointer; color:var(--text); font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-weight:600; font-size:13px; letter-spacing:0; transition:border-color 180ms ease, color 180ms ease; }
#themeToggle:hover { border-color:var(--brand-line-mid); color:var(--brand); }
#themeToggle .theme-name { line-height:1; }
#themeToggle svg { flex:none; }
.vh { position:absolute; width:1px; height:1px; margin:-1px; padding:0; overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap; border:0; }
* { box-sizing: border-box; }
body { margin:0; background:var(--bg); color:var(--text); font-family:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif; -webkit-font-smoothing:antialiased; }
html[data-theme-anim] body, html[data-theme-anim] nav, html[data-theme-anim] section, html[data-theme-anim] footer, html[data-theme-anim] .manifest, html[data-theme-anim] input, html[data-theme-anim] textarea, html[data-theme-anim] select { transition:background-color 200ms ease, color 200ms ease; }
a { color:var(--brand); text-decoration:none; transition:color 200ms ease; }
a:hover { color:var(--accent-text); }
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible { outline:2px solid var(--brand); outline-offset:2px; }
::selection { background:var(--tint); color:var(--brand); }
.mono { font-family:'DM Mono',ui-monospace,Menlo,monospace; }
.wrap { max-width:1100px; margin:0 auto; padding:0 24px; }
.body-p { font-size:20px; line-height:1.65; max-width:60ch; color:var(--text); text-wrap:pretty; }
.skip-link { position:fixed; top:10px; left:10px; z-index:200; background:var(--brand); color:var(--on-brand); font-weight:600; font-size:14px; padding:12px 18px; border-radius:8px; transform:translateY(-80px); transition:transform 150ms ease; }
.skip-link:focus { transform:translateY(0); color:var(--on-brand); }
@keyframes fadeUp { from{opacity:0;transform:translateY(24px)} to{opacity:1;transform:translateY(0)} }
@keyframes riseIn { from{transform:translateY(110%)} to{transform:translateY(0)} }
@keyframes blinkL { 0%,95.5%,100%{transform:scaleY(1)} 97%{transform:scaleY(0.1)} 98.5%{transform:scaleY(1)} }
@keyframes blinkR { 0%,96%,100%{transform:scaleY(1)} 97.5%{transform:scaleY(0.1)} 99%{transform:scaleY(1)} }
@keyframes lidBreathe { 0%,100%{transform:translateY(0)} 50%{transform:translateY(-1.5px)} }
@keyframes squashIn { from{transform:scale(0.94,1.06)} to{transform:scale(1,1)} }
nav.bar { position:fixed; top:0; left:0; right:0; z-index:50; height:48px; background:var(--nav-bg); backdrop-filter:saturate(180%) blur(20px); -webkit-backdrop-filter:saturate(180%) blur(20px); border-bottom:1px solid var(--line); opacity:0; pointer-events:none; transition:opacity 200ms ease; }
nav.bar.on { opacity:1; pointer-events:auto; }
nav.bar .wrap { height:48px; display:flex; align-items:center; justify-content:space-between; gap:16px; }
nav.bar a.brand { display:flex; align-items:center; gap:10px; color:var(--text); font-weight:600; font-size:14px; }
nav.bar .links { display:flex; align-items:center; gap:14px; font-size:14px; }
/* Every link here is a plain <a>, so the browser already shows a pointer —
   this is the "add a little pop, don't make it disappear" hover the video
   argues for: a hairline underline that grows in, no colour swap, no motion. */
nav.bar .links a { color:var(--text); text-decoration:none;
  background-image:linear-gradient(var(--text), var(--text));
  background-repeat:no-repeat; background-position:0 100%; background-size:0% 1px;
  transition:background-size 160ms ease; padding-bottom:2px; }
nav.bar .links a:hover, nav.bar .links a:focus-visible { background-size:100% 1px; }
nav.bar .links a[aria-current="true"]:hover { background-size:0% 1px; }
nav.bar .links a.cta { color:var(--brand); font-weight:600;
  background-image:linear-gradient(var(--brand), var(--brand)); }
#themeToggle { width:44px; height:44px; display:flex; align-items:center; justify-content:center; background:none; border:none; cursor:pointer; color:var(--text); padding:0; }
/* Phones and tablets: the menu bar on one line on every page, including the
   ones that don't load design.css — logo, Sign in, the theme switch and the
   menu button. Below about 800px the full row of links no longer fits on one
   line, and wrapped words looked broken, so the links move into the menu. */
@media (max-width:800px) {
  nav.bar .links a:not(.login) { display:none; }
  nav.bar .links { gap:4px; }
  nav.bar a.brand, nav.bar .links a { white-space:nowrap; }
  #themeToggle .theme-name { display:none; }
}
.eyebrow { font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-weight:700; font-size:14px; letter-spacing:0; color:var(--text-secondary); margin:0 0 12px; }
h1, h2 { font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-weight:700; letter-spacing:-0.035em; line-height:1.12; }
h2.hd { font-size:clamp(30px,4.1vw,39px); color:var(--brand); margin:0; }
.mask-l { display:block; overflow:hidden; }
.mask-l > span { display:block; }
.btn { font-size:19px; font-weight:600; padding:12px 24px; border-radius:8px; display:inline-block; }
.btn.solid { background:var(--brand); color:var(--on-brand); transition:background-color 200ms ease; }
.btn.solid:hover { background:var(--brand-press); color:var(--on-brand); }
/* A secondary button on the light-green card needs its own ground, or the
   outline alone leaves it floating in the tint. */
.btn.line { color:var(--brand); background:var(--surface); border:1.5px solid var(--brand-line-mid); transition:color 200ms ease, border-color 200ms ease, background-color 200ms ease; }
.btn.line:hover { border-color:var(--brand); color:var(--brand-press); background:var(--tint); }
.prow { border-bottom:1px solid var(--line); }
.prow .num { grid-area:num; font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-size:14px; color:var(--text-secondary); }
.prow .ttl { grid-area:ttl; display:flex; align-items:center; gap:10px; font-size:19px; font-weight:600; color:var(--text); }
.step-icon { flex:none; color:var(--brand); }
.prow .caret { grid-area:caret; font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-size:14px; color:var(--text-secondary); justify-self:end; }
.prow .pdetail { display:grid; grid-template-rows:0fr; transition:grid-template-rows 300ms ease; }
.prow.open .pdetail { grid-template-rows:1fr; }
.prow .pdetail > div { overflow:hidden; }
.cards-grid .card p.body { font-size:17px; line-height:1.6; color:var(--text); margin:0; }
form.join { display:grid; grid-template-columns:1fr 1fr; gap:14px; }
form.join input, form.join select, form.join textarea { border:1px solid var(--line); background:var(--bg); padding:12px 14px; font-size:14px; font-family:inherit; border-radius:8px; transition:border-color 200ms ease; color:var(--text); }
form.join input:focus, form.join textarea:focus { border-color:var(--brand); }
form.join .span2 { grid-column:span 2; }
form.join textarea { resize:none; }
form.join button { grid-column:span 2; justify-self:start; font-size:19px; font-weight:600; font-family:inherit; background:var(--brand); color:var(--on-brand); border:none; padding:12px 26px; border-radius:8px; cursor:pointer; transition:background-color 200ms ease; }
form.join button:hover { background:var(--brand-press); }
footer { background:var(--bg); border-top:1px solid var(--line); }
footer .wrap.top { padding:32px 24px 12px; display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:16px; font-size:14px; color:var(--text-secondary); }
/* Footer page index: every deeper page is one click from any page. */
footer .foot-links { display:flex; flex-wrap:wrap; gap:8px 22px; padding:4px 24px 20px; font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-weight:600; font-size:14px; }
footer .foot-links a { color:var(--brand); text-decoration:none; }
footer .foot-links a:hover { color:var(--accent-text); text-decoration:underline; }
/* Header for the deeper pages (tracking, why, team). */
.page-head { padding-top:88px; padding-bottom:48px; max-width:820px; }
.page-back { display:inline-block; font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-weight:600; font-size:14px; margin:0 0 20px; }
.page-head h1 { font-size:clamp(32px,5vw,48px); margin:0; color:var(--text); }
.page-head .body-p { margin:16px 0 0; max-width:60ch; }
@media (max-width:640px) { .page-head { padding-top:72px; padding-bottom:32px; } }
footer .privacy { padding:0 24px 28px; font-size:13px; color:var(--text-secondary); max-width:1100px; margin:0 auto; }
footer .privacy a { color:var(--text-secondary); text-decoration:underline; text-underline-offset:2px; }
footer .privacy a:hover { color:var(--brand); }

/* ---------------------------------------------------------------------------
   Unverified-claim flag. Phase 2 rewrote four claims the project cannot yet
   substantiate into explicit future/conditional voice. Each rewritten phrase
   is wrapped in .unverified so it stays visible during review rather than
   quietly reading as fact. Accent-orange, per the existing palette — no new
   colour is introduced.
   --------------------------------------------------------------------------- */
/* A dotted orange underline, offset clear of descenders: it flags the claim
   without the highlighter block the tinted background used to paint. */
.unverified { color:var(--accent-text); text-decoration-line:underline; text-decoration-style:dotted;
  text-decoration-color:var(--accent); text-decoration-thickness:1.5px; text-underline-offset:4px; }

/* Planned operations. One list for every school, filtered by status, rather
   than three hand-kept tiers. The status is on the row, so a school can never
   appear without one — which is the promise the old tier headings made
   structurally and this one makes per record. */
/* Filter bar. Two radiogroups stacked read as one repeated control unless
   each is named and the second is visually subordinate, which is what the
   label column and the lighter borough pills do. */
.filter-bar { display:grid; gap:10px; margin:0 0 22px; }
.filter-group { display:grid; grid-template-columns:74px minmax(0,1fr); align-items:center; gap:12px; }
.filter-label { font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  font-weight:700; font-size:11px; letter-spacing:0.09em; text-transform:uppercase; color:var(--text-secondary); }
.site-filter { display:flex; flex-wrap:wrap; gap:6px; margin:0; }
.site-filter-opt { position:relative; display:inline-flex; }
.site-filter-opt input { position:absolute; inset:0; width:100%; height:100%; margin:0; opacity:0; cursor:pointer; }
.site-filter-opt > span { display:inline-flex; align-items:center; gap:6px;
  font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  font-weight:600; font-size:12.5px; line-height:1; padding:7px 12px; border-radius:8px;
  border:1px solid transparent; color:var(--text-secondary); background:var(--surface);
  transition:background-color 140ms ease, color 140ms ease; }
.site-filter-opt > span .count { font-weight:500; font-size:11.5px; color:var(--text-secondary);
  font-variant-numeric:tabular-nums; }
.site-filter-opt:hover > span { color:var(--text); background:var(--tint); }
.site-filter-opt input:checked + span { background:var(--brand); color:var(--on-brand); border-color:var(--brand); }
.site-filter-opt input:checked + span .count { color:var(--on-brand); opacity:0.75; }
.site-filter-opt input:focus-visible + span { outline:2px solid var(--brand); outline-offset:2px; }
/* The borough row is a refinement of the status row, so it sits a step back. */
#sitesBoroughFilter .site-filter-opt > span { font-weight:500; background:transparent; }
#sitesBoroughFilter .site-filter-opt input:checked + span { background:var(--tint); color:var(--brand); border-color:var(--brand-line-mid); font-weight:700; }
#sitesBoroughFilter .site-filter-opt input:checked + span .count { color:var(--brand); }
@media (max-width:560px) {
  .filter-group { grid-template-columns:minmax(0,1fr); gap:6px; }
}

/* School tracker. Two rows per card and nothing stretchy between them: the
   name, then borough and status on one baseline. The previous version used a
   1fr middle track, which left every card two-thirds empty. */
.site-rows { list-style:none; margin:0; padding:0; display:grid;
  grid-template-columns:repeat(auto-fit,minmax(228px,1fr)); gap:12px; align-items:stretch; }
.site-row { display:grid; grid-template-columns:minmax(0,1fr) auto;
  grid-template-areas:"nm nm" "meta status"; align-items:end; gap:12px;
  background:var(--surface); border:1px solid var(--brand-line-soft); border-radius:8px;
  padding:14px 15px 13px; color:var(--text);
  animation:siteRowIn 420ms cubic-bezier(0.16,1,0.3,1) both;
  transition:border-color 140ms ease, background-color 140ms ease; }
.site-row:hover { border-color:var(--brand-line-mid); background:var(--tint); }
.site-row .nm { grid-area:nm; min-width:0;
  font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  font-weight:600; font-size:15.5px; line-height:1.3; letter-spacing:-0.01em; text-wrap:balance; }
.site-row .meta { grid-area:meta; display:flex; flex-wrap:wrap; align-items:center; gap:6px; min-width:0; }
.site-row .boro { font-size:13px; color:var(--text-secondary); }
.site-row .tag { font-size:10.5px; font-weight:600; color:var(--text-secondary);
  background:var(--bg); border-radius:999px; padding:2px 7px; }
.site-row .status { grid-area:status; justify-self:end; white-space:nowrap;
  font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  font-size:10px; font-weight:700; letter-spacing:0.04em; text-transform:uppercase;
  padding:3px 8px; border-radius:4px; }
.site-row .status.s-setup, .site-row .status.s-active { color:var(--on-brand); background:var(--brand); }
.site-row .status.s-conversation { color:var(--brand); background:var(--tint); border:1px solid var(--brand-line-mid); }
.site-row .status.s-target { color:var(--text-secondary); background:transparent; border:1px dashed var(--line); }
@media (max-width:420px) { .site-rows { grid-template-columns:1fr; } }
.site-empty { font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-size:14px; color:var(--text-secondary); margin:0; padding:22px 0; }
@keyframes siteRowIn { from { opacity:0; transform:translateY(8px); } to { opacity:1; transform:none; } }


/* Scroll-in utility. Paired with STB.initScrollFx: the resting state is the
   finished one, so anything the observer never reaches (JS off, no
   IntersectionObserver, reduced motion) still reads correctly. */
.fade-in-up, .fade-in { will-change:opacity, transform; }
.fade-in-up { opacity:0; transform:translateY(20px); transition:opacity 600ms cubic-bezier(0.16,1,0.3,1), transform 600ms cubic-bezier(0.16,1,0.3,1); }
.fade-in { opacity:0; transition:opacity 600ms ease-out; }
.fade-in-up.visible, .fade-in.visible { opacity:1; transform:none; }
.fade-in-up.visible, .fade-in.visible { will-change:auto; }
@media (prefers-reduced-motion: reduce) {
  .fade-in-up, .fade-in { opacity:1 !important; transform:none !important; transition:none !important; }
  .site-row { animation:none !important; }
}
html.no-js .fade-in-up, html.no-js .fade-in { opacity:1; transform:none; }
/* !important because the reveal code sets an inline transition, and the
   stat cells carry an inline transition-delay in the markup; both would
   otherwise re-animate the jump from the .fade-in-up resting opacity. */
html.no-reveal .fade-in-up, html.no-reveal .fade-in {
  opacity:1 !important; transform:none !important; transition:none !important; will-change:auto; }

/* Mascot micro-interactions. The face is the brand, so it reacts: a small
   bounce when the reader is over the control it sits in, and a nod when a
   process row opens. Transform only — no layout is touched, so a hover
   cannot reflow the row under the pointer. */
@keyframes mascotBounce { 0%,100% { transform:translateY(0); } 30% { transform:translateY(-5px); } 60% { transform:translateY(-1px); } }
.prow .pmasc, footer .mascot-slot, #mascotJoin { transition:transform 240ms cubic-bezier(0.16,1,0.3,1); }
.prow > button:hover .pmasc, .prow > button:focus-visible .pmasc,
.mascot-hover:hover .mascot-slot, .mascot-hover:focus-visible .mascot-slot { animation:mascotBounce 620ms cubic-bezier(0.16,1,0.3,1); }
.prow > button:hover .pmasc { transform:translateY(-2px); }
footer .mascot-slot:hover, #mascotJoin:hover { transform:translateY(-3px); }
@media (prefers-reduced-motion: reduce) {
  .prow > button:hover .pmasc, .mascot-hover:hover .mascot-slot,
  footer .mascot-slot:hover, #mascotJoin:hover { animation:none !important; transform:none !important; }
}

/* ---------------------------------------------------------------------------
   Hero box. The canvas is sized by its container and never scroll-jacks:
   no scroll-snap, no overscroll-behaviour, no touch-action override that
   would stop the page moving under a vertical drag.
   --------------------------------------------------------------------------- */
#heroBoxWrap { position:relative; width:100%; max-width:420px; }
#heroBox { display:block; width:100%; height:auto; outline-offset:6px; }
#heroBox[tabindex]:focus-visible { outline:2px solid var(--brand); }
#heroBoxHint { position:absolute; left:50%; bottom:-6px; transform:translate(-50%,8px); margin:0; padding:5px 11px; border:1px solid var(--brand-line-mid); border-radius:999px; background:var(--surface); color:var(--text-secondary); font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-size:11px; white-space:nowrap; opacity:0; pointer-events:none; transition:opacity 320ms ease, transform 320ms ease; }
#heroBoxHint.on { opacity:1; transform:translate(-50%,0); }
#heroBoxHint.gone { opacity:0 !important; transform:translate(-50%,8px) !important; }

/* ===========================================================================
   PHASE 5 — quality of life
   =========================================================================== */

/* --- 10. Focus. Every interactive element, every theme. --------------------
   The original rule listed five element types by name, which missed anything
   made focusable with tabindex (the hero box), <summary>, and [role=button].
   --brand is AA-contrasting against every surface in all three themes, so one
   ring colour serves all of them. */
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible,
textarea:focus-visible, summary:focus-visible, [tabindex]:focus-visible,
[role="button"]:focus-visible, [contenteditable]:focus-visible {
  outline:2px solid var(--brand); outline-offset:2px; border-radius:4px;
}
/* Windows high-contrast mode paints its own ring but drops colour, so keep a
   visible outline there rather than relying on the token. */
@media (forced-colors: active) {
  a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible,
  textarea:focus-visible, [tabindex]:focus-visible { outline:2px solid Highlight; }
}

/* --- 8. Reading progress ------------------------------------------------- */
#progressBar { position:fixed; top:0; left:0; height:2px; width:100%; z-index:60; transform-origin:0 50%; transform:scaleX(0); background:var(--brand); pointer-events:none; }
nav.bar .links a[aria-current="true"] { color:var(--brand); box-shadow:inset 0 -2px 0 var(--brand); }

/* --- 8. Heading anchors -------------------------------------------------- */
.anchor-link { display:inline-flex; align-items:center; justify-content:center; width:1.6em; height:1.6em; margin-left:0.3em; padding:0; border:none; background:none; border-radius:4px; cursor:pointer; color:var(--text-secondary); opacity:0; transition:opacity 160ms ease, color 160ms ease; vertical-align:middle; }
h2:hover > .anchor-link, h3:hover > .anchor-link, .anchor-link:focus-visible { opacity:1; }
.anchor-link:hover { color:var(--brand); }
.anchor-link[data-copied="1"] { opacity:1; color:var(--brand); }

/* --- 1. Command palette -------------------------------------------------- */
#paletteBackdrop { position:fixed; inset:0; z-index:190; background:rgba(0,0,0,0.42); opacity:0; pointer-events:none; transition:opacity 140ms ease; }
#paletteBackdrop.on { opacity:1; pointer-events:auto; }
#palette { position:fixed; z-index:191; top:12vh; left:50%; transform:translate(-50%,-8px); width:min(560px, calc(100vw - 32px)); background:var(--surface); border:1px solid var(--brand-line); border-radius:8px; box-shadow:0 18px 50px var(--paper-shadow); opacity:0; pointer-events:none; transition:opacity 140ms ease, transform 140ms ease; overflow:hidden; }
#palette.on { opacity:1; pointer-events:auto; transform:translate(-50%,0); }
#paletteInput { width:100%; border:none; border-bottom:1px solid var(--line); background:none; color:var(--text); font-family:inherit; font-size:17px; padding:16px 18px; }
#paletteInput:focus { outline:none; }
#paletteList { list-style:none; margin:0; padding:6px; max-height:52vh; overflow-y:auto; }
#paletteList li { margin:0; }
#paletteList button { display:flex; align-items:baseline; gap:10px; width:100%; text-align:left; background:none; border:none; border-radius:8px; padding:10px 12px; cursor:pointer; color:var(--text); font-family:inherit; font-size:15px; }
#paletteList button .kind { font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-size:11px; letter-spacing:0.06em; text-transform:uppercase; color:var(--text-secondary); flex:none; }
#paletteList button mark { background:none; color:var(--brand); font-weight:600; }
#paletteList li[aria-selected="true"] button { background:var(--tint); }
#paletteList li[aria-selected="true"] button .kind { color:var(--brand); }
#paletteEmpty { padding:18px; margin:0; color:var(--text-secondary); font-size:14px; }
#paletteHint { display:flex; gap:14px; padding:9px 14px; border-top:1px solid var(--line); font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-size:11px; color:var(--text-secondary); }

/* --- 2. Offline banner --------------------------------------------------- */
#offlineBanner { position:fixed; left:0; right:0; bottom:0; z-index:70; display:none; padding:9px 16px; background:var(--brand); color:var(--on-brand); font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-size:13px; text-align:center; }
#offlineBanner.on { display:block; }

/* --- 7. Unit toggle ------------------------------------------------------ */
#unitToggle { display:inline-flex; align-items:center; gap:6px; min-height:36px; padding:0 10px; background:none; border:1px solid var(--line); border-radius:999px; cursor:pointer; color:var(--text); font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-size:12px; letter-spacing:0.04em; transition:border-color 180ms ease, color 180ms ease; }
#unitToggle:hover { border-color:var(--brand-line-mid); color:var(--brand); }
#unitToggle[hidden] { display:none; }

/* --- 4/6. Run packet + CSV ---------------------------------------------- */
/* Explicit column counts rather than auto-fit: with six fields, auto-fit
   produced a different arrangement at almost every width, including a lone
   trailing field on its own row. */
.packet-form { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:16px 18px; margin-top:18px; }
@media (max-width:900px) { .packet-form { grid-template-columns:repeat(2,minmax(0,1fr)); } }
@media (max-width:560px) { .packet-form { grid-template-columns:minmax(0,1fr); } }
.packet-form label { display:grid; gap:7px; align-content:start; font-size:13px; font-weight:600;
  color:var(--text); }
.packet-form input, .packet-form textarea { width:100%; box-sizing:border-box;
  border:1px solid var(--rule); background:var(--surface); color:var(--text);
  font-family:inherit; font-size:14px; padding:11px 12px; border-radius:8px;
  transition:border-color 140ms ease, box-shadow 140ms ease; }
.packet-form input:hover, .packet-form textarea:hover { border-color:var(--brand-line-mid); }
.packet-form input:focus-visible, .packet-form textarea:focus-visible {
  outline:none; border-color:var(--brand); box-shadow:0 0 0 3px var(--brand-line-soft); }
/* The UA placeholder grey lands at 4.23:1 on this ground. --placeholder is
   set per theme to clear 4.5:1 against the field it actually sits in. */
.packet-form input::placeholder, .packet-form textarea::placeholder,
input::placeholder, textarea::placeholder { color:var(--placeholder); opacity:1; }
.packet-form .span-all { grid-column:1/-1; }
.packet-actions { display:flex; flex-wrap:wrap; gap:10px; margin-top:16px; }
.btn-sm { display:inline-flex; align-items:center; gap:6px; font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-weight:700; font-size:14px; padding:10px 16px; border-radius:8px; border:1.5px solid var(--brand-line-mid); background:var(--surface); color:var(--brand); cursor:pointer; transition:border-color 140ms ease, background-color 140ms ease, box-shadow 140ms ease; }
.btn-sm:hover:not(:disabled) { border-color:var(--brand); background:var(--tint); }
.btn-sm.solid { background:var(--brand); color:var(--on-brand); border-color:var(--brand); }
.btn-sm.solid:hover:not(:disabled) { background:var(--brand-press); border-color:var(--brand-press); }
.btn-sm:disabled { opacity:0.5; cursor:not-allowed; }
.packet-note { font-size:13px; line-height:1.6; color:var(--text-secondary); margin:14px 0 0; max-width:62ch; }
#runPacketOut { display:none; margin-top:26px; }
#runPacketOut.on { display:block; }
.packet-doc { border:1px solid var(--rule); border-radius:8px; padding:22px; background:var(--surface); margin-top:16px; }
.packet-doc h3 { font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-size:16px; margin:0 0 4px; color:var(--text); }
.packet-doc .packet-sub { font-family:'DM Mono',ui-monospace,Menlo,monospace; font-size:12px; color:var(--text-secondary); margin:0 0 16px; }
.packet-doc table { width:100%; border-collapse:collapse; font-family:'DM Mono',ui-monospace,Menlo,monospace; font-size:13px; }
.packet-doc th, .packet-doc td { text-align:left; padding:7px 8px; border-bottom:1px solid var(--line-soft); color:var(--text); }
.packet-doc th { font-size:11px; letter-spacing:0.07em; text-transform:uppercase; color:var(--text-secondary); }
.packet-doc td.num { font-variant-numeric:tabular-nums; }
.packet-doc .sign { display:grid; grid-template-columns:repeat(auto-fit,minmax(200px,1fr)); gap:22px; margin-top:24px; }
.packet-doc .sign p { margin:0; font-size:12px; color:var(--text-secondary); border-top:1px solid var(--rule); padding-top:7px; }
/* Program rule: operational paperwork carries no mascot. Every theme, screen
   and print alike — a generated manifest or temperature log is a record, not
   a brand surface. */
.packet-doc .mascot-slot, .packet-doc [data-mascot] { display:none !important; }

/* --- 9. Reduced motion, audited -----------------------------------------
   Not just the scrub: every animation and transition declared anywhere in
   this stylesheet, plus the inline ones the pages set on reveal elements.
   Animations are cancelled rather than merely stopped so elements land on
   their final frame instead of freezing mid-reveal. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration:0.001ms !important;
    animation-delay:0ms !important;
    animation-iteration-count:1 !important;
    transition-duration:0.001ms !important;
    transition-delay:0ms !important;
    scroll-behavior:auto !important;
  }
  html { scroll-behavior:auto !important; }
  .prow .pdetail, .doc-panel { transition:none !important; }
  #progressBar { transition:none !important; }
  #palette, #paletteBackdrop { transition:none !important; }
  .anchor-link { transition:none !important; }
}

/* --- 3. Print. Black on white regardless of the active theme. ------------ */
@media print {
  /* Repoint the tokens rather than overriding hundreds of rules. Because
     these are the same custom properties every rule already reads, the whole
     page turns monochrome in one move — and it does so from dark and stock
     just as thoroughly as from light. */
  :root, :root[data-theme="light"], :root[data-theme="dark"], :root[data-theme="stock"] {
    --bg:#FFFFFF; --surface:#FFFFFF; --tint:#FFFFFF; --text:#000000; --text-secondary:#333333;
    --rule:#000000; --brand:#000000; --accent:#000000; --accent-text:#000000;
    --on-brand:#FFFFFF; --brand-press:#000000;
    --line:#000000; --line-soft:#BBBBBB;
    --brand-line:#000000; --brand-line-soft:#BBBBBB; --brand-line-mid:#000000;
    --mascot-fill:#FFFFFF; --mascot-stroke:#000000; --box-side:#FFFFFF; --box-interior:#FFFFFF; --box-shine:rgba(255,255,255,0);
    --nav-bg:#FFFFFF; --paper-shadow:transparent; --grain-op:0;
  }
  html, body { background:#FFFFFF !important; color:#000000 !important; }
  /* US Letter, portrait, with margins that keep the manifest inside every
     printer's unprintable edge. Declared rather than left to the dialog so a
     packet printed in one school matches a packet printed in another. */
  @page { size:Letter portrait; margin:14mm 14mm 16mm; }

  /* Chrome, decoration and every interactive control. */
  nav.bar, .skip-link, #themeToggle, #themeStatus, #unitToggle, #progressBar,
  #palette, #paletteBackdrop, #offlineBanner, .divider, .box-band, #heroBoxWrap, #formWrap,
  .paper-grain, #chips, .anchor-link, .doc-copy, .doc-download, .doc-toggle,
  .video-thumb, .packet-form, .packet-actions, .mascot-slot, [data-mascot],
  .empty-state .mascot-slot { display:none !important; }
  * { animation:none !important; transition:none !important; box-shadow:none !important; }
  #heropin { height:auto !important; }
  #top, .thead { position:static !important; min-height:0 !important; }

  /* Every collapsed template prints at full content. */
  .prow .pdetail, .doc-panel { display:block !important; grid-template-rows:1fr !important; }
  .prow .pdetail > div, .doc-panel > div { overflow:visible !important; height:auto !important; }
  .prow.open .pdetail, .doc-panel { visibility:visible !important; }
  .doc-text { max-height:none !important; overflow:visible !important; white-space:pre-wrap !important; border:1px solid #000 !important; font-size:10.5pt !important; }

  /* Link targets, since a printed page cannot be clicked. */
  a[href^="http"]::after, a[href^="mailto"]::after { content:" <" attr(href) ">"; font-weight:400; font-size:0.82em; word-break:break-all; }

  section, .limits-grid > div, .site-row { break-inside:avoid; page-break-inside:avoid; }
  .site-filter, .site-rows { break-inside:auto; }
  h1, h2, h3 { break-after:avoid; page-break-after:avoid; }
  /* The memo and the agreement have to stand alone, so each document card
     starts a fresh page. They are too long to forbid internal breaks, so the
     rule is "own page, may continue" rather than "never split". */
  .cards-grid .card:has(.doc-text) { break-before:page; page-break-before:always; break-inside:auto; }
  .packet-doc { break-inside:avoid; page-break-inside:avoid; border:1px solid #000 !important; }
  /* Nothing in a packet may be split across a page: a temperature row cut in
     half is a record nobody can sign. Rows stay whole, the header repeats on
     any continuation page, and a heading never lands as the last line. */
  .packet-doc table { width:100% !important; border-collapse:collapse !important; }
  .packet-doc thead { display:table-header-group; }
  .packet-doc tfoot { display:table-footer-group; }
  .packet-doc tr, .packet-doc .sign { break-inside:avoid; page-break-inside:avoid; }
  .packet-doc th, .packet-doc td { border:1px solid #000 !important; padding:5pt 7pt !important; font-size:10.5pt !important; color:#000 !important; background:#fff !important; }
  .packet-doc h3, .packet-doc .packet-sub, .packet-doc .sign p { color:#000 !important; }
  .packet-doc h3 { break-after:avoid; page-break-after:avoid; }
  /* A packet is paperwork: exact colours matter less than legibility, but the
     threshold flags must survive a printer that drops backgrounds. */
  .packet-doc, .packet-doc * { -webkit-print-color-adjust:exact; print-color-adjust:exact; }

  /* Printing a generated run packet prints the packet, not the website. */
  body.print-packet > *:not(#replicate) { display:none !important; }
  body.print-packet .fade-in-up, body.print-packet .fade-in,
  .fade-in-up, .fade-in { opacity:1 !important; transform:none !important; }
  canvas, #heroBox, #midBox { display:none !important; }
  /* The output lives inside #runPacket, which lives inside the section's
     .wrap — so the chain from body down to the documents has to stay visible
     while every sibling along it is hidden. Hiding by "not the output" alone
     hid the output's own parent and printed a blank sheet. */
  body.print-packet #replicate > .wrap > *:not(#runPacket) { display:none !important; }
  body.print-packet #runPacket > *:not(#runPacketOut) { display:none !important; }
  body.print-packet #replicate, body.print-packet #runPacket, body.print-packet #runPacketOut {
    display:block !important; background:#fff !important; border:none !important; padding:0 !important; margin:0 !important; }
  body.print-packet .packet-doc:first-of-type { break-before:auto; page-break-before:auto; }
}

/* 10. The nav fades in on scroll, which meant a keyboard user could tab into
   the theme and unit controls while they were still at opacity 0 — a focus
   ring nobody can see. Reveal the bar whenever anything inside it has focus. */
nav.bar:focus-within { opacity:1; pointer-events:auto; }

/* ===========================================================================
   Polish pass
   =========================================================================== */

/* Hero. The pre-launch statement used to be set larger than the h1 below it,
   which inverted the hierarchy — two display headings competing, and the one
   that won was not the heading. The h1 now leads and the pre-launch state
   reads as what it is: a status panel, subordinate to the claim above it. */
/* Wraps naturally and balances rather than being split into hand-authored
   masked lines: at this size no fixed phrase fits the hero column across every
   viewport, and a mask line that wraps breaks mid-phrase. */
.hero-h1 { font-size:clamp(30px,3.6vw,42px); line-height:1.13; letter-spacing:-0.035em; margin:10px 0 0; color:var(--text); max-width:28ch; text-wrap:balance; }
.hero-h1 em { display:block; margin-top:0.35em; }
.hero-h1 em { font-style:normal; color:var(--brand); }
#heroBoxWrap { max-width:460px; }
.prelaunch { position:relative; margin:30px 0 0; padding:16px 20px 18px; background:var(--tint); border-left:3px solid var(--brand); border-radius:0 10px 10px 0; max-width:52ch; }
.prelaunch-tag { font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-weight:500; font-size:11px; letter-spacing:0.12em; text-transform:uppercase; color:var(--brand); margin:0 0 7px; }
.prelaunch-line { font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-weight:700; font-size:clamp(19px,1.9vw,23px); line-height:1.25; letter-spacing:-0.02em; color:var(--text); margin:0; }
.prelaunch-sub { font-size:14px; line-height:1.6; color:var(--text-secondary); margin:8px 0 0; }

/* Planned operations, wide viewports. The list is a single column of rows by
   design: statuses are only comparable when they share an axis, and a row
   that carries its own status badge does not need a column of its own. */
.site-row { font-size:17px; padding:14px 0; }
#sites .cite { max-width:62ch; }

/* Manifest. The "not published yet" note sat inside the mono header strip,
   where a full sentence with a dotted underline read as a broken link next to
   the controls. It belongs under the table, as a footnote to the log. */
.manifest-foot { margin:0; padding:12px 20px 14px; border-top:1px solid var(--brand-line-soft); font-family:'DM Mono',ui-monospace,Menlo,monospace; font-size:12px; line-height:1.55; color:var(--text-secondary); }
.mhead .right { gap:12px; }
#mascotMood { width:44px; }

/* Run packet. A two-column table splits 50/50 by default, stranding every
   value in the middle of the page. */
.packet-doc table.kv { table-layout:fixed; }
.packet-doc table.kv th[scope="row"] { width:34%; }
.packet-doc table.kv td { width:66%; }

/* Section rhythm: the tier rules and the sources rule were the only hairlines
   that ran wider than the text they belonged to. */
#sites .site-rows { max-width:none; }


/* ============================================================================
   NETWORK MAP + the UI added alongside it
   ============================================================================
   Every colour is a theme token, so the map, its pins and its legend follow
   light / dark / stock exactly as the rest of the page does. Leaflet's own
   chrome is re-skinned rather than left in its default blue-grey.
   ========================================================================= */

/* --- stats strip ------------------------------------------------------- */
.stats-strip { background:var(--brand); color:var(--on-brand); }
.stats-strip .wrap { display:flex; flex-wrap:wrap; gap:8px 34px; padding-top:10px; padding-bottom:10px; }
.stats-strip .stat-item { display:inline-flex; align-items:baseline; gap:8px; }
.stats-strip .stat-fig { font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-weight:500; font-size:16px; font-variant-numeric:tabular-nums; }
.stats-strip .stat-cap { font-size:13px; opacity:0.88; }
@media (max-width:700px) {
  /* One figure per line rather than a wrapped row: at this width the third
     item was overflowing the viewport instead of wrapping. */
  .stats-strip .wrap { flex-direction:column; gap:3px; }
  .stats-strip .stat-item { flex-wrap:wrap; }
  .stats-strip .stat-cap { font-size:12px; }
}

/* --- delivery-log preview toggle --------------------------------------- */
.sim-bar { margin-top:28px; display:flex; flex-wrap:wrap; align-items:center; gap:12px 18px; }
.sim-controls { display:inline-flex; gap:8px; }
.sim-btn { font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-weight:600; font-size:13px; color:var(--text-secondary);
  background:var(--surface); border:1px solid var(--brand-line-mid); border-radius:999px; padding:7px 14px; cursor:pointer;
  transition:color 160ms ease, border-color 160ms ease, background-color 160ms ease; }
.sim-btn:hover { color:var(--brand); border-color:var(--brand); }
.sim-btn.is-on { background:var(--brand); border-color:var(--brand); color:var(--on-brand); }
.sim-note { font-size:13px; color:var(--text-secondary); margin:0; }
/* The one piece of chrome that must never be subtle: it is the only thing
   separating a preview from a record. */
.sim-banner[hidden] { display:none; }
.sim-banner { display:block; margin:16px 0 0; padding:12px 14px; border-radius:8px;
  border:2px dashed var(--accent); background:var(--surface);
  font-size:14px; line-height:1.6; color:var(--text); max-width:70ch; }
.sim-banner strong { color:var(--accent-text); letter-spacing:0.04em; }

/* --- map shell ---------------------------------------------------------- */
.map-shell { position:relative; border:1px solid var(--brand-line); border-radius:8px; overflow:hidden; box-shadow:0 3px 14px var(--paper-shadow); }
.map-canvas { height:clamp(360px,58vh,560px); width:100%; background:var(--bg); }
/* Clear of the transport bar. */
.map-shell .leaflet-bottom.leaflet-left { bottom:56px; }
@media (max-width:600px) { .map-shell .leaflet-bottom.leaflet-left { bottom:54px; } }
.map-canvas:focus-visible { outline:3px solid var(--accent); outline-offset:-3px; }
.map-fallback { padding:28px; margin:0; font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-size:14px; color:var(--text-secondary); }

/* Interaction gate: the map never swallows a page scroll until asked. */
.map-gate { display:block; width:100%; margin-top:10px; padding:9px 14px; cursor:pointer;
  font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-weight:600; font-size:13px;
  color:var(--brand); background:var(--surface); border:1px dashed var(--brand-line-mid); border-radius:8px; }
.map-gate:hover { border-color:var(--brand); }

.map-controls { display:flex; flex-wrap:wrap; align-items:center; gap:14px 20px; margin-top:16px; }
.map-legend { display:flex; flex-wrap:wrap; gap:8px 16px; font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-size:12px; color:var(--text-secondary); }
.map-legend .lg-item { display:inline-flex; align-items:center; gap:6px; }
.map-legend .lg-sw { width:14px; height:14px; border-radius:4px; border:1px solid var(--line); display:inline-block; }
.map-legend .lg-nodata { background:var(--bg); border-style:dashed; }
.map-caption { font-size:15px; line-height:1.6; color:var(--text); margin:18px 0 0; max-width:62ch; text-wrap:pretty; }
#network .cite { font-size:13px; line-height:1.6; color:var(--text-secondary); margin:10px 0 0; max-width:62ch; }
#network .cite code { font-family:'DM Mono',ui-monospace,Menlo,monospace; font-size:12px; }

/* --- markers ------------------------------------------------------------ */
.pin-wrap { position:relative; display:block; width:14px; height:14px; }
.pin-dot { position:absolute; inset:0; box-sizing:border-box; }
/* Delivering: a solid filled disc with a light collar — reads as "on". */
.pin-dot.pin-setup, .pin-dot.pin-active { border-radius:50%; background:var(--brand); border:3px solid var(--surface);
  box-shadow:0 0 0 1.5px var(--brand); }
/* In conversation: a half-filled disc — started, not finished. */
.pin-dot.pin-conversation { border-radius:50%; background:var(--surface); border:3px solid var(--brand);
  background-image:linear-gradient(to right, var(--brand) 50%, transparent 50%); }
/* Target: a hollow ring, dashed — nothing agreed. */
.pin-dot.pin-target { border-radius:50%; background:var(--surface); border:2px dashed var(--text-secondary); }
.pin-text { position:absolute; left:20px; top:50%; transform:translateY(-50%);
  font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  font-weight:600; font-size:10.5px; letter-spacing:0.02em; white-space:nowrap;
  color:var(--text); background:var(--surface); border:1px solid var(--brand-line-mid);
  border-radius:4px; padding:2px 6px; }
/* Only the in-setup site pulses. A target or in-conversation school must
   never read as live. */
.pin-live::before { content:""; position:absolute; inset:-4px; border-radius:50%;
  box-shadow:0 0 0 4px var(--brand); opacity:0; animation:pinPulse 2.4s ease-out infinite; }
@keyframes pinPulse {
  0% { opacity:0.55; transform:scale(1); }
  70% { opacity:0; transform:scale(1.5); }
  100% { opacity:0; transform:scale(1.5); }
}

/* --- run schematic ------------------------------------------------------ */
.route-animate { animation:routeDash 1.4s linear infinite; }
@keyframes routeDash { to { stroke-dashoffset:-28; } }
.route-badge { display:inline-block; transform:translate(-50%,-50%);
  font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-size:10px; line-height:1.35; text-align:center; white-space:nowrap;
  color:var(--accent-text); background:var(--surface); border:1px solid var(--accent); border-radius:4px; padding:3px 6px; }
.route-badge em { font-style:normal; opacity:0.8; }

/* --- Leaflet chrome, re-skinned ---------------------------------------- */
.leaflet-container { background:var(--bg); font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; }
.leaflet-bar a, .leaflet-bar a:hover { background:var(--surface); color:var(--text); border-bottom-color:var(--line); }
.leaflet-bar a:hover { color:var(--brand); }
.leaflet-control-attribution { background:var(--surface) !important; color:var(--text-secondary) !important; font-size:11px !important; }
.leaflet-control-attribution a { color:var(--brand) !important; }
.leaflet-popup-content-wrapper, .leaflet-popup-tip { background:var(--surface); color:var(--text); box-shadow:0 3px 14px var(--paper-shadow); }
.leaflet-popup-content { margin:12px 14px; font-size:13px; }
.leaflet-popup-content strong { display:block; font-size:14px; color:var(--text); margin-bottom:4px; }
.leaflet-popup-content .pop-line { display:block; color:var(--text-secondary); }
.leaflet-popup-content .pop-note { display:block; margin-top:6px; font-size:12px; color:var(--accent-text); }
.map-tip { background:var(--surface) !important; color:var(--text) !important; border:1px solid var(--rule) !important;
  font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-size:11px !important; }

@media (max-width:600px) {
  .map-canvas { height:400px; }
  .pin-text { font-size:10px; }
}

@media (prefers-reduced-motion: reduce) {
  .pin-live::before, .route-animate { animation:none !important; }
  .pin-live::before { display:none !important; }
}

@media print {
  .stats-strip, .map-shell, .map-gate, .map-controls, .sim-controls { display:none !important; }
  .sim-banner { border:2px solid #000 !important; }
}


/* --- projection HUD ------------------------------------------------------
   Sits over the bottom of the map. The caption carries the narration; the
   flag under it is the one element that separates the real acts from the
   hypothetical one, so it is the loudest thing in the component. */
.map-hud { position:absolute; z-index:500; left:0; right:0; bottom:0; pointer-events:none;
  /* Bottom padding clears Leaflet's attribution, which sits in the same
     corner and must stay legible. */
  /* Left padding clears the zoom control, which shares this corner; bottom
     padding clears Leaflet's attribution. */
  padding:14px 16px 28px 58px; display:grid; gap:8px;
  background:linear-gradient(to top, var(--surface) 62%, transparent); }
.hud-counts { display:flex; gap:22px; }
.hud-stat { display:inline-flex; align-items:baseline; gap:6px;
  font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-size:12px; color:var(--text-secondary); }
.hud-stat b { font-size:22px; font-weight:500; color:var(--brand); font-variant-numeric:tabular-nums; }
.hud-caption { margin:0; font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-weight:600;
  font-size:clamp(14px,1.7vw,17px); line-height:1.45; color:var(--text); max-width:60ch; text-wrap:pretty; }
.hud-flag { margin:0; font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-size:11.5px; letter-spacing:0.03em;
  color:var(--accent-text); border-left:3px solid var(--accent); padding-left:9px; }
.hud-flag[hidden] { display:none; }
.btn-play { font-weight:700; }
.btn-play[disabled] { opacity:0.6; cursor:default; }
@media (max-width:600px) {
  .map-hud { padding:10px 12px 12px 52px; }
  .hud-stat b { font-size:18px; }
  .hud-caption { font-size:13px; }
}
@media (prefers-reduced-motion: reduce) { .map-hud { transition:none !important; } }
@media print { .map-hud { display:none !important; } }


/* --- map polish: depth, borough labels, floating legend ------------------ */
/* A soft inner vignette gives the map a horizon; without a tile layer the
   flat outline otherwise floats. */
.map-shell::after { content:""; position:absolute; inset:0; pointer-events:none; z-index:400;
  box-shadow:inset 0 0 70px -20px var(--paper-shadow); border-radius:inherit; }
.boro-label { display:inline-block; transform:translate(-50%,-50%);
  font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  font-weight:700; font-size:10.5px; letter-spacing:0.14em; text-transform:uppercase;
  color:var(--text-secondary); opacity:0.75; white-space:nowrap; pointer-events:none;
  text-shadow:0 0 4px var(--bg), 0 0 4px var(--bg), 0 0 8px var(--bg); }
.map-legend-card { position:absolute; z-index:500; right:12px; top:12px; display:grid; gap:5px;
  background:var(--surface); border:1px solid var(--brand-line-soft); border-radius:8px;
  padding:10px 12px; box-shadow:0 4px 16px var(--paper-shadow); max-width:158px; }
.map-legend-card .lg-title { font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  font-weight:700; font-size:10px; letter-spacing:0.08em; text-transform:uppercase; color:var(--text-secondary); }
.map-legend-card .lg-item { font-size:11.5px; }
.map-legend-card .lg-sw { width:12px; height:12px; border-radius:4px; }
/* Districts under the cursor animate their edge rather than snapping. */
.leaflet-interactive { transition:fill-opacity 140ms ease, stroke-width 140ms ease; }
@media (max-width:600px) {
  .map-legend-card { right:8px; top:auto; bottom:96px; padding:8px 10px; max-width:132px; }
  .map-legend-card .lg-item { font-size:10.5px; }
  .boro-label { font-size:9px; letter-spacing:0.1em; }
}
@media (prefers-reduced-motion: reduce) { .leaflet-interactive { transition:none !important; } }
@media print { .map-legend-card, .map-shell::after { display:none !important; } }


/* --- playback transport + disambiguation watermark ----------------------- */
.map-playbar { position:absolute; z-index:520; left:0; right:0; bottom:0;
  display:flex; align-items:center; gap:10px; padding:8px 12px;
  background:var(--surface); border-top:1px solid var(--brand-line-soft); }
.pb-btn { display:inline-flex; align-items:center; justify-content:center; flex:none;
  width:32px; height:32px; border-radius:50%; cursor:pointer;
  background:var(--brand); border:1px solid var(--brand); color:var(--on-brand); }
.pb-btn:hover { background:var(--brand-press); border-color:var(--brand-press); }
.pb-btn:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
/* Play triangle / pause bars, drawn rather than typeset so they stay crisp. */
.pb-icon { display:block; width:0; height:0; margin-left:2px;
  border-top:6px solid transparent; border-bottom:6px solid transparent; border-left:10px solid currentColor; }
.pb-play.is-playing .pb-icon { width:9px; height:11px; margin-left:0; border:none;
  border-left:3px solid currentColor; border-right:3px solid currentColor; }
.pb-scrub { flex:1 1 auto; min-width:60px; accent-color:var(--brand); height:20px; cursor:pointer; }
.pb-scrub:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }
.pb-time { flex:none; font-family:'DM Mono',ui-monospace,Menlo,monospace; font-size:11px;
  color:var(--text-secondary); font-variant-numeric:tabular-nums; }
.pb-speeds { flex:none; display:inline-flex; gap:3px; }
.pb-rate { font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  font-weight:600; font-size:11px; padding:5px 8px; border-radius:4px; cursor:pointer;
  background:transparent; border:1px solid transparent; color:var(--text-secondary); }
.pb-rate:hover { color:var(--text); background:var(--tint); }
.pb-rate[aria-pressed="true"] { background:var(--brand); border-color:var(--brand); color:var(--on-brand); }
.pb-rate:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }

/* Anchored inside the map frame, so it cannot be scrolled away from the
   thing it qualifies. */
.map-watermark { position:absolute; z-index:510; left:12px; top:12px; margin:0;
  max-width:min(320px, calc(100% - 24px));
  font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  font-size:11px; line-height:1.45; color:var(--text);
  background:var(--surface); border:2px solid var(--accent); border-left-width:5px;
  border-radius:8px; padding:7px 10px; box-shadow:0 3px 12px var(--paper-shadow); }
.map-watermark[hidden] { display:none; }
.map-watermark strong { display:block; font-size:10px; letter-spacing:0.1em;
  color:var(--accent-text); margin-bottom:2px; }

/* The HUD sits above the transport rather than under it. */
.map-hud { bottom:49px; }
.map-legend-card { top:66px; }
.seed-dot { transition:fill-opacity 260ms ease; }

@media (max-width:600px) {
  .map-playbar { gap:7px; padding:7px 9px; }
  .pb-time { display:none; }
  .pb-rate { padding:5px 6px; font-size:10px; }
  .map-watermark { left:8px; top:auto; bottom:112px; font-size:10px; max-width:calc(100% - 16px); }
  .map-legend-card { top:auto; bottom:180px; }
  .map-hud { bottom:47px; }
}
@media (prefers-reduced-motion: reduce) { .seed-dot { transition:none !important; } }
@media print { .map-playbar, .map-watermark { display:none !important; } }

/* A label suppressed for collision. The pin and its popup are untouched — the
   label comes back on hover or keyboard focus, and on zoom in. */
.pin-muted .pin-text { opacity:0; pointer-events:none; transition:opacity 140ms ease; }
.pin-muted:hover .pin-text, .pin-muted:focus-within .pin-text { opacity:1; }
@media (prefers-reduced-motion: reduce) { .pin-muted .pin-text { transition:none !important; } }


/* --- cluster icon, themed from our own tokens ---------------------------
   MarkerCluster.Default.css is not loaded; this is the whole appearance. */
.pin-cluster { display:flex; flex-direction:column; align-items:center; justify-content:center;
  width:34px; height:34px; border-radius:50%; box-sizing:border-box;
  background:var(--surface); border:2px solid var(--brand);
  box-shadow:0 2px 8px var(--paper-shadow); cursor:pointer;
  font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  transition:transform 140ms ease, box-shadow 140ms ease; }
.pin-cluster b { font-size:13px; font-weight:800; line-height:1; color:var(--brand); }
.pin-cluster .pin-cluster-lbl { font-size:7px; font-weight:600; letter-spacing:0.06em;
  text-transform:uppercase; line-height:1; color:var(--text-secondary); margin-top:1px; }
/* A cluster holding a live site says so, rather than averaging it away. */
.pin-cluster-live { background:var(--brand); border-color:var(--surface);
  box-shadow:0 0 0 2px var(--brand), 0 2px 8px var(--paper-shadow); }
.pin-cluster-live b { color:var(--on-brand); }
.pin-cluster-live .pin-cluster-lbl { color:var(--on-brand); opacity:0.8; }
.leaflet-marker-icon:hover .pin-cluster { transform:scale(1.08); }
.leaflet-marker-icon:focus-visible { outline:2px solid var(--accent); outline-offset:3px; border-radius:50%; }
.leaflet-cluster-spider-leg { stroke:var(--brand-line-mid); }
@media (prefers-reduced-motion: reduce) {
  .pin-cluster { transition:none !important; }
  .leaflet-cluster-anim .leaflet-marker-icon, .leaflet-cluster-anim .leaflet-marker-shadow,
  .leaflet-cluster-spider-leg { transition:none !important; }
}

/* --- school emblem carousel (team page + home) --------------------------
   A marquee: the row is cloned once by script and the pair slides left by
   exactly one row's width, so the loop is seamless. Emblems are masks
   filled with the brand green, so every logo matches in every theme. */
.emblems { padding:24px 0 40px; }
.emblems-title { margin:8px 0 10px; text-align:center; font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;
  font-weight:700; font-size:clamp(17px,1.7vw,20px); letter-spacing:-0.01em; color:var(--text); }
.emblem-track { overflow:hidden; padding:12px 0; }
.emblem-row { list-style:none; margin:0; padding:0 12px; display:flex; flex-wrap:wrap; justify-content:center; gap:16px 48px; }
.emblem { flex:none; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:10px; min-width:140px; min-height:112px; }
.emblem-mark { display:none; width:88px; height:88px; background:var(--brand);
  -webkit-mask:var(--logo) center / contain no-repeat; mask:var(--logo) center / contain no-repeat; }
.emblem.has-logo .emblem-mark { display:block; }
.emblem.wide .emblem-mark { width:150px; }
.emblem-name { font-family:'Plus Jakarta Sans',-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif; font-weight:800; font-size:20px; letter-spacing:-0.02em; color:var(--brand); white-space:nowrap; }
.emblem.has-logo .emblem-name { font-size:13px; font-weight:600; letter-spacing:0; }
.emblem-track.is-moving { -webkit-mask-image:linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); mask-image:linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
.emblem-track.is-moving .emblem-rail { display:flex; width:max-content; animation:emblemScroll var(--dur,36s) linear infinite; }
.emblem-track.is-moving .emblem-row { flex-wrap:nowrap; padding:0; gap:0; }
.emblem-track.is-moving .emblem { margin-right:56px; }
.emblem-track.is-moving:hover .emblem-rail, .emblem-track.is-moving:focus-within .emblem-rail { animation-play-state:paused; }
@keyframes emblemScroll { from { transform:translateX(0); } to { transform:translateX(-50%); } }
/* --- delivery photo carousel (home page, Our Impact) ----------------------
   One photo in the middle, its neighbours smaller and blurred to either
   side, the rest out of sight (assets/site.js: GALLERY, initGallery). Each
   photo's place comes from its data-pos, and the move, scale and blur
   animate between places. The photos are portrait, so each slide is 3:4. */
.impact-gallery { margin-top:72px; }
.photo-track { position:relative; }
.photo-frame { --h:clamp(340px, 44vw, 540px); position:relative; height:var(--h); overflow:hidden; overflow:clip;
  -webkit-mask-image:linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent);
  mask-image:linear-gradient(90deg, transparent, #000 7%, #000 93%, transparent); }
.photo-slide { position:absolute; top:0; left:50%; height:100%; aspect-ratio:3/4; margin:0;
  transform:translateX(-50%) translateX(150%) scale(0.7); opacity:0; pointer-events:none; }
.photo-frame.is-ready .photo-slide { transition:transform 700ms cubic-bezier(0.22,1,0.36,1), filter 700ms ease, opacity 700ms ease; }
.photo-slide[data-pos="0"] { transform:translateX(-50%); opacity:1; z-index:3; pointer-events:auto; }
.photo-slide[data-pos="1"], .photo-slide[data-pos="-1"] { opacity:0.55; filter:blur(5px) saturate(0.8); z-index:2; pointer-events:auto; }
.photo-slide[data-pos="1"] { transform:translateX(-50%) translateX(84%) scale(0.84); }
.photo-slide[data-pos="-1"] { transform:translateX(-50%) translateX(-84%) scale(0.84); }
.photo-slide[data-pos="-2"] { transform:translateX(-50%) translateX(-150%) scale(0.7); }
.photo-slide button { all:unset; box-sizing:border-box; display:block; width:100%; height:100%; border-radius:20px; overflow:hidden;
  cursor:pointer; background:var(--tint); box-shadow:0 24px 50px -28px var(--paper-shadow); }
.photo-slide[data-pos="0"] button { cursor:zoom-in; }
.photo-slide button:focus-visible { outline:3px solid var(--brand); outline-offset:4px; }
.photo-slide img { width:100%; height:100%; object-fit:cover; display:block; }
.photo-slide .photo-cap { position:absolute; left:0; right:0; bottom:0; margin:0; padding:12px 16px; border-radius:0 0 20px 20px;
  font-size:13px; color:#fff; line-height:1.4; pointer-events:none;
  background:linear-gradient(0deg, rgba(0,0,0,0.6), transparent); }
.photo-slide:not([data-pos="0"]) .photo-cap { opacity:0; }
.photo-arrow { position:absolute; top:50%; z-index:4; width:48px; height:48px; margin-top:-24px; padding:0; border-radius:50%;
  display:grid; place-items:center; border:1px solid var(--line); background:var(--surface); color:var(--text); cursor:pointer;
  box-shadow:0 8px 20px -8px var(--paper-shadow); transition:background-color 160ms ease, transform 160ms ease; }
.photo-arrow:hover { background:var(--tint); transform:scale(1.05); }
.photo-arrow:focus-visible { outline:2px solid var(--brand); outline-offset:3px; }
.photo-arrow-prev { left:max(8px, calc(50% - var(--h) * 0.375 - 120px)); }
.photo-arrow-next { right:max(8px, calc(50% - var(--h) * 0.375 - 120px)); }
.photo-dots { display:flex; justify-content:center; gap:8px; margin:20px 0 0; }
.photo-dots button { all:unset; cursor:pointer; width:8px; height:8px; border-radius:50%; background:var(--line);
  transition:background-color 160ms ease, transform 160ms ease; }
.photo-dots button.is-active { background:var(--brand); transform:scale(1.3); }
.photo-dots button:focus-visible { outline:2px solid var(--brand); outline-offset:3px; }
@media (max-width:700px) {
  .impact-gallery { margin-top:48px; }
  .photo-arrow { width:40px; height:40px; margin-top:-20px; }
  .photo-slide button, .photo-slide .photo-cap { border-radius:16px; }
}
@media (prefers-reduced-motion: reduce) { .photo-frame.is-ready .photo-slide, .photo-arrow { transition:none; } }

.photo-lightbox { border:none; border-radius:14px; padding:0; max-width:min(92vw, 900px); max-height:88vh;
  background:var(--surface); box-shadow:0 20px 60px -20px rgba(0,0,0,0.5); }
.photo-lightbox::backdrop { background:rgba(0,0,0,0.72); }
.photo-lightbox img { display:block; width:100%; max-height:76vh; object-fit:contain; background:#000; }
.photo-lightbox-cap { margin:0; padding:12px 16px; font-size:14px; color:var(--text-secondary); }
.photo-lightbox-close { position:absolute; top:8px; right:8px; width:32px; height:32px; border-radius:50%;
  border:1px solid var(--line); background:var(--surface); color:var(--text); font-size:20px; line-height:1; cursor:pointer; }
.photo-lightbox-close:hover { background:var(--tint); }

/* ---------- phone menu (built by site.js) ----------
   Hidden above 800px, where the bar already shows every link. */
.nav-burger { display:none; width:40px; height:40px; align-items:center; justify-content:center;
  background:none; border:none; padding:0; cursor:pointer; color:var(--text); border-radius:8px; }
.nav-burger:focus-visible { outline:2px solid var(--brand); outline-offset:2px; }
.nav-burger path { transition:transform 200ms ease, opacity 150ms ease; transform-origin:12px 12px; }
nav.bar.menu-open .nav-burger .nb-top { transform:translateY(5px) rotate(45deg); }
nav.bar.menu-open .nav-burger .nb-mid { opacity:0; }
nav.bar.menu-open .nav-burger .nb-bot { transform:translateY(-5px) rotate(-45deg); }
.nav-menu { display:none; }
@media (max-width:800px) {
  .nav-burger { display:flex; }
  nav.bar.menu-open { background:var(--bg); }
  .nav-menu:not([hidden]) { display:flex; flex-direction:column; position:absolute; top:48px; left:0; right:0;
    max-height:calc(100svh - 48px); overflow-y:auto; padding:8px 16px 16px; background:var(--bg);
    border-bottom:1px solid var(--line); box-shadow:0 18px 30px -20px var(--paper-shadow, rgba(0,0,0,0.25)); }
  .nav-menu a { display:block; padding:14px 8px; font-size:17px; font-weight:500; color:var(--text);
    text-decoration:none; border-bottom:1px solid var(--line-soft, var(--line)); }
  .nav-menu a:last-child { border-bottom:none; }
  .nav-menu a:hover, .nav-menu a:focus-visible { color:var(--brand); }
  .nav-menu a[aria-current="page"] { color:var(--brand); font-weight:600; }
  .nav-menu a.cta { color:var(--brand); font-weight:600; }
  /* Sign in is already a button in the bar; it's repeated here at the end. */
  .nav-menu a.login { color:var(--brand); font-weight:600; }
}
@media print { .nav-burger, .nav-menu { display:none !important; } }
