/* ============================================================
   Flourishing Futures: AI for Human Possibility
   Redesign — GT Maru + Newsreader + Atkinson Hyperlegible Next
   ============================================================ */

/* --- GT Maru (display / subheaders / nav) --- */
@font-face {
  font-family: 'GT Maru';
  src: url('../fonts/GTMaruRegular.woff2') format('woff2'), url('../fonts/GTMaruRegular.ttf') format('truetype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'GT Maru';
  src: url('../fonts/GTMaruMedium.woff2') format('woff2'), url('../fonts/GTMaruMedium.ttf') format('truetype');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'GT Maru';
  src: url('../fonts/GTMaruBold.woff2') format('woff2'), url('../fonts/GTMaruBold.ttf') format('truetype');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'GT Maru';
  src: url('../fonts/GTMaruBlack.woff2') format('woff2'), url('../fonts/GTMaruBlack.ttf') format('truetype');
  font-weight: 900;
  font-style: normal;
  font-display: swap;
}

/* --- Reset --- */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

/* --- Custom Properties --- */
:root {
  --red: #E42600;
  --yellow: #FFCC00;   /* was #E4B103 (read muddy behind "What we do"), 2026-10-06 */
  --green: #009D3C;
  --blue: #1934BE;
  --black: #1B1B1B;
  --white: #F3F3F3;
  --lime: #5FFF84;   /* button accent */

  /* Theme semantic tokens — default to today's values so the Default theme is
     visually unchanged. Overridden under html[data-theme="light|dark"] below.
     --field-ink  = text that sits ON a coloured field (not on a white card).
     --section-accent = the single dark-maroon accent band used in Dark mode. */
  --field-ink: var(--white);
  --section-accent: var(--black);

  /* Mobile menu key colour, resolved per page via body[data-key]. */
  --key: var(--blue);          /* default page key colour */

  /* Shared type scale (About page). Three tiers + eyebrow so every section
     reads with one Title / Subheader / Body rhythm. --fs-subhead matches the
     Home page's .things__heading ("Research & Measurement"). */
  --fs-title: clamp(2.9rem, 6vw, 3.4rem);   /* stays clearly above the subheader */
  --fs-subhead: 1.9rem;        /* == .things__heading; bumps to 2.3rem on mobile */
  --fs-list: clamp(1.5rem, 2.2vw, 1.7rem);   /* dense lists (develop accordion) */
  --fs-body: 1rem;
  --fs-eyebrow: 1rem;

  --font-display: 'GT Maru', 'Nunito', 'Rounded Mplus 1c', system-ui, sans-serif;
  --font-serif: 'Newsreader', Georgia, 'Times New Roman', serif;
  --font-body: 'Atkinson Hyperlegible Next', -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;

  --container: 900px;
  --container-wide: 1200px;
}

/* Subheader grows on mobile, matching .things__heading's 1.9rem → 2.3rem. */
@media (max-width: 768px) {
  :root { --fs-subhead: 2.3rem; }
}

/* --- Base --- */
html {
  font-size: 16px;
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.6;
  color: var(--black);
  background: var(--white);
}

img {
  max-width: 100%;
  height: auto;
  display: block;
}

a {
  color: var(--blue);
  text-decoration: none;
}

/* --- Layout --- */
.container {
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 1.5rem;
}

.container--wide {
  max-width: var(--container-wide);
  margin: 0 auto;
  padding: 0 1.5rem;
}

/* ============================================================
   HERO SECTION
   ============================================================ */
.hero {
  position: relative;
  background: var(--red); /* JS overrides per rotating scene */
  color: var(--title-color, var(--white));
  overflow: hidden;
  padding: 0;
  min-height: 92vh;
  display: flex;
  flex-direction: column;
  transition: background 0.6s ease;
}


.hero__logo {
  position: relative;
  z-index: 10;
  padding: 1.75rem 0 0 2.5rem;
}

/* White wordmark SVG by default (dark scenes); flipped to black on light
   scenes (the gold tile) for contrast. */
.hero__logo-mark {
  display: block;
  width: 268px;
  height: auto;
  transition: filter 0.6s ease;
}

.hero.logo-dark .hero__logo-mark {
  filter: brightness(0);   /* black */
}

.hero__headline {
  position: relative;
  z-index: 10;
  text-align: center;
  padding: 2rem 2rem;
  margin: auto 0;   /* centre in the open space below the logo */
}

.hero__title {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: clamp(2rem, 5.2vw, 4.6rem);
  line-height: 1.05;
  color: var(--title-color, var(--white));
  max-width: 820px;   /* narrow enough to break each question onto two lines */
  margin: 0 auto;
  text-transform: lowercase;
}

/* Per-letter blur/fade transition on scene change. Words stay intact (they
   don't break mid-word); letters animate individually with a JS stagger delay. */
.hero__title .word {
  display: inline-block;
  white-space: nowrap;
}
.hero__title .ltr {
  display: inline-block;
  opacity: 0;
  filter: blur(12px);
  transform: translateY(0.12em);
  transition: opacity 0.5s ease, filter 0.5s ease, transform 0.5s ease;
  /* (no will-change: ~50 letters each holding a GPU layer is heavy on phones,
     and the browser promotes them during the transition anyway) */
}
.hero__title .ltr.is-in {
  opacity: 1;
  filter: blur(0);
  transform: none;
}

.hero__title u {
  text-decoration: underline;
  text-decoration-color: currentColor;
  text-underline-offset: 0.1em;
  text-decoration-thickness: 2px;
}

/* ---- Rotating character stage ---- */
.hero__stage {
  position: absolute;
  inset: 0;
  z-index: 2;
  min-height: 0;
  margin: 0;
  pointer-events: none;
}

.hero__scene {
  position: absolute;
  inset: 0;
  opacity: 0;
  pointer-events: none;
}

.hero__scene.is-active {
  opacity: 1;
}

.scene-stage {
  position: absolute;
  inset: 0;
}

/* Each scene stacks several full-bleed brush-doodle LAYERS (one per element of
   the tile). They share the tile's viewBox and use identical cover/centre, so
   they overlay pixel-perfect over the scene's flat colour field; the JS cursor
   parallax nudges each by its own data-depth (see moveDoodle in index.html).
   DOM order = paint order (background layer first, accents on top). */
.hero__layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  /* Overscan so the parallax drift never exposes the field edge. */
  transform: scale(1.08);
  will-change: transform;
  transition: transform 0.25s ease-out;
}

/* Playful "duck" — each character (a group INSIDE the lockup) bobs down and
   springs back on mouse-over, so only the shape you point at reacts. --duck is
   set per lockup in JS (in user units) so the drop reads ~consistent on screen. */
@keyframes char-bob {
  0%   { transform: translateY(0); }
  24%  { transform: translateY(var(--duck, 40px)); }
  56%  { transform: translateY(calc(var(--duck, 40px) * -0.22)); }
  100% { transform: translateY(0); }
}
.char-part.is-bobbing {
  animation: char-bob 0.6s cubic-bezier(0.34, 1.25, 0.5, 1);
}

/* ---- Split human | machine hero (prototype) ----
   Each question gets its own scene: a human (left) and machine (right) half
   that paint over the hero's own field and clip their art (the divider is a
   hard edge). Scenes crossfade on rotation. Each scene sets its own
   --split-human / --split-machine. On portrait screens the halves stack
   top | bottom (keep the aspect-ratio query in sync with PORTRAIT in
   js/hero-magnet.js). */
.hero-split .hero__scene {
  display: flex;
  transition: opacity 0.9s ease;
}
.split__half {
  position: relative;
  flex: 1 1 50%;
  overflow: hidden;
  container-type: size;   /* lets scenes size art against the half (cqh) */
  background: var(--split-human);
}
.split__half--machine { background: var(--split-machine); }

/* ---- Interaction 1: magnetic shapes (References/Hero_Interaction_1.jpg) ----
   js/hero-magnet.js drives each .magnet__shape's transform. */
.hero-scene--magnet {
  --split-human:   #A7E307;   /* eyedropped from the design */
  --split-machine: #001FE4;
}

.magnet__shape {
  position: absolute;
  top: 0;
  left: 0;
  will-change: transform;
}
.magnet__shape > img,
.magnet__shape > svg {
  display: block;
  width: 100%;
  height: auto;
  opacity: 0;
  transform: scale(0.6);
  transition: opacity 0.5s ease, transform 0.8s cubic-bezier(0.34, 1.56, 0.5, 1);
}
.hero-scene--magnet.is-in .magnet__shape > * {
  opacity: 1;
  transform: none;
}
@media (prefers-reduced-motion: reduce) {
  .magnet__shape > * { transition: none; }
}

/* The pill blinks (JS toggles .is-blinking every few seconds + on click). */
.magnet__eye {
  transform-box: fill-box;
  transform-origin: center;
}
.is-blinking .magnet__eye { animation: magnet-blink 0.24s ease-in-out; }
@keyframes magnet-blink {
  0%, 100% { transform: none; }
  45%, 55% { transform: scaleY(0.08); }
}

/* The question sits on one half (human by default; .hero--title-right moves
   it to the machine half, swapped while the title is faded out), left-aligned
   and vertically centred. */
.hero--split .hero__headline {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: 50%;
  margin: 0;
  padding: 0 2rem 0 2.5rem;
  display: flex;
  align-items: center;
  text-align: left;
  pointer-events: none;
}
.hero--split.hero--title-right .hero__headline { left: 50%; padding-left: 3rem; }
.hero--split .hero__title {
  font-size: clamp(2.2rem, 5.6vw, 7rem);   /* a touch under the design's ~6.7vw */
  line-height: 1;
  max-width: none;
  margin: 0;
}

@media (max-aspect-ratio: 1/1) {
  .hero-split .hero__scene { flex-direction: column; }
  .hero--split .hero__headline {
    bottom: 50%;
    width: auto;
    right: 0;
    padding: 4.5rem 1.5rem 1.5rem;   /* clear the corner theme button */
  }
  .hero--split.hero--title-right .hero__headline { left: 0; top: 50%; bottom: 0; padding: 1.5rem; }
  .hero--split .hero__title { font-size: clamp(2.2rem, 9vw, 4.2rem); }
}

/* Dark: brown halves, shapes take the shared doodle tint (one step lighter so
   the moving shapes still read). */
html[data-theme="dark"] .hero-scene--magnet {
  --split-human:   #1A1111;
  --split-machine: #231717;
}
html[data-theme="dark"] .magnet__shape:not(.has-eyes) {
  filter: brightness(0) invert(0.16) sepia(1) saturate(2) hue-rotate(-45deg);   /* → #492B29 */
}
/* The two faces are inline SVG, so recolour their paint directly instead: body
   in the same #492B29 as the filtered shapes, eyes in their half's background
   brown so they read as cut-outs and the whole set stays in the browns. */
html[data-theme="dark"] .magnet__shape .magnet__body { fill: #492B29; }
html[data-theme="dark"] .split__half--human .magnet__ink   { stroke: var(--split-human); }
html[data-theme="dark"] .split__half--machine .magnet__ink { stroke: var(--split-machine); }
html[data-theme="dark"] .split__half--machine .magnet__ink-fill { fill: var(--split-machine); }

/* ---- Interaction 3: language reels (References/Hero_Interaction_3.jpg) ----
   Each half is a vertical reel of speech bubbles, positioned + spun by
   js/hero-lang.js. Bubbles are <use>s of fill-less <symbol>s, so `color`
   paints them; .is-flipped mirrors one so its tail points outward. */
.hero-scene--lang {
  --split-human:   #08D21C;   /* eyedropped from the design */
  --split-machine: #FF976A;
}
.lang__sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.lang__reel { position: absolute; inset: 0; }
.lang__bubble {
  position: absolute;
  top: 0;
  will-change: transform;
  transition: filter 0.4s ease;
}
.lang__art { display: block; width: 100%; height: auto; overflow: visible; }
.lang__art.is-flipped { transform: scaleX(-1); }
.lang__art use { fill: currentColor; }   /* the symbol's paths have no fill, so they inherit this */

/* A matched bubble says hello in its side's language (text sits on the body). */
.lang__say {
  position: absolute;
  left: 0;
  right: 0;
  transform: translateY(-50%) scale(0.85);
  /* GT Maru (rounded, like the bubbles) to set it apart from the serif title.
     GT Maru is Latin-only, so the other scripts fall back to rounded/clean
     system faces (Hiragino Maru on Apple for Japanese). */
  font-family: 'GT Maru', 'Hiragino Maru Gothic ProN', 'Hiragino Sans', 'PingFang SC',
    'Noto Sans Devanagari', 'Noto Sans Tamil', 'Noto Sans SC', 'Noto Sans JP', system-ui, sans-serif;
  font-weight: 700;
  line-height: 1;
  text-align: center;
  white-space: nowrap;
  color: #001FE5;   /* hollow bubbles: the text sits on the field (deep blue reads on both) */
  opacity: 0;
  transition: opacity 0.35s ease, transform 0.5s cubic-bezier(0.34, 1.56, 0.5, 1);
  pointer-events: none;
}
/* Chinese shouldn't borrow the Japanese rounded face's kanji forms. */
.lang__say:lang(zh) {
  font-family: 'GT Maru', 'PingFang SC', 'Hiragino Sans GB', 'Noto Sans SC', 'Microsoft YaHei', system-ui, sans-serif;
}
.lang__bubble.is-matched .lang__say {
  opacity: 1;
  transform: translateY(-50%) scale(1);
  transition-delay: 0.15s;
}
/* While a match holds, the other bubbles step back a little. */
.hero-scene--lang.is-match .lang__bubble:not(.is-matched) { filter: saturate(0.5) opacity(0.6); }

/* Dark: brown halves and brown bubbles (two tones, so shapes still read). */
html[data-theme="dark"] .hero-scene--lang {
  --split-human:   #1A1111;
  --split-machine: #231717;
}
html[data-theme="dark"] .lang__bubble { color: #492B29 !important; }   /* beats the inline per-bubble colour */
html[data-theme="dark"] .lang__bubble[data-colour="yellow"],
html[data-theme="dark"] .lang__bubble[data-colour="white"],
html[data-theme="dark"] .lang__bubble[data-colour="pink"] { color: #5C3634 !important; }
html[data-theme="dark"] .lang__say { color: #E6C697 !important; }   /* cream (Flofu's dark palette), not the title's off-white */

/* ---- Interaction 2: reflective ripples (References/Hero_Interaction_2.jpg) ----
   Each half holds a 1000×1264 artboard (the design's half-frame) that COVERS
   the half and is anchored to the divider, so the two cloud halves always meet
   there. Everything inside is %-placed by js/hero-reflect.js. */
.hero-scene--reflect {
  --split-human:   #0166FF;   /* eyedropped from the design */
  --split-machine: #FF2AA0;
}
.reflect__art {
  position: absolute;
  top: 50%;
  width: max(100%, 100cqh * 1000 / 1264);
  aspect-ratio: 1000 / 1264;
  transform: translateY(-50%);
}
.split__half--human .reflect__art   { right: 0; }
.split__half--machine .reflect__art { left: 0; }
@supports not (width: 1cqh) {
  .reflect__art { width: 100%; }
}
.reflect__waves { position: absolute; inset: 0; }
.reflect__ring,
.reflect__piece {
  position: absolute;
  display: block;
  height: auto;
  will-change: transform;
}
.reflect__piece > img,
.reflect__piece > svg { display: block; width: 100%; height: auto; }
.reflect__piece--cloud { transform-origin: 100% 50%; }   /* breathes from the divider */
.reflect__piece--drawn { transform-origin: 0 50%; }

/* Arrival: the cloud halves slide in from the divider, then the rings bloom. */
.reflect__piece,
.reflect__waves {
  opacity: 0;
  transition: opacity 1.2s ease 0.15s;
}
.hero-scene--reflect.is-active .reflect__piece,
.hero-scene--reflect.is-active .reflect__waves { opacity: 1; }
.hero-scene--reflect.is-active .reflect__waves { transition-delay: 0.45s; }

/* Dark: brown halves; the cloud, drawn half and rings take browns, the smile
   cuts out in the field colour (like Interaction 1's faces). */
html[data-theme="dark"] .hero-scene--reflect {
  --split-human:   #1A1111;
  --split-machine: #231717;
}
html[data-theme="dark"] .reflect__body { fill: #492B29; }
html[data-theme="dark"] .reflect__smile { stroke: var(--split-human); }
html[data-theme="dark"] .reflect__piece--drawn:not(.reflect__piece--eye) {
  filter: brightness(0) invert(0.16) sepia(1) saturate(2) hue-rotate(-45deg);   /* → #492B29 */
}
html[data-theme="dark"] .reflect__ring {
  filter: brightness(0) invert(0.1) sepia(1) saturate(2) hue-rotate(-45deg);    /* fainter #2E1B1A */
}
html[data-theme="dark"] .reflect__piece--eye {
  filter: brightness(0) invert(0.06) sepia(1) saturate(2) hue-rotate(-45deg);   /* → #1C1010, cut-out */
}


/* ---- "There's more below" peek ----
   Now and then (js/hero-peek.js adds .is-peeking) the Vision sun from the next
   section rises over the hero's bottom edge like a sunrise, hops once, turns a
   little and sinks back. The edge is the horizon: the nav's top rule on
   desktop, the fixed bottom bar's top on phones (--peek-floor, set in JS).
   .hero-peek is a box sitting on that line that clips the sun below it.
   --d = disc diameter; the rays spill ~0.2d past it, so at its height
   ~0.2d of disc + the rays show (about 115px on a laptop, 65px on a phone). */
.hero-peek {
  --d: clamp(150px, 19vw, 280px);
  position: absolute;
  left: 50%;
  bottom: var(--peek-floor, 0px);
  z-index: 5;                     /* over the scenes, under the question (10) */
  width: calc(var(--d) * 1.8);    /* room for the rays + text ring either side */
  height: calc(var(--d) * 0.7);   /* ...and above, at the top of the hop */
  margin-left: calc(var(--d) * -0.9);
  overflow: hidden;               /* the horizon: nothing shows below it, even
                                     once the hero scrolls up past the phone bar */
  pointer-events: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.hero-peek__sun {
  position: absolute;
  left: calc(var(--d) * 0.4);
  top: 100%;                      /* disc top on the horizon... */
  width: var(--d);
  aspect-ratio: 1;
  transform: translateY(calc(var(--d) * 0.4));   /* ...then down, rays, ring and all, out of sight */
}
.hero-peek.is-peeking .hero-peek__sun {
  pointer-events: auto;
  animation: hero-peek-rise 2.9s both;
}
.hero-peek.is-peeking .hero-peek__rays   { animation: hero-peek-turn 2.9s ease-in-out both; }
.hero-peek.is-peeking .hero-peek__spiral { animation: hero-peek-churn 2.9s ease-in-out both; }
.hero-peek.is-leaving .hero-peek__sun {
  opacity: 0;
  transition: opacity 0.3s ease;
}
/* Rise (eased out), settle, a small hop, settle, wait a beat, sink (eased in).
   Underdamped like the rest of the hero: overshoots a touch and settles. */
@keyframes hero-peek-rise {
  0%   { transform: translateY(calc(var(--d) *  0.4));  animation-timing-function: cubic-bezier(0.2, 0.7, 0.3, 1); }
  26%  { transform: translateY(calc(var(--d) * -0.25)); animation-timing-function: ease-in-out; }
  36%  { transform: translateY(calc(var(--d) * -0.19)); animation-timing-function: cubic-bezier(0.3, 0, 0.4, 1); }
  46%  { transform: translateY(calc(var(--d) * -0.29)); animation-timing-function: cubic-bezier(0.5, 0, 0.6, 1); }
  56%  { transform: translateY(calc(var(--d) * -0.2));  animation-timing-function: ease-in-out; }
  74%  { transform: translateY(calc(var(--d) * -0.21)); animation-timing-function: cubic-bezier(0.5, 0, 0.8, 0.4); }
  100% { transform: translateY(calc(var(--d) *  0.4)); }
}
/* Hovering holds it up (so it doesn't sink out from under the cursor).
   Mouse only: a tap leaves a sticky :hover on phones. */
@media (hover: hover) {
  .hero-peek:hover .hero-peek__sun,
  .hero-peek:hover .hero-peek__layer,
  .hero-peek:hover .hero-peek__half svg { animation-play-state: paused; }
}

/* The "Explore More —" ring (built in js/hero-peek.js), just outside the rays.
   Two copies, each clipped to one side of the divider so each takes its own
   half's ink (both use the lower half's on portrait screens, where the sun
   sits wholly in it). Inks are contrast-checked against each field. */
.hero-peek {
  --ink-l: #1B1B1B;
  --ink-r: #1B1B1B;
}
.hero[data-scene="0"] .hero-peek { --ink-r: var(--yellow); }   /* lime | deep blue */
html[data-theme="dark"] .hero .hero-peek { --ink-l: #E6C697; --ink-r: #E6C697; }   /* Flofu's cream */
.hero-peek__ring {
  position: absolute;
  inset: -35%;                    /* the SVG's viewBox is 1.7× the disc */
  pointer-events: none;
}
.hero-peek__half {
  position: absolute;
  inset: 0;
  color: var(--ink-l);
  clip-path: inset(0 50% 0 0);
  transition: color 0.6s ease;    /* follows the hero's colour change */
}
.hero-peek__half--r {
  color: var(--ink-r);
  clip-path: inset(0 0 0 50%);
}
@media (max-aspect-ratio: 1/1) {
  .hero-peek__half--l { color: var(--ink-r); }
}
.hero-peek__half svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
  transform: rotate(var(--ring-a0, 0deg));
}
/* The words are part of the button too (hit-testing stops at the peek box's
   clip, so only the visible arc takes taps). */
.hero-peek.is-peeking .hero-peek__ring { pointer-events: auto; }
.hero-peek.is-peeking .hero-peek__half svg { animation: hero-peek-ring 2.9s ease-in-out both; }
.hero-peek__text {
  font-family: var(--font-display);
  font-weight: 500;
  letter-spacing: 0.04em;
  fill: currentColor;
}
@keyframes hero-peek-ring {
  from { transform: rotate(calc(var(--ring-a0, 0deg) - 6deg)); }
  to   { transform: rotate(calc(var(--ring-a0, 0deg) + 8deg)); }
}
@keyframes hero-peek-turn  { from { transform: rotate(0deg); }   to { transform: rotate(32deg); } }
@keyframes hero-peek-churn { from { transform: rotate(0deg); }   to { transform: rotate(-20deg); } }
/* Idle most of the time, so don't keep its layers promoted (the animation
   promotes them while it runs). */
.hero-peek__layer { will-change: auto; }
/* Reduced motion: no peeking about, just the sun resting half-risen. */
.hero-peek.is-still .hero-peek__sun {
  transform: translateY(calc(var(--d) * -0.15));
  pointer-events: auto;
}


/* ============================================================
   NAVIGATION
   ============================================================ */
.site-nav {
  /* Default: wears the current key-visual colour (set by paint() as --nav-bg).
     Fills white on hover or once the page is scrolled. */
  background: var(--nav-bg, var(--white));
  border-top: 1.5px solid var(--black);      /* keeps the coloured bar from blending into the hero */
  border-bottom: 1.5px solid var(--black);
  position: sticky;
  top: 0;
  z-index: 100;
  padding: 0;
  transition: background 0.35s ease;
}

.site-nav:hover,
.site-nav.is-white {
  background: var(--white);
}

.site-nav__inner {
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

/* Wordmark fades in once the hero has scrolled away. */
.site-nav__brand {
  display: block;
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}

.site-nav.is-scrolled .site-nav__brand {
  opacity: 1;
  pointer-events: auto;
}

.site-nav__brand-img {
  height: 34px;   /* two-line wordmark */
  width: auto;
  filter: brightness(0);   /* white SVG → black on the white nav */
}

@media (max-width: 768px) {
  .site-nav__brand { display: none; }
}

.site-nav__links {
  display: flex;
  list-style: none;
  padding: 0;
  margin: 0;
  gap: 0;
}

.site-nav__links li {
  margin: 0;
}

/* Each nav item is themed to the key colour of the page it links to:
   Home=blue, About=red, Lab=green, Resource Hub=blue, Community=yellow.
   Drives the hover + active (selected) colour below. */
.site-nav__links li:nth-child(1) { --nav-accent: var(--blue); }
.site-nav__links li:nth-child(2) { --nav-accent: var(--red); }
.site-nav__links li:nth-child(3) { --nav-accent: var(--green); }
.site-nav__links li:nth-child(4) { --nav-accent: var(--blue); }
.site-nav__links li:nth-child(5) { --nav-accent: var(--yellow); }

.site-nav__links a {
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: 1.05rem;
  text-decoration: none;
  color: var(--nav-fg, var(--black));   /* contrasts with the coloured bar */
  text-transform: none;
  padding: 1.1rem 2rem;
  display: block;
  transition: color 0.2s, transform 0.2s ease;
}

/* Subtle scale-up on hover. */
.site-nav__links a:hover {
  transform: scale(1.15);
}

/* On the coloured bar the active link just stays in the contrast colour. */
.site-nav__links a.active {
  color: var(--nav-fg, var(--black));
}

/* Once white (hover or scrolled), links go dark with a blue hover/active. */
.site-nav:hover .site-nav__links a,
.site-nav.is-white .site-nav__links a {
  color: var(--black);
}
.site-nav:hover .site-nav__links a:hover,
.site-nav:hover .site-nav__links a.active,
.site-nav.is-white .site-nav__links a:hover,
.site-nav.is-white .site-nav__links a.active {
  color: var(--nav-accent, var(--blue));
}

/* Desktop: three columns (wordmark | links | spare, for the theme switch), so
   the links stay centred but can never run into the wordmark. In a narrower
   window the links tighten and the wordmark shrinks to fit its column. */
@media (min-width: 769px) {
  .site-nav__inner {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    column-gap: 1rem;
  }
  .site-nav__brand {
    grid-column: 1;
    justify-self: start;
    position: static;
    transform: none;
    min-width: 0;
    max-width: 100%;
  }
  .site-nav__brand-img { display: block; width: 230px; max-width: 100%; height: auto; }
  .site-nav__links { grid-column: 2; }
  .site-nav__links a {
    font-size: clamp(0.9rem, 0.55rem + 0.75vw, 1.05rem);
    padding-left: clamp(0.55rem, 4.93vw - 1.82rem, 2rem);
    padding-right: clamp(0.55rem, 4.93vw - 1.82rem, 2rem);
  }
}

/* ============================================================
   VISION / MISSION SECTION
   ============================================================ */
.vision {
  position: relative;
  isolation: isolate;
  background-color: var(--blue);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 5rem 1.5rem;
  text-align: center;
  overflow: hidden;
}

/* The sun behind the vision statement (References/Sun.svg), turned by
   js/home-sections.js. .vision__sun is a square box the size of the sun's
   DISC, centred on the section. The disc itself is plain CSS (it was only a
   gradient circle). The rays are the full artboard (3393×3719, disc r=1386 at
   1749,1782), offset so the disc fills the box and rotating about the disc's
   centre; they spill past the box and get clipped by the section. The rays are
   a pre-flattened WebP (img/vision-sun-rays.webp, built from the SVG at 2000px):
   as an SVG its ~8,000 brush curves made phones lag while it turned and swelled.
   The spiral stays an SVG, cropped to its own bounds.
   Child combinator keeps it under the later `.vision > *` rule. */
.vision > .vision__sun {
  position: absolute;
  left: 50%;
  top: 50%;
  width: max(89vw, 120vh);
  aspect-ratio: 1;
  transform: translate(-50%, -50%);   /* JS adds a small cursor/tilt nudge */
  z-index: 0;
  pointer-events: none;
}
.vision__sun-disc,
.about-hero__sun-disc {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: linear-gradient(#FF9500, #FE2A00);
}
.vision__sun-layer,
.about-hero__sun-layer,
.hero-peek__layer {
  position: absolute;
  max-width: none;
  height: auto;
  will-change: transform;
}
.vision__sun-rays,
.about-hero__sun-rays,
.hero-peek__rays {
  left: -13.086%;            /* 50% − 1749.14 / 2772.66 */
  top: -14.257%;             /* 50% − 1781.64 / 2772.66 */
  width: 122.37%;            /* 3393 / 2772.66 */
  transform-origin: 51.552% 47.906%;   /* the disc's centre within the art */
}
/* The spiral SVG's viewBox is cropped to the drawing (588.7,656.5 2220.7×2273.3). */
.vision__sun-spiral,
.about-hero__sun-spiral,
.hero-peek__spiral {
  left: 8.147%;              /* (588.7 − 362.81) / 2772.66 */
  top: 9.420%;               /* (656.5 − 395.31) / 2772.66 */
  width: 80.093%;            /* 2220.7 / 2772.66 */
  transform-origin: 52.256% 49.494%;
}
/* Each turning layer has a light and a dark copy; Dark mode swaps them (see
   the theme block) instead of filtering a layer that's moving every frame. */
.sun-dark { display: none; }

.vision > *,
.lately > *,
.site-footer > * {
  position: relative;
  z-index: 1;
}

.vision__label {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 1rem;
  color: var(--field-ink);
  margin-bottom: 1.5rem;
}

.vision__text {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: 2.75rem;
  line-height: 1.05;
  color: var(--field-ink);
  max-width: 880px;
  margin: 0 auto 2.5rem;
}

.vision__body {
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 1rem;
  line-height: 1.5;
  color: var(--field-ink);
  max-width: 700px;
  margin: 0 auto 1.5rem;
  text-align: center;
}

.vision__cta {
  margin-top: 2rem;
}
/* On the sun the CTA is a white pill with dark ink (per the wireframe); hover
   keeps the shared flowing-rainbow fill. */
.vision .btn:not(:hover) {
  background: var(--white);
  color: var(--black);
}

/* ============================================================
   BUTTONS
   ============================================================ */
.btn {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 0.95rem;
  text-decoration: none;
  padding: 0.85rem 2.25rem;
  border: none;
  color: var(--blue);
  background: var(--lime);
  cursor: pointer;
  border-radius: 100px;
  transition: transform 0.25s cubic-bezier(0.34, 1.4, 0.5, 1), box-shadow 0.25s ease;
}

.btn:hover {
  transform: scale(1.08);
  text-decoration: none;
  color: var(--white);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.16);
  background-image: linear-gradient(90deg, var(--red), var(--yellow), var(--green), var(--yellow), var(--red));
  background-size: 200% 100%;
  animation: btn-flow 2s linear infinite;
}

@keyframes btn-flow {
  to { background-position: -200% 50%; }
}

/* ============================================================
   ON-SCROLL REVEALS
   ============================================================ */
/* Simple block reveal: rise + fade when scrolled into view. */
[data-reveal] {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 0.7s ease, transform 0.7s cubic-bezier(0.2, 0.7, 0.2, 1);
  transition-delay: var(--reveal-delay, 0s);
}
[data-reveal].is-in { opacity: 1; transform: none; }

/* Line-by-line text reveal (JS splits the text into .reveal-line blocks). */
.reveal-line { display: block; overflow: hidden; padding-bottom: 0.04em; }
.reveal-line > span {
  display: inline-block;
  opacity: 0;
  transform: translateY(1.1em);
  transition: opacity 0.6s ease, transform 0.65s cubic-bezier(0.2, 0.75, 0.2, 1);
}
.reveal-lines.is-in .reveal-line > span { opacity: 1; transform: none; }

/* Partner logos scale up one-by-one, left to right. */
.partner-logo {
  opacity: 0;
  transform: scale(0.6);
  transition: opacity 0.5s ease, transform 0.5s cubic-bezier(0.34, 1.35, 0.5, 1);
}
.partner-logo.is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  [data-reveal], .reveal-line > span, .partner-logo {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
  }
}

.btn--outline {
  background: transparent;
  border: 1.5px solid var(--black);
  color: var(--black);
}

.btn--outline:hover {
  background: var(--black);
  color: var(--white);
}

/* ============================================================
   PARTNERS SECTION
   ============================================================ */
/* ============================================================
   THINGS WE DO  (yellow, 3 columns over white brush-doodles)
   ============================================================ */
.things {
  background: var(--yellow);
  padding: 6rem 1.5rem;
  text-align: center;
  position: relative;
  isolation: isolate;
  overflow: hidden;
  min-height: 100vh;              /* full-height section, like the hero */
  display: flex;
  flex-direction: column;
  justify-content: center;       /* centre the label + columns in the space */
}

.things__label {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 1rem;
  color: var(--black);
  margin-bottom: 3.5rem;
}

.things__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 3.5rem;
  width: 100%;
  max-width: var(--container-wide);
  margin: 0 auto;
}

.things__col {
  position: relative;
  isolation: isolate;
  padding: 1.5rem 1rem;
}

/* Big illustration behind each column (telescope / pencil / community, from
   References/{Telescope,Pencil,Community}.svg). Sized by width, centred, purely decorative.
   Wrapper handles the cursor PARALLAX drift (JS sets --px/--py); the inner
   image handles the springy SCALE bounce on column hover — kept on separate
   elements so the two transforms never fight. */
.things__doodle-wrap {
  position: absolute;
  left: 50%;
  top: 50%;
  /* Uniform box across all three columns (grid stretches the columns to equal
     height), so the doodles render at an equal scale and stay evenly placed
     regardless of each source SVG's aspect ratio. */
  width: 116%;
  height: 135%;
  z-index: 0;
  pointer-events: none;
  transform: translate(-50%, -50%) translate(var(--px, 0px), var(--py, 0px));
  transition: transform 0.3s ease-out;
}

.things__doodle {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;         /* scale to the shared box, preserve aspect */
  object-position: center;
  transform: scale(1);
  transition: transform 0.55s cubic-bezier(0.34, 1.56, 0.64, 1),   /* overshoot = bounce */
              opacity 0.6s ease;
}

/* While someone's reading a column, its illustration fades back so the copy
   wins. Hover on desktop; on touch screens js/home-sections.js adds
   .is-reading to the column crossing the middle of the screen. */
@media (hover: hover) {
  .things__col:hover .things__doodle {
    transform: scale(1.07);
    opacity: 0.4;
  }
}
.things__col.is-reading .things__doodle { opacity: 0.4; }
/* Dark mode swaps in hand-mapped brown versions (img/things-*-dark.svg) that
   keep each illustration's brush lines distinct from its block shapes. The
   hidden copy is display:none + loading=lazy, so it's never downloaded. */
.things__doodle--dark { display: none; }
html[data-theme="dark"] .things__doodle:not(.things__doodle--dark) { display: none; }
html[data-theme="dark"] .things__doodle--dark { display: block; }

.things__col-inner {
  position: relative;
  z-index: 1;
}

.things__heading {
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: 1.9rem;
  line-height: 1.05;
  color: var(--black);
  margin-bottom: 1.25rem;
}

.things__body {
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 0.9rem;
  line-height: 1.55;
  color: var(--black);
  text-align: center;
}

@media (max-width: 768px) {
  .things__grid { grid-template-columns: 1fr; gap: 3.5rem; }
  /* Stacked vertically here, so shrink the doodle box and contain its height to
     its own column — otherwise adjacent doodles overlap and muddy each other. */
  .things__doodle-wrap { width: 70%; height: 100%; }
}

.partners-section {
  background: var(--white);
  border-top: 1.5px solid var(--black);
  border-bottom: 1.5px solid var(--black);
  padding: 4rem 1.5rem;
  text-align: center;
}

.partners-section__title {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 1rem;
  color: var(--black);
  margin-bottom: 2.5rem;
}

.partners {
  display: flex;
  flex-wrap: wrap;
  gap: 2rem 3.5rem;
  align-items: center;
  justify-content: center;
  margin-bottom: 2.5rem;
}

.partner-logo img {
  height: 102px;
  width: auto;
  object-fit: contain;
}

/* dxd is a wide wordmark; it's a transparent PNG (no white box to knock out),
   so size it down a touch to sit visually in line with the other logos. */
.partner-logo--dxd img {
  height: 48px;
}

.partners-section__cta {
  margin-top: 1rem;
}

/* ============================================================
   LATELY SECTION
   ============================================================ */
.lately {
  background: #8800FF;   /* purple field (was --red); the starburst is a softer #8F72FA */
  padding: 4rem 1.5rem 5rem;
  overflow: hidden;
  position: relative;
  isolation: isolate;
}

/* Full-section gold brush-doodle behind the card deck (Lately Card Illustration.svg). */
.lately__doodle {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  z-index: 0;
  pointer-events: none;
}

.lately__title {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 1rem;
  color: var(--field-ink);
  text-align: center;
  margin-bottom: 2.5rem;
  position: relative;
  z-index: 5;
}

/* Flip-deck: a stack of three cycling cards, above the section doodle */
.lately__deck {
  position: relative;
  max-width: 880px;
  margin: 0 auto;
  z-index: 2;
}

.lately__stack {
  position: relative;
  z-index: 2;
  min-height: 440px;
}

.lately-card {
  position: absolute;
  inset: 0;
  background: var(--white);
  border: 1.5px solid var(--black);
  border-radius: 1.75rem;
  overflow: hidden;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  min-height: 440px;
  cursor: pointer;
  transform-origin: center bottom;
  transition: transform 0.55s cubic-bezier(.34, 1.1, .5, 1), opacity 0.4s ease,
              background-color 0.35s ease;
  will-change: transform;
}

/* Stacked positions (0 = front). All cards are absolute so none of them drive
   the stack height — the stack is given a fixed height (the tallest card,
   measured in JS) so the section stays a constant height as cards cycle and
   never nudges the footer up and down. Back cards peek out via their offsets. */
.lately-card[data-pos="0"] { transform: translate(0, 0) rotate(0deg); z-index: 3; }
/* The front card is a deep purple-black that sits quietly on the purple field,
   with light copy (18:1); the cards peeking out behind it are a flat coral
   (their copy is hidden, so they only read as a colour edge). The colours
   cross-fade as a card moves to the front or back. */
.lately-card { background: #EC5D4A; }
.lately-card > * { opacity: 0; transition: opacity 0.3s ease; }
.lately-card[data-pos="0"] { background: #0A031C; }
.lately-card[data-pos="0"] > * { opacity: 1; }
.lately-card[data-pos="0"] .lately-card__heading,
.lately-card[data-pos="0"] .lately-card__body { color: var(--white); }
.lately-card[data-pos="1"] { transform: translate(16px, 20px) rotate(1.6deg); z-index: 2; }
.lately-card[data-pos="2"] { transform: translate(32px, 40px) rotate(3.2deg); z-index: 1; }

/* Front card lifts up before being sent to the back */
.lately-card.is-flipping {
  transform: translate(-12px, -46px) rotate(-3deg) scale(1.02);
  z-index: 5;
}

.lately-card__content {
  padding: 2.5rem;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

/* Lock the CTA to the bottom of the card so it never rides up/down with body
   length. The auto top-margin pushes it down; the content's 2.5rem bottom
   padding mirrors the heading's 2.5rem top padding. */
.lately-card__content > div:last-child {
  margin-top: auto;
}

.lately-card__heading {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: 2rem;
  line-height: 1.1;
  color: var(--black);
}

.lately-card__body {
  font-family: var(--font-body);
  font-weight: 300;
  font-size: 0.85rem;
  line-height: 1.55;
  color: var(--black);
}

.lately-card__image {
  position: relative;               /* frame the photo fills exactly */
  overflow: hidden;
  border-radius: 0.75rem;
  margin: 1.25rem 1.25rem 1.25rem 0;
  min-height: 0;                    /* let it match the card, not the photo's intrinsic height */
}

.lately-card__image img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;                /* crop-to-fill inside the frame, never overflow */
}

@media (max-width: 768px) {
  /* Vertical card: image on top, text below (per the mobile design). The DOM
     order is content-then-image, so lift the image to the top with order. */
  .lately-card {
    grid-template-columns: 1fr;
    min-height: auto;
  }

  .lately-card__image {
    order: -1;
    margin: 1.25rem 1.25rem 0;
    min-height: 240px;
  }

  .lately-card__content {
    padding: 1.75rem 1.75rem 2rem;
  }
}

/* ============================================================
   SITE FOOTER (brand lockup)
   Replaces the old redundant footer nav bar. The "AI for Human
   Possibilities" lockup is a single-colour SVG (img/footer.svg?v=20261006)
   painted via mask, so its ink can be recoloured per page for
   contrast against the footer's background colour.
   ============================================================ */
.site-footer {
  /* Full-bleed colour bar: white wordmark logo left, initiative credit right,
     with a thin white rule on top. The bar colour is chosen to contrast the
     section above — the home page's purple "lately" section sits above a
     deeper purple footer (.site-footer--purple), set apart by the white rule. */
  background: var(--footer-bg, var(--red));
  position: relative;
  isolation: isolate;
  z-index: 600;   /* paints in front of Flofu (z-index 500) so he tucks behind it */
  border-top: 1.5px solid var(--white);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.4rem 2.4vw;
}

/* Home: a deeper purple than the Lately field above it, so the end of the
   page stays in one colour family (the white top rule still separates them). */
.site-footer--purple { --footer-bg: #6500BE; }

/* White wordmark (the SVG ink is already white). */
.site-footer__lockup {
  display: block;
  height: 42px;
  width: auto;
  flex-shrink: 0;
}

/* Initiative credit, right side. Live text (Newsreader regular). */
.site-footer__credit {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: 1rem;
  line-height: 1.2;
  color: var(--field-ink);
  text-align: right;
}

/* ============================================================
   GENERIC SECTIONS (reused from existing design)
   ============================================================ */
.section {
  padding: 5rem 0;
}

.section__label {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--black);
  margin-bottom: 1.5rem;
}

.section__header {
  margin-bottom: 2.5rem;
}

.section__header h2 {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: 1.75rem;
  line-height: 1.25;
  margin-bottom: 0.5rem;
}

.section__header p {
  font-family: var(--font-body);
  font-size: 0.975rem;
  line-height: 1.7;
  max-width: 640px;
  color: var(--black);
}

.section--blue {
  background: var(--blue);
  color: var(--field-ink);
}

.section--blue p,
.section--blue .section__label,
.section--blue a {
  color: var(--field-ink);
}

/* --- Cards --- */
.cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 1.5rem;
}

.card {
  padding: 2rem;
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  background: var(--white);
  border-radius: 1rem;
  box-shadow: 0 1px 3px rgba(0,0,0,0.06), 0 4px 12px rgba(0,0,0,0.04);
  transition: box-shadow 0.2s;
}

.card:hover {
  box-shadow: 0 2px 8px rgba(0,0,0,0.1), 0 8px 24px rgba(0,0,0,0.06);
}

.card__label {
  font-family: var(--font-body);
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--red);
}

.card__title {
  font-family: var(--font-serif);
  font-size: 1.05rem;
  font-weight: 500;
  line-height: 1.35;
}

.card__body {
  font-family: var(--font-body);
  font-size: 0.875rem;
  color: var(--black);
  line-height: 1.6;
  flex: 1;
  margin: 0;
}

.card__link {
  font-family: var(--font-body);
  font-size: 0.8rem;
  color: var(--blue);
  text-decoration: underline;
  margin-top: auto;
}

.badge {
  display: inline-block;
  font-family: var(--font-body);
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 0.25rem 0.75rem;
  color: var(--field-ink);
  background: var(--blue);
  border-radius: 2rem;
  width: fit-content;
}

.badge--muted {
  background: var(--black);
}

/* --- Event List --- */
.event-list {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.event-item {
  display: grid;
  grid-template-columns: 80px 1fr auto;
  gap: 1.5rem;
  padding: 1.75rem 2rem;
  align-items: start;
  background: var(--white);
  border-radius: 1rem;
  box-shadow: 0 1px 3px rgba(0,0,0,0.06), 0 4px 12px rgba(0,0,0,0.04);
}

.event-item__date {
  font-family: var(--font-body);
  font-size: 0.75rem;
  color: var(--black);
  line-height: 1.4;
}

.event-item__date strong {
  display: block;
  font-size: 1.5rem;
  color: var(--blue);
  font-weight: 400;
  font-family: var(--font-serif);
  line-height: 1;
  margin-bottom: 0.2rem;
}

.event-item__title {
  font-family: var(--font-serif);
  font-size: 1rem;
  font-weight: 500;
  line-height: 1.35;
  margin-bottom: 0.35rem;
}

.event-item__body {
  font-family: var(--font-body);
  font-size: 0.825rem;
  color: var(--black);
  margin: 0;
}

.event-item__action {
  align-self: center;
}

/* --- Resource List --- */
.resource-list {
  display: flex;
  flex-direction: column;
  border-radius: 1rem;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(0,0,0,0.06), 0 4px 12px rgba(0,0,0,0.04);
}

.resource-item {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 1.5rem;
  padding: 1.1rem 1.75rem;
  border-bottom: 1.5px solid var(--white);
  background: var(--white);
  transition: background 0.15s;
}

.resource-item:hover {
  background: var(--white);
}

.resource-item:last-child {
  border-bottom: none;
}

.resource-item__title {
  font-family: var(--font-serif);
  font-size: 0.95rem;
  font-weight: 400;
  color: var(--black);
}

.resource-item__meta {
  font-family: var(--font-body);
  font-size: 0.75rem;
  color: var(--black);
  white-space: nowrap;
  flex-shrink: 0;
}

/* --- Community CTA --- */
.community-cta {
  display: flex;
  flex-direction: column;
  gap: 1rem;
  max-width: 560px;
  margin: 0 auto;
  text-align: center;
}

/* --- Workstreams --- */
.workstreams {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 1.5rem;
}

.workstream-item {
  padding: 2rem;
  background: var(--white);
  border-radius: 1rem;
  box-shadow: 0 1px 3px rgba(0,0,0,0.06), 0 4px 12px rgba(0,0,0,0.04);
}

.workstream-item__num {
  font-family: var(--font-body);
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--red);
  margin-bottom: 0.5rem;
}

.workstream-item__title {
  font-family: var(--font-serif);
  font-size: 1rem;
  font-weight: 500;
  margin-bottom: 0.75rem;
  line-height: 1.3;
}

.workstream-item__body {
  font-family: var(--font-body);
  font-size: 0.85rem;
  color: var(--black);
  line-height: 1.6;
  margin: 0;
}

.section--blue .workstream-item {
  background: rgba(255, 255, 255, 0.12);
  box-shadow: none;
  color: var(--field-ink);
}

.section--blue .workstream-item__num {
  color: var(--yellow);
}

.section--blue .workstream-item__title {
  color: var(--field-ink);
}

.section--blue .workstream-item__body {
  color: var(--field-ink);
}

.section--blue .btn--white {
  background: var(--white);
  color: var(--black);
  border: none;
}

/* --- Page Header (subpages) --- */
.page-header {
  padding: 4rem 0 3rem;
  background: linear-gradient(to bottom, #FFB6E1, var(--white));
  text-align: center;
}

.page-header__eyebrow {
  font-family: var(--font-body);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color: var(--black);
  margin-bottom: 1rem;
}

.page-header__title {
  font-family: var(--font-serif);
  font-size: 2.5rem;
  font-weight: 500;
  margin-bottom: 1rem;
}

.page-header__intro {
  max-width: 640px;
  font-size: 1rem;
  font-family: var(--font-body);
  color: var(--black);
  margin-left: auto;
  margin-right: auto;
}

/* --- Prose --- */
.prose {
  max-width: 680px;
}

.prose h2 {
  font-family: var(--font-serif);
  margin-top: 2.5rem;
  margin-bottom: 0.75rem;
}

.prose h3 {
  font-family: var(--font-serif);
  margin-top: 1.75rem;
  margin-bottom: 0.5rem;
}

.prose p {
  font-family: var(--font-body);
  margin-bottom: 1.1em;
  line-height: 1.7;
  color: var(--black);
}

.prose ul, .prose ol {
  font-family: var(--font-body);
  padding-left: 1.5em;
  margin-bottom: 1.1em;
  font-size: 0.975rem;
}

.prose--center {
  margin-left: auto;
  margin-right: auto;
  text-align: center;
}

/* --- Two-column --- */
.two-col {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 3rem;
}

/* --- Levels (subpages) --- */
.levels {
  display: flex;
  flex-direction: column;
  border-radius: 1rem;
  overflow: hidden;
  box-shadow: 0 1px 3px rgba(0,0,0,0.06), 0 4px 12px rgba(0,0,0,0.04);
}

.level-item {
  padding: 2rem;
  border-bottom: 1.5px solid var(--white);
  background: var(--white);
}

.level-item:last-child { border-bottom: none; }

.level-item__num {
  font-family: var(--font-body);
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--red);
  margin-bottom: 0.5rem;
}

.level-item__title {
  font-family: var(--font-serif);
  font-size: 1.1rem;
  font-weight: 500;
  margin-bottom: 0.25rem;
}

.level-item__question {
  font-family: var(--font-body);
  font-size: 0.8rem;
  color: var(--blue);
  font-style: italic;
  margin-bottom: 0.75rem;
}

.level-item__body {
  font-family: var(--font-body);
  font-size: 0.9rem;
  color: var(--black);
  line-height: 1.65;
  max-width: 680px;
  margin: 0;
}

/* --- Inset Panel --- */
.inset-panel {
  background: var(--white);
  border-radius: 1rem;
  padding: 3rem;
  color: var(--black);
}

.inset-panel p { color: var(--black); }

/* --- Back Link --- */
.back-link {
  display: inline-block;
  font-family: var(--font-body);
  font-size: 0.8rem;
  color: var(--blue);
  text-decoration: none;
  margin-bottom: 1.5rem;
}
.back-link:hover { text-decoration: underline; }
.back-link::before { content: '\2190\00a0'; }

/* ============================================================
   RESPONSIVE
   ============================================================ */
@media (max-width: 768px) {
  /* --- Full-height stacked sections (svh accounts for mobile browser chrome) --- */
  .hero   { min-height: 100vh; min-height: 100svh; }
  .vision { min-height: 100vh; min-height: 100svh; }
  .things { min-height: 100vh; min-height: 100svh; }

  /* --- Hero: wordmark now lives in the bottom bar, so drop the hero logo mark.
     Headline goes large and left-aligned, dropping across more lines. --- */
  .hero__logo { display: none; }
  .hero__headline {
    text-align: left;
    padding: 2rem 1.5rem;
  }
  .hero__title {
    font-size: clamp(2.8rem, 12vw, 4.2rem);
    max-width: none;
    margin: 0;
    line-height: 1.0;
  }

  /* Narrow screens keep the locked artboard composition and crop its sides. */

  /* --- Vision: bigger serif statement across more lines (per mobile design) --- */
  .vision__text {
    font-size: clamp(2rem, 7.5vw, 2.6rem);
  }

  .vision__body {
    font-size: 0.95rem;
  }

  /* --- Things: larger stacked headings --- */
  .things__heading {
    font-size: 2.3rem;
  }
  .things__body {
    font-size: 1rem;
    max-width: 32ch;
    margin-left: auto;
    margin-right: auto;
  }

  /* --- Partners: shrink logos, hold to a max of two rows (3 + 2) --- */
  .partners {
    gap: 1.5rem 2rem;
    max-width: 340px;
    margin-left: auto;
    margin-right: auto;
  }

  .partner-logo img {
    height: 42px;
  }
  .partner-logo--dxd img {
    height: 22px;
  }

  .lately-card__heading {
    font-size: 1.6rem;
  }

  .cards {
    grid-template-columns: 1fr;
  }

  .workstreams {
    grid-template-columns: 1fr;
  }

  .two-col {
    grid-template-columns: 1fr;
    gap: 1.5rem;
  }

  .event-item {
    grid-template-columns: 60px 1fr;
  }

  .event-item__action {
    grid-column: 2;
    justify-self: start;
  }

  .resource-item {
    flex-direction: column;
    gap: 0.35rem;
  }

  .page-header__title {
    font-size: 1.75rem;
  }

  .inset-panel {
    padding: 2rem 1.5rem;
  }

  /* Footer: the wordmark now lives in the sticky bottom bar, so drop it here to
     avoid showing "Flourishing Futures…" twice; keep just the credit, centred. */
  .site-footer {
    justify-content: center;
    text-align: center;
    padding: 1rem 1.5rem;
  }
  .site-footer__lockup { display: none; }
  /* Keep the credit on one line, shrinking with the viewport so it never wraps. */
  .site-footer__credit { text-align: center; white-space: nowrap; font-size: clamp(0.6rem, 3.2vw, 1rem); }
}

@media (max-width: 480px) {
  .hero__logo-mark {
    width: 150px;
  }

  .hero__headline {
    padding: 2rem 1.25rem 0;
  }

  .site-nav__links a {
    padding: 0.7rem 0.5rem;
    font-size: 0.68rem;
  }
}

/* ============================================================
   FLOATING ASSISTANT ("Flofu")
   Fixed bottom-right, above the content. Hidden until the user
   scrolls off the landing hero, then slides up and stays put.
   ============================================================ */
.site-assistant {
  position: fixed;
  right: 1.25rem;
  bottom: 0;                            /* flat feet flush with the window edge */
  z-index: 500;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  pointer-events: none;                 /* wrapper is inert; children opt back in */
  opacity: 0;
  transform: translateY(130%);
  /* Ease-out with NO overshoot: it must not bounce up past its resting spot,
     which would lift the flat feet off the window edge and reveal the crop. */
  transition: transform 0.55s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.35s ease;
}
.site-assistant.is-visible {
  opacity: 1;
  transform: translateY(0);
}

.site-assistant__char {
  pointer-events: auto;
  display: block;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  width: clamp(112px, 13vw, 164px);
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.2s ease;
  /* Sink the eels a touch so the drawing's faded tail slips below the window
     edge — they read as heads poking up out of the ground rather than a
     picture that stops. The bottom "extra length" is what bobs into view. */
  --flofu-sink: 8%;
  transform: translateY(var(--flofu-sink, 0px));
}
.site-assistant__char:hover { transform: translateY(calc(var(--flofu-sink, 0px) - 3px)); }
.site-assistant__char:focus-visible {
  outline: 3px solid var(--blue);
  outline-offset: 4px;
  border-radius: 12px;
}
.assistant-svg { display: block; width: 100%; height: auto; }

/* Its one eye reuses the hero pupil convention (JS transforms this group). */
.site-assistant .pupil { transition: transform 0.12s ease; }

/* Manifesto words Flofu can quip about — a very subtle dotted underline hints
   they're interactive; the ? cursor reinforces it. */
.flofu-cue {
  cursor: help;
  text-decoration: underline dotted;
  text-decoration-thickness: 2px;
  text-underline-offset: 0.18em;
  text-decoration-color: color-mix(in srgb, currentColor 68%, transparent);
}

/* Speech bubble — real HTML text so future messages can change. Hidden until
   the character is tapped (.is-open on the wrapper). */
.site-assistant__bubble {
  pointer-events: none;
  margin: 0 0.5rem 0.5rem 0;
  padding: 0.55rem 1.1rem;
  max-width: 80vw;              /* safety cap only — quips stay on one line */
  background: var(--black);
  color: var(--white);
  font-family: var(--font-serif);
  font-weight: 600;
  font-size: 1.05rem;
  line-height: 1.25;
  border-radius: 999px;
  white-space: nowrap;          /* single line so the pill hugs the text, no side gaps */
  position: relative;
  opacity: 0;
  transform: translateY(6px) scale(0.96);
  transform-origin: bottom right;
  transition: opacity 0.18s ease, transform 0.18s ease;   /* used for the EXIT */
}
/* Little tail pointing down toward the character. */
.site-assistant__bubble::after {
  content: "";
  position: absolute;
  right: 2.25rem;
  bottom: -7px;
  width: 16px;
  height: 16px;
  background: var(--black);
  border-radius: 3px;
  transform: rotate(45deg);
}
.site-assistant.is-open .site-assistant__bubble {
  pointer-events: auto;
  opacity: 1;
  transform: translateY(0) scale(1);
  /* iMessage-style pop on entrance; replayed on every click via JS. */
  animation: bubble-pop 0.3s cubic-bezier(0.34, 1.5, 0.5, 1);
}
@keyframes bubble-pop {
  0%   { opacity: 0; transform: translateY(6px) scale(0.4); }
  55%  { opacity: 1; transform: translateY(0) scale(1.05); }
  100% { opacity: 1; transform: translateY(0) scale(1); }
}

@media (max-width: 768px) {
  /* Tuck him just behind the fixed bottom bar's top edge (it paints in front) so
     he reads as popping up from behind it; a touch smaller so he's unobtrusive.
     On the home page the scroll script raises him to rest on the footer at the
     very bottom. */
  .site-assistant { right: 0.75rem; bottom: 50px; }
  .site-assistant__char { width: clamp(76px, 22vw, 104px); }
  .site-assistant__bubble { font-size: 0.9rem; }
}

@media (prefers-reduced-motion: reduce) {
  .site-assistant {
    transition: opacity 0.2s ease;
    transform: none;
  }
  .site-assistant.is-visible { transform: none; }
  .site-assistant__bubble {
    transition: opacity 0.2s ease;
    transform: none;
  }
  .site-assistant.is-open .site-assistant__bubble { transform: none; animation: none; }
  .site-assistant .pupil { transition: none; }
}

/* ============================================================
   ABOUT PAGE
   Brings the About page in line with the home art direction:
   full-bleed brush-doodle illustrations behind bold colour
   fields, serif statements, on-scroll reveals.
   ============================================================ */

/* Nav sits at the very top of the About page (no hero above it), so it wears
   the solid-white treatment from the start with its wordmark always shown. */
.site-nav--solid { background: var(--white); }
.site-nav--solid .site-nav__brand { opacity: 1; pointer-events: auto; }
.site-nav--solid .site-nav__links a { color: var(--black); }
.site-nav--solid .site-nav__links a:hover,
.site-nav--solid .site-nav__links a.active { color: var(--nav-accent, var(--blue)); }

/* White outline pill (used on the coloured sections). */
.btn--outline-white {
  background: transparent;
  border: 1.5px solid var(--white);
  color: var(--white);
}
.btn--outline-white:hover {
  background: var(--white);
  color: var(--black);
}

/* Light footer variant (dark ink on white) for the About page. */
.site-footer--light { background: var(--white); border-top: 1.5px solid var(--black); }
.site-footer--light .site-footer__lockup { filter: brightness(0); }
.site-footer--light .site-footer__credit { color: var(--black); }

/* On mobile the footer sits right above the white bottom bar, so give the light
   footer a green fill to keep it distinct from the bar; credit flips to white. */
@media (max-width: 768px) {
  .site-footer--light { background: var(--green); border-top-color: var(--green); }
  .site-footer--light .site-footer__credit { color: var(--white); }
}

/* ---- 1. Hero: "What matters most to us" (red, sunrise) ---- */
.about-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: #D92400;   /* a clean sunrise red (the wireframe's #D23C20 read muddy) */
  color: var(--field-ink);
  min-height: 100vh;
  min-height: 100svh;   /* full viewport (accounts for mobile browser chrome) */
  display: flex;
  flex-direction: column;
  justify-content: center;
  text-align: center;
  padding: 6rem 1.5rem;
}
/* The sunrise (js/about-sunrise.js). Per the wireframe, the disc is ~92% of
   the width and sits low: top arc ~14% down, centre ~72% down, so its lower
   half sinks below the section. .about-hero__sun is a square the size of the
   DISC; the layers reuse the home Vision sun's offsets (see .vision__sun-layer)
   so the disc fills the box and turns about its own centre. JS sets the rise
   via transform, starting below the fold. */
.about-hero__sun {
  position: absolute;
  left: 50%;
  top: 14%;
  width: max(92vw, 100vh);
  aspect-ratio: 1;
  transform: translate(-50%, 55%);   /* pre-rise pose until the JS takes over */
  z-index: 0;
  pointer-events: none;
}
.about-hero.is-risen .about-hero__sun { transform: translate(-50%, 0); }
/* (The layers share the home Vision sun's rules above.) */
/* The sky warms as the sun comes up: a soft orange glow behind it. JS fades
   its opacity in with the rise (on this element only, so the rest of the hero
   isn't restyled every frame). */
.about-hero__glow {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: radial-gradient(ellipse 80% 70% at 50% 85%, rgba(255, 149, 0, 0.45), rgba(255, 149, 0, 0) 70%);
  will-change: opacity;
}
.about-hero__inner {
  position: relative;
  z-index: 1;
  max-width: 680px;
  margin: 0 auto;
}
.about-hero__label,
.about-drive__label {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 1rem;
  color: var(--field-ink);
  margin-bottom: 1.5rem;
}
.about-hero__title {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: var(--fs-title);
  line-height: 1.06;
  color: var(--field-ink);
  margin: 0 auto 1.75rem;
}
.about-hero__title-lead {
  display: block;
  font-weight: 500;         /* same treatment as the rest of the title */
  font-size: 1em;
  margin-bottom: 0.15em;
}
.about-hero__body {
  font-family: var(--font-body);
  font-weight: 300;
  font-size: var(--fs-body);
  line-height: 1.55;
  color: var(--field-ink);
  max-width: 580px;
  margin: 0 auto 2rem;
}
.about-hero__cta { margin-top: 0.5rem; }

/* ---- 2. "We work to drive..." (green, a blooming succulent) ---- */
.about-drive {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  background: #004106;   /* deep green behind the bright plant: one family, but dark
                            enough that the bloom still pops (was blue #081EDC). The
                            copy sits on the plant's bright middle, not this field. */
  border-top: 1.5px solid var(--black);   /* page divider from the red hero above */
  text-align: center;
  padding: 6.5rem 1.5rem;
}
/* The succulent (js/about-bloom.js), seen from above and centred on the
   section. Per the wireframe its leaves run well past the edges (the plant is
   ~1.6× the section width), so only the rosette sits fully in view. */
.about-drive__bloom {
  position: absolute;
  left: 50%;
  top: 50%;
  width: max(160vw, 200vh);
  aspect-ratio: 1;
  transform: translate(-50%, -50%);   /* js/about-bloom.js adds the slow turn + breath here */
  z-index: 0;
  pointer-events: none;
  will-change: transform;   /* one layer, turned whole (turning the <svg> redrew every path) */
}
.succ {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
}
/* Petals are SVG <g>s: will-change on them doesn't buy compositing, so leave it off. */
/* Phones + touch tablets: the plant sits still and open (js/about-bloom.js skips
   them), so no GPU layer: at this size it ran past what a phone can hold. */
@media (max-width: 768px), (hover: none) {
  .about-drive__bloom { will-change: auto; }
}
@media (max-width: 768px) {
  /* Phones: the column of text is far taller than it is wide, so the plant is
     sized off the SECTION's height (it always runs past the top and bottom)
     rather than the screen: at 2× the section's height its solid middle (the
     petals and rosette) covers the whole text column, so the dark-green copy
     never falls onto the deep-green field between the leaf tips. The copy is
     small and the side padding slim so the column stays short (~16-21 lines
     on a phone) and the plant doesn't have to be enormous. */
  .about-drive { padding: 3.5rem 0; }
  .about-drive__inner { padding: 0 1.25rem; }
  .about-drive__bloom { width: auto; height: max(200%, 230vw); }
  .about-drive__label { margin-bottom: 1.2rem; }
  .about-drive__title { font-size: 1.5rem; line-height: 1.15; margin-bottom: 1.25rem; }
  .about-drive__body { font-size: 0.9rem; line-height: 1.5; margin-bottom: 0.875rem; }
}

/* The text column sits above the plant; transparent to the pointer except the
   genuinely interactive bits (the button + Flofu cue words). */
.about-drive__inner { position: relative; z-index: 1; pointer-events: none; }
.about-drive__inner .btn,
.about-drive__inner .flofu-cue { pointer-events: auto; }
.about-drive__title {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: var(--fs-title);
  line-height: 1.08;
  color: #003615;   /* deep green on the bright plant (5.3:1 or better on every paint) */
  max-width: 820px;
  margin: 0 auto 2.25rem;
}
.about-drive__body {
  font-family: var(--font-body);
  font-weight: 300;
  font-size: var(--fs-body);
  line-height: 1.55;
  color: #003615;
  max-width: 680px;
  margin: 0 auto 1.4rem;
}
.about-drive__label { color: #003615; }
.about-drive__cta { margin-top: 2rem; }

/* ---- 3. "Why here, why now?" (blue, 3 numbered columns) ---- */
.about-why {
  background: var(--blue);
  color: var(--field-ink);
  padding: 6rem 1.5rem;
  text-align: center;
}
.about-why__label {
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 1rem;
  color: #5FD35F;   /* the same green as the 1-2-3 badges (4.8:1 on the blue) */
  margin-bottom: 3.5rem;
}
.about-why__cols {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 3rem;
  max-width: var(--container-wide);
  margin: 0 auto;
}
/* Wrapper drifts toward the cursor (JS parallax); the inner image springs on
   column hover — kept on separate elements so the two transforms never fight
   (same split as the home "things" doodles). */
.about-why__num-wrap {
  display: block;
  width: 118px;
  margin: 0 auto 1.5rem;
  transition: transform 0.3s ease-out;
  will-change: transform;
}
.about-why__num {
  display: block;
  width: 100%;
  height: auto;
  transform: rotate(0deg) scale(1);
  transition: transform 0.55s cubic-bezier(0.34, 1.56, 0.64, 1);   /* overshoot bounce */
}
.about-why__col:hover .about-why__num { transform: rotate(-4deg) scale(1.1); }
.about-why__col-title {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: var(--fs-subhead);
  line-height: 1.15;
  color: var(--field-ink);
  margin-bottom: 1rem;
}
.about-why__col-body {
  font-family: var(--font-body);
  font-weight: 300;
  font-size: var(--fs-body);
  line-height: 1.55;
  color: var(--field-ink);
  max-width: 340px;
  margin: 0 auto;
}

/* ---- 4. "A shift towards..." (off-white, lime looping arrow + 4 labels) ---- */
.about-shift {
  background: #EAEAEA;   /* a calm off-white (was yellow); the arrow is lime */
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 6rem 1.5rem;
  text-align: center;
  overflow: hidden;
}
.about-shift__title {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: var(--fs-title);
  line-height: 1.08;
  color: var(--black);
  max-width: 980px;
  margin: 0 auto;
}
/* The four points sit in one neat, top-aligned row; the brush arrow (Arrow.svg)
   sits BEHIND them, spanning the row, and "draws on" left-to-right via a clip-path
   wipe as the section scrolls in (drawArrow in the inline script). Under reduced
   motion the JS is skipped and the arrow simply shows fully. */
.about-shift__diagram {
  position: relative;
  max-width: 1200px;
  margin: 4rem auto 0;
  display: flex;
  align-items: flex-start;
  gap: 2.5rem;
  padding: 4rem 0;
}
.about-shift__arrow {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 100%;
  height: auto;
  object-fit: contain;
  z-index: 0;
  pointer-events: none;
  will-change: clip-path;
}
.about-shift__item {
  position: relative;
  z-index: 1;
  flex: 1 1 0;
  text-align: left;
}
.about-shift__item h3 {
  font-family: var(--font-serif);
  font-weight: 700;
  font-size: var(--fs-subhead);
  line-height: 1.1;
  color: var(--black);
  margin-bottom: 0.45rem;
}
.about-shift__item p {
  font-family: var(--font-body);
  font-weight: 400;
  font-size: var(--fs-body);
  line-height: 1.55;
  color: var(--black);
}

/* ---- 5. "We work to develop..." (blue, green scribble + outcomes box) ---- */
.about-develop {
  position: relative;
  overflow: hidden;              /* clip the green scribble that runs past the box */
  background: #0066FF;           /* easier on the eyes than the white it replaced */
  padding: 5.5rem 1.5rem 6rem;
}
.about-develop__label {
  position: relative;
  z-index: 2;                    /* stays above the green scribble behind the box */
  font-family: var(--font-display);
  font-weight: 900;
  font-size: 1rem;
  color: var(--field-ink);       /* 4.4:1 on the blue (black was 3.6:1) */
  text-align: center;
  margin-bottom: 3rem;
}
.about-develop__inner {
  position: relative;
  max-width: 1000px;
  margin: 0 auto;
}
/* Full-bleed: the hand-drawn green squiggle runs edge to edge across the whole
   section (behind the box, over the critters), clipped by overflow:hidden. The
   1.04 overscan lets js/about-critters.js drift it without exposing an edge. */
.about-develop__art {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  z-index: 0;
  pointer-events: none;
  transform: scale(1.04);
  will-change: transform;
}

/* The three blob critters (js/about-critters.js). Each .dev-critter is pinned
   by its EYES: left/top is where the eye pair goes, and the translate pulls the
   art back by --fx/--fy (the eyes' spot within it), so the faces always land in
   the open space beside the box and the bodies tuck in behind it. */
.dev-critters { position: absolute; inset: 0; z-index: 0; pointer-events: none; }
.dev-critter {
  position: absolute;
  transform: translate(calc(var(--fx) * -100%), calc(var(--fy) * -100%));
}
.dev-critter__bob { will-change: transform; }
.dev-critter__svg { display: block; width: 100%; height: auto; overflow: visible; }
/* Wide screens: faces in the gutters either side of the 760px box (the middle
   of the left gutter is 25% − 190px; of the right, 75% + 190px). */
.dev-critter--green  { left: max(7%, calc(25% - 190px)); top: 15%; width: clamp(300px, 36vw, 640px); }
.dev-critter--blue   { left: min(93%, calc(75% + 190px)); top: 44%; width: clamp(260px, 30vw, 540px); }
.dev-critter--orange { left: max(8%, calc(25% - 175px)); top: 84%; width: clamp(280px, 32vw, 560px); }
/* Narrower: no gutters, so faces move into the bands above / below the box. */
@media (max-width: 1080px) {
  .dev-critter--green  { left: 17%; top: 3.6rem; width: 300px; }
  .dev-critter--blue   { left: 84%; top: calc(100% - 2.6rem); width: 260px; }
  .dev-critter--orange { left: 18%; top: calc(100% - 2.8rem); width: 280px; }
}
@media (max-width: 560px) {
  .dev-critter--green  { left: 14%; top: 3.4rem; width: 220px; }
  .dev-critter--blue   { left: 86%; top: calc(100% - 2.4rem); width: 190px; }
  .dev-critter--orange { left: 16%; top: calc(100% - 2.6rem); width: 200px; }
}
/* Blinks (each eye squashes about its own centre). */
.dev-critter__eye { transform-box: fill-box; transform-origin: center; }
.dev-critter__eyes.is-blinking .dev-critter__eye { animation: critter-blink 0.22s ease-in-out; }
@keyframes critter-blink {
  0%, 100% { transform: none; }
  45%, 55% { transform: scaleY(0.1); }
}
.about-develop__box {
  position: relative;
  z-index: 1;
  max-width: 760px;
  margin: 0 auto;
  background: var(--white);
  border: 1.5px solid var(--black);
  border-radius: 1.5rem;
  padding: 0.5rem 2.75rem 1rem;
}
.about-develop__item {
  padding: 1.6rem 0;
  border-bottom: 1.5px solid var(--black);
}
.about-develop__item--last { border-bottom: none; }
.about-develop__item-heading {
  margin: 0;
  font: inherit;
}
.about-develop__item-trigger {
  display: flex;
  width: 100%;
  align-items: flex-start;       /* pin the +/- to the title's first line */
  justify-content: space-between;
  gap: 1rem;
  padding: 0;
  background: none;
  border: 0;
  text-align: left;
  cursor: pointer;
  color: inherit;
}
.about-develop__item-title {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: var(--fs-list);
  line-height: 1.12;
  color: var(--black);
  transition: transform 0.25s ease, color 0.25s ease;
}
.about-develop__item-trigger:hover .about-develop__item-title,
.about-develop__item-trigger:focus-visible .about-develop__item-title {
  transform: translateX(4px);
  color: var(--green);              /* matches the green squiggle behind the box */
}
/* Persistent +/- icon: two bars drawn in currentColor. The vertical bar
   collapses (scaleY 0) when the row opens, morphing the + into a -. */
.about-develop__item-icon {
  position: relative;
  flex: none;
  width: 18px;
  /* Height matches the title's first line box (font-size x line-height), and the
     trigger's flex-start alignment tops it with the title — so the cross sits
     centred on line 1 regardless of how many lines the title wraps to. */
  font-size: var(--fs-list);
  height: 1.12em;
  color: var(--black);
  transition: color 0.25s ease;
}
.about-develop__item-icon::before,
.about-develop__item-icon::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  background: currentColor;
  transition: transform 0.45s cubic-bezier(0.65, 0, 0.35, 1);
}
.about-develop__item-icon::before {          /* horizontal bar (always shown) */
  width: 18px;
  height: 2px;
  transform: translate(-50%, -50%);
}
.about-develop__item-icon::after {           /* vertical bar (hidden when open) */
  width: 2px;
  height: 18px;
  transform: translate(-50%, -50%);
}
.about-develop__item.is-open .about-develop__item-icon::after {
  transform: translate(-50%, -50%) scaleY(0);
}
.about-develop__item-trigger:hover .about-develop__item-icon,
.about-develop__item-trigger:focus-visible .about-develop__item-icon {
  color: var(--green);              /* matches the green squiggle behind the box */
}
/* Collapse via grid-rows 0fr -> 1fr; inner wrapper clips the content. */
.about-develop__item-panel {
  display: grid;
  grid-template-rows: 0fr;
  /* ease-in-out both ends: gentle start, gentle settle */
  transition: grid-template-rows 0.45s cubic-bezier(0.65, 0, 0.35, 1);
}
.about-develop__item.is-open .about-develop__item-panel {
  grid-template-rows: 1fr;
}
.about-develop__item-panel-inner {
  overflow: hidden;
  min-height: 0;
}
.about-develop__item-desc {
  font-family: var(--font-body);
  font-weight: 300;
  font-size: var(--fs-body);
  line-height: 1.55;
  color: var(--black);
  margin-top: 0.85rem;
  max-width: 560px;
}
@media (prefers-reduced-motion: reduce) {
  .about-develop__item-title,
  .about-develop__item-icon,
  .about-develop__item-panel {
    transition: none;
  }
  .about-develop__item-icon::before,
  .about-develop__item-icon::after {
    transition: none;
  }
}

@media (max-width: 900px) {
  .about-why__cols { grid-template-columns: 1fr; gap: 3.5rem; }
  .about-why__col-body { max-width: 420px; }

  /* Gold section: stack the labels vertically and rotate the brush arrow so it
     points DOWN behind the stack (it spans the row horizontally on desktop). The
     draw-on clip then wipes top-to-bottom, toward the arrowhead. */
  .about-shift__diagram {
    flex-direction: column;
    align-items: stretch;
    max-width: 540px;
    padding: 2.5rem 0;
    gap: 2.75rem;
    position: relative;
  }
  .about-shift__arrow {
    position: absolute;
    top: 50%;
    left: 50%;
    width: 64vh;                 /* pre-rotation width becomes the visual height */
    height: auto;
    margin: 0;
    transform: translate(-50%, -50%) rotate(90deg);
    transform-origin: center;
  }
  .about-shift__item {
    text-align: center;
    margin: 0 auto 0.5rem;
  }
  .about-shift__item p { max-width: 360px; margin: 0 auto; }
}

@media (max-width: 768px) {
  .about-develop__box { padding: 0.5rem 1.5rem 1rem; }
  .about-develop__art { height: 102%; }

  /* Shrink the 1/2/3 brush numerals ~20% on mobile (118px -> 94px). */
  .about-why__num-wrap { width: 94px; }
}

/* ============================================================
   LAB PAGE
   Single-screen "Meet the AI Lab / Coming soon" hero on the green
   field — two-colour brush-doodle parallax (mirrors .about-hero__*),
   a riso grain overlay, and Flofu docked over a transparent footer.
   ============================================================ */
.lab-hero {
  position: relative;
  /* Fill the window under the sticky top nav (~62px, in the page flow), so
     the whole workbench fits without scrolling. */
  min-height: calc(100vh - 62px);
  min-height: calc(100svh - 62px);
  display: flex;
  flex-direction: column;
  background: var(--lab-field);
  overflow: hidden;
}
/* The Lab is one green family, like Dark mode is one brown family: a deep
   forest field, with every toy repainted in jade / teal / mint / sage / lime
   (img/lab-toy-*.svg + the face templates in the-lab.html). The lens of the
   telescope and the eyes are the only notes that aren't green. */
.lab-hero,
.site-footer--lab { --lab-field: #0A4429; }
html[data-theme="dark"] .lab-hero,
html[data-theme="dark"] .site-footer--lab { --lab-field: var(--green); }   /* the dark brown field */
/* The workbench (js/lab-toys.js): shapes are absolutely placed by the physics
   loop (transform per frame). The stage itself never takes the pointer, so
   links and text stay usable; the hero handles grab / drop. */
.lab-toys {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  pointer-events: none;
}
.lab-toy {
  position: absolute;
  top: 0;
  left: 0;
  will-change: transform;
  transition: opacity 0.6s ease, filter 0.2s ease;
}
.lab-toy > img { display: block; width: 100%; height: 100%; object-fit: contain; pointer-events: none; user-select: none; }
.lab-toy.is-leaving { opacity: 0; }
/* A freshly merged shape pops in (on the inner art, so it doesn't fight the
   physics transform on .lab-toy). */
.lab-toy.is-born > * { animation: lab-born 0.55s cubic-bezier(0.34, 1.56, 0.5, 1); }
@keyframes lab-born { 0% { transform: scale(0.6); } 100% { transform: scale(1); } }
.lab-toy > svg { display: block; width: 100%; height: 100%; overflow: visible; }
/* Faces: eyes blink about their own centres. */
.lab-eye__lid { transform-box: fill-box; transform-origin: center; }
.lab-toy.is-blinking .lab-eye__lid { animation: lab-blink 0.24s ease-in-out; }
@keyframes lab-blink { 0%, 100% { transform: none; } 45%, 55% { transform: scaleY(0.08); } }
/* The burst where two ideas combine: 8 dots fly out and fade. */
.lab-burst { position: absolute; width: 0; height: 0; pointer-events: none; z-index: 2; }
.lab-burst > i {
  position: absolute;
  left: -7px; top: -7px;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--lime);
  animation: lab-burst 0.8s cubic-bezier(0.2, 0.7, 0.3, 1) forwards;
}
.lab-burst > i:nth-child(even) { background: #B8F04A; width: 10px; height: 10px; left: -5px; top: -5px; }
@keyframes lab-burst {
  0%   { transform: rotate(var(--a)) translateX(0) scale(1); opacity: 1; }
  100% { transform: rotate(var(--a)) translateX(calc(var(--s) * 0.6)) scale(0.3); opacity: 0; }
}
/* Reduced motion: a still line-up along the floor. */
.lab-toy.is-static { top: auto; bottom: -2%; }
.lab-toy.is-static > img { height: auto; }
.lab-hero { cursor: crosshair; touch-action: pan-y; }   /* click empty space = drop an idea */
.lab-hero.is-over-toy { cursor: grab; }
.lab-hero.is-grabbing, .lab-hero.is-grabbing * { cursor: grabbing; }
.lab-hero a, .lab-hero button { cursor: pointer; }
.lab-hero__inner {
  position: relative;
  z-index: 2;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 1.4rem;
  max-width: var(--container-wide);
  margin: 0 auto;
  padding: 4rem 1.5rem 3.5rem;   /* the nav is in the flow above, so no big clearance needed */
  pointer-events: none;        /* shapes can be grabbed through the gaps … */
}
.lab-hero__inner > * { pointer-events: auto; }   /* … but the copy and links still work */
/* Narrow screens: shapes fall BEHIND the copy (no glass shelf), so the copy
   gets a soft green halo to stay readable over them. */
/* Copy that shapes can drift over (all of it on narrow screens; on wide ones
   everything but the headline, which has the glass) gets a soft green halo. */
.lab-hero__inner > *:not(.lab-hero__title),
.lab-hero.is-narrow-bench .lab-hero__inner > * {
  text-shadow: 0 0 18px var(--lab-field), 0 0 6px var(--lab-field);
}
.lab-hero__title { cursor: text; }
.lab-hero__label {
  font-family: var(--font-display);
  font-weight: 900;
  color: var(--lime);
  font-size: 1.05rem;
  letter-spacing: 0.01em;
  margin: 0;
  max-width: 100%;
}
.lab-hero__title {
  font-family: var(--font-serif);
  font-weight: 500;
  color: var(--field-ink);
  line-height: 1.05;
  font-size: clamp(2rem, 5.2vw, 4.6rem);
  margin: 0;
  max-width: min(22ch, 100%);
}
.lab-hero__soon {
  font-family: var(--font-display);
  font-weight: 900;
  color: #7FE0B0;   /* mint: in the field's family, not a blue that fights it */
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: 1.05rem;
  margin: 0.4rem 0;
}
.lab-hero__cta {
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--field-ink);
  font-size: 1.05rem;
  line-height: 1.5;
  max-width: min(42ch, 100%);
  margin: 0;
}
.lab-hero__chat {
  color: var(--field-ink);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.lab-hero__chat:hover { color: var(--lime); }

/* Lab footer: its own solid green bar below the hero (same pattern as the
   home/about footers — a colour band with the shared white top rule), so the
   brush doodles never cut into the wordmark or credit. Ink is lime for
   legibility on the green. */
.site-footer--lab { background: var(--lab-field); color: var(--lime); }   /* match the lab-hero field */
/* Lab footer ink is the page's lime (matches the hero label + "Let's chat")
   for legibility on the green. The wordmark is inlined as an SVG whose path
   is fill:currentColor, so this colour drives it (robust everywhere, unlike a
   same-origin CSS mask). Sizing is inherited from the base .site-footer__lockup
   rule (height 42px, width auto from the SVG's own aspect ratio). */
.site-footer--lab .site-footer__lockup { color: var(--lime); }
.site-footer--lab .site-footer__credit { color: var(--lime); }

@media (max-width: 768px) {
  /* The fixed bar sits at the BOTTOM on mobile, so drop the big top padding that
     was clearing a top nav — balanced padding lets the content centre properly
     (fixes the awkward empty band up top). Title grows to fill the field. */
  .lab-hero { min-height: 100vh; min-height: 100svh; }   /* nav is a fixed bottom bar here */
  .lab-hero__inner { padding: 2.5rem 1.5rem; gap: 1.2rem; }
  .lab-hero__title { font-size: clamp(2.6rem, 12vw, 3.4rem); }
  .site-footer--lab {
    flex-wrap: wrap;
    justify-content: center;
    text-align: center;
    padding: 1.4rem 1.5rem;
    background: #06321F;   /* a shade deeper than the hero, so the bar still reads as its own band */
  }
  .site-footer--lab .site-footer__credit { text-align: center; color: var(--white); }
}

/* ============================================================
   MOBILE NAV — bottom bar hamburger + liquid-glass menu
   -----------------------------------------------------------
   SHARED COMPONENT: this block is duplicated verbatim in
   css/styles.css. Keep the two copies in sync.

   Desktop (>768px): the burger and overlay are hidden; the
   normal horizontal .site-nav is untouched.
   Mobile (<=768px): .site-nav becomes a fixed bottom bar with
   the wordmark + a brush hamburger; tapping balloons a
   full-screen frosted overlay up from the hamburger.
   ============================================================ */

/* Page key colour → --key (drives the glass tint + inverted bar). */
body[data-key="blue"]   { --key: var(--blue); }
body[data-key="red"]    { --key: var(--red); }
body[data-key="green"]  { --key: var(--green); }
body[data-key="yellow"] { --key: var(--yellow); }

/* Hidden on desktop. */
.nav-burger { display: none; }
.mobile-menu { display: none; }

/* Brush hamburger / close button (two crossfading brush icons). */
.nav-burger {
  position: relative;
  width: 46px;
  height: 38px;
  border: 0;
  padding: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  flex-shrink: 0;
}
.nav-burger__icon {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  transition: opacity 0.4s ease, transform 0.45s cubic-bezier(.34, 1.1, .5, 1);
}
/* The hamburger's brush artwork is wider than the X's, so it reads larger in
   the same box — trim it ~15% so the two icons feel matched. */
.nav-burger__icon--menu  { opacity: 1; transform: rotate(0deg)  scale(0.85); }
.nav-burger__icon--close { opacity: 0; transform: rotate(-90deg) scale(0.7); }

/* Full-screen liquid-glass overlay. */
.mobile-menu {
  position: fixed;
  inset: 0;
  z-index: 900;                 /* above footer (600) + Flofu (500); bar sits above this */
  align-items: center;
  justify-content: center;
  padding: 2rem 1.5rem 96px;    /* bottom pad clears the fixed bar */
  /* Solid key-colour fill. The frosted backdrop-blur + translucency were dropped
     — animating a clipped blur is too expensive on mobile (flickers) for what it
     added. Clip-path alone (no filter) balloons cheaply and smoothly. */
  background: var(--key);
  /* Balloon out from the hamburger (bottom-right); own GPU layer for a steady raster. */
  clip-path: circle(0% at calc(100% - 2.7rem) calc(100% - 1.9rem));
  opacity: 0;
  pointer-events: none;
  transform: translateZ(0);
  -webkit-transform: translateZ(0);
  will-change: clip-path;
  transition: clip-path 0.55s cubic-bezier(.22, 1, .36, 1), opacity 0.3s ease;
}
.mobile-menu.is-open {
  clip-path: circle(150% at calc(100% - 2.7rem) calc(100% - 1.9rem));
  opacity: 1;
  pointer-events: auto;
}

.mobile-menu__links {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(1.4rem, 5.2vh, 2.9rem);
  margin: 0;
}
.mobile-menu__links a {
  font-family: var(--font-serif);
  font-weight: 500;
  font-size: clamp(2rem, 8.5vw, 3rem);
  line-height: 1;
  text-transform: lowercase;
  text-decoration: none;
  color: var(--white);
  /* gentle rise-in, staggered when the menu opens */
  opacity: 0;
  transform: translateY(14px);
  transition: opacity 0.4s ease, transform 0.45s cubic-bezier(.22, 1, .36, 1);
}
.mobile-menu.is-open .mobile-menu__links a {
  opacity: 1;
  transform: none;
}
.mobile-menu.is-open .mobile-menu__links a:nth-child(1) { transition-delay: 0.10s; }
.mobile-menu.is-open .mobile-menu__links a:nth-child(2) { transition-delay: 0.16s; }
.mobile-menu.is-open .mobile-menu__links a:nth-child(3) { transition-delay: 0.22s; }
.mobile-menu.is-open .mobile-menu__links a:nth-child(4) { transition-delay: 0.28s; }
.mobile-menu.is-open .mobile-menu__links a:nth-child(5) { transition-delay: 0.34s; }
.mobile-menu__links a.active { color: var(--lime); }

@media (max-width: 768px) {
  /* Show the mobile controls, hide the desktop link row. */
  .nav-burger  { display: block; }
  .mobile-menu { display: flex; }
  .site-nav__links { display: none; }

  /* Nav becomes a fixed bottom bar (overrides sticky-top). */
  .site-nav {
    position: fixed;
    top: auto;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 950;                 /* stays above the glass overlay */
    background: var(--white);     /* always white when closed */
  }
  .site-nav__inner {
    justify-content: space-between;
    padding: 0.55rem 1.25rem;
    gap: 1rem;
  }
  /* Wordmark returns to the flow (left), always visible. */
  .site-nav__brand {
    display: flex;
    position: static;
    transform: none;
    opacity: 1;
    pointer-events: auto;
  }
  .site-nav__brand-img { height: 30px; }

  /* Reserve space so the fixed bar never hides the footer/content. */
  body { padding-bottom: 52px; }   /* fallback; mobile-nav.js sets the exact bar height */
  body.menu-open-lock { overflow: hidden; }

  /* Colour layer cross-faded via OPACITY (composited on the GPU) instead of a
     background-color transition — that keeps the white->key change smooth even
     while the main thread is busy compositing the menu's blur. Sits above the
     white bar but below the content (the container is lifted to z-index 1). */
  .site-nav > .container--wide { position: relative; z-index: 1; }
  .site-nav::after {
    content: "";
    position: absolute;
    inset: 0;
    background: var(--key);
    opacity: 0;
    pointer-events: none;
    transform: translateZ(0);
    transition: opacity 0.4s ease;
  }
  .site-nav.menu-open::after { opacity: 1; }

  /* Open state: wordmark goes light, hamburger crossfades into the X. */
  .site-nav.menu-open .site-nav__brand-img { filter: none; }  /* SVG is white */
  .site-nav.menu-open .nav-burger__icon--menu  { opacity: 0; transform: rotate(90deg) scale(0.6); }
  .site-nav.menu-open .nav-burger__icon--close { opacity: 1; transform: rotate(0deg)  scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .mobile-menu,
  .mobile-menu__links a,
  .nav-burger__icon { transition: opacity 0.2s ease; }
  .mobile-menu { clip-path: none; }
  .mobile-menu.is-open { clip-path: none; }
  .mobile-menu.is-open .mobile-menu__links a { transition-delay: 0s; transform: none; }
}

/* ============================================================
   THEME MODE — DARK  (warm deep-brown)
   ------------------------------------------------------------
   Default = no [data-theme] attribute (today's vibrant look).
   Dark = a warm, low-key brown scheme sampled from References/
   DarkMode.jpg. Only the full-bleed hue FIELDS darken to browns;
   white cards, the partners band, nav and footer stay light, so
   there is NO black↔white flip. The 4 hue tokens remap to browns
   (which recolours every var-driven field for free), --field-ink
   goes off-white, and the hero TITLE is a dusty rose (the one
   coloured ink in the mockup). All brush-doodle art — incl. the
   inline Flofu, which also gets its own dark artwork — is tinted
   to a faint warm brown by a uniform CSS filter.
   An inline <head> snippet sets data-theme before paint (no flash);
   js/theme.js wires the top-right switcher + the page-wipe on change.

   Sampled palette: field #1A1111 · deeper field #150F0F ·
   maroon accent band #371919 · hero title rose #A96666 ·
   field ink #F7F6F6 · faint doodle #2E1B1A.
   ============================================================ */

html[data-theme="dark"] {
  /* The 4 brand hues → warm browns. Each hue is a field somewhere, so this
     darkens every section background at once; kept subtly distinct by depth. */
  --red:    #1F1414;   /* .lately / .about-hero / .cmty fields */
  --yellow: #231717;   /* .things base (overridden to the maroon accent below) */
  --green:  #1A1111;   /* .vision / lab / about-drive base */
  --blue:   #171011;   /* .section--blue / about-why / res-hero / cmty-experts */
  --black:  #1B1B1B;   /* unchanged — body ink + borders stay dark on white cards */
  --white:  #F3F3F3;   /* unchanged — cards / partners / nav / footer stay light */
  --lime:   #5FFF84;   /* unchanged — button pill stays lime */
  --title-color:   #A96666;   /* hero title: dusty rose */
  --field-ink:     #F7F6F6;   /* text on the dark fields: warm off-white */
  --section-accent:#371919;   /* the richer maroon "what we do" band */
}

/* The maroon accent band ("what we do" / drive) sits a step richer than the
   near-black fields around it. */
html[data-theme="dark"] .things,
html[data-theme="dark"] .about-drive { background: var(--section-accent); }

/* Field text that was hard-coded off-palette (not --field-ink), now illegible on
   the dark fields → force to the warm off-white. The home "A future in which…"
   vision statement was --lime; the "Things we do" label + Research/Design/Community
   headings & body were --black; the about "A shift towards…" title was --blue and
   its 4 point h3/p were --black. */
html[data-theme="dark"] .about-shift { background: var(--yellow); }   /* the browned token, not the light #EAEAEA */
html[data-theme="dark"] .vision__text,
html[data-theme="dark"] .things__label,
html[data-theme="dark"] .things__heading,
html[data-theme="dark"] .things__body,
html[data-theme="dark"] .about-shift__title,
html[data-theme="dark"] .about-shift__item h3,
html[data-theme="dark"] .about-shift__item p { color: var(--field-ink); }

/* "We work to develop…" is inverted in Dark: the normally-white section goes dark
   and its green scribble art becomes a light warm squiggle (#3D2222-ish). The
   outcomes box stays a light card, so its accordion text keeps its own colours. */
html[data-theme="dark"] .about-develop { background: var(--green); }
html[data-theme="dark"] .about-develop__label { color: var(--field-ink); }
html[data-theme="dark"] .about-develop__art {
  filter: brightness(0) invert(0.14) sepia(1) saturate(2) hue-rotate(-40deg);
}
/* Critters: each its own brown, eyes cut out in the field colour (as with the
   home hero faces), so they keep their personality on the dark field. */
html[data-theme="dark"] .dev-critter--green  .dev-critter__body { fill: #4A2826; }
html[data-theme="dark"] .dev-critter--blue   .dev-critter__body { fill: #5C3634; }
html[data-theme="dark"] .dev-critter--orange .dev-critter__body { fill: #6E413E; }
html[data-theme="dark"] .dev-critter__eye { fill: #1A1111; }

/* Doodle & mascot recolour — faint warm brown.
   brightness(0) crushes each SVG's baked hue to black regardless of its source
   colour; invert(.1) sepia saturate hue-rotate then tints that flat black to the
   sampled #2E1B1A, so every differently-coloured doodle lands on one faint tone
   just above the field. Covers <img> doodles AND the inline about-page blobs.
   (Flofu is handled separately — it swaps to its own dark artwork, below.) */
html[data-theme="dark"] .hero__layer,
html[data-theme="dark"] .lately__doodle,
html[data-theme="dark"] .about-develop__art,
html[data-theme="dark"] .about-shift__arrow,
html[data-theme="dark"] .about-why__num {
  filter: brightness(0) invert(0.1) sepia(1) saturate(2) hue-rotate(-45deg);
}
/* Lab toys: a tint that KEEPS each shape's own light/dark detail (eyes, brush
   lines, highlights) instead of flattening it, mapped into the warm browns. */
html[data-theme="dark"] .lab-toy > * {
  filter: grayscale(1) sepia(1) saturate(1.5) hue-rotate(-28deg) brightness(var(--toy-dim, 0.48)) contrast(1.15);
}
html[data-theme="dark"] .lab-toy.is-held > * {
  filter: grayscale(1) sepia(1) saturate(1.5) hue-rotate(-28deg) brightness(calc(var(--toy-dim, 0.48) * 1.25)) contrast(1.15);
}
/* The tint reads each toy's lightness, and the green repaint made some lighter
   than the old multicolour art. These per-shape levels land every toy on the
   same brown it had before, so Dark mode looks unchanged. */
.lab-toy--star     { --toy-dim: 0.24; }
.lab-toy--blob     { --toy-dim: 0.31; }
.lab-toy--hoops    { --toy-dim: 0.33; }
.lab-toy--scribble { --toy-dim: 0.37; }
.lab-toy--triangle { --toy-dim: 0.41; }
.lab-toy--pencil   { --toy-dim: 0.43; }
.lab-toy--bubble   { --toy-dim: 0.71; }
/* About succulent: each ring its own brown (like the "What we do" art) so the
   petals stay legible as a plant, with the scribbled outline in rose. */
html[data-theme="dark"] .succ__leaf-a   { fill: #4A2826; }
html[data-theme="dark"] .succ__leaf-b   { fill: #3F2120; }
html[data-theme="dark"] .succ__petal    { fill: #5C3634; }
html[data-theme="dark"] .succ__rosette  { fill: #6E413E; }
html[data-theme="dark"] .succ__core     { fill: #5C3634; }
html[data-theme="dark"] .succ__scribble { fill: #A96666; }
html[data-theme="dark"] .succ__outline  { fill: #8A514E; }
/* The deep-green copy would vanish on the browns; back to the dark-mode ink. */
html[data-theme="dark"] .about-drive__title,
html[data-theme="dark"] .about-drive__body,
html[data-theme="dark"] .about-drive__label,
html[data-theme="dark"] .about-why__label { color: var(--field-ink); }   /* (both are green in Default) */
/* About sunrise: back to the dark red-brown field, and a faint ember glow
   instead of the bright orange sky. */
html[data-theme="dark"] .about-hero,
html[data-theme="dark"] .lately { background: var(--red); }
/* Dark mirrors the Default deck: a dimmed warm parchment front card (dark ink
   10.8:1; still 11:1 off the brown field so it doesn't sink) and dusty-rose
   cards peeking behind it (the theme's one accent colour). */
html[data-theme="dark"] .lately-card { background: #A96666; }
html[data-theme="dark"] .lately-card[data-pos="0"] { background: #D6CBC2; }
html[data-theme="dark"] .lately-card[data-pos="0"] .lately-card__heading,
html[data-theme="dark"] .lately-card[data-pos="0"] .lately-card__body { color: var(--black); }
html[data-theme="dark"] .about-hero__glow {
  background: radial-gradient(ellipse 80% 70% at 50% 85%, rgba(183, 89, 45, 0.18), rgba(183, 89, 45, 0) 70%);
}
/* The sun: the disc in the faint doodle brown, and the spiral + rays a step
   lighter (#492B29, pre-tinted *-dark copies) so they still read. These used
   to be CSS filters, which phones re-ran on every frame of the spin. */
html[data-theme="dark"] .vision__sun-disc,
html[data-theme="dark"] .about-hero__sun-disc { background: #2E1B1A; }
html[data-theme="dark"] .sun-light { display: none; }
html[data-theme="dark"] .sun-dark { display: block; }
/* About page: the "Why here, why now" 1-2-3 number badges, the "We work to drive…"
   blob characters/art, and the "A shift towards…" squiggly arrow were hard to see
   at the general faint tone but overpowering at the full rose — lift them to a
   mid-brown (#6B4240), visible without dominating. */
html[data-theme="dark"] .about-why__num,
html[data-theme="dark"] .about-shift__arrow {
  filter: brightness(0) invert(0.24) sepia(1) saturate(1.8) hue-rotate(-46deg);
}

/* Flofu: the mascot keeps its own detail (eyes, two eels, seaweed) rather than
   being flattened by the doodle filter, so instead we remap its baked fills to
   the dark-mode palette sampled from References/Flofu_Darkmode.svg. Same artwork,
   same path/pupil geometry — only the paint changes, so cursor eye-tracking and
   the eel-bob machinery are untouched. Each source hue → its dark counterpart;
   the white sclera stays white. */
html[data-theme="dark"] .assistant-svg path[fill="#E4B103"] { fill: #B7592D; }  /* body → rust */
html[data-theme="dark"] .assistant-svg path[fill="#00A744"] { fill: #4AA670; }  /* green seaweed */
html[data-theme="dark"] .assistant-svg path[fill="#CCCCCC"] { fill: #A96666; }  /* grey → rose */
html[data-theme="dark"] .assistant-svg path[fill="#0066FF"] { fill: #270D0D; }  /* outline + iris → deep brown */
html[data-theme="dark"] .assistant-svg path[fill="#1934BE"] { fill: #5A2F2F; }
html[data-theme="dark"] .assistant-svg path[fill="#1D8949"] { fill: #E6C697; }  /* → cream */

/* Buttons stay a colourful lime pill in Dark (an intentional pop of brand). The
   hue tokens that drive the hover-flow gradient are browned under the theme, so
   pin the button to literal brand hues and re-assert its text. */
html[data-theme="dark"] a.btn { color: #1934BE; background: #5FFF84; }
html[data-theme="dark"] a.btn:hover {
  color: #F3F3F3;
  background-image: linear-gradient(90deg, #E42600, #FFCC00, #009D3C, #FFCC00, #E42600);
}

/* ---- Dark navbar on ALL pages: a deep-brown bar that BRIGHTENS TO OFF-WHITE on
   hover (the home behaviour the user liked). When it brightens, the links,
   wordmark and theme icon flip to dark so they stay legible on the light bar.
   This treatment overrides the subpages' solid-white nav (site-nav--solid /
   is-white) and the home nav's inline --nav-bg; !important beats the inline
   background paint() writes on the home nav. ---- */
html[data-theme="dark"] .site-nav,
html[data-theme="dark"] .site-nav--solid {
  background: #150F0F !important;
  border-top-color: #3D2222;
  border-bottom-color: #3D2222;
}
/* Brightening is HOVER-ONLY in dark mode: the bar stays dark at rest AND on
   scroll (unlike Default, where the home nav turns white once scrolled) and only
   flips to off-white while hovered. When it brightens, the links, wordmark and
   icon flip dark so they stay legible. */
html[data-theme="dark"] .site-nav:hover { background: var(--white) !important; }

/* Links on the dark bar — INVERTED emphasis: the current/active page reads
   brightest (off-white) and the rest recede to brown; hovering any link lifts it
   to off-white as the affordance. On home the JS adds `.is-white` when scrolled
   (bar stays dark in this theme), and the base `.site-nav.is-white ... a {--black}`
   rule (specificity 0,3,1) would otherwise force black on the dark bar — so these
   rules include `.is-white` to out-specify it and stay legible. */
html[data-theme="dark"] .site-nav__links a,
html[data-theme="dark"] .site-nav.is-white .site-nav__links a,
html[data-theme="dark"] .site-nav--solid .site-nav__links a { color: #A96666; }
html[data-theme="dark"] .site-nav__links a.active,
html[data-theme="dark"] .site-nav__links a:hover,
html[data-theme="dark"] .site-nav.is-white .site-nav__links a.active,
html[data-theme="dark"] .site-nav.is-white .site-nav__links a:hover,
html[data-theme="dark"] .site-nav--solid .site-nav__links a.active,
html[data-theme="dark"] .site-nav--solid .site-nav__links a:hover { color: #F7F6F6; }
/* When the bar brightens on hover, everything flips to dark/rose for legibility
   on the off-white: non-active brown→dark, active/hovered → rose. */
html[data-theme="dark"] .site-nav:hover .site-nav__links a,
html[data-theme="dark"] .site-nav.is-white:hover .site-nav__links a { color: #1B1B1B; }
html[data-theme="dark"] .site-nav:hover .site-nav__links a.active,
html[data-theme="dark"] .site-nav:hover .site-nav__links a:hover,
html[data-theme="dark"] .site-nav.is-white:hover .site-nav__links a.active,
html[data-theme="dark"] .site-nav.is-white:hover .site-nav__links a:hover { color: #A96666; }

/* Wordmark: white SVG stays white on the dark bar; flips black on the off-white. */
html[data-theme="dark"] .site-nav__brand-img { filter: none; }
html[data-theme="dark"] .site-nav:hover .site-nav__brand-img { filter: brightness(0); }

/* Theme icon docked in the nav: off-white on the dark bar, dark on the off-white
   bar (overrides the --nav-fg default, which is rose on home / --black elsewhere
   and would be illegible on the dark subpage bars). */
html[data-theme="dark"] .theme-switch--nav .theme-switch__btn {
  border-color: #F7F6F6;
  color: #F7F6F6;
}
html[data-theme="dark"] .site-nav:hover .theme-switch--nav .theme-switch__btn {
  border-color: #1B1B1B;
  color: #1B1B1B;
}

/* ---- Dark footer on ALL pages: one dark bar with light text, regardless of the
   page's footer variant (--light / --lab / --red / --blue). ---- */
html[data-theme="dark"] .site-footer,
html[data-theme="dark"] .site-footer--light,
html[data-theme="dark"] .site-footer--lab {
  background: #150F0F;
  border-top-color: #3D2222;
}
html[data-theme="dark"] .site-footer__lockup { filter: none; color: #F7F6F6; }
html[data-theme="dark"] .site-footer__credit { color: #F7F6F6; }

/* ============================================================
   THEME SWITCHER CONTROL (top-right of nav)
   ============================================================ */
.theme-switch {
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  z-index: 20;
}
.theme-switch__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  padding: 0;
  border: 1.5px solid var(--nav-fg, var(--black));
  border-radius: 100px;
  background: transparent;
  color: var(--nav-fg, var(--black));
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease,
              transform 0.25s cubic-bezier(0.34, 1.4, 0.5, 1);
  -webkit-tap-highlight-color: transparent;
}
/* Playful hover: the same flowing-rainbow fill as the site buttons, with a little
   springy scale-up. The icon stroke goes white to read on the colour. */
.theme-switch__btn:hover {
  transform: scale(1.1);
  border-color: transparent;
  color: #F3F3F3 !important;
  /* Literal brand hues (not the tokens, which are browned in dark) so the rainbow
     pops in both themes. */
  background-image: linear-gradient(90deg, #E42600, #FFCC00, #009D3C, #FFCC00, #E42600);
  background-size: 200% 100%;
  animation: btn-flow 2s linear infinite;
}
.theme-switch__btn svg { width: 24px; height: 24px; display: block; }
.theme-switch__btn svg path { stroke: currentColor; }

/* Default theme, home nav: the docked icon inherits --nav-fg (the hero ink, often
   white), which vanishes when the bar brightens to white on hover/scroll. Flip it
   to black on the white bar. (Dark theme handles this in its own block above.) */
html:not([data-theme]) .site-nav:hover .theme-switch--nav .theme-switch__btn,
html:not([data-theme]) .site-nav.is-white .theme-switch--nav .theme-switch__btn {
  border-color: var(--black);
  color: var(--black);
}

/* Popover menu — always in the DOM so it can animate; hidden via opacity +
   scale + pointer-events, revealed on .is-open with a bubbly elastic pop. */
.theme-switch__menu {
  position: absolute;
  right: 0;
  top: calc(100% + 10px);
  min-width: 190px;
  padding: 0.4rem;
  border: 1.5px solid var(--black);
  border-radius: 14px;
  background: var(--white);
  box-shadow: 0 12px 30px rgba(0,0,0,0.18);
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
  transform-origin: top right;
  opacity: 0;
  transform: scale(0.6) translateY(-8px);
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
}
.theme-switch.is-open .theme-switch__menu {
  opacity: 1;
  pointer-events: auto;
  /* elastic overshoot as the whole popover springs open */
  transform: scale(1) translateY(0);
  transition: transform 0.42s cubic-bezier(0.34, 1.56, 0.5, 1), opacity 0.16s ease;
}
/* "Pick a style!" heading at the top of the menu: small, muted and set apart
   by a rule, so it reads as a hint rather than another option. */
.theme-switch__label {
  margin: 0 0 0.2rem;
  padding: 0.35rem 0.85rem 0.55rem;
  border-bottom: 1px dashed rgba(27, 27, 27, 0.2);
  font-family: var(--font-body);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(27, 27, 27, 0.55);
  white-space: nowrap;
  cursor: default;
  user-select: none;
}
.theme-switch__opt {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  width: 100%;
  padding: 0.6rem 0.85rem;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--black);
  font-family: var(--font-body);
  font-size: 0.95rem;
  text-align: left;
  cursor: pointer;
  white-space: nowrap;
  /* each option starts small + low, then springs up when the menu opens */
  opacity: 0;
  transform: scale(0.8) translateY(6px);
  transition: background 0.15s ease, transform 0.2s ease, opacity 0.2s ease;
}
.theme-switch.is-open .theme-switch__opt {
  opacity: 1;
  transform: scale(1) translateY(0);
  transition: background 0.15s ease,
              transform 0.5s cubic-bezier(0.34, 1.7, 0.5, 1),
              opacity 0.2s ease;
}
/* staggered bubble-up, in order (of-type: the menu's first child is its label) */
.theme-switch.is-open .theme-switch__opt:nth-of-type(1) { transition-delay: 0.06s; }
.theme-switch.is-open .theme-switch__opt:nth-of-type(2) { transition-delay: 0.13s; }
.theme-switch.is-open .theme-switch__opt:nth-of-type(3) { transition-delay: 0.20s; }
/* hovering an option gives it the same flowing-rainbow fill as the buttons */
/* Each option's hover fill previews the theme it switches to: "Trendy (Default)"
   flows the brand rainbow; "Grownup (Dark)" flows a light-brown → light-beige. */
.theme-switch__opt:hover {
  transform: scale(1.04);
  background-size: 200% 100%;
  animation: btn-flow 2s linear infinite;
}
.theme-switch__opt[data-theme="default"]:hover {
  color: #F3F3F3;
  background-image: linear-gradient(90deg, #E42600, #FFCC00, #009D3C, #FFCC00, #E42600);
}
.theme-switch__opt[data-theme="dark"]:hover {
  color: #E6C697;   /* light beige text — reads like the actual dark theme */
  background-image: linear-gradient(90deg, #1A1111, #3D2222, #4A2A2A, #3D2222, #1A1111);
}
.theme-switch__opt[data-theme="default"]:hover::after { color: #F3F3F3 !important; }
.theme-switch__opt[data-theme="dark"]:hover::after { color: #E6C697 !important; }
.theme-switch__opt[aria-checked="true"] { font-weight: 700; }
.theme-switch__opt[aria-checked="true"]::after { content: "✓"; color: var(--blue); }
.theme-switch__opt[aria-checked="false"]::after { content: ""; }

/* Reduced motion: no springs — just show/hide instantly. */
@media (prefers-reduced-motion: reduce) {
  .theme-switch__menu,
  .theme-switch.is-open .theme-switch__menu,
  .theme-switch__opt,
  .theme-switch.is-open .theme-switch__opt {
    transition: opacity 0.12s ease;
    transform: none;
  }
}

/* ---- Home page: the theme button starts in the hero's top-right corner and
   then "sticks" into the nav, mirroring the wordmark logo (.hero__logo →
   .site-nav__brand). The nav-docked copy is hidden until the page is scrolled;
   the hero-corner copy lives in the hero flow and scrolls away with it. On the
   subpages (which have no .hero__logo, so no corner copy) the nav copy just
   shows, since those navs are always visible. ---- */

/* The hero-corner switch: top-right of the hero, vertically centred on the
   two-line wordmark opposite it (it was sitting too high before — the base
   .theme-switch top:50%/translate centred against a zero-height box). */
.theme-switch-corner {
  position: absolute;
  top: 0;
  right: 2.5rem;
  /* Above the hero headline (z-index 10, later in the DOM): on short laptop
     screens the headline's box rises into the open menu's bottom option, but
     only for the taller questions, so "Very Official" went dead and came back
     as the scenes rotated. The closed menu is pointer-events:none, so this
     never blocks the headline. */
  z-index: 11;
  /* Box spans from the hero top (0) down past the wordmark by an equal margin:
     2 × 1.75rem top-pad + the wordmark's render height. Centring the button in
     this box puts its centre at the box's half-height = 1.75rem + half the
     wordmark height = the wordmark's own vertical centre. */
  height: calc(1.75rem * 2 + 268px * 69 / 467);
  display: flex;
  align-items: center;
}/* Undo the base .theme-switch absolute/translate centring inside this wrapper
   (that box is zero-height in the nav; here the flex wrapper does the centring). */
.theme-switch--corner {
  position: static;
  transform: none;
}
.theme-switch--corner .theme-switch__btn {
  border-color: var(--title-color, var(--white));
  color: var(--title-color, var(--white));
}

/* The nav-docked switch fades in once scrolled, exactly like .site-nav__brand. */
.site-nav .theme-switch--nav {
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.3s ease;
}
.site-nav.is-scrolled .theme-switch--nav,
.site-nav--solid .theme-switch--nav {   /* subpages: always-visible solid nav */
  opacity: 1;
  pointer-events: auto;
}

/* Mobile: nav becomes a fixed bottom bar — dock the switch beside the burger
   (with a clear gap between the two icons), and drop the hero-corner copy
   (the hero logo is hidden on mobile too). */
@media (max-width: 768px) {
  .theme-switch__menu { bottom: calc(100% + 10px); top: auto; }
  .theme-switch-corner { display: none; }
  /* In the flex row (not absolute) so it can never sit on the wordmark:
     wordmark | switch (pushed right) | burger. */
  .site-nav .theme-switch--nav {
    opacity: 1;
    pointer-events: auto;
    position: relative;
    top: auto;
    right: auto;
    transform: none;
    order: 1;
    margin-left: auto;
    flex-shrink: 0;
  }
  .site-nav .nav-burger { order: 2; }
  /* The wordmark shrinks to whatever the icons leave (208px = container +
     bar padding, two gaps, switch and burger). */
  .site-nav__brand { min-width: 0; }
  .site-nav__brand-img { height: auto; width: min(203px, calc(100vw - 208px)); }
}
/* Thin phones: tighten the padding and icons so the wordmark keeps its size
   for longer (136px = the same sum at these smaller sizes). */
@media (max-width: 420px) {
  .site-nav > .container--wide { padding: 0 1rem; }
  .site-nav__inner { padding: 0.55rem 0.25rem; gap: 0.625rem; }
  .site-nav .theme-switch--nav .theme-switch__btn { width: 36px; height: 36px; }
  .site-nav .theme-switch--nav .theme-switch__btn svg { width: 20px; height: 20px; }
  .site-nav .nav-burger { width: 40px; height: 33px; }
  .site-nav__brand-img { width: min(203px, calc(100vw - 136px)); }
}

/* Dark mode mobile: the burger icon SVG is black and would vanish on the dark
   bar — invert it to off-white (it flips back to black when the bar brightens
   on tap/hover, matching the links/wordmark). */
@media (max-width: 768px) {
  html[data-theme="dark"] .nav-burger__icon { filter: invert(1) brightness(1.4); }
  html[data-theme="dark"] .site-nav:hover .nav-burger__icon { filter: none; }
}
