/* ============================================================================
   HENRY COLLINS — THEME MODULE
   ----------------------------------------------------------------------------
   Single source of truth for the whole site. Nothing in the PHP templates
   carries a style="" attribute any more; every visual decision lives here.

   Structure
     1  Tokens ................ colour, type, spacing, motion
     2  Base .................. reset, document defaults, a11y
     3  Layout ................ .band / .wrap / .grid
     4  Typography ............ .eyebrow / .h-* / .lede / .prose / .meta
     5  Controls .............. .btn / .link-arrow / .fld
     6  Components ............ header, footer, hero, cta, card, media, …
     7  Page modules .......... accordion, slider, pillars, programs, events
     8  Motion ................ reveal, hover-lift, keyframes
     9  Responsive ............ one place, class-based

   THEMING A SECTION
     Put a band class on <section> and everything inside inherits the palette:

       <section class="band band--purple">        dark purple, gold eyebrow
       <section class="band band--paper2 rule-b"> light, hairline bottom rule

     Light sections pick their accent (card rules, numerals, kickers) with an
     accent class — .accent--purple, .accent--green, … — so one attribute
     re-themes an entire section.
   ============================================================================ */


/* ============================================================================
   1  TOKENS
   ============================================================================ */
:root {
  /* -- Surfaces ------------------------------------------------------------ */
  --paper:        #F3EDE1;
   /* --paper:        #FAF8F3; */
  --paper2:       #FBF7EE;
  /* --paper2:       #FAF8F3; */
  --ink:          #1B1712;
  --sub:          #6E6558;
  --line:         #E2D8C6;
  --muted:        #CBBFA9;
  --muted-2:      #B5AB99;
  --prose:        #2C2822;
  --placeholder:  #A89E8E;

  /* -- Brand --------------------------------------------------------------- */
  --blue:         #123742;
  --blueHi:       #1C5568;
  --teal:         #1C5568;
  --purple:       #5E4C7A;
  /* The Foundation green runs as a four-step scale rather than a single hue, so
     the Outreach page can build light, mid and dark sections out of one colour
     instead of borrowing ink / purple / blue for its dark bands. Gold stays the
     only warm accent on top of it. */
  --greenInk:     #16281F;
  --greenDeep:    #2F5540;
  --green:        #3F6B52;
  --greenBright:  #4E8467;
  --bronze:       #7A5230;
  --tan:          #B98A38;
  --gold:         #D9AC5B;
  --rust:         #8B3A1F;

  /* -- Night palette: the Applications page ---------------------------------
     Software gets its own surface: a cool slate rather than near-black, so
     screenshots of real UI sit on it without the page reading as a void. The
     three steps are deliberately far apart — the hero and timeline take the
     deepest tone, the application grid sits a full step lighter so the cards
     have something to lift off, and the screenshot chrome is lighter again. */
  --night:        #0E212B;
  --night-2:      #16323E;
  --night-3:      #1E4453;
  --tealBright:   #2FBFA3;
  --on-night:     #EAF3F1;
  --fade-night:   rgba(234,243,241,.8);
  --hair-night:   rgba(140,215,200,.24);

  /* -- Foregrounds used on dark bands -------------------------------------- */
  --on-blue:      #FBF7EE;
  --on-green:     #EAF1EC;
  --on-purple:    #F0ECF4;
  --on-bronze:    #F4EEE4;

  /* -- Translucent ink/paper (dark-band body copy, hairlines) -------------- */
  --fade-strong:  rgba(234,241,236,.88);
  --fade:         rgba(234,241,236,.82);
  --fade-soft:    rgba(243,237,225,.72);
  --fade-weak:    rgba(243,237,225,.55);
  --hair-light:   rgba(255,255,255,.20);
  --hair-lighter: rgba(255,255,255,.12);

  /* -- Type ---------------------------------------------------------------- */
  --font-sans: 'Hanken Grotesk', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* -- Layout -------------------------------------------------------------- */
  --wrap-max:  1280px;
  --wrap-x:    44px;
  --wrap-y:    76px;
  --gap:       24px;
  --gap-lg:    56px;

  /* -- Radii --------------------------------------------------------------- */
  --r-xs:   2px;
  --r-sm:   5px;
  --r-md:   6px;
  --r-lg:  10px;
  --r-pill: 40px;

  /* -- Motion -------------------------------------------------------------- */
  --ease:   cubic-bezier(.16,.84,.44,1);
  --t-fast: .25s;
  --t-base: .3s;
  --t-slow: .45s;

  /* -- Elevation ----------------------------------------------------------- */
  --shadow-card: 0 16px 34px rgba(18,55,66,.13);
  --shadow-lift: 0 18px 40px rgba(18,55,66,.16);
  --shadow-soft: 0 12px 28px rgba(18,55,66,.10);

  /* -- Contextual: reassigned by band/accent classes ----------------------- */
  --accent:       var(--blue);
  --band-bg:      transparent;
  --band-fg:      var(--ink);
  --band-eyebrow: var(--sub);
  --band-hair:    var(--line);
}


/* ============================================================================
   2  BASE
   ============================================================================ */
*, *::before, *::after { box-sizing: border-box; }

/* Must beat the display value on components like .btn */
[hidden] { display: none !important; }

html, body { margin: 0; }

/* In-page anchors ease rather than jump; the reduced-motion block turns it off */
html { scroll-behavior: smooth; }

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; }

a { color: inherit; }
a:hover { opacity: .78; }

:focus-visible {
  outline: 3px solid currentColor;
  outline-offset: 3px;
  border-radius: var(--r-xs);
}

.skip-link {
  position: absolute; left: -9999px; top: 0; z-index: 999;
  background: var(--ink); color: var(--paper2);
  padding: 12px 20px;
  font-family: var(--font-mono); font-size: 13px;
}
.skip-link:focus { left: 8px; top: 8px; }

/* Screen-reader-only utility */
.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}


/* ============================================================================
   3  LAYOUT
   ============================================================================ */

/* -- Band: the themed full-bleed section shell ----------------------------- */
.band {
  background: var(--band-bg);
  color: var(--band-fg);
}

.band--paper      { --band-bg: var(--paper);  }
.band--paper2     { --band-bg: var(--paper2); }

.band--blue       { --band-bg: var(--blue);      --band-fg: var(--on-blue);   --accent: var(--gold); --band-eyebrow: var(--gold); --band-hair: var(--hair-light); }
.band--blue-hi    { --band-bg: var(--blueHi);    --band-fg: var(--on-blue);   --accent: var(--gold); --band-eyebrow: var(--gold); --band-hair: var(--hair-light); }
.band--purple     { --band-bg: var(--purple);    --band-fg: var(--on-purple); --accent: var(--gold); --band-eyebrow: var(--gold); --band-hair: var(--hair-light); }
.band--bronze     { --band-bg: var(--bronze);    --band-fg: var(--on-bronze); --accent: var(--gold); --band-eyebrow: var(--gold); --band-hair: var(--hair-light); }
.band--green      { --band-bg: var(--green);     --band-fg: var(--on-green);  --accent: var(--gold); --band-eyebrow: var(--gold); --band-hair: var(--hair-light); }
.band--green-deep { --band-bg: var(--greenDeep); --band-fg: var(--on-green);  --accent: var(--gold); --band-eyebrow: var(--gold); --band-hair: var(--hair-light); }
/* The darkest step — what .band--ink would otherwise be used for on a page
   whose colour is green. Same weight on the page, none of the hue clash. */
.band--green-ink  { --band-bg: var(--greenInk);  --band-fg: var(--on-green);  --accent: var(--gold); --band-eyebrow: var(--gold); --band-hair: var(--hair-light); }
.band--ink        { --band-bg: var(--ink);       --band-fg: var(--paper2);    --accent: var(--gold); --band-eyebrow: var(--gold); --band-hair: var(--hair-light); }
.band--night      { --band-bg: var(--night);     --band-fg: var(--on-night);  --accent: var(--tealBright); --band-eyebrow: var(--tealBright); --band-hair: var(--hair-night); }
.band--night-2    { --band-bg: var(--night-2);   --band-fg: var(--on-night);  --accent: var(--tealBright); --band-eyebrow: var(--tealBright); --band-hair: var(--hair-night); }

/* Accent-only themes for light sections */
.accent--blue    { --accent: var(--blue);    }
.accent--blue-hi { --accent: var(--blueHi);  }
.accent--purple  { --accent: var(--purple);  }
.accent--green   { --accent: var(--green);   }
.accent--green-deep { --accent: var(--greenDeep); }
/* Decorative only — at 3.7:1 on paper this is fine for a rule, a badge or a
   bullet, but it must not be asked to carry small text. */
.accent--green-bright { --accent: var(--greenBright); }
.accent--bronze  { --accent: var(--bronze);  }
.accent--gold    { --accent: var(--gold);    }
.accent--teal    { --accent: #14806D;         }  /* the night teal, darkened for paper */

/* Section rules — hairline, not a hard divider. Follows --band-hair so the line
   stays soft on paper bands and light-on-dark inside coloured bands. */
.rule-b { border-bottom: 1px solid var(--band-hair); }
.rule-t { border-top: 1px solid var(--band-hair); }

/* -- Wrap: the 1280px content column --------------------------------------- */
.wrap {
  max-width: var(--wrap-max);
  margin: 0 auto;
  padding: var(--wrap-y) var(--wrap-x);
}
.wrap--hero   { --wrap-y: 82px; padding-bottom: 68px; }
.wrap--hero-l { --wrap-y: 86px; padding-bottom: 78px; }
.wrap--cta    { --wrap-y: 88px; text-align: center; }
.wrap--cta-l  { --wrap-y: 96px; text-align: center; }
.wrap--strip  { --wrap-y: 34px; }
.wrap--slim   { --wrap-y: 64px; }
.wrap--flush   { padding-top: 0; }
.wrap--flush-b { padding-bottom: 0; }

/* -- Grid ------------------------------------------------------------------ */
.grid { display: grid; gap: var(--gap); }

.grid--2       { grid-template-columns: repeat(2, 1fr); }
.grid--3       { grid-template-columns: repeat(3, 1fr); }
.grid--4       { grid-template-columns: repeat(4, 1fr); }
.grid--split   { grid-template-columns: 1fr 1fr; }
.grid--aside   { grid-template-columns: .7fr 1.3fr;   }  /* narrow title + prose */
.grid--acc     { grid-template-columns: .85fr 1.15fr; }  /* title + accordion   */
.grid--media   { grid-template-columns: .8fr 1.2fr;   }  /* cover + copy        */
.grid--video   { grid-template-columns: 1fr 1.35fr;   }
.grid--join    { grid-template-columns: 1.1fr .9fr;   }
.grid--pillars { grid-template-columns: 1.05fr 1.95fr; }
.grid--form    { grid-template-columns: 1.35fr .65fr; }
.grid--endcap  { grid-template-columns: 1fr auto; }      /* copy + button       */
.grid--label   { grid-template-columns: auto 1fr; }      /* side label + block  */

.grid--gap-lg  { gap: var(--gap-lg); }
.grid--gap-sm  { gap: 16px; }
.grid--gap-0   { gap: 0; }
.grid--middle  { align-items: center; }
.grid--top     { align-items: start; }
.grid--bottom  { align-items: end; }

/* -- Section head: eyebrow + title on the left, control on the right -------- */
.sec-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  flex-wrap: wrap;
  gap: 16px;
}
.sec-head--baseline { align-items: baseline; }

/* -- Small helpers --------------------------------------------------------- */
.row       { display: flex; align-items: center; gap: 12px; }
.row--wrap { flex-wrap: wrap; }
.stack     { display: flex; flex-direction: column; }
.center    { text-align: center; }
.mt-0  { margin-top: 0; }
.mt-sm { margin-top: 18px; }
.mt-md { margin-top: 26px; }
.mt-lg { margin-top: 34px; }

/* Width constraints for pull-aside blocks (testimonial slots, callouts) */
.measure        { max-width: 600px; }
.measure--sm    { max-width: 560px; }
.measure--lg    { max-width: 640px; }


/* ============================================================================
   4  TYPOGRAPHY
   ============================================================================ */

/* -- Eyebrow / kicker ------------------------------------------------------ */
.eyebrow {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--band-eyebrow);
}
.eyebrow--hero   { letter-spacing: .18em; color: var(--gold); margin-bottom: 24px; display: block; }
.eyebrow--accent { color: var(--accent); letter-spacing: .14em; }
.eyebrow--sm     { font-size: 10.5px; letter-spacing: .1em; }
.eyebrow--tight  { letter-spacing: .12em; }
.eyebrow--vert   { writing-mode: vertical-rl; transform: rotate(180deg); }

/* -- Headings -------------------------------------------------------------- */
.h-hero {
  font-size: clamp(40px, 7.6vw, 72px);
  line-height: 1.0;
  font-weight: 900;
  letter-spacing: -.035em;
  margin: 0;
  max-width: 16ch;
}
.h-hero--xl { font-size: clamp(40px, 8.6vw, 82px); line-height: .98; }
.h-hero--lg { font-size: clamp(40px, 7.8vw, 74px); line-height: 1.02; }

.h-section {
  font-size: clamp(28px, 4.6vw, 44px);
  line-height: 1.04;
  font-weight: 900;
  letter-spacing: -.03em;
  margin: 14px 0 0;
}
.h-section--sm { font-size: clamp(26px, 3.8vw, 36px); }
.h-section--md { font-size: clamp(27px, 4.2vw, 40px); }
.h-section--lg { font-size: clamp(30px, 5vw,   48px); }

.h-cta {
  font-size: clamp(34px, 6.4vw, 60px);
  line-height: 1.02;
  font-weight: 900;
  letter-spacing: -.04em;
  margin: 0;
}
.h-cta--sm { font-size: clamp(30px, 5.6vw, 54px); letter-spacing: -.03em; }
.h-cta--lg { font-size: clamp(38px, 7.4vw, 72px); }

.h-card   { font-size: 24px; font-weight: 800; letter-spacing: -.01em; margin: 14px 0 0; }
.h-card--sm { font-size: 19px; margin: 0; }
.h-card--md { font-size: 20px; margin: 0; }
.h-card--lg { font-size: 34px; font-weight: 900; letter-spacing: -.02em; margin: 12px 0 0; line-height: 1.08; }

.h-underline {
  font-size: 22px; font-weight: 800; letter-spacing: -.01em;
  margin: 0 0 20px; padding-bottom: 4px;
  border-bottom: 3px solid var(--accent);
  display: inline-block;
}

/* Gold emphasis inside a heading */
.hl { color: var(--gold); }
.hl--teal { color: var(--tealBright); }

/* -- Body copy ------------------------------------------------------------- */
.lede {
  font-size: 17px; line-height: 1.6;
  color: var(--sub);
  margin: 22px 0 0;
  max-width: 34ch;
}
.lede--wide { max-width: 52ch; }
.lede--sm   { font-size: 16px; max-width: 56ch; }
.lede--onband { color: var(--fade-soft); margin: 20px 0 0; max-width: 40ch; }

/* Supporting paragraph on a coloured band — no rule above it */
.band-lede { font-size: 18px; line-height: 1.6; color: var(--fade); margin: 20px 0 0; max-width: 46ch; }

.hero-lede {
  font-size: 19px; line-height: 1.55;
  color: var(--fade);
  max-width: 56ch;
  margin: 32px 0 0;
  border-top: 1px solid var(--band-hair);
  padding-top: 24px;
}
.hero-lede--lg { font-size: 20px; max-width: 60ch; color: var(--fade-strong); }

.cta-lede {
  font-size: 18px; line-height: 1.55;
  color: var(--fade);
  margin: 18px auto 0;
  max-width: 44ch;
}

.prose {
  font-size: 19px; line-height: 1.65;
  color: var(--prose);
  max-width: 60ch;
}
.prose p { margin: 0; }
.prose p + p { margin-top: 22px; }

.copy   { font-size: 17px; line-height: 1.65; color: var(--prose); max-width: 52ch; margin: 22px 0 0; }
.copy--tight { margin-top: 18px; }
.copy--book  { font-size: 18px; max-width: 54ch; }

.note { font-size: 15px; line-height: 1.6; color: var(--sub); margin: 12px 0 0; }

/* Bulleted list for light bands — the .who__facts twin, which is drawn in
   --fade / --hair-light and so only works on the dark hero it lives in. */
.ticks {
  list-style: none;
  margin: 22px 0 0; padding: 0;
  display: grid; gap: 10px;
  max-width: 54ch;
}
.ticks li {
  position: relative;
  padding-left: 22px;
  font-size: 16px; line-height: 1.55;
  color: var(--prose);
}
.ticks li::before {
  content: "";
  position: absolute; left: 0; top: .5em;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--accent);
}

/* Deck line sitting under a short title (SATA / SAPM) */
.subtitle { font-size: 16px; font-weight: 600; color: var(--sub); margin-top: 4px; }

/* -- Mono meta ------------------------------------------------------------- */
.meta {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .06em;
  line-height: 1.6;
  color: var(--sub);
}
.meta--upper { text-transform: uppercase; letter-spacing: .08em; }
.meta--lg    { font-size: 12px; }
.meta--accent{ color: var(--accent); }


/* ============================================================================
   5  CONTROLS
   ============================================================================ */
.btn {
  display: inline-block;
  padding: 16px 32px;
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 15px;
  line-height: 1;
  text-decoration: none;
  white-space: nowrap;
  border: 1px solid transparent;
  border-radius: var(--r-xs);
  cursor: pointer;
  transition: opacity var(--t-fast);
}
.btn--gold   { background: var(--gold);   color: var(--ink); }
.btn--accent { background: var(--accent); color: #fff; }
.btn--ink    { background: var(--blue);   color: var(--paper2); }
.btn--ghost  { background: transparent;   color: var(--band-fg); border-color: rgba(255,255,255,.6); }
/* Night-page primary: the glow is the hover state, so the button reads as a
   control rather than as one more block of colour on a dark surface. */
.btn--teal   { background: var(--tealBright); color: #05221C; transition: box-shadow var(--t-base), transform var(--t-base) var(--ease), opacity var(--t-fast); }
.btn--teal:hover { opacity: 1; transform: translateY(-2px); box-shadow: 0 12px 30px rgba(47,191,163,.32); }

.btn--sm  { padding: 13px 24px; font-size: 14px; }
.btn--nav { padding: 10px 18px; font-size: 13.5px; }
.btn--md  { padding: 15px 28px; }

/* Understated mono link with a rule under it */
.link-arrow {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 13px;
  color: var(--ink);
  border-bottom: 1px solid currentColor;
  padding-bottom: 2px;
  text-decoration: none;
}
.link-arrow--onband { color: var(--band-fg); }
.link-arrow--gold   { color: var(--gold); }

/* Circular carousel control — shared by archive, activity and blog scrollers */
.nav-btn {
  width: 48px; height: 48px;
  border-radius: 50%;
  border: 1px solid var(--ink);
  background: transparent;
  color: var(--ink);
  font-size: 18px;
  cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  transition: background var(--t-fast), color var(--t-fast);
}
.nav-btn:hover { background: var(--ink); color: var(--paper); }
.nav-btn.swiper-button-disabled { opacity: .3; cursor: default; }

/* -- Form fields ----------------------------------------------------------- */
.fld {
  width: 100%;
  font-family: var(--font-sans);
  font-size: 16px;
  color: var(--ink);
  background: var(--paper2);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  padding: 14px 16px;
  outline: none;
}
.fld:focus { border-color: var(--blue); box-shadow: 0 0 0 3px rgba(18,55,66,.12); }
.fld::placeholder { color: var(--placeholder); }
textarea.fld { resize: vertical; }

.field { margin-top: 16px; }
.field__label {
  display: block;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--sub);
  margin-bottom: 8px;
}

.honeypot { position: absolute; left: -9999px; }


/* ============================================================================
   6  COMPONENTS
   ============================================================================ */

/* -- Site header ----------------------------------------------------------- */
.site-headwrap {
  background: var(--paper);
  border-bottom: 2px solid var(--ink);
}

.topbar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  padding: 10px var(--wrap-x);
  background: var(--ink);
  color: var(--paper2);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: .1em;
}
.topbar__mid { text-align: center; opacity: .7; }
.topbar__end { text-align: right; }

.nav {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  padding: 20px var(--wrap-x);
  max-width: var(--wrap-max);
  margin: 0 auto;
}
.nav__brand {
  font-weight: 900;
  font-size: 21px;
  letter-spacing: -.02em;
  color: var(--ink);
  text-decoration: none;
}
.nav__links { display: flex; gap: 26px; align-items: center; }
.nav__link {
  font-size: 13.5px;
  font-weight: 600;
  text-decoration: none;
  color: var(--ink);
  border-bottom: 2px solid transparent;
  padding-bottom: 3px;
}
.nav__link[aria-current="page"] { color: var(--blue); border-bottom-color: var(--blue); }

.nav-toggle {
  display: none;
  background: none; border: 0; cursor: pointer;
  padding: 8px; margin-left: auto;
}
.nav-toggle span {
  display: block; width: 24px; height: 2px;
  background: var(--ink); margin: 5px 0;
  transition: transform var(--t-fast), opacity var(--t-fast);
}

/* -- Site footer ----------------------------------------------------------- */
.site-footer {
  background: var(--ink);
  color: var(--paper2);
  font-family: var(--font-sans);
}
.site-footer__grid {
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: 48px;
  max-width: var(--wrap-max);
  margin: 0 auto;
  padding: 64px var(--wrap-x) 40px;
}
.site-footer__brand { font-weight: 900; font-size: 24px; letter-spacing: -.02em; }
.site-footer__blurb {
  font-size: 15px; line-height: 1.6;
  color: rgba(243,237,225,.62);
  margin: 14px 0 0; max-width: 34ch;
}
.site-footer__heading {
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 16px;
}
.site-footer__links { display: flex; flex-direction: column; gap: 11px; font-size: 14.5px; }
.site-footer__links a { color: rgba(243,237,225,.82); text-decoration: none; }
.site-footer__links span { color: var(--fade-weak); }
.site-footer__legal { max-width: var(--wrap-max); margin: 0 auto; padding: 0 var(--wrap-x) 40px; }
.site-footer__legal-inner {
  border-top: 1px solid rgba(243,237,225,.16);
  padding-top: 22px;
  display: flex; justify-content: space-between; align-items: center;
  gap: 16px; flex-wrap: wrap;
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .06em;
  color: var(--fade-weak);
}

/* -- Hero ------------------------------------------------------------------ */
.hero__meta {
  display: flex; gap: 36px; flex-wrap: wrap;
  margin-top: 34px; padding-top: 24px;
  border-top: 1px solid var(--band-hair);
  font-family: var(--font-mono);
  font-size: 12px; letter-spacing: .06em;
  color: rgba(234,241,236,.72);
}
.hero__actions { display: flex; gap: 16px; margin-top: 34px; flex-wrap: wrap; }

/* Home hero: typewriter line + button share a rule */
.hero__foot {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 40px;
  align-items: end;
  margin-top: 40px;
  padding-top: 28px;
  border-top: 1px solid var(--band-hair);
}
.hero__foot p { font-size: 19px; line-height: 1.55; color: var(--fade); max-width: 56ch; margin: 0; }

/* Pill badge used on the Outreach hero */
.hero__badge {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-mono);
  font-size: 12px; letter-spacing: .16em; text-transform: uppercase;
  color: var(--on-green);
  background: var(--hair-lighter);
  padding: 8px 16px;
  border-radius: var(--r-pill);
  margin-bottom: 26px;
}
.hero__badge::before {
  content: ""; width: 8px; height: 8px;
  border-radius: 50%; background: var(--gold);
}
/* Applications hero: the dot breathes, the way a status light does */
.hero__badge--live {
  color: var(--tealBright);
  background: rgba(47,191,163,.10);
  border: 1px solid var(--hair-night);
}
.hero__badge--live::before { background: var(--tealBright); animation: pulseDot 2.4s var(--ease) infinite; }

/* -- Outreach hero: the green aura ------------------------------------------
   Everything decorative lives in .hero-out__fx behind the copy, so the hero is
   a normal band the moment any of it is switched off. Two soft radial washes
   drift on their own; a third follows the pointer and only exists once JS
   starts writing --mx / --my (fine pointers only — see enhance.js). No blur
   filters: the gradients are already soft, and a 600px blur on a full-bleed
   band is the one thing that would make this hero expensive to paint. */
.hero-out { position: relative; isolation: isolate; overflow: hidden; }
.hero-out__wrap { position: relative; z-index: 1; }

.hero-out__fx {
  position: absolute; inset: 0; z-index: 0;
  overflow: hidden;
  pointer-events: none;
}

/* Fine dot texture, faded out towards the left so it never competes with the
   headline sitting over it */
.hero-out__fx::before {
  content: ''; position: absolute; inset: 0;
  background-image: radial-gradient(rgba(255,255,255,.20) 1px, transparent 1.6px);
  background-size: 26px 26px;
  opacity: .45;
  -webkit-mask-image: radial-gradient(115% 85% at 82% 12%, #000 8%, transparent 68%);
          mask-image: radial-gradient(115% 85% at 82% 12%, #000 8%, transparent 68%);
}

/* Hands the hero off to the stat strip below instead of ending on a hard edge */
.hero-out__fx::after {
  content: ''; position: absolute; inset: auto 0 0 0; height: 140px;
  background: linear-gradient(to bottom, rgba(47,85,64,0), rgba(31,60,45,.72));
}

.hero-out__blob {
  position: absolute;
  border-radius: 50%;
  will-change: transform;
}
.hero-out__blob--a {
  width: 58vw; height: 58vw; max-width: 760px; max-height: 760px;
  top: -26%; right: -8%;
  background: radial-gradient(circle, rgba(78,132,103,.85), rgba(78,132,103,0) 68%);
  animation: heroDriftA 19s var(--ease) infinite alternate;
}
.hero-out__blob--b {
  width: 52vw; height: 52vw; max-width: 660px; max-height: 660px;
  left: -14%; bottom: -34%;
  background: radial-gradient(circle, rgba(22,40,31,.72), rgba(22,40,31,0) 70%);
  animation: heroDriftB 24s var(--ease) infinite alternate;
}
/* A single gold wash, low and wide, so the gold in the badge, the highlighted
   words and the buttons reads as one warm light rather than three spot colours */
.hero-out__blob--c {
  width: 44vw; height: 30vw; max-width: 560px; max-height: 380px;
  right: 6%; bottom: -12%;
  background: radial-gradient(circle, rgba(217,172,91,.20), rgba(217,172,91,0) 70%);
  animation: heroDriftA 21s var(--ease) 1.5s infinite alternate;
}

.hero-out__light {
  position: absolute; inset: 0;
  opacity: 0;
  transition: opacity .55s var(--ease);
  background: radial-gradient(560px circle at var(--mx, 50%) var(--my, 38%), rgba(217,172,91,.15), transparent 62%);
}
.hero-out.is-lit .hero-out__light { opacity: 1; }

/* The badge dot breathes the way the Applications status light does, in gold */
.hero-out .hero__badge {
  background: rgba(255,255,255,.10);
  border: 1px solid var(--hair-light);
  backdrop-filter: blur(2px);
}
.hero-out .hero__badge::before { animation: pulseGold 2.8s var(--ease) infinite; }

/* The highlighted words get their rule drawn under them once the headline has
   finished rising, so the eye lands on the phrase the page is arguing for. */
.hero-out .hl { position: relative; }
.hero-out .hl::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: -.07em;
  height: 3px; border-radius: 2px;
  background: currentColor; opacity: .5;
  transform: scaleX(0); transform-origin: 0 50%;
  animation: drawRule .85s var(--ease) 1s forwards;
}

/* Hero buttons lift rather than just fading, so the two routes out of the hero
   feel like controls. Gold keeps its own glow; the ghost fills instead. */
.hero-out .btn {
  transition: transform var(--t-base) var(--ease), box-shadow var(--t-base),
              background var(--t-fast), border-color var(--t-fast), opacity var(--t-fast);
}
.hero-out .btn:hover { opacity: 1; transform: translateY(-2px); }
.hero-out .btn--gold:hover  { box-shadow: 0 14px 32px rgba(217,172,91,.34); }
.hero-out .btn--ghost:hover { background: rgba(255,255,255,.12); border-color: var(--paper); }

/* -- CTA band -------------------------------------------------------------- */
.cta__actions {
  display: flex; gap: 18px;
  justify-content: center; align-items: center;
  flex-wrap: wrap;
  margin-top: 32px;
}

/* -- Teaser banner (home → section handoffs) ------------------------------- */
.teaser { display: grid; grid-template-columns: 1fr auto; gap: 40px; align-items: center; }
.teaser .eyebrow { opacity: .78; color: var(--band-fg); }
.teaser h2 { max-width: 24ch; }
/* The banners stack directly on top of each other, so their buttons sit in a
   vertical column down the right edge. A shared min-width keeps that column a
   straight line instead of a ragged edge that follows the label lengths —
   min-width rather than a fixed width so the longest label can still grow. */
.teaser .btn {
  background: var(--band-fg); color: var(--band-bg);
  min-width: 330px; text-align: center;
}

/* -- Credibility / stat strip ---------------------------------------------- */
.strip { display: grid; grid-template-columns: repeat(4, 1fr); }
.strip__item { padding: 0 30px; border-right: 1px solid var(--band-hair); }
.strip__item:first-child { padding-left: 0; }
.strip__item:last-child  { padding-right: 0; border-right: 0; }
.strip__label {
  font-family: var(--font-mono);
  font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--sub); margin-bottom: 8px;
}
.strip__value { font-size: 18px; font-weight: 800; letter-spacing: -.01em; }
.strip__value--italic { font-style: italic; }

/* Dark stat variant (Outreach) */
.strip--dark { --band-hair: rgba(255,255,255,.18); }
.strip--dark .strip__value { font-size: 40px; font-weight: 900; letter-spacing: -.02em; color: var(--gold); }
.strip--dark .strip__label { color: rgba(234,241,236,.7); margin: 4px 0 0; }

/* -- Card ------------------------------------------------------------------ */
.card {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 28px;
}
.card--on-paper   { background: var(--paper);  }
.card--on-paper2  { background: var(--paper2); }
.card--top        { border-top:  4px solid var(--accent); }
.card--top-thick  { border-top:  5px solid var(--accent); border-radius: 8px; }
.card--left       { border-left: 4px solid var(--accent); }
.card--left-thick { border-left: 5px solid var(--accent); }
.card--pad-md     { padding: 32px; }
.card--pad-lg     { padding: 34px; }

.card__index { font-family: var(--font-mono); font-size: 12px; color: var(--accent); }
.card__statement {
  font-size: 19px; line-height: 1.5; font-weight: 600;
  letter-spacing: -.01em; margin: 16px 0 0;
}

/* -- Media box ------------------------------------------------------------- */
.media {
  aspect-ratio: var(--media-ratio, 4/3);
  border-radius: var(--r-sm);
  border: 1px solid var(--line);
  background:
    repeating-linear-gradient(45deg, var(--line) 0 9px, transparent 9px 18px),
    var(--media-surface, var(--paper2));
  display: flex; align-items: center; justify-content: center;
  overflow: hidden;
}
.media--3-4  { --media-ratio: 3/4; }
.media--16-10{ --media-ratio: 16/10; }
.media--on-paper { --media-surface: var(--paper); }
.media--cap  { max-width: 340px; }

.media__label {
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .08em;
  color: var(--sub);
  text-align: center;
  padding: 8px;
}

/* When a real image is present, drop the stripes and show the artifact whole */
.media.has-img {
  background-image: none;
  background-color: var(--media-surface, var(--paper2));
  padding: 0;
}
.media.has-img .hc-img { object-fit: contain; padding: 10px; }
.media.has-img.fit-cover .hc-img { object-fit: cover; padding: 0; }
.media.has-img.on-dark { --media-surface: var(--blue); }

.hc-img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* -- Definition rows (Problem / Approach / Status) -------------------------- */
.deflist { display: flex; flex-direction: column; gap: 16px; margin-top: 24px; }
.deflist__term {
  font-family: var(--font-mono);
  font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--accent); margin-bottom: 5px;
}
.deflist__desc { font-size: 16px; line-height: 1.6; margin: 0; color: var(--prose); }

/* -- Row list (clients, bylines, mastheads) -------------------------------- */
.rowlist { display: flex; flex-direction: column; }
.rowlist__row {
  display: flex; justify-content: space-between; align-items: center;
  gap: 16px;
  padding: 16px 0;
  border-bottom: 1px solid var(--line);
}
.rowlist__row:last-child { border-bottom: 0; }
.rowlist__name { font-size: 18px; font-weight: 700; }
.rowlist--lg .rowlist__row {
  padding: 20px 0;
  align-items: baseline;
  border-bottom: 0;
  border-top: 1px solid var(--line);
}
.rowlist--lg .rowlist__row:last-child { border-bottom: 1px solid var(--line); }
.rowlist--lg .rowlist__name { font-size: 22px; font-weight: 800; letter-spacing: -.01em; }

/* -- Numbered feature rows (signature talks) ------------------------------- */
.numrow {
  display: grid;
  grid-template-columns: 80px 1fr auto;
  gap: 28px;
  align-items: start;
  padding: 26px 0;
  border-top: 1px solid var(--line);
}
.numrow:last-child { border-bottom: 1px solid var(--line); }
.numrow__num { font-size: 28px; font-weight: 900; color: var(--accent); letter-spacing: -.02em; }
.numrow__title { font-size: 23px; font-weight: 800; letter-spacing: -.01em; margin: 0; }
.numrow__body { font-size: 15px; line-height: 1.6; color: var(--sub); margin: 8px 0 0; max-width: 64ch; }

/* -- Steps (how to engage) ------------------------------------------------- */
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0; }
.steps__item { padding: 0 30px; border-right: 1px solid var(--line); }
.steps__item:first-child { padding-left: 0; }
.steps__item:last-child  { padding-right: 0; border-right: 0; }
.steps__num { font-size: 44px; font-weight: 900; color: var(--accent); letter-spacing: -.03em; }
.steps__title { font-size: 19px; font-weight: 800; margin: 14px 0 0; }
.steps__body { font-size: 15px; line-height: 1.6; color: var(--sub); margin: 10px 0 0; }

/* -- Big figure pair (50+ articles / 1 book) -------------------------------- */
.figures { display: flex; gap: 40px; margin-top: 28px; }
.figures__num { font-size: 34px; font-weight: 900; color: var(--accent); letter-spacing: -.02em; }
.figures__label { font-family: var(--font-mono); font-size: 11px; color: var(--sub); margin-top: 4px; }

/* -- Chips / pills --------------------------------------------------------- */
.chips { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 24px; }
.chip {
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--accent);
  background: rgba(27,23,18,.06);                              /* fallback */
  background: color-mix(in srgb, var(--accent) 10%, transparent);
  padding: 8px 14px;
  border-radius: var(--r-pill);
}
.chip--outline {
  color: rgba(243,237,225,.8);
  background: transparent;
  border: 1px solid rgba(255,255,255,.24);
  text-transform: none;
}

.badge {
  position: absolute; top: 14px; left: 14px; z-index: 2;
  font-family: var(--font-mono);
  font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--paper);
  background: rgba(27,23,18,.55);
  padding: 5px 11px;
  border-radius: var(--r-pill);
}
.badge--gold { color: var(--gold); }

/* -- Quote blocks ---------------------------------------------------------- */
.quote { font-size: 17px; line-height: 1.5; font-weight: 600; letter-spacing: -.01em; margin: 22px 0 8px; max-width: 44ch; }
.quote--lead { font-size: 21px; line-height: 1.45; font-weight: 700; margin: 20px 0; }
.quote__by { font-family: var(--font-mono); font-size: 11px; color: var(--sub); }
.quote__by--ruled { border-bottom: 1px solid var(--line); padding-bottom: 20px; }
.quote__role { opacity: .65; }

/* Testimonial figure (home grid) */
.testi {
  margin: 0;
  background: var(--paper);
  border: 1px solid var(--line);
  border-top: 4px solid var(--accent);
  border-radius: var(--r-md);
  padding: 32px;
}
.testi__quote { font-size: 16px; line-height: 1.55; font-weight: 600; letter-spacing: -.01em; margin: 0; }
.testi__by {
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .06em;
  color: var(--sub);
  margin-top: 22px; line-height: 1.6;
}
.testi__role { opacity: .65; }

/* Testimonial slider (home) */
.testi-swiper { padding-bottom: 8px; }
.testi-swiper .swiper-slide { height: auto; display: flex; }
.testi-swiper .testi {
  flex: 1; display: flex; flex-direction: column;
  transition: transform var(--t-slow) var(--ease), box-shadow var(--t-slow);
}
.testi-swiper .testi:hover { transform: translateY(-6px); box-shadow: var(--shadow-lift); }
.testi-swiper .testi__by { margin-top: auto; padding-top: 22px; }

/* Gold treatment: the top rule alone is a 4px sliver, so the warm cast has to
   carry into the card body and the attribution rule to actually register. The
   quote itself stays ink — gold body copy on paper fails contrast. */
.testi.accent--gold {
  background: linear-gradient(180deg, rgba(217,172,91,.14), rgba(217,172,91,.03) 55%, transparent);
  background-color: var(--paper);
  /* Per-side, never the `border-color` shorthand — that would repaint the gold
     top rule that .testi draws from --accent. */
  border-left-color: rgba(217,172,91,.42);
  border-right-color: rgba(217,172,91,.42);
  border-bottom-color: rgba(217,172,91,.42);
  border-top-width: 5px;
}
.testi.accent--gold:hover { box-shadow: 0 18px 40px rgba(217,172,91,.26); }
.testi.accent--gold .testi__by { border-top: 1px solid rgba(217,172,91,.38); color: var(--bronze); }
.testi.accent--gold .testi__role { color: var(--sub); opacity: .8; }
/* Dots match the archive gallery: a static, full-width row under the cards with
   a pill-shaped active bullet. Do not turn on Swiper's dynamicBullets here — it
   centres its row with left:50% on a fixed inline width, which needs absolute
   positioning and so drifts off-centre against the static row below. */
.testi-swiper .swiper-pagination { position: static; margin-top: 22px; }
.testi-swiper .swiper-pagination-bullet { background: var(--muted); opacity: 1; width: 9px; height: 9px; transition: var(--t-base); }
.testi-swiper .swiper-pagination-bullet-active { background: var(--gold); width: 26px; border-radius: var(--r-sm); }

/* Compact expandable side-card */
.testi-box {
  margin: 0;
  background: var(--paper2);
  border: 1px solid var(--line);
  border-left: 4px solid var(--accent);
  border-radius: var(--r-md);
  padding: 24px;
  transition: box-shadow var(--t-base), border-color var(--t-base);
}
.testi-box:hover { box-shadow: var(--shadow-soft); }
.testi-box__context {
  font-family: var(--font-mono);
  font-size: 10px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 12px;
}
.testi-quote {
  margin: 0;
  font-size: 15.5px; line-height: 1.55; font-weight: 500;
  color: var(--ink);
  transition: max-height var(--t-slow) var(--ease);
}
.testi-quote.is-clamped {
  display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical;
  overflow: hidden;
}
.testi-quote.is-open { -webkit-line-clamp: unset; display: block; }
.testi-more {
  margin-top: 10px;
  background: none; border: 0; padding: 0; cursor: pointer;
  font-family: var(--font-mono);
  font-size: 11.5px; letter-spacing: .06em;
  color: var(--accent);
  border-bottom: 1px solid currentColor;
}
.testi-more:hover { opacity: .75; }
.testi-box__by {
  margin-top: 16px; padding-top: 14px;
  border-top: 1px solid var(--line);
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .05em;
  color: var(--sub);
}
.testi-box__who { color: var(--ink); font-weight: 600; }
.testi-box__role { opacity: .8; }

/* -- Work tile (image over label over title) -------------------------------- */
.tile { text-decoration: none; color: var(--ink); display: block; }
.tile__kicker {
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .08em;
  color: var(--purple);
  margin: 16px 0 6px;
}
.tile__title { font-size: 20px; font-weight: 800; margin: 0; letter-spacing: -.01em; }


/* ============================================================================
   7  PAGE MODULES
   ============================================================================ */

/* -- Accordion (five transitions) ------------------------------------------ */
.acc-row {
  display: grid;
  grid-template-columns: 72px 1fr auto;
  gap: 20px;
  align-items: start;
  padding: 22px;
  cursor: pointer;
  border-top: 1px solid var(--line);
  background: transparent;
  transition: background var(--t-base);
}
.acc-row.is-open { background: var(--acc-open-bg, var(--paper2)); }
.acc--on-paper2 .acc-row.is-open { --acc-open-bg: var(--paper); }

.acc-num {
  font-weight: 900; font-size: 30px;
  color: var(--muted);
  line-height: 1; letter-spacing: -.02em;
  transition: color var(--t-base);
}
.acc-row.is-open .acc-num { color: var(--accent); }

.acc-title { font-size: 20px; font-weight: 800; letter-spacing: -.01em; }
.acc-meta {
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--sub); margin-top: 4px;
}
.acc-body {
  max-height: 0; opacity: 0; margin: 0; overflow: hidden;
  transition: max-height .4s ease, opacity .4s ease, margin .4s ease;
}
.acc-row.is-open .acc-body { max-height: 320px; opacity: 1; margin: 12px 0 0; }
.acc-body p { font-size: 15px; line-height: 1.6; color: var(--sub); margin: 0; max-width: 52ch; }

.acc-sign {
  font-size: 24px; font-weight: 400; line-height: 1;
  color: var(--sub);
  transition: transform var(--t-base), color var(--t-base);
}
.acc-row.is-open .acc-sign { transform: rotate(45deg); color: var(--accent); }

/* -- Offerings slider ------------------------------------------------------ */
.slider-panel {
  background: var(--paper);
  border: 1px solid var(--line);
  border-left: 5px solid var(--accent);
  border-radius: var(--r-md);
  padding: 44px;
  display: grid;
  grid-template-columns: 190px 1fr;
  gap: 40px;
  align-items: center;
  min-height: 210px;
  transition: border-color var(--t-base);
}
.slider-panel__aside { border-right: 1px solid var(--line); padding-right: 32px; }
.slider-panel__num { font-size: 84px; font-weight: 900; line-height: 1; letter-spacing: -.03em; color: var(--accent); }
.slider-panel__tag {
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .12em; text-transform: uppercase;
  margin-top: 10px; color: var(--sub);
}
.slider-panel__title { font-size: 38px; font-weight: 900; letter-spacing: -.02em; margin: 0; line-height: 1.05; }
.slider-panel__desc { font-size: 18px; line-height: 1.6; color: var(--sub); margin: 16px 0 0; max-width: 52ch; }

.slider-dots { display: flex; gap: 10px; margin-top: 26px; align-items: center; }
.slide-dot {
  width: 10px; height: 10px;
  border-radius: 5px; border: none; padding: 0;
  cursor: pointer;
  background: var(--muted);
  transition: width var(--t-base) ease, background var(--t-base) ease;
}
.slide-dot.is-active { width: 28px; background: var(--accent); }
.slider-counter {
  margin-left: 12px;
  font-family: var(--font-mono);
  font-size: 12px; letter-spacing: .06em; color: var(--sub);
}

/* -- Archive gallery ------------------------------------------------------- */
.archive-swiper { padding-bottom: 8px; }
.archive-swiper .swiper-slide { height: auto; }

.archive-card {
  position: relative; display: block;
  aspect-ratio: 3/4;
  border-radius: var(--r-sm);
  overflow: hidden;
  border: 1px solid var(--line);
  /* The image itself is set inline via background-image, NOT through a custom
     property: a relative url() inside a custom property resolves against this
     stylesheet (/assets/css/) instead of the document, which 404s. */
  background-color: var(--paper2);
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  cursor: zoom-in;
  text-decoration: none;
  transition: transform var(--t-slow) var(--ease), box-shadow var(--t-slow);
}
.archive-card:hover { transform: translateY(-6px); box-shadow: var(--shadow-lift); opacity: 1; }
.archive-card img { width: 100%; height: 100%; object-fit: cover; display: block; }
.archive-card .cap {
  position: absolute; left: 0; right: 0; bottom: 0;
  padding: 16px;
  background: linear-gradient(0deg, rgba(27,23,18,.82), rgba(27,23,18,0));
  display: flex; flex-direction: column; gap: 5px;
}
.archive-card .era { font-family: var(--font-mono); font-size: 11px; font-weight: 600; letter-spacing: .1em; color: var(--gold); }
.archive-card .lab { font-family: var(--font-mono); font-size: 11px; letter-spacing: .04em; color: var(--paper); }
.archive-card .zoom {
  position: absolute; top: 12px; right: 12px;
  width: 34px; height: 34px; border-radius: 50%;
  background: rgba(27,23,18,.62); color: var(--paper);
  display: flex; align-items: center; justify-content: center;
  font-size: 15px; opacity: 0; transform: scale(.8);
  transition: var(--t-fast);
}
.archive-card:hover .zoom { opacity: 1; transform: scale(1); }
.archive-card__hit { position: absolute; inset: 0; z-index: 3; }

.archive-swiper .swiper-pagination { position: static; margin-top: 22px; }
.archive-swiper .swiper-pagination-bullet { background: var(--muted); opacity: 1; width: 9px; height: 9px; transition: var(--t-base); }
.archive-swiper .swiper-pagination-bullet-active { background: var(--blue); width: 26px; border-radius: var(--r-sm); }

/* Timeline scale in the archive header */
.timescale { display: flex; align-items: center; gap: 12px; font-family: var(--font-mono); font-size: 11px; letter-spacing: .1em; text-transform: uppercase; color: var(--sub); }
.timescale__now { color: var(--blue); }
.timescale__bar { width: 90px; height: 2px; background: linear-gradient(90deg, var(--blue), var(--line)); }

/* Lightbox theming */
.glightbox-clean .gslide-description { background: var(--ink); }
.glightbox-clean .gslide-title { color: var(--paper); font-family: var(--font-sans); }
.glightbox-clean .gslide-desc  { color: var(--gold); font-family: var(--font-mono); font-size: 12px; }

/* -- Blog cards ------------------------------------------------------------ */
.blog-scroll {
  display: flex; gap: 22px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  padding-bottom: 14px;
  scrollbar-width: thin;
  scrollbar-color: var(--muted) transparent;
}
.blog-scroll::-webkit-scrollbar { height: 8px; }
.blog-scroll::-webkit-scrollbar-track { background: transparent; }
.blog-scroll::-webkit-scrollbar-thumb { background: var(--muted); border-radius: 4px; }
.blog-scroll::-webkit-scrollbar-thumb:hover { background: var(--blue); }

.blog-card {
  display: flex; flex-direction: column;
  text-decoration: none; color: var(--ink);
  background: var(--paper2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  overflow: hidden;
  transition: transform var(--t-base) var(--ease), box-shadow var(--t-base), border-color var(--t-base);
}
.blog-card:hover { opacity: 1; border-color: var(--blue); }
.blog-card:hover .blog-card-cta { color: var(--ink); }
.blog-card--scroll { flex: 0 0 300px; scroll-snap-align: start; }

.blog-card-media {
  position: relative; display: block; overflow: hidden;
  aspect-ratio: 16/10;
  background:
    repeating-linear-gradient(45deg, var(--line) 0 9px, transparent 9px 18px),
    var(--paper);
}
.blog-card-media.has-img { background: var(--paper2); }
.blog-card-media .hc-img { transition: transform .5s var(--ease); }
.blog-card:hover .blog-card-media .hc-img { transform: scale(1.04); }
.blog-card-media__label {
  display: flex; width: 100%; height: 100%;
  align-items: center; justify-content: center;
  font-family: var(--font-mono);
  font-size: 10.5px; letter-spacing: .08em; color: var(--sub);
}

.blog-card__body { display: flex; flex-direction: column; gap: 10px; padding: 22px; flex: 1; }
.blog-card__meta {
  display: flex; gap: 10px; align-items: center;
  font-family: var(--font-mono);
  font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--bronze);
}
.blog-card__sep  { opacity: .45; }
.blog-card__date { color: var(--sub); }
.blog-card__title { font-size: 19px; font-weight: 800; letter-spacing: -.01em; line-height: 1.25; }
.blog-card--scroll .blog-card__title { font-size: 17px; }
.blog-card__excerpt { font-size: 14px; line-height: 1.55; color: var(--sub); }
.blog-card-cta {
  margin-top: auto; padding-top: 12px;
  font-family: var(--font-mono); font-size: 12px; color: var(--blue);
}

/* -- Outreach: pillars ----------------------------------------------------- */
.pillar-tabs { display: flex; flex-direction: column; gap: 8px; }
.pillar-tab {
  display: flex; align-items: center; gap: 16px;
  width: 100%;
  cursor: pointer; text-align: left;
  padding: 18px 20px;
  border-radius: 8px;
  border: 1px solid var(--line);
  background: transparent;
  font-family: var(--font-sans);
  color: inherit;
  transition: border-color var(--t-fast), background var(--t-fast);
}
.pillar-tab.is-active { border-color: var(--accent); background: var(--paper); }
.pillar-num {
  font-family: var(--font-mono);
  font-size: 14px; font-weight: 600;
  color: var(--muted-2); min-width: 22px;
  transition: color var(--t-fast);
}
.pillar-tab.is-active .pillar-num { color: var(--accent); }
.pillar-tab__title { font-size: 18px; font-weight: 800; letter-spacing: -.01em; }

.pillar-panel {
  background: var(--paper);
  border: 1px solid var(--line);
  border-left: 5px solid var(--accent);
  border-radius: var(--r-lg);
  padding: 44px;
  min-height: 320px;
}
.pillar-body { display: none; }
.pillar-body.is-active { display: block; }
.pillar-body__lede { font-size: 19px; line-height: 1.6; color: var(--sub); margin: 18px 0 0; max-width: 52ch; }

/* -- Outreach: mission / vision / aim -------------------------------------- */
/* Each card is a photo header that doubles as the toggle, over a statement that
   always reads, over a panel of detail that opens. Deliberately a different
   interaction from the pillar tabs below — same page, so the two sections
   should not look like the same widget twice. */
.aimset { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; align-items: start; }

.aim {
  background: var(--paper);
  border: 1px solid var(--line);
  border-top: 5px solid var(--accent);
  border-radius: var(--r-lg);
  overflow: hidden;
  transition: transform var(--t-base) var(--ease), box-shadow var(--t-base);
}
.aim:hover,
.aim.is-open { box-shadow: var(--shadow-card); }
.aim:hover { transform: translateY(-4px); }

/* Head — the whole photo block is the button */
.aim__head {
  position: relative; display: block; width: 100%;
  padding: 0; border: 0; background: none;
  font-family: var(--font-sans); color: inherit; text-align: left;
  cursor: pointer;
}
.aim__photo {
  display: block; height: 176px;
  background-color: var(--paper2);
  background-position: center; background-size: cover; background-repeat: no-repeat;
  transition: transform .5s var(--ease);
}
.aim:hover .aim__photo { transform: scale(1.04); }

/* Scrim keeps the label legible whatever the photo underneath is doing */
.aim__head::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(0deg, rgba(27,23,18,.80) 0%, rgba(27,23,18,.10) 62%, rgba(27,23,18,.28) 100%);
  pointer-events: none;
}
.aim__badge {
  position: absolute; top: 14px; left: 14px; z-index: 2;
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--accent); color: var(--paper);
  display: flex; align-items: center; justify-content: center;
  transition: transform var(--t-base) var(--ease);
}
.aim__badge svg { width: 20px; height: 20px; }
.aim:hover .aim__badge { transform: scale(1.08); }

.aim__label {
  position: absolute; left: 18px; bottom: 15px; z-index: 2;
  font-family: var(--font-mono);
  font-size: 11.5px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--paper);
}
.aim__chev {
  position: absolute; right: 16px; bottom: 12px; z-index: 2;
  width: 28px; height: 28px; border-radius: 50%;
  border: 1px solid rgba(255,255,255,.55);
  display: flex; align-items: center; justify-content: center;
  transition: background var(--t-fast), border-color var(--t-fast);
}
.aim__chev::before {
  content: ''; width: 7px; height: 7px; margin-top: -3px;
  border-right: 1.5px solid var(--paper); border-bottom: 1.5px solid var(--paper);
  transform: rotate(45deg);
  transition: transform var(--t-base) var(--ease);
}
.aim.is-open .aim__chev::before { transform: rotate(-135deg); margin-top: 3px; }
.aim__head:hover .aim__chev { background: rgba(255,255,255,.16); border-color: var(--paper); }
.aim__head:focus-visible .aim__chev { background: rgba(255,255,255,.22); border-color: var(--paper); }

.aim__body { padding: 22px 24px 24px; }
.aim__statement {
  margin: 0;
  font-size: 17px; line-height: 1.55; font-weight: 600; letter-spacing: -.01em;
}

/* 0fr → 1fr animates the panel open without hard-coding a max-height that would
   have to be re-guessed every time the copy changes. */
.aim__panel {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows var(--t-slow) var(--ease);
}
.aim.is-open .aim__panel { grid-template-rows: 1fr; }
.aim__panel > * { overflow: hidden; }

/* All three start closed. On a real pointer, hovering opens a card without
   asking for a click; the click handler stays for touch and keyboard, where
   there is no hover to rely on. Gated behind hover:hover so a tap on a phone
   does not leave a card stuck open under a lingering :hover. */
@media (hover: hover) and (pointer: fine) {
  .aim:hover .aim__panel { grid-template-rows: 1fr; }
  .aim:hover .aim__chev::before { transform: rotate(-135deg); margin-top: 3px; }
}

.aim__points { list-style: none; margin: 0; padding: 18px 0 0; }
.aim__points li {
  position: relative; padding-left: 20px;
  font-size: 14.5px; line-height: 1.55; color: var(--sub);
}
.aim__points li + li { margin-top: 11px; }
.aim__points li::before {
  content: ''; position: absolute; left: 0; top: 8px;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--accent);
}

/* -- Outreach: programs ---------------------------------------------------- */
.prog-card {
  cursor: pointer;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.prog-card__head {
  position: relative; height: 170px;
  background:
    repeating-linear-gradient(45deg, rgba(255,255,255,.12) 0 10px, transparent 10px 20px),
    var(--prog-bg, var(--green));
}
.prog-card__sign {
  position: absolute; bottom: 14px; right: 18px;
  font-family: var(--font-mono);
  font-size: 30px; font-weight: 600;
  color: rgba(243,237,225,.9);
}
.prog-card__body { padding: 26px 28px; }
.prog-card__title { font-size: 24px; font-weight: 800; letter-spacing: -.01em; margin: 0; }
.prog-body {
  max-height: 0; opacity: 0; overflow: hidden;
  transition: max-height .4s ease, opacity .4s ease;
}
.prog-card.is-open .prog-body { max-height: 240px; opacity: 1; }
.prog-body p { font-size: 15.5px; line-height: 1.6; color: var(--sub); margin: 12px 0 0; }

/* -- Outreach: video ------------------------------------------------------- */
.video-frame {
  border-radius: var(--r-lg);
  overflow: hidden;
  border: 1px solid rgba(255,255,255,.16);
  box-shadow: 0 24px 60px rgba(0,0,0,.4);
  background: #000;
  aspect-ratio: 16/9;
}
.video-frame iframe { width: 100%; height: 100%; border: 0; display: block; }

/* -- Outreach: activity cards ---------------------------------------------- */
/* Slides size to the tallest card so every tile in the row matches, and the
   media strip stays a fixed height so all photos crop to the same box. */
.act-swiper .swiper-slide { height: auto; }

.act-card {
  text-decoration: none;
  display: flex;
  flex-direction: column;
  height: 100%;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  overflow: hidden;
  background: var(--paper2);
}
.act-card__media {
  position: relative;
  height: 190px;
  flex: none;
  background:
    repeating-linear-gradient(45deg, rgba(255,255,255,.12) 0 10px, transparent 10px 20px),
    var(--act-bg, var(--green));
}
.act-card__media.has-img { background: var(--paper2); }
.act-card__play {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  width: 56px; height: 56px; border-radius: 50%;
  background: rgba(255,255,255,.92); color: var(--ink);
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; padding-left: 4px;
}
.act-card__body { padding: 22px; flex: 1; display: flex; flex-direction: column; }
.act-card__title { font-size: 20px; font-weight: 800; letter-spacing: -.01em; margin: 10px 0 0; line-height: 1.2; color: var(--ink); }
.act-card__desc { font-size: 14px; line-height: 1.55; color: var(--sub); margin: 8px 0 0; }
.act-card__cta { display: inline-block; margin-top: auto; padding-top: 14px; font-family: var(--font-mono); font-size: 12px; color: var(--accent); }

/* -- Outreach: events ------------------------------------------------------ */
.event-row {
  text-decoration: none; color: var(--ink);
  display: grid;
  grid-template-columns: 130px 1fr auto;
  gap: 32px;
  align-items: center;
  padding: 26px 28px;
  border: 1px solid var(--line);
  background: var(--paper2);
  border-radius: var(--r-md);
  margin-bottom: 8px;
}
.event-row__date { text-align: center; border-right: 1px solid var(--line); }
.event-row__day { font-size: 38px; font-weight: 900; letter-spacing: -.02em; color: var(--accent); line-height: 1; }
.event-row__mon {
  font-family: var(--font-mono);
  font-size: 12px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--sub); margin-top: 4px;
}
.event-row__title { font-size: 22px; font-weight: 800; letter-spacing: -.01em; margin: 0; }
.event-row__meta { font-family: var(--font-mono); font-size: 12px; letter-spacing: .04em; color: var(--sub); margin-top: 6px; }
.event-row__arrow { font-family: var(--font-mono); font-size: 14px; color: var(--accent); }

/* -- Outreach: socials ----------------------------------------------------- */
.social-list { display: grid; gap: 12px; }
.social-row {
  text-decoration: none;
  display: flex; align-items: center; gap: 14px;
  padding: 18px 20px;
  border: 1px solid rgba(255,255,255,.3);
  border-radius: 8px;
  color: var(--on-green);
}
.social-row__icon {
  width: 38px; height: 38px;
  border-radius: 9px;
  background: rgba(255,255,255,.14);
  display: flex; align-items: center; justify-content: center;
  flex: none;
}
.social-row__name { font-size: 17px; font-weight: 800; }
.social-row__out { margin-left: auto; font-family: var(--font-mono); font-size: 15px; color: var(--gold); }

/* -- Contact --------------------------------------------------------------- */
.reason-grid { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 22px; }
.reason {
  font-family: var(--font-sans);
  font-size: 15px; font-weight: 700;
  cursor: pointer;
  padding: 12px 20px;
  border-radius: var(--r-xs);
  border: 1px solid var(--line);
  background: var(--paper2);
  color: var(--ink);
  transition: background var(--t-fast), color var(--t-fast), border-color var(--t-fast);
}
.reason.is-active { background: var(--blue); color: var(--paper2); border-color: var(--blue); }

.regarding {
  display: flex; align-items: center; gap: 12px;
  margin: 20px 0 24px;
  background: var(--paper2);
  border: 1px solid var(--line);
  border-left: 4px solid var(--blue);
  border-radius: var(--r-sm);
  padding: 14px 18px;
}
.regarding__label {
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--sub);
}
.regarding__value { font-size: 16px; font-weight: 800; color: var(--blue); }

.form-status { display: none; margin-top: 16px; font-family: var(--font-mono); font-size: 13px; }
.form-status.is-ok  { display: block; color: var(--greenDeep); }
.form-status.is-err { display: block; color: var(--rust); }

.channel {
  text-decoration: none; color: var(--ink);
  display: block;
  padding: 20px 0;
  border-top: 1px solid var(--line);
}
.channel:last-child { border-bottom: 1px solid var(--line); }
.channel__label {
  font-family: var(--font-mono);
  font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--sub); margin-bottom: 6px;
}
.channel__value { font-size: 19px; font-weight: 800; letter-spacing: -.01em; }

/* -- Writing: in-development callout --------------------------------------- */
.callout { border-left: 3px solid var(--accent); padding-left: 32px; }
.callout__title { font-size: 32px; font-weight: 900; letter-spacing: -.02em; margin: 0; max-width: 22ch; }
.callout__body { font-size: 16px; line-height: 1.6; color: var(--sub); margin: 14px 0 0; max-width: 56ch; }


/* -- Outreach: the problem / pain-point band -------------------------------- */
.factgrid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--gap); margin-top: 38px; }
.fact { border-top: 3px solid var(--gold); padding-top: 20px; }
.fact__figure {
  font-size: clamp(36px, 4.2vw, 54px);
  font-weight: 900; letter-spacing: -.03em; line-height: 1;
  color: var(--gold);
}
.fact__label {
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--band-fg); opacity: .7;
  margin-top: 12px;
}
.fact__body { font-size: 15.5px; line-height: 1.55; color: var(--fade-soft); margin: 10px 0 0; }
.source-note {
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .04em;
  color: var(--fade-weak);
  margin: 30px 0 0;
}

/* -- Embedded media (YouTube, LinkedIn posts) ------------------------------- */
.embed {
  position: relative;
  width: 100%;
  border-radius: var(--r-lg);
  overflow: hidden;
  border: 1px solid var(--line);
  background: #000;
}
.embed--16-9 { aspect-ratio: 16/9; }
.embed--post { aspect-ratio: 504/399; background: var(--paper2); }
.embed iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; display: block; }

/* -- Outreach: program feature sections ------------------------------------ */
.feature__media { display: flex; flex-direction: column; gap: 16px; }

/* Every lead media box in a feature renders at one size — full column width on
   a single 16/9 box — so a YouTube embed, a LinkedIn post and a still photo all
   occupy the same footprint instead of each following its own source ratio.
   Stills letterbox against the paper surface rather than being cropped, except
   where a feature opts into fit-cover. */
.feature__media .embed,
.feature__media .media { width: 100%; aspect-ratio: 16/9; }
.feature__num {
  font-family: var(--font-mono);
  font-size: 12px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--accent);
}

/* The copy column owns its own rhythm rather than each child bringing its own
   margin, so heading → prose → prose → links all sit on one even step no
   matter which optional pieces (subtitle, extra paragraphs, links) a feature
   uses. The kicker and deck line are the two deliberate exceptions: they read
   as part of the title block, so they sit tight against it. */
.feature__copy > * + *        { margin-top: 20px; }
.feature__copy > .h-section   { margin-top: 12px; }
.feature__copy > .subtitle    { margin-top: 8px;  }
.feature__copy > :first-child { margin-top: 0;    }

/* Thumbnail strip — click to open in the lightbox */
.thumbstrip { display: flex; gap: 12px; flex-wrap: wrap; }
.thumb {
  position: relative;
  width: 148px; height: 111px;
  border-radius: var(--r-sm);
  overflow: hidden;
  border: 1px solid var(--line);
  background: var(--paper2);
  display: block;
  cursor: zoom-in;
  transition: transform var(--t-base) var(--ease), box-shadow var(--t-base);
}
.thumb:hover { transform: translateY(-3px); box-shadow: var(--shadow-card); opacity: 1; }
.thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* UI screenshots and covers must not be cropped — show them whole */
.thumb--contain img { object-fit: contain; padding: 6px; }

/* A media box that opens full size */
.media--zoom { cursor: zoom-in; }

/* -- Donate actions -------------------------------------------------------- */
/* Direct-giving buttons ship hidden and appear as soon as a href is filled
   into data/outreach.json → donate.direct[].href */
.donate-actions { display: flex; gap: 14px; flex-wrap: wrap; margin-top: 30px; }

/* -- Outreach: page-scoped colour ------------------------------------------
   Sections theme themselves through .band-- / .accent-- classes, but a few
   shared components still name a colour outright — blog cards were drawn for
   the blue-accented pages they normally sit on, and the elevation tokens carry
   a blue cast. Rebinding them under the page's data-page attribute keeps the
   Outreach page one green family without repainting Writing or Blog. */
body[data-page="outreach"] {
  --shadow-card: 0 16px 34px rgba(22,40,31,.16);
  --shadow-lift: 0 18px 40px rgba(22,40,31,.20);
  --shadow-soft: 0 12px 28px rgba(22,40,31,.12);
}
body[data-page="outreach"] .blog-card:hover     { border-color: var(--green); }
body[data-page="outreach"] .blog-card__meta     { color: var(--greenDeep); }
body[data-page="outreach"] .blog-card-cta       { color: var(--green); }
body[data-page="outreach"] .blog-scroll::-webkit-scrollbar-thumb:hover { background: var(--green); }
/* The scrim over the aim photos is warm ink everywhere else; here it is the
   darkest green, so a photo header cools into the band instead of the page. */
body[data-page="outreach"] .aim__head::after {
  background: linear-gradient(0deg, rgba(22,40,31,.82) 0%, rgba(22,40,31,.10) 62%, rgba(22,40,31,.30) 100%);
}

/* -- Consulting: practitioner hero ----------------------------------------- */
/* The advisory read: headline on the left, who you would actually be hiring on
   the right. The portrait is a 184px source, so the frame is capped just under
   it — scaling it up would only make it soft. */
.hero-consult {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 316px;
  gap: var(--gap-lg);
  align-items: center;
}

.who {
  background: var(--hair-lighter);
  border: 1px solid var(--hair-light);
  border-radius: var(--r-lg);
  padding: 30px 28px;
  text-align: center;
}
.who__portrait {
  width: 148px; height: 148px;
  margin: 0 auto;
  border-radius: 50%;
  overflow: hidden;
  border: 3px solid var(--gold);
  background: var(--paper2);
  box-shadow: 0 14px 30px rgba(0,0,0,.3);
}
.who__portrait img { width: 100%; height: 100%; object-fit: cover; display: block; }

.who__name { font-size: 23px; font-weight: 900; letter-spacing: -.02em; margin-top: 18px; }
.who__role {
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--gold);
  margin-top: 7px;
}
.who__facts {
  list-style: none;
  margin: 20px 0 0; padding: 18px 0 0;
  border-top: 1px solid var(--hair-light);
  display: grid; gap: 11px;
  text-align: left;
}
.who__facts li {
  position: relative;
  padding-left: 20px;
  font-size: 13.5px; line-height: 1.5;
  color: var(--fade);
}
.who__facts li::before {
  content: "";
  position: absolute; left: 0; top: .48em;
  width: 7px; height: 7px;
  border-radius: 50%;
  background: var(--gold);
}

/* Small round portrait over the closing CTA — the page ends on the person */
.cta-avatar {
  width: 78px; height: 78px;
  margin: 0 auto 24px;
  border-radius: 50%;
  overflow: hidden;
  border: 2px solid var(--gold);
}
.cta-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* -- Consulting: on-this-page nav ------------------------------------------ */
/* The site header does not stick, so this bar owns the top of the viewport once
   the hero scrolls away. It is plain anchors: it works before enhance.js loads,
   and the script only adds the aria-current that tracks the reader's position. */
.pagenav {
  position: sticky; top: 0; z-index: 80;
  background: var(--paper);
  border-bottom: 1px solid var(--line);
}
.pagenav__inner {
  max-width: var(--wrap-max);
  margin: 0 auto;
  padding: 0 var(--wrap-x);
  min-height: 58px;
  display: flex; align-items: center; gap: 22px;
}
.pagenav__label {
  font-family: var(--font-mono);
  font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--sub); white-space: nowrap;
}
.pagenav__list {
  list-style: none; margin: 0; padding: 0;
  /* min-width:0 is what actually lets this flex item scroll — without it the
     item floors at its content width and pushes the whole page sideways. */
  flex: 1; min-width: 0;
  display: flex; align-items: center; gap: 2px;
  /* The row scrolls sideways on narrow screens rather than wrapping the bar
     onto a second line and stealing viewport height from the content. */
  overflow-x: auto;
  scrollbar-width: none;
}
.pagenav__list::-webkit-scrollbar { display: none; }
.pagenav__link {
  display: block; white-space: nowrap;
  padding: 9px 12px;
  font-size: 13.5px; font-weight: 600;
  text-decoration: none;
  color: var(--sub);
  border-bottom: 2px solid transparent;
  transition: color var(--t-fast), background var(--t-fast);
}
.pagenav__link:hover { color: var(--ink); background: rgba(27,23,18,.05); opacity: 1; }
.pagenav__link[aria-current="true"] { color: var(--blueHi); border-bottom-color: var(--blueHi); }
/* Matches the page's own blue rather than the darker site-wide .btn--ink */
.pagenav__cta { margin-left: auto; background: var(--blueHi); }

/* Anchored sections clear the sticky bar when jumped to */
[data-page="consulting"] .band[id] { scroll-margin-top: 66px; }

/* -- Consulting: engagement cards ------------------------------------------ */
/* The paragraph is always visible; the disclosure only re-states those same
   facts as a scannable list. Native <details>, so it opens without JavaScript
   and screen readers get the expanded/collapsed state for free. */
.ecard { display: flex; flex-direction: column; }
.ecard .note { flex: 1; }
.ecard--paper { background: var(--paper); }

/* Icon and index share the card's top line — the icon names the kind of work
   at a glance, the numeral keeps the reading order. */
.ecard__head { display: flex; align-items: center; gap: 13px; }
.ecard__icon {
  flex: none;
  width: 42px; height: 42px;
  display: grid; place-items: center;
  border-radius: var(--r-md);
  color: var(--accent);
  background: rgba(27,23,18,.06);                              /* fallback */
  background: color-mix(in srgb, var(--accent) 11%, transparent);
  transition: transform var(--t-base) var(--ease), background var(--t-base);
}
.ecard__icon svg { width: 22px; height: 22px; }
.ecard:hover .ecard__icon {
  transform: translateY(-2px) scale(1.06);
  background: color-mix(in srgb, var(--accent) 18%, transparent);
}
.ecard .card__index { line-height: 1; }

.disclose { margin-top: 20px; padding-top: 14px; border-top: 1px solid var(--line); }
.disclose__summary {
  display: flex; align-items: center; gap: 10px;
  padding: 4px 0;
  cursor: pointer;
  list-style: none;
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--accent);
}
.disclose__summary::-webkit-details-marker { display: none; }
.disclose__summary:hover .disclose__icon { background: rgba(27,23,18,.07); }

.disclose__icon {
  position: relative; flex: none;
  width: 18px; height: 18px;
  border: 1px solid currentColor; border-radius: 50%;
  transition: background var(--t-fast);
}
.disclose__icon::before,
.disclose__icon::after {
  content: ""; position: absolute;
  top: 50%; left: 4px; right: 4px; height: 1px;
  background: currentColor;
  transform: translateY(-50%);
}
/* Plus becomes minus: the vertical stroke rotates flat onto the horizontal one */
.disclose__icon::after { transform: translateY(-50%) rotate(90deg); transition: transform var(--t-fast) var(--ease); }
.disclose[open] .disclose__icon::after { transform: translateY(-50%) rotate(0deg); }

.disclose__panel { padding-top: 14px; animation: fadeUp .35s var(--ease) both; }

/* -- Consulting: at-a-glance fact list ------------------------------------- */
.glance { margin: 0; display: grid; gap: 11px; }
.glance__row { display: grid; grid-template-columns: 108px 1fr; gap: 14px; align-items: baseline; }
.glance__term {
  font-family: var(--font-mono);
  font-size: 10.5px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--sub);
}
.glance__desc { margin: 0; font-size: 14.5px; line-height: 1.55; color: var(--prose); }

/* Ruled variant — rows separated rather than spaced, for the longer case lists.
   Colours come from the band, so the list reads correctly on paper or on the
   blue foresight band without a second set of rules. */
.glance--ruled { gap: 0; }
.glance--ruled .glance__row { padding: 13px 0; border-top: 1px solid var(--band-hair); }
.glance--ruled .glance__term { color: var(--accent); }
.glance--ruled .glance__desc { color: var(--band-fg); opacity: .84; }

/* -- Consulting: market foresight cases ------------------------------------ */
/* Both cases and both documents ship visible and stacked. enhance.js adds
   .is-tabbed and unhides the tab bar and pager, so with JavaScript off the
   reader still reaches every case — the controls are an upgrade, not the only
   route in. Everything here is drawn from --band-*, so the block survives being
   moved to a different coloured band. */
.cases {
  display: grid;
  grid-template-columns: minmax(0, .82fr) minmax(0, 1.18fr);
  gap: var(--gap-lg);
  align-items: start;
}
.cases__stage { display: grid; gap: 26px; }

.cases__nav { display: flex; align-items: center; gap: 12px; }
.cases__count { color: var(--band-fg); opacity: .7; white-space: nowrap; }

/* Carousel buttons on a coloured band */
.nav-btn--onband { border-color: var(--band-fg); color: var(--band-fg); }
.nav-btn--onband:hover { background: var(--band-fg); color: var(--band-bg); opacity: 1; }

.artifact { margin: 0; }
.cases.is-tabbed .artifact { display: none; }
.cases.is-tabbed .artifact.is-active { display: block; animation: caseIn .45s var(--ease) both; }

.artifact__frame {
  position: relative; display: block;
  border: 1px solid var(--band-hair);
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--paper2);
  box-shadow: 0 20px 44px rgba(0,0,0,.26);
  cursor: zoom-in;
  transition: transform var(--t-base) var(--ease), box-shadow var(--t-base);
}
.artifact__frame:hover, .artifact__frame:focus-visible { opacity: 1; }
.artifact__frame:hover { transform: translateY(-4px); box-shadow: 0 26px 54px rgba(0,0,0,.34); }
.artifact__frame img { display: block; width: 100%; height: auto; transition: transform .5s var(--ease); }
.artifact__frame:hover img { transform: scale(1.02); }

.artifact__zoom {
  position: absolute; left: 50%; bottom: 16px;
  transform: translateX(-50%) translateY(6px);
  padding: 8px 15px;
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .08em;
  color: var(--paper);
  background: rgba(27,23,18,.8);
  border-radius: var(--r-pill);
  opacity: 0;
  transition: opacity var(--t-fast), transform var(--t-fast) var(--ease);
}
.artifact__frame:hover .artifact__zoom,
.artifact__frame:focus-visible .artifact__zoom { opacity: 1; transform: translateX(-50%) translateY(0); }

.artifact__cap {
  font-family: var(--font-mono);
  font-size: 11px; line-height: 1.6; letter-spacing: .04em;
  color: var(--band-fg); opacity: .68;
  margin: 12px 0 0;
}

.cases__tabs { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 28px; }
.case-tab {
  display: flex; align-items: center; gap: 13px;
  text-align: left;
  padding: 12px 18px;
  background: transparent;
  border: 1px solid var(--band-hair);
  border-radius: var(--r-md);
  color: var(--band-fg);
  font-family: var(--font-sans);
  cursor: pointer;
  transition: background var(--t-fast), border-color var(--t-fast),
              color var(--t-fast), transform var(--t-fast) var(--ease);
}
.case-tab:hover { border-color: var(--accent); transform: translateY(-2px); }
/* Filled pill follows the site's gold-on-ink button pairing, which holds for
   any dark band — every one of them resolves --accent to gold. */
.case-tab.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--ink);
  transform: none;
}
.case-tab__icon { flex: none; display: grid; place-items: center; opacity: .8; }
.case-tab__icon svg { width: 22px; height: 22px; }
.case-tab.is-active .case-tab__icon { opacity: 1; }
.case-tab__text   { display: grid; gap: 3px; }
.case-tab__year   { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .12em; opacity: .72; }
.case-tab__name   { font-size: 19px; font-weight: 800; letter-spacing: -.01em; }
.case-tab__kicker { font-size: 12.5px; opacity: .82; }

.case { max-width: 62ch; }
.case + .case { margin-top: 40px; padding-top: 40px; border-top: 1px solid var(--band-hair); }
.cases.is-tabbed .case { display: none; margin-top: 0; padding-top: 0; border-top: 0; }
.cases.is-tabbed .case.is-active { display: block; }
.case__kicker { color: var(--accent); }
.case__body { font-size: 16.5px; line-height: 1.7; color: var(--band-fg); opacity: .86; margin: 18px 0 0; }
.case .glance { margin-top: 26px; }

/* The swapped-in case assembles rather than appearing all at once: kicker,
   title, paragraph and fact list each land a beat apart. Four children, four
   delays — the reduced-motion block collapses them all to nothing. */
.cases.is-tabbed .case.is-active > * { animation: caseIn .45s var(--ease) both; }
.cases.is-tabbed .case.is-active > :nth-child(1) { animation-delay: .02s; }
.cases.is-tabbed .case.is-active > :nth-child(2) { animation-delay: .07s; }
.cases.is-tabbed .case.is-active > :nth-child(3) { animation-delay: .12s; }
.cases.is-tabbed .case.is-active > :nth-child(4) { animation-delay: .17s; }

/* -- Consulting: how-to-engage flow ---------------------------------------- */
.steps--flow .steps__item { transition: transform var(--t-base) var(--ease); }
.steps--flow .steps__item:hover { transform: translateY(-3px); }

/* ============================================================================
   APPLICATIONS — the night page
   ----------------------------------------------------------------------------
   The one page that runs dark end to end. It is about software, so it borrows
   software's own vocabulary: a night surface, a drifting code grid, browser
   chrome around every screenshot, mono for anything a machine would print.

   Everything below is either scoped to a class this page alone uses, or to
   [data-page="application"] — no other page changes because this file grew.
   ============================================================================ */

/* -- Ambient background: grid + glow --------------------------------------- */
/* Both are decorative and pointer-transparent, so they never sit between the
   reader and a link. The grid is masked to fade out before it reaches the copy
   rather than running edge to edge behind the text. */
.codegrid {
  position: absolute; inset: 0;
  pointer-events: none;
  background-image:
    linear-gradient(var(--hair-night) 1px, transparent 1px),
    linear-gradient(90deg, var(--hair-night) 1px, transparent 1px);
  background-size: 62px 62px;
  opacity: .55;
  -webkit-mask-image: radial-gradient(120% 78% at 22% 0%, #000 8%, transparent 72%);
          mask-image: radial-gradient(120% 78% at 22% 0%, #000 8%, transparent 72%);
  animation: gridDrift 34s linear infinite;
}
.codegrid--soft { opacity: .3; animation-duration: 52s; }

.glow {
  position: absolute;
  pointer-events: none;
  width: 46vw; height: 46vw;
  max-width: 640px; max-height: 640px;
  border-radius: 50%;
  filter: blur(10px);
  opacity: .5;
}
.glow--a { top: -16%;  right: -6%;  background: radial-gradient(circle, rgba(47,191,163,.26) 0%, transparent 66%); animation: floatGlow 17s var(--ease) infinite; }
.glow--b { bottom: -28%; left: -12%; background: radial-gradient(circle, rgba(94,76,122,.34) 0%, transparent 66%); animation: floatGlow 23s var(--ease) infinite reverse; }
.glow--c { top: 4%; left: 42%; background: radial-gradient(circle, rgba(217,172,91,.16) 0%, transparent 66%); animation: floatGlow 29s var(--ease) infinite; }

/* -- Hero ------------------------------------------------------------------ */
.apphero, .appwork, .eras-band, .appcta { position: relative; overflow: hidden; }
/* The content column sits above the ambience in every night section — the grid
   and the glows are painted behind it, never over a link. */
.apphero__wrap,
.appwork > .wrap,
.eras-band > .wrap,
.appcta > .wrap { position: relative; z-index: 1; }
.apphero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.06fr) minmax(0, .94fr);
  gap: var(--gap-lg);
  align-items: center;
}
/* Each headline line is its own .riseWrap and must not wrap inside one, so the
   type is set to the longest of the three lines rather than to the usual hero
   scale — the copy column here is only half the page wide. */
.apphero .h-hero { font-size: clamp(32px, 4.3vw, 52px); line-height: 1.06; max-width: 22ch; }
.apphero .hero-lede { border-top-color: var(--hair-night); }

/* Hero counters — the numerals count up once the block is on screen (JS), and
   simply read as their final value when it is not available. */
.hstats {
  display: grid; grid-template-columns: repeat(3, auto);
  justify-content: start;
  gap: 44px;
  margin: 40px 0 0; padding-top: 26px;
  border-top: 1px solid var(--hair-night);
}
.hstat__num {
  font-size: clamp(30px, 3.4vw, 40px);
  font-weight: 900; letter-spacing: -.03em; line-height: 1;
  color: var(--tealBright);
  font-variant-numeric: tabular-nums;
}
.hstat__label {
  font-family: var(--font-mono);
  font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase;
  color: var(--fade-night); opacity: .72;
  margin: 10px 0 0;
}

/* -- Terminal panel -------------------------------------------------------- */
.terminal {
  background: rgba(6,20,27,.68);
  border: 1px solid var(--hair-night);
  border-radius: var(--r-lg);
  box-shadow: 0 34px 80px rgba(0,0,0,.55);
  overflow: hidden;
}
.terminal__bar {
  display: flex; align-items: center; gap: 8px;
  padding: 13px 16px;
  background: rgba(255,255,255,.04);
  border-bottom: 1px solid var(--hair-night);
}
.terminal__dot, .shot__dot { width: 11px; height: 11px; border-radius: 50%; flex: none; }
.terminal__dot--r, .shot__dot--r { background: #FF5F57; }
.terminal__dot--y, .shot__dot--y { background: #FEBC2E; }
.terminal__dot--g, .shot__dot--g { background: #28C840; }
.terminal__name {
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .08em;
  color: var(--fade-night); opacity: .55;
  margin-left: 10px;
}
.terminal__body {
  padding: 22px 22px 26px;
  font-family: var(--font-mono);
  font-size: 13px; line-height: 2;
  min-height: 268px;
}
.terminal__line { margin: 0; white-space: pre-wrap; color: var(--on-night); }
.terminal__line--out { color: var(--fade-night); opacity: .68; padding-left: 16px; }
.terminal__prompt { color: var(--tealBright); margin-right: 8px; }
/* While the panel is being typed out, lines that have not been reached yet are
   held back rather than removed, so nothing reflows as each one lands. */
.terminal.is-typing .terminal__line { visibility: hidden; }
.terminal.is-typing .terminal__line.is-typed { visibility: visible; }

/* -- Filter bar ------------------------------------------------------------ */
.filterbar {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  margin-top: 34px; padding-top: 26px;
  border-top: 1px solid var(--hair-night);
}
.filterbar__label {
  font-family: var(--font-mono);
  font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase;
  color: var(--fade-night); opacity: .6;
}
.filterbar__set { display: flex; gap: 8px; flex-wrap: wrap; }
.filter {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 9px 16px;
  font-family: var(--font-mono);
  font-size: 11.5px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--fade-night);
  background: transparent;
  border: 1px solid var(--hair-night);
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: color var(--t-fast), background var(--t-fast), border-color var(--t-fast);
}
.filter:hover { color: var(--on-night); border-color: rgba(47,191,163,.55); opacity: 1; }
.filter.is-active { background: var(--tealBright); border-color: var(--tealBright); color: #05221C; }
.filter__n { font-size: 10px; opacity: .6; }
.filterbar__count {
  margin: 0 0 0 auto;
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .06em;
  color: var(--fade-night); opacity: .55;
}

/* -- Application grid ------------------------------------------------------ */
.appgrid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 26px;
  margin-top: 32px;
}
.appgrid__empty {
  font-family: var(--font-mono); font-size: 13px;
  color: var(--fade-night); opacity: .6;
  margin: 30px 0 0;
}

.appcard {
  position: relative;
  display: flex; flex-direction: column;
  background: linear-gradient(180deg, rgba(255,255,255,.10), rgba(255,255,255,.045));
  border: 1px solid var(--hair-night);
  border-radius: var(--r-lg);
  overflow: hidden;
  /* One transform chain, driven entirely by custom properties, so the three
     things that move a card never fight over the same declaration: the filter's
     FLIP glide (--fx/--fy), the pointer tilt (--rx/--ry) and the hover lift
     (--ty) each own their own slot and compose here. */
  transform: perspective(900px)
             translate3d(var(--fx, 0px), var(--fy, 0px), 0)
             rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg))
             translateY(var(--ty, 0px));
  transition: transform var(--t-slow) var(--ease), border-color var(--t-base), box-shadow var(--t-slow);
}
/* While the pointer is on a card the tilt has to feel attached to the cursor,
   not eased behind it; while FLIP is setting the start offset there must be no
   transition at all or the card would animate to its own starting point. */
.appcard.is-tilting { transition: transform .12s linear, border-color var(--t-base), box-shadow var(--t-slow); }
.appcard.is-flipping { transition: none; }

/* Pointer spotlight — sits above the card surface and below its content, so it
   lights the card without washing out the copy. */
.appcard::after {
  content: "";
  position: absolute; inset: 0; z-index: 0;
  background: radial-gradient(340px circle at var(--mx, 50%) var(--my, 0%), rgba(47,191,163,.16), transparent 62%);
  opacity: 0;
  transition: opacity var(--t-base);
  pointer-events: none;
}
.appcard.is-lit::after { opacity: 1; }
.appcard > * { position: relative; z-index: 1; }
/* A hairline that lights along the top edge on hover — the card's "power on" */
.appcard::before {
  content: "";
  position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, var(--tealBright), var(--gold));
  transform: scaleX(0); transform-origin: 0 50%;
  transition: transform var(--t-slow) var(--ease);
  z-index: 3;
}
.appcard:hover, .appcard:focus-within {
  --ty: -6px;
  border-color: rgba(47,191,163,.42);
  box-shadow: 0 26px 60px rgba(0,0,0,.5);
}
.appcard:hover::before, .appcard:focus-within::before { transform: scaleX(1); }
.appcard[hidden] { display: none; }
.appcard.is-entering { animation: fadeUp .45s var(--ease) both; animation-delay: calc(var(--i, 0) * 45ms); }

/* Screenshot in browser chrome ------------------------------------------- */
.shot { position: relative; background: var(--night-3); border-bottom: 1px solid var(--hair-night); }
.shot__bar {
  display: flex; align-items: center; gap: 7px;
  padding: 10px 14px;
  background: rgba(0,0,0,.20);
}
.shot__url {
  flex: 1; min-width: 0;
  margin-left: 8px; padding: 4px 10px;
  border-radius: var(--r-pill);
  background: rgba(255,255,255,.06);
  font-family: var(--font-mono);
  font-size: 10px; letter-spacing: .04em;
  color: var(--fade-night); opacity: .62;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.shot__img {
  display: block; position: relative;
  aspect-ratio: 16/10;
  overflow: hidden;
  background: var(--night-3);
  cursor: zoom-in;
}
.shot__img img {
  width: 100%; height: 100%;
  object-fit: cover; object-position: top center;
  display: block;
  transition: transform .8s var(--ease);
}
.appcard:hover .shot__img img { transform: scale(1.05); }
.shot__img:hover, .shot__img:focus-visible { opacity: 1; }

/* Phone mock-ups and desktop UI shots are the wrong shape for a 16:10 crop —
   cropping them throws away the very thing the card is showing. These sit whole
   inside the frame instead, letterboxed against the chrome surface. */
.shot__img--contain img { object-fit: contain; object-position: center; padding: 12px; }
.appcard:hover .shot__img--contain img { transform: scale(1.03); }
/* Light sweeps across the capture on hover */
.shot__img::after {
  content: "";
  position: absolute; inset: 0;
  background: linear-gradient(105deg, transparent 38%, rgba(255,255,255,.13) 50%, transparent 62%);
  transform: translateX(-110%);
  pointer-events: none;
}
.appcard:hover .shot__img::after { animation: shine 1.1s var(--ease) forwards; }

.shot__img--empty {
  display: grid; place-items: center;
  cursor: default;
  background:
    repeating-linear-gradient(45deg, rgba(120,200,186,.10) 0 9px, transparent 9px 18px),
    var(--night-3);
}
.shot__ph {
  font-family: var(--font-mono);
  font-size: 11px; line-height: 1.8; letter-spacing: .06em;
  text-align: center;
  color: var(--fade-night); opacity: .55;
  padding: 10px;
}
.shot__zoom {
  position: absolute; left: 50%; bottom: 14px;
  transform: translateX(-50%) translateY(6px);
  padding: 7px 14px;
  font-family: var(--font-mono);
  font-size: 10.5px; letter-spacing: .08em;
  color: var(--on-night);
  background: rgba(3,13,18,.82);
  border: 1px solid var(--hair-night);
  border-radius: var(--r-pill);
  opacity: 0;
  transition: opacity var(--t-fast), transform var(--t-fast) var(--ease);
}
.shot__img:hover .shot__zoom,
.shot__img:focus-visible .shot__zoom { opacity: 1; transform: translateX(-50%) translateY(0); }

/* Card copy --------------------------------------------------------------- */
.appcard__body { flex: 1; padding: 22px 22px 4px; }
.appcard__head { display: grid; grid-template-columns: auto 1fr auto; gap: 13px; align-items: start; }
.appcard__icon {
  width: 38px; height: 38px; flex: none;
  display: grid; place-items: center;
  border: 1px solid var(--hair-night);
  border-radius: var(--r-md);
  color: var(--tealBright);
  background: rgba(47,191,163,.08);
  transition: background var(--t-base), transform var(--t-base) var(--ease);
}
.appcard__icon svg { width: 20px; height: 20px; }
.appcard:hover .appcard__icon { background: rgba(47,191,163,.18); transform: translateY(-2px); }
.appcard__title { font-size: 19px; font-weight: 800; letter-spacing: -.01em; margin: 0; }
.appcard__sub {
  font-size: 13px; font-weight: 600;
  color: var(--tealBright);
  margin: 3px 0 0;
}
.appcard__idx {
  font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .1em;
  color: var(--fade-night); opacity: .38;
}
.appcard__text {
  font-size: 14.5px; line-height: 1.65;
  color: var(--fade-night); opacity: .92;
  margin: 16px 0 20px;
}
.appcard__foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
  margin: 0 22px; padding: 15px 0 20px;
  border-top: 1px solid var(--hair-night);
}
.appchip {
  font-family: var(--font-mono);
  font-size: 10px; letter-spacing: .1em; text-transform: uppercase;
  color: var(--fade-night); opacity: .7;
  border: 1px solid var(--hair-night);
  border-radius: var(--r-pill);
  padding: 5px 11px;
}
.applink {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--font-mono);
  font-size: 12px; letter-spacing: .06em;
  color: var(--tealBright);
  text-decoration: none;
  background: none; border: 0; padding: 0;
  cursor: pointer;
}
.applink:hover { opacity: 1; }
.applink__arrow { transition: transform var(--t-fast) var(--ease); }
.applink:hover .applink__arrow { transform: translate(3px, -3px); }

/* -- Timeline: the era rail ------------------------------------------------ */
/* Every panel ships visible and stacked; enhance.js adds .is-tabbed and turns
   the row of decades into a real tablist. Without JavaScript the reader still
   gets all five eras in order. */
.eras { position: relative; margin-top: 46px; }
.eras__rail {
  position: relative;
  display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 12px;
}
.eras__line {
  position: absolute; top: 33px; left: 10%; right: 10%; height: 2px;
  background: var(--hair-night);
  overflow: hidden;
}
.eras__fill {
  position: absolute; inset: 0 auto 0 0;
  width: 0;
  background: linear-gradient(90deg, var(--tealBright), var(--gold));
  transition: width 1.8s var(--ease);
}
.eras.is-in .eras__fill { width: 100%; }

.era {
  position: relative; z-index: 1;
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  padding: 0 6px;
  background: none; border: 0;
  color: inherit;
  font-family: var(--font-sans);
  cursor: pointer;
  text-align: center;
}
.era__dot {
  position: relative;
  width: 68px; height: 68px;
  display: grid; place-items: center;
  border: 1px solid var(--hair-night);
  border-radius: 50%;
  background: var(--night-2);
  color: var(--fade-night);
  transition: transform var(--t-base) var(--ease), border-color var(--t-base),
              background var(--t-base), color var(--t-base), box-shadow var(--t-base);
}
.era__dot svg { width: 26px; height: 26px; }
.era:hover .era__dot { border-color: rgba(47,191,163,.55); color: var(--on-night); transform: translateY(-3px); }
.era.is-active .era__dot {
  border-color: var(--tealBright);
  background: rgba(47,191,163,.14);
  color: var(--tealBright);
  box-shadow: 0 0 0 7px rgba(47,191,163,.07);
  transform: scale(1.05);
}
.era__year {
  font-family: var(--font-mono);
  font-size: 12px; letter-spacing: .14em;
  color: var(--fade-night); opacity: .7;
  transition: color var(--t-base), opacity var(--t-base);
}
.era.is-active .era__year { color: var(--tealBright); opacity: 1; }
.era__name {
  font-size: 13px; font-weight: 700; line-height: 1.45;
  max-width: 18ch;
  color: var(--fade-night); opacity: .78;
}
.era.is-active .era__name { color: var(--on-night); opacity: 1; }

.eras__panels { margin-top: 46px; }
.erapanel {
  display: grid; grid-template-columns: 160px 1fr;
  gap: 32px; align-items: baseline;
  padding: 28px 0;
  border-top: 1px solid var(--hair-night);
}
.eras.is-tabbed .erapanel { display: none; border-top: 0; padding: 0; }
.eras.is-tabbed .erapanel.is-active {
  display: grid;
  animation: fadeUp .45s var(--ease) both;
  border-top: 1px solid var(--hair-night);
  padding-top: 30px;
}
.erapanel__year {
  font-size: clamp(34px, 4.4vw, 54px);
  font-weight: 900; letter-spacing: -.03em; line-height: 1;
  color: var(--tealBright);
}
.erapanel__title { font-size: clamp(21px, 2.6vw, 28px); font-weight: 800; letter-spacing: -.02em; margin: 0; }
.erapanel__body { font-size: 16.5px; line-height: 1.7; color: var(--fade-night); opacity: .82; margin: 12px 0 0; max-width: 56ch; }

/* Section titles that centre on this page only */
.center-md { text-align: center; margin-left: auto; margin-right: auto; }
.eras-band .band-lede { margin-left: auto; margin-right: auto; text-align: center; }

/* -- Closing highlights ---------------------------------------------------- */
.hilites { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 30px 26px; }
.hilite { display: grid; grid-template-columns: auto 1fr; gap: 15px; align-items: start; }
.hilite__icon {
  width: 46px; height: 46px; flex: none;
  display: grid; place-items: center;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  color: var(--accent);
  background: var(--paper);
  transition: background var(--t-base), color var(--t-base), transform var(--t-base) var(--ease);
}
.hilite__icon svg { width: 22px; height: 22px; }
.hilite:hover .hilite__icon { background: var(--accent); color: var(--paper2); transform: translateY(-3px); }
.hilite__title { font-size: 17px; font-weight: 800; letter-spacing: -.01em; margin: 4px 0 0; }
.hilite__body { font-size: 14.5px; line-height: 1.6; color: var(--sub); margin: 7px 0 0; }

/* -- Interaction layer ------------------------------------------------------
   Everything below is created or driven by enhance.js. None of it carries
   content, and none of it is required to read the page — each piece is either
   built in JS or stays invisible until JS starts feeding it a value.
   -------------------------------------------------------------------------- */

/* Hero light that follows the pointer. Sits over the grid, under the copy. */
.apphero__light {
  position: absolute; inset: 0;
  pointer-events: none;
  background: radial-gradient(680px circle at var(--mx, 30%) var(--my, 30%), rgba(47,191,163,.12), transparent 68%);
  opacity: 0;
  transition: opacity .5s var(--ease);
}
.apphero.is-lit .apphero__light { opacity: 1; }

/* Scroll parallax. The element only moves once JS writes --py to it. */
[data-parallax] { transform: translate3d(0, var(--py, 0px), 0); }

/* Era autoplay ring: a conic sweep masked down to a 2.5px band, so the active
   decade shows how long it has before the rail moves on. Injected by JS. */
.era__ring {
  position: absolute; inset: -6px;
  border-radius: 50%;
  background: conic-gradient(var(--tealBright) calc(var(--p, 0) * 1%), transparent 0);
  -webkit-mask: radial-gradient(closest-side, transparent calc(100% - 2.5px), #000 calc(100% - 2.5px));
          mask: radial-gradient(closest-side, transparent calc(100% - 2.5px), #000 calc(100% - 2.5px));
  opacity: 0;
  transition: opacity var(--t-base);
  pointer-events: none;
}
.era.is-active .era__ring { opacity: .95; }
.eras.is-held .era__ring { opacity: .3; }

/* Keyboard hint on the filter bar */
.filterbar__hint {
  display: inline-flex; align-items: center; gap: 6px;
  font-family: var(--font-mono);
  font-size: 10.5px; letter-spacing: .06em;
  color: var(--fade-night); opacity: .5;
}
.kbd {
  display: inline-block; min-width: 17px; text-align: center;
  padding: 2px 5px;
  font-family: var(--font-mono); font-size: 10px; line-height: 1.2;
  color: var(--on-night);
  background: rgba(255,255,255,.08);
  border: 1px solid var(--hair-night);
  border-bottom-width: 2px;
  border-radius: 4px;
}

/* -- Reading progress ------------------------------------------------------ */
/* Injected by enhance.js, so it only ever exists where it can be driven. */
.readbar {
  position: fixed; inset: 0 0 auto 0;
  height: 3px; z-index: 200;
  transform: scaleX(var(--p, 0)); transform-origin: 0 50%;
  background: linear-gradient(90deg, var(--tealBright), var(--gold));
  pointer-events: none;
}


/* ============================================================================
   8  MOTION
   ============================================================================ */
@keyframes fadeUp { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
/* Case swap: rises and settles from slightly small, so a document reads as
   being placed on the table rather than cross-fading in place. */
@keyframes caseIn { from { opacity: 0; transform: translateY(14px) scale(.985); } to { opacity: 1; transform: none; } }
@keyframes riseIn { from { transform: translateY(115%); } to { transform: translateY(0); } }
@keyframes blink  { 0%,49% { opacity: 1; } 50%,100% { opacity: 0; } }

/* Applications page ambience */
@keyframes gridDrift { from { background-position: 0 0, 0 0; } to { background-position: 62px 62px, 62px 62px; } }
@keyframes floatGlow {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  50%      { transform: translate3d(-4%, 6%, 0) scale(1.09); }
}
@keyframes shine { to { transform: translateX(110%); } }
@keyframes pulseDot {
  0%, 100% { box-shadow: 0 0 0 0 rgba(47,191,163,.5); }
  60%      { box-shadow: 0 0 0 7px rgba(47,191,163,0); }
}

/* Outreach hero ambience. The two drifts are deliberately different lengths so
   the washes never return to the same arrangement twice while you read. */
@keyframes pulseGold {
  0%, 100% { box-shadow: 0 0 0 0 rgba(217,172,91,.55); }
  60%      { box-shadow: 0 0 0 8px rgba(217,172,91,0); }
}
@keyframes heroDriftA {
  from { transform: translate3d(0, 0, 0) scale(1); }
  to   { transform: translate3d(-6%, 5%, 0) scale(1.12); }
}
@keyframes heroDriftB {
  from { transform: translate3d(0, 0, 0) scale(1.06); }
  to   { transform: translate3d(7%, -6%, 0) scale(1); }
}
@keyframes drawRule { to { transform: scaleX(1); } }

.fade-up { animation: fadeUp .6s both; }
.cursor  { animation: blink 1.05s steps(1) infinite; color: var(--gold); }

.riseWrap {
  overflow: hidden;
  display: block;
  padding-bottom: .2em;
  margin-bottom: -.2em;
}
.riseWrap > span { display: block; animation: riseIn .85s var(--ease) both; }
.riseWrap:nth-of-type(1) > span { animation-delay: .05s; }
.riseWrap:nth-of-type(2) > span { animation-delay: .15s; }
.riseWrap:nth-of-type(3) > span { animation-delay: .23s; }

/* Scroll reveal — content is visible by default; JS opts in, so no-JS is safe */
.js-reveal [data-reveal] {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
  will-change: opacity, transform;
}
.js-reveal [data-reveal].is-in { opacity: 1; transform: none; }

/* Card / tile hover lift */
.hover-lift { transition: transform var(--t-base) var(--ease), box-shadow var(--t-base); }
.hover-lift:hover { transform: translateY(-4px); box-shadow: var(--shadow-card); opacity: 1; }

.media.has-img .hc-img { transition: transform .5s var(--ease); }
.media.has-img:hover .hc-img { transform: scale(1.03); }


/* ============================================================================
   9  RESPONSIVE — all breakpoints live here, keyed to classes only
   ============================================================================ */
@media (max-width: 1024px) {
  .slider-panel { grid-template-columns: 150px 1fr; gap: 28px; padding: 34px; }
  .grid--pillars { grid-template-columns: 1fr; }

  /* Applications: three cards across becomes two, and the terminal drops under
     the hero copy rather than being squeezed beside it. */
  .apphero__grid { grid-template-columns: 1fr; }
  /* One column again, so the headline gets the full hero scale back */
  .apphero .h-hero { font-size: clamp(36px, 6.6vw, 64px); max-width: 20ch; }
  .appgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 900px) {
  :root { --wrap-x: 22px; --wrap-y: 48px; --gap-lg: 34px; }

  .wrap--hero   { --wrap-y: 54px; padding-bottom: 44px; }
  .wrap--hero-l { --wrap-y: 56px; padding-bottom: 46px; }
  .wrap--cta,
  .wrap--cta-l  { --wrap-y: 56px; }
  .wrap--strip  { --wrap-y: 26px; }
  .wrap--slim   { --wrap-y: 40px; }

  /* Every multi-column grid collapses from one place */
  .grid--2, .grid--3, .grid--split, .grid--aside, .grid--acc,
  .grid--media, .grid--video, .grid--join, .grid--form,
  .grid--endcap, .grid--label, .teaser, .hero__foot, .steps,
  .site-footer__grid {
    grid-template-columns: 1fr;
  }
  .grid--endcap, .teaser, .hero__foot { align-items: start; }
  .site-footer__grid { gap: 32px; }

  /* Stacked, the teaser buttons are already the same width as the column, so the
     desktop min-width only risks overflowing a narrow phone. */
  .teaser .btn { min-width: 0; width: 100%; white-space: normal; }

  .strip { grid-template-columns: repeat(2, 1fr); row-gap: 24px; }
  .strip__item { padding: 0 20px 0 0; }
  .strip__item:nth-child(2n) { padding-right: 0; border-right: 0; }

  .steps__item { padding: 0 0 24px; border-right: 0; border-bottom: 1px solid var(--line); }
  .steps__item:last-child { padding-bottom: 0; border-bottom: 0; }

  .slider-panel { grid-template-columns: 1fr; }
  .slider-panel__aside { border-right: 0; border-bottom: 1px solid var(--line); padding: 0 0 20px; }

  .numrow  { grid-template-columns: 56px 1fr; gap: 18px; }
  .numrow > .meta { grid-column: 2; }

  .event-row { grid-template-columns: 90px 1fr auto; gap: 18px; padding: 20px; }

  .pillar-panel { padding: 28px; min-height: 0; }
  .prose { font-size: 17px; }
  .eyebrow--vert { writing-mode: horizontal-tb; transform: none; }
  .callout { padding-left: 20px; }

  /* Mobile nav */
  .nav__links { display: none; }
  .nav-toggle { display: block; }
  body.nav-open .nav__links {
    display: flex;
    position: absolute; left: 0; right: 0; top: 100%;
    flex-direction: column; align-items: flex-start; gap: 4px;
    background: var(--paper);
    border-bottom: 2px solid var(--ink);
    padding: 16px var(--wrap-x) 24px;
    z-index: 90;
  }
  .topbar__mid { display: none; }
  .topbar { grid-template-columns: 1fr auto; }

  .blog-card--scroll { flex-basis: 78vw; }
  .media--cap { max-width: none; }

  .factgrid { grid-template-columns: repeat(2, 1fr); gap: 28px; }

  /* Stack the aim cards — three across is unreadable at this width. There is no
     hover here, so the photo header is the tap target and each card opens on
     tap; the statement stays visible either way. */
  .aimset { grid-template-columns: 1fr; gap: 16px; }
  .aim__photo { height: 200px; }

  /* Consulting: the practitioner card drops under the headline, the document
     stage moves above the copy, and the sticky bar drops to just its link row
     so it stays one line high. */
  .hero-consult { grid-template-columns: 1fr; }
  .who { max-width: 360px; }
  .cases { grid-template-columns: 1fr; }
  .cases__stage { max-width: 420px; }
  .pagenav__inner { min-height: 52px; gap: 0; padding: 0 12px; }
  .pagenav__label,
  .pagenav__cta { display: none; }
  [data-page="consulting"] .band[id] { scroll-margin-top: 58px; }

  /* Applications ---------------------------------------------------------- */
  .appgrid, .hilites { grid-template-columns: 1fr; }
  .hstats { gap: 28px; }
  .terminal__body { min-height: 0; font-size: 12px; padding: 18px 16px 22px; }

  /* The era rail turns into a scrollable row of decades: five 68px nodes will
     not fit across a phone, and stacking them would bury the panel. */
  .eras__rail {
    grid-template-columns: none;
    grid-auto-flow: column;
    grid-auto-columns: 116px;
    overflow-x: auto;
    scrollbar-width: none;
    padding-bottom: 6px;
  }
  .eras__rail::-webkit-scrollbar { display: none; }
  .eras__line { display: none; }
  .era__name { font-size: 12px; }
  .eras__panels { margin-top: 32px; }
  .erapanel { grid-template-columns: 1fr; gap: 12px; }
  .center-md, .eras-band .band-lede { text-align: left; }
  .glow { filter: blur(6px); opacity: .38; }
}

@media (max-width: 520px) {
  .strip { grid-template-columns: 1fr; }
  .strip__item { padding: 0; border-right: 0; }
  .grid--4 { grid-template-columns: 1fr; }
  .rowlist__row { flex-direction: column; align-items: flex-start; gap: 4px; }
  .event-row { grid-template-columns: 70px 1fr; }
  .event-row__arrow { display: none; }
  .btn { padding: 14px 24px; }
  .factgrid { grid-template-columns: 1fr; }
  .thumb { width: 84px; height: 63px; }

  /* Term over description — 108px of label column is too much of a 320px screen */
  .glance__row { grid-template-columns: 1fr; gap: 3px; }
  .case-tab { flex: 1; }

  /* Applications: the three hero counters sit two-up rather than shrinking */
  .hstats { grid-template-columns: repeat(2, auto); gap: 22px 30px; }
  .filterbar__count { margin-left: 0; }
  .appcard__foot { padding-bottom: 18px; }
}

@media (min-width: 521px) and (max-width: 900px) {
  .grid--4 { grid-template-columns: repeat(2, 1fr); }
}

/* Touch devices never fire :hover, so the zoom affordance is shown outright */
@media (hover: none) {
  .artifact__zoom { opacity: 1; transform: translateX(-50%); }
  .shot__zoom { opacity: 1; transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  .js-reveal [data-reveal] { opacity: 1 !important; transform: none !important; }
  .hover-lift:hover { transform: none; }
  .media.has-img:hover .hc-img { transform: none; }
  .aim:hover { transform: none; }
  .aim:hover .aim__photo { transform: none; }
  .aim:hover .aim__badge { transform: none; }
  .artifact__frame:hover img { transform: none; }
  .artifact__frame:hover { transform: none; }
  .steps--flow .steps__item:hover { transform: none; }
  .ecard:hover .ecard__icon { transform: none; }
  .case-tab:hover { transform: none; }

  /* Outreach: the hero keeps its aura, loses the drift, and the rule under the
     highlighted words is simply already drawn */
  .hero-out__blob, .hero-out .hero__badge::before { animation: none; }
  .hero-out .hl::after { animation: none; transform: scaleX(1); }
  .hero-out .btn:hover { transform: none; }

  /* Applications: the page keeps its look, loses its movement */
  .codegrid, .glow, .hero__badge--live::before { animation: none; }
  [data-parallax] { transform: none; }
  .appcard { transform: none; }
  .appcard:hover { transform: none; }
  .appcard:hover .shot__img img { transform: none; }
  .appcard:hover .shot__img::after { animation: none; }
  .appcard:hover .appcard__icon { transform: none; }
  .era:hover .era__dot { transform: none; }
  .era.is-active .era__dot { transform: none; }
  .eras__fill { transition: none; }
  .hilite:hover .hilite__icon { transform: none; }
  .btn--teal:hover { transform: none; }
  .terminal.is-typing .terminal__line { visibility: visible; }
}
