/* ---- self-hosted webfonts (SIL Open Font License 1.1) ----
   Fraunces, Inter — variable woff2, latin + latin-ext.
   Files live in /assets/fonts, shared by all four directions. */

@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/fraunces-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Fraunces';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('../fonts/fraunces-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('../fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('../fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* ---- end webfonts */

/* ==========================================================================
   SPG Leaders — Design System
   Network. Learn. Grow.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  /* Brand — derived from the SPG arc mark */
  --blue-700: #14539f;
  --blue-600: #1b6ac9;
  --blue-500: #2b82e0;
  --blue-400: #59a1ee;
  --blue-100: #e3eefc;
  --blue-50:  #f1f7fe;

  --amber-500: #f2b01e;
  --amber-400: #ffc84a;
  --amber-100: #fdf1d6;

  --coral-500: #e4573d;
  --coral-100: #fbe6e1;

  /* Neutrals */
  --ink-900: #08111d;
  --ink-800: #0d1b2c;
  --ink-700: #14273d;
  --ink-600: #1e344f;
  --slate-700: #33475f;
  --slate-500: #5a6a80;
  --slate-400: #7d8ba0;
  --line: rgba(8, 17, 29, 0.10);
  --line-soft: rgba(8, 17, 29, 0.06);
  --paper: #ffffff;
  --sand: #f6f6f3;
  --sand-2: #eeeeea;

  /* Semantic */
  --bg: var(--paper);
  --fg: var(--ink-900);
  --fg-muted: var(--slate-500);
  --accent: var(--blue-600);

  /* Type */
  --font-display: "Fraunces", "Iowan Old Style", Georgia, serif;
  --font-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

  --step--1: clamp(0.82rem, 0.79rem + 0.13vw, 0.89rem);
  --step-0:  clamp(1rem, 0.96rem + 0.18vw, 1.09rem);
  --step-1:  clamp(1.18rem, 1.1rem + 0.36vw, 1.4rem);
  --step-2:  clamp(1.45rem, 1.3rem + 0.7vw, 1.9rem);
  --step-3:  clamp(1.8rem, 1.5rem + 1.4vw, 2.7rem);
  --step-4:  clamp(2.2rem, 1.6rem + 2.6vw, 3.9rem);
  --step-5:  clamp(2.7rem, 1.7rem + 4.2vw, 5.4rem);

  /* Space */
  --gutter: clamp(1.25rem, 4vw, 3rem);
  --section: clamp(4.5rem, 8vw, 8.5rem);
  --container: 1240px;

  /* Shape */
  --r-xs: 8px;
  --r-sm: 12px;
  --r-md: 18px;
  --r-lg: 26px;
  --r-xl: 36px;
  --r-full: 999px;

  --shadow-xs: 0 1px 2px rgba(8, 17, 29, 0.06);
  --shadow-sm: 0 2px 8px rgba(8, 17, 29, 0.06), 0 1px 2px rgba(8, 17, 29, 0.04);
  --shadow-md: 0 10px 30px -12px rgba(8, 17, 29, 0.18), 0 2px 6px rgba(8, 17, 29, 0.05);
  --shadow-lg: 0 30px 70px -30px rgba(8, 17, 29, 0.32), 0 4px 14px rgba(8, 17, 29, 0.06);
  --shadow-glow: 0 20px 60px -22px rgba(27, 106, 201, 0.55);

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);
}

/* --------------------------------------------------------------------------
   2. Base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

/* Component display rules (.event, .card…) would otherwise beat the UA [hidden] rule. */
[hidden] { display: none !important; }

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: 100px;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font-family: var(--font-sans);
  font-size: var(--step-0);
  line-height: 1.65;
  font-feature-settings: "cv02", "cv03", "cv11", "ss01";
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  /*
   * Contain sideways overflow without breaking position: sticky.
   *
   * `overflow-x: hidden` on the body makes overflow-y compute to `auto`, which
   * turns the body into a scroll container. Chrome hands that scrolling to the
   * viewport and sticky keeps working; Safari does not, and every sticky
   * descendant silently stops sticking — which is what killed the scroll-driven
   * Services section on iPhone while every desktop browser looked fine.
   *
   * `overflow-x: clip` trims the same overflow without creating a scroll
   * container, so sticky survives. The `hidden` above it is the fallback for
   * anything too old to know `clip`; those browsers keep the previous
   * behaviour rather than losing the containment.
   */
  overflow-x: hidden;
  overflow-x: clip;
}

body.is-locked { overflow: hidden; }

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

a { color: inherit; text-decoration: none; }

h1, h2, h3, h4, h5 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-variation-settings: "SOFT" 0, "WONK" 0;
  line-height: 1.08;
  letter-spacing: -0.022em;
  text-wrap: balance;
}

h1 { font-size: var(--step-5); }
h2 { font-size: var(--step-4); }
h3 { font-size: var(--step-2); }
h4 { font-size: var(--step-1); }

p { margin: 0 0 1em; text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

ul, ol { margin: 0; padding: 0; }
li { list-style: none; }

::selection { background: var(--amber-400); color: var(--ink-900); }

:focus-visible {
  outline: 2px solid var(--blue-500);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 999;
  background: var(--ink-900);
  color: #fff;
  padding: 0.85rem 1.4rem;
  border-radius: 0 0 var(--r-sm) 0;
}
.skip-link:focus { left: 0; }

/* --------------------------------------------------------------------------
   3. Layout primitives
   -------------------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container--narrow { max-width: 860px; }

.section { padding-block: var(--section); position: relative; }
.section--tight { padding-block: clamp(3rem, 5vw, 5rem); }
.section--flush-top { padding-top: 0; }

.grid { display: grid; gap: clamp(1.25rem, 2.4vw, 2rem); }
.grid-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.grid-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.grid-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.stack { display: grid; gap: 1.25rem; justify-items: start; }
.cluster { display: flex; flex-wrap: wrap; gap: 0.75rem; align-items: center; }
.center { text-align: center; }
.center .stack { justify-items: center; }

.divider { height: 1px; background: var(--line-soft); border: 0; margin: 0; }

/* --------------------------------------------------------------------------
   4. Typography helpers
   -------------------------------------------------------------------------- */
.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--font-sans);
  font-size: 0.74rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--blue-600);
}
.eyebrow::before {
  content: "";
  width: 26px;
  height: 2px;
  border-radius: 2px;
  background: linear-gradient(90deg, var(--blue-500), var(--amber-500));
}
.eyebrow--plain::before { display: none; }

.lede {
  font-size: var(--step-1);
  line-height: 1.55;
  color: var(--slate-700);
  max-width: 62ch;
}

.muted { color: var(--fg-muted); }
.measure { max-width: 60ch; }
.measure-sm { max-width: 46ch; }

/* Highlighter stroke. Uses text-decoration rather than a background gradient:
   the underline is anchored to the baseline, so the band stays correctly
   positioned through the glyphs at any font size and in any fallback face —
   a percentage gradient is anchored to the font's ascent/descent box instead,
   which shifts the band as soon as the metrics change. The decoration paints
   behind the glyph fill, so the letters stay legible on top of it. */
.underline-mark {
  text-decoration-line: underline;
  text-decoration-color: var(--amber-400);
  text-decoration-thickness: 0.28em;
  text-underline-offset: -0.17em;
  text-decoration-skip-ink: none;
}

.text-gradient {
  background: linear-gradient(100deg, var(--blue-400), var(--blue-100) 55%, var(--amber-400));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.section-head {
  display: grid;
  gap: 1.1rem;
  max-width: 720px;
  margin-bottom: clamp(2.5rem, 4vw, 3.75rem);
}
.section-head--split {
  max-width: none;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  align-items: end;
  gap: clamp(1.5rem, 4vw, 3rem);
}
.section-head--center { margin-inline: auto; text-align: center; justify-items: center; }

/* --------------------------------------------------------------------------
   5. Buttons
   -------------------------------------------------------------------------- */
.btn {
  --btn-bg: var(--ink-900);
  --btn-fg: #fff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  padding: 0.95rem 1.6rem;
  border: 1px solid transparent;
  border-radius: var(--r-full);
  background: var(--btn-bg);
  color: var(--btn-fg);
  font-family: var(--font-sans);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: -0.005em;
  cursor: pointer;
  transition: transform 0.35s var(--ease), box-shadow 0.35s var(--ease),
              background-color 0.25s ease, color 0.25s ease, border-color 0.25s ease;
  white-space: nowrap;
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }
.btn svg { width: 16px; height: 16px; transition: transform 0.35s var(--ease); }
.btn:hover svg { transform: translateX(3px); }
/* A leading icon (e.g. WhatsApp) sits before the label, so the arrow's
   hover-shift-right reads as movement toward the text rather than away from
   it, which is backwards for a leading icon. Sized up from the shared 16px —
   two classes to outweigh ".btn svg" rather than repeat the whole rule. */
.btn .btn__icon { width: 32px; height: 32px; }
.btn:hover .btn__icon { transform: none; }

.btn--primary {
  --btn-bg: var(--blue-600);
  box-shadow: var(--shadow-glow);
}
.btn--primary:hover { --btn-bg: var(--blue-700); }

.btn--dark { --btn-bg: var(--ink-900); box-shadow: var(--shadow-md); }

.btn--light {
  --btn-bg: #fff;
  --btn-fg: var(--ink-900);
  box-shadow: var(--shadow-md);
}

.btn--outline {
  --btn-bg: transparent;
  --btn-fg: var(--ink-900);
  border-color: var(--line);
}
.btn--outline:hover { border-color: var(--ink-900); background: var(--ink-900); --btn-fg: #fff; }

.btn--ghost-light {
  --btn-bg: rgba(255, 255, 255, 0.06);
  --btn-fg: #fff;
  border-color: rgba(255, 255, 255, 0.22);
  backdrop-filter: blur(8px);
}
.btn--ghost-light:hover { --btn-bg: rgba(255, 255, 255, 0.14); }

.btn--sm { padding: 0.65rem 1.15rem; font-size: 0.86rem; }
.btn--block { width: 100%; }

.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-weight: 600;
  font-size: 0.93rem;
  color: var(--blue-600);
}
.link-arrow svg { width: 15px; height: 15px; transition: transform 0.35s var(--ease); }
.link-arrow:hover svg { transform: translateX(4px); }

/* --------------------------------------------------------------------------
   6. Header / navigation
   -------------------------------------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  transition: background-color 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease;
  border-bottom: 1px solid transparent;
}
.site-header::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(255, 255, 255, 0.82);
  backdrop-filter: blur(14px) saturate(160%);
  opacity: 0;
  transition: opacity 0.35s ease;
  pointer-events: none;
}
.site-header.is-stuck::before { opacity: 1; }
.site-header.is-stuck { border-bottom-color: var(--line-soft); }

.nav {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: 82px;
}

.brand { display: inline-flex; align-items: center; gap: 0.7rem; flex-shrink: 0; }
.brand__mark { width: 42px; height: 42px; flex-shrink: 0; }
.brand__text { display: grid; line-height: 1; }
.brand__name {
  font-family: var(--font-sans);
  font-weight: 800;
  font-size: 1.06rem;
  letter-spacing: -0.03em;
}
.brand__tag {
  /* 0.6rem rendered at 9.6px, below a comfortable floor for supporting text
     on a phone. Raised to clear 11px; the layout shift is under 2px. */
  font-size: 0.69rem;
  font-weight: 600;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  /* slate-400 gives only 3.45:1 here, below the 4.5:1 AA floor for small text. */
  color: var(--slate-500);
  margin-top: 3px;
}
/* The header tagline is supporting text, and at the narrowest phone widths it
   is the thing that breaks the bar: 188px of letter-spaced caps beside the logo
   and name pushed the CTA and menu button 15px off-screen at 320px. The brand
   name alone identifies the site there, so the tagline steps aside rather than
   the controls. */
@media (max-width: 380px) {
  .site-header .brand__tag { display: none; }
}


.nav__menu { display: flex; align-items: center; gap: 0.15rem; }
/* The in-menu CTA is a mobile-drawer affordance only — the header has its own. */
.nav__menu > li > .btn { display: none; }
.nav__link {
  position: relative;
  display: inline-block;
  padding: 0.5rem 0.78rem;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--slate-700);
  border-radius: var(--r-full);
  transition: color 0.2s ease, background-color 0.2s ease;
}
.nav__link:hover { color: var(--ink-900); background: var(--sand); }
.nav__link[aria-current="page"] { color: var(--ink-900); font-weight: 600; }
.nav__link[aria-current="page"]::after {
  content: "";
  position: absolute;
  left: 0.78rem;
  right: 0.78rem;
  bottom: 0.18rem;
  height: 2px;
  border-radius: 2px;
  background: var(--amber-500);
}

.nav__actions { display: flex; align-items: center; gap: 0.6rem; }

.nav__toggle {
  display: none;
  width: 44px;
  height: 44px;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: #fff;
  cursor: pointer;
  padding: 0;
  /* flex, not grid: grid stretches the three rows and breaks the X transform */
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.nav__toggle span {
  display: block;
  width: 18px;
  height: 1.8px;
  border-radius: 2px;
  background: var(--ink-900);
  transition: transform 0.3s var(--ease), opacity 0.2s ease;
}
.nav__toggle span + span { margin-top: 4.5px; }
.nav__toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.3px) rotate(45deg); }
.nav__toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav__toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.3px) rotate(-45deg); }

@media (max-width: 1080px) {
  .nav__toggle { display: flex; }
  .nav__actions .btn { display: none; }
  .nav__menu {
    position: fixed;
    inset: 82px 0 0;
    flex-direction: column;
    align-items: stretch;
    justify-content: flex-start;
    gap: 0;
    padding: 1.5rem var(--gutter) 3rem;
    background: #fff;
    border-top: 1px solid var(--line-soft);
    transform: translateY(-8px);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.28s ease, transform 0.28s var(--ease), visibility 0.28s;
    overflow-y: auto;
  }
  .nav__menu.is-open { opacity: 1; visibility: visible; transform: none; }
  .nav__link {
    display: block;
    padding: 1rem 0.25rem;
    font-size: 1.15rem;
    font-weight: 600;
    border-radius: 0;
    border-bottom: 1px solid var(--line-soft);
  }
  .nav__link:hover { background: transparent; }
  .nav__link[aria-current="page"]::after { display: none; }
  .nav__link[aria-current="page"] { color: var(--blue-600); }
  .nav__menu > li > .btn { margin-top: 1.6rem; display: inline-flex; }
}

/* --------------------------------------------------------------------------
   7. Surfaces
   -------------------------------------------------------------------------- */
.surface-sand { background: var(--sand); }
.surface-blue { background: var(--blue-50); }

.surface-ink {
  background: var(--ink-900);
  color: rgba(255, 255, 255, 0.78);
  --fg: #fff;
  --fg-muted: rgba(255, 255, 255, 0.62);
  --line: rgba(255, 255, 255, 0.14);
  --line-soft: rgba(255, 255, 255, 0.09);
}
.surface-ink h1, .surface-ink h2, .surface-ink h3, .surface-ink h4 { color: #fff; }
/*
 * Dark surfaces, grouped: .eyebrow and .lede both declare their own colour, so
 * they override whatever the surface sets on itself and have to be restated
 * here. The CTA band is one of these and was missing from the list — its lede
 * kept the light-background slate and came out at 1.25:1 on the blue end of the
 * gradient. .lede takes the band's own colour rather than a repeated literal.
 */
.surface-ink .eyebrow,
.cta-band .eyebrow { color: var(--amber-400); }

.surface-ink .lede { color: rgba(255, 255, 255, 0.74); }
.cta-band .lede { color: inherit; }
.surface-ink .muted { color: rgba(255, 255, 255, 0.58); }

.aurora { position: relative; overflow: hidden; isolation: isolate; }
.aurora::before,
.aurora::after {
  content: "";
  position: absolute;
  z-index: -1;
  border-radius: 50%;
  filter: blur(90px);
  opacity: 0.55;
  pointer-events: none;
}
.aurora::before {
  width: 46vw; height: 46vw;
  top: -18vw; right: -12vw;
  background: radial-gradient(circle, var(--blue-500), transparent 68%);
}
.aurora::after {
  width: 38vw; height: 38vw;
  bottom: -20vw; left: -10vw;
  background: radial-gradient(circle, var(--coral-500), transparent 70%);
  opacity: 0.32;
}

.grid-lines {
  position: absolute;
  inset: 0;
  z-index: -1;
  background-image:
    linear-gradient(to right, var(--line-soft) 1px, transparent 1px),
    linear-gradient(to bottom, var(--line-soft) 1px, transparent 1px);
  background-size: 74px 74px;
  mask-image: radial-gradient(ellipse 80% 60% at 50% 0%, #000 30%, transparent 78%);
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   8. Hero
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  padding-block: clamp(3.5rem, 7vw, 6.5rem) clamp(4rem, 7vw, 7rem);
  overflow: hidden;
}
.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(2.5rem, 5vw, 4.5rem);
  align-items: center;
}
.hero__title { font-size: var(--step-5); }
.hero__copy { display: grid; gap: 1.6rem; justify-items: start; }

.pill {
  display: inline-flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.42rem 0.9rem 0.42rem 0.5rem;
  border: 1px solid var(--line);
  border-radius: var(--r-full);
  background: rgba(255, 255, 255, 0.7);
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--slate-700);
  backdrop-filter: blur(6px);
}
.pill__dot {
  display: grid;
  place-items: center;
  padding: 0.2rem 0.55rem;
  border-radius: var(--r-full);
  background: var(--blue-600);
  color: #fff;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
.surface-ink .pill {
  background: rgba(255, 255, 255, 0.06);
  border-color: rgba(255, 255, 255, 0.16);
  color: rgba(255, 255, 255, 0.82);
}

/* Hero visual composition */
/* isolate keeps the ring and the wordmark ordered against each other here,
   rather than against whatever else the page happens to stack. */
/* container-type lets the wordmark size itself against this box in cqw, rather
   than against the viewport — the panel's width does not track the viewport, so
   a vw-based size drifted out of proportion between breakpoints. */
.hero__visual { position: relative; aspect-ratio: 1 / 1; isolation: isolate; container-type: inline-size; }
/* Explicitly below the wordmark, so the ordering does not rest on the ring
   merely having no z-index of its own. */
.hero__orbit { position: absolute; inset: 0; z-index: 1; animation: spin 60s linear infinite; }

/* The rings. Drawn as an SVG filling the box, so it is concentric with it and
   rotates about its own centre with no origin correction needed. */
.hero__orbit--mark { animation-duration: 50s; }

/* The wordmark holds still while the ring turns around it, placed as the printed
   logo places it: large, left of centre, and overhanging the ring on the left.

   The three numbers below are measured off the logo artwork and expressed
   against the ring's outer radius, so they transfer to the traced vector ring
   whatever size it renders at. In the source, the wordmark is 0.842 of the ring
   diameter wide and its centre sits 0.333 radii left and 0.064 radii above the
   ring centre. The traced ring is built about (200,200) with an outer radius of
   197.4 viewBox units, which converts those to:

     width  0.842 x 2 x 197.4 / 400 = 83.1% of the box
     left   50% - (0.333 x 197.4 / 400) = 33.6%
     top    50% - (0.064 x 197.4 / 400) = 46.8%

   left/top carry the offset because a percentage there resolves against this
   box; the -50% translate then resolves against the image itself, which is what
   centres it. Mixing the two in one translate would measure both against the
   image and put the mark in the wrong place.

   The mark overhangs the box on the left, by design — that is the logo's own
   crop, and no ancestor clips it. It also crosses the strokes, which only works
   because the glyphs are solid: cut from the colour logo they are hollow and the
   ring shows straight through them. See CLAUDE.md before changing the source.

   will-change promotes this to its own compositor layer. Without it the turning
   ring's layer can paint over the wordmark regardless of z-index — and freezing
   the animation to check drops that layer and hides the fault, so this is not
   something a still screenshot can verify. */
.hero__mark {
  position: absolute;
  top: 46.8%;
  left: 33.6%;
  z-index: 2;
  width: 83.1%;
  height: auto;
  transform: translate(-50%, -50%);
  will-change: transform;
  pointer-events: none;
  /* An inline SVG, not an <img>. The wordmark is drawn as a white bevelled face
     with an extruded edge and a cast shadow by the #spg-mark-3d filter, which
     is built from the artwork's alpha in spg_hero_orbit(). White sits on a pale
     photograph here, so the extrusion and shadow are what give it an edge to
     stay legible against.

     The filter's shadow spreads past the artwork's own box, so this must not
     clip it. */
  overflow: visible;
  aspect-ratio: 873 / 319;
}

.hero__orbit--reverse { animation-duration: 90s; animation-direction: reverse; }

/* A faint inner trace, turning the other way for a little depth. */
.hero__orbit--trace { animation-duration: 37s; animation-direction: reverse; }

@keyframes spin { to { transform: rotate(360deg); } }

.hero__panel {
  position: absolute;
  /* Top of the stack, over both the ring and the wordmark. These used to rely
     on coming last in the markup, which stopped being enough once the ring took
     a z-index of its own. */
  z-index: 3;
  border-radius: var(--r-lg);
  background: rgba(255, 255, 255, 0.9);
  border: 1px solid var(--line-soft);
  box-shadow: var(--shadow-lg);
  padding: 1.1rem 1.25rem;
  backdrop-filter: blur(12px);
  display: grid;
  gap: 0.25rem;
  animation: float 7s var(--ease-in-out) infinite;
}
.hero__panel--a { top: 8%; left: -4%; width: 200px; }
.hero__panel--b { bottom: 14%; right: -2%; width: 220px; animation-delay: -2.4s; }
.hero__panel--c { bottom: -2%; left: 12%; width: 190px; animation-delay: -4.8s; }

.hero__panel .num {
  font-family: var(--font-display);
  font-size: 1.85rem;
  font-weight: 600;
  letter-spacing: -0.03em;
  color: var(--ink-900);
  line-height: 1;
}
.hero__panel .label {
  font-size: 0.76rem;
  font-weight: 500;
  color: var(--slate-500);
}

@keyframes float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-12px); }
}

/* --------------------------------------------------------------------------
   9. Cards
   -------------------------------------------------------------------------- */
.card {
  position: relative;
  display: grid;
  gap: 0.85rem;
  padding: clamp(1.5rem, 2.4vw, 2rem);
  background: #fff;
  border: 1px solid var(--line-soft);
  border-radius: var(--r-lg);
  transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease), border-color 0.3s ease;
}
.card:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); border-color: var(--line); }
.card h3 { font-size: var(--step-1); }
.card p { color: var(--slate-500); font-size: 0.95rem; }

.surface-ink .card {
  background: rgba(255, 255, 255, 0.04);
  border-color: rgba(255, 255, 255, 0.1);
}
.surface-ink .card:hover { background: rgba(255, 255, 255, 0.07); }
.surface-ink .card p { color: rgba(255, 255, 255, 0.62); }

.card__icon {
  display: grid;
  place-items: center;
  width: 50px;
  height: 50px;
  border-radius: 14px;
  background: var(--blue-50);
  color: var(--blue-600);
  margin-bottom: 0.4rem;
}
.card__icon svg { width: 23px; height: 23px; }
.card__icon--amber { background: var(--amber-100); color: #a4720a; }
.card__icon--coral { background: var(--coral-100); color: #b83a24; }
.surface-ink .card__icon { background: rgba(255, 255, 255, 0.08); color: var(--amber-400); }

.card__num {
  font-family: var(--font-display);
  font-size: 0.95rem;
  font-weight: 600;
  color: var(--blue-600);
  letter-spacing: 0.04em;
}

/* --------------------------------------------------------------------------
   Community programs (Join section)
   -------------------------------------------------------------------------- */

/*
 * A dark band holding a tab list and a detail panel: pick a service on the
 * left, read it on the right. The earlier four-column card treatment is gone
 * rather than layered under this.
 */

.programs {
  --programs-line: rgb(255 255 255 / 0.12);
  /* Each service overrides this on its own tab and panel. */
  --service-accent: var(--blue-400);
}

/* Dark surfaces turn the eyebrow amber, which is right where amber is the
   band's accent. Here the accent is blue — it runs through the active tab, the
   engine label, the icon ring and the status pill — so an amber eyebrow would
   be the only warm note in the section. Matches the supplied design. */
.programs .eyebrow { color: var(--blue-400); }

.programs__head {
  display: grid;
  gap: clamp(1.25rem, 3vw, 2.5rem);
  align-items: end;
  margin-bottom: clamp(2.5rem, 6vw, 4.5rem);
}

@media (min-width: 901px) {
  .programs__head { grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr); }
  /* The lede sits beside the heading's last line, not under it. */
  .programs__lede { padding-bottom: 0.5rem; }
}

.programs__head h2 { margin: 0.6rem 0 0; color: #fff; }
.programs__lede { margin: 0; max-width: 42ch; }

/* The one accent in the heading. Italic because that is what distinguishes an
   ampersand set as ornament from one set as punctuation. */
.gold-mark { color: var(--amber-500); font-style: italic; }

.programs__switch {
  display: grid;
  gap: clamp(2rem, 4vw, 3.5rem);
  align-items: start;
}

@media (min-width: 901px) {
  .programs__switch { grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr); }
}

/* --- the tab list ---------------------------------------------------------- */

.programs__tabs { display: flex; flex-direction: column; }

.programs__tab {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 0.35rem 1rem;
  padding: clamp(0.9rem, 1.8vw, 1.25rem) 0;
  background: none;
  /* No border here: the progress rail below each tab already draws the divider,
     and a border as well put two lines at every boundary. */
  border: 0;
  text-align: left;
  cursor: pointer;
  color: rgb(255 255 255 / 0.38);
  transition: color 0.3s ease;
}

.programs__tab:hover { color: rgb(255 255 255 / 0.7); }
.programs__tab.is-active { color: #fff; }

.programs__tab-num {
  grid-row: 1;
  font-size: 0.81rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: inherit;
  opacity: 0.75;
}

.programs__tab-kicker {
  grid-row: 1;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}

.programs__tab.is-active .programs__tab-num,
.programs__tab.is-active .programs__tab-kicker { color: var(--service-accent); opacity: 1; }

.programs__tab-name {
  grid-row: 2;
  grid-column: 2;
  font-family: var(--font-display);
  /* 42px at desktop, as the supplied design has it — the names carry the list
     and were noticeably undersized against it at 30px. */
  font-size: clamp(1.5rem, 1rem + 1.8vw, 2.6rem);
  letter-spacing: -0.02em;
  color: inherit;
}

.programs__tab-arrow {
  grid-row: 1;
  grid-column: 3;
  opacity: 0;
  transform: translateX(-6px);
  transition: opacity 0.3s ease, transform 0.3s ease;
}

.programs__tab.is-active .programs__tab-arrow { opacity: 1; transform: none; }

/* The progress rail doubles as the active underline: it reads as a plain rule
   when nothing is advancing, and fills while the timer runs. */
.programs__tab-rail {
  grid-row: 3;
  grid-column: 1 / -1;
  margin-top: 0.75rem;
  height: 2px;
  background: var(--programs-line);
  overflow: hidden;
}

.programs__tab-fill {
  display: block;
  height: 100%;
  background: var(--service-accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0ms linear;
}

.programs__tab:not(.is-active) .programs__tab-fill { transform: scaleX(0) !important; }

/* --- the detail panel ------------------------------------------------------ */

.programs__panels { position: relative; }

.programs__panel {
  position: relative;
  overflow: hidden;
  padding: clamp(1.75rem, 3.5vw, 2.75rem);
  border: 1px solid var(--programs-line);
  border-radius: var(--r-lg, 18px);
  background: rgb(255 255 255 / 0.035);
}

/* Only once the script is running do hidden panels mean anything — before
   that every panel is on show and simply stacks, which is the no-JS reading. */
.programs__switch:not(.is-enhanced) .programs__panel + .programs__panel { margin-top: 1rem; }

.programs__switch.is-enhanced .programs__panel { display: none; }
.programs__switch.is-enhanced .programs__panel.is-active {
  display: block;
  animation: programs-in 0.45s ease both;
}

@keyframes programs-in {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

.programs__panel-top {
  display: flex;
  align-items: center;
  gap: 0.9rem;
  margin-bottom: clamp(1.5rem, 3vw, 2.25rem);
}

.programs__panel-icon {
  display: grid;
  place-items: center;
  width: 52px;
  height: 52px;
  flex: 0 0 auto;
  border: 1px solid var(--service-accent);
  border-radius: var(--r-full);
  color: var(--service-accent);
}

.programs__panel-engine {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--service-accent);
}

.programs__status {
  margin-left: auto;
  padding: 0.3rem 0.8rem;
  border-radius: var(--r-full);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* Live reads as the service's own colour; anything not yet open is the same
   colour held back, so the two are told apart by weight rather than by hue. */
.programs__status--live { background: var(--service-accent); color: var(--ink-900); }
.programs__status--upcoming {
  background: color-mix(in srgb, var(--service-accent) 18%, transparent);
  color: var(--service-accent);
}

.programs__panel-title {
  margin: 0 0 0.9rem;
  color: #fff;
  font-size: clamp(1.7rem, 3.4vw, 2.6rem);
}

.programs__panel-text {
  margin: 0;
  max-width: 52ch;
  color: rgb(255 255 255 / 0.76);
  font-size: var(--step-0);
}

.programs__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem;
  margin: clamp(1.25rem, 2.5vw, 1.75rem) 0 0;
  padding: 0;
}

.programs__chips li {
  list-style: none;
  padding: 0.5rem 1rem;
  border: 1px solid var(--programs-line);
  border-radius: var(--r-full);
  font-size: 0.86rem;
  color: rgb(255 255 255 / 0.88);
}

.programs__cta { margin-top: clamp(1.5rem, 3vw, 2rem); }

.programs__cta--muted {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  /* The real CTA is a .btn, which never wraps. This one is a bare span, so its
     label broke across two lines beside the arrow without being told not to. */
  white-space: nowrap;
  font-weight: 700;
  color: rgb(255 255 255 / 0.45);
}

/* The oversized number behind the panel. Outlined rather than filled so it
   stays a watermark; it is decorative and carries no meaning the tab list
   does not already give. */
.programs__ghost {
  position: absolute;
  right: -0.06em;
  bottom: -0.34em;
  font-family: var(--font-display);
  font-size: clamp(9rem, 20vw, 15rem);
  line-height: 1;
  color: transparent;
  -webkit-text-stroke: 1px color-mix(in srgb, var(--service-accent) 30%, transparent);
  pointer-events: none;
  user-select: none;
}

.programs__footnote {
  margin: clamp(2.5rem, 5vw, 4rem) 0 0;
  text-align: center;
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1rem, 1.8vw, 1.25rem);
  color: rgb(255 255 255 / 0.55);
}

/* Below the two-column breakpoint the tab list becomes a numbered row and
   nothing else.

   Stacking the desktop list does not work: four full-height rows ran to 376px
   on a phone, so the section took 1.6 screens and the tab you picked sat well
   away from the content it controls.

   Each tab keeps its number, so all four services are marked and the position
   is plain. The current service is also named, on its own line above the row:
   the name belongs to the active tab but is lifted out to span the full width,
   which is why the row is the positioned ancestor here rather than the tab.

   Titles cross over rather than cutting: the outgoing one is taken out of flow
   and laid over the line it is leaving, so the two pass without the row jumping
   by the height of a line. The kicker and arrow stay clipped — they would only
   repeat what the panel says. */
@media (max-width: 900px) {
  .programs__tabs {
    display: flex;
    /* The base rule stacks these in a column for the desktop list. Without
       resetting that here the numbers come out one above another. */
    flex-direction: row;
    align-items: flex-end;
    gap: 0.6rem;
    margin-bottom: 0.4rem;
    /* Holds the lifted title, and anchors it: the tabs themselves go static
       below so the name resolves against this row and can span it. */
    position: relative;
    padding-top: 3.1rem;
  }

  .programs__tab {
    position: static;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    gap: 0.4rem;
    /* Wide enough to hit comfortably, and each takes an equal share so the row
       reads as a scale rather than four loose numbers. */
    flex: 1 1 0;
    min-height: 44px;
    padding: 0.5rem 0 0;
    border: 0;
  }

  .programs__tab > *:not(.programs__tab-num):not(.programs__tab-rail) {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
  }

  .programs__tab-num {
    grid-row: 1;
    grid-column: 1;
    font-size: 0.95rem;
    font-weight: 700;
    opacity: 1;
    transition: color 0.3s ease;
  }

  .programs__tab.is-active .programs__tab-num { color: var(--service-accent); }

  /* The rail sits under its own number, so the filling bar marks which service
     is running as well as how far through it is. */
  .programs__tab-rail {
    grid-row: 2;
    grid-column: 1;
    width: 100%;
    margin: 0;
  }

  /* The current name, lifted clear of its own tab to span the row. */
  .programs__tab.is-active > .programs__tab-name,
  .programs__tab.is-leaving > .programs__tab-name {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    width: auto;
    height: auto;
    overflow: visible;
    clip-path: none;
    white-space: normal;
    text-align: left;
    font-size: clamp(1.4rem, 5.5vw, 1.85rem);
    line-height: 1.15;
    color: #fff;
  }

  .programs__tab.is-active > .programs__tab-name {
    animation: programs-title-in 0.45s ease both;
  }

  .programs__tab.is-leaving > .programs__tab-name {
    animation: programs-title-out 0.4s ease both;
    pointer-events: none;
  }
}

@keyframes programs-title-in {
  from { opacity: 0; transform: translateY(80%); }
  to   { opacity: 1; transform: none; }
}

@keyframes programs-title-out {
  from { opacity: 1; transform: none; }
  to   { opacity: 0; transform: translateY(-80%); }
}

/* Pinned scrolling on narrow screens.
   The wrapper is given height so there is something to scroll through, and the
   switcher sticks while that height passes. Both only apply once the script has
   added .is-pinned, so with no JavaScript the section stays an ordinary stack
   and the wrapper is just a div.

   --programs-pin-steps is the number of services after the first, written by
   the script: one screenful of scrolling each. */
@media (max-width: 900px) {
  .programs.is-pinned .programs__pin {
    min-height: calc(100% + (var(--programs-pin-steps, 0) * 78vh));
  }

  .programs.is-pinned .programs__switch {
    position: sticky;
    /*
     * Clear of the sticky site header. The script measures that header and
     * writes --programs-pin-top, because the header is not a fixed height —
     * it was 83px on a phone against the 6.5rem (104px) assumed here, and
     * those 21px were the difference between the panel's button sitting on
     * screen and below the fold on a 667px-tall iPhone SE.
     */
    top: var(--programs-pin-top, 6.5rem);
  }

  /*
   * Buy back the height the pinned layout needs, at every mobile width.
   *
   * This was originally gated on `max-height: 760px`, so a tall phone never
   * received it — and with the client's real service copy, which runs 180-230
   * characters against the 70-90 of the sample content, a tall phone is
   * exactly where the switcher stopped fitting. An iPhone 14 came out 16px
   * over and so declined to pin at all.
   *
   * Nothing is removed here, only set more tightly. The script still refuses
   * to pin if it does not fit even so, which is what keeps the panel's button
   * on screen rather than below the fold.
   */
  .programs__switch { gap: 1rem; }
  .programs__tabs { margin-bottom: 0; }
  .programs__panel { padding: 1.25rem; }
  .programs__panel-top { margin-bottom: 0.75rem; }
  .programs__panel-title { margin-bottom: 0.5rem; }
  .programs__panel-text { margin-bottom: 0.75rem; }
  .programs__chips { gap: 0.35rem; margin-bottom: 0.9rem; }
  .programs__chips li { padding: 0.3rem 0.65rem; font-size: 0.8rem; }

}

@media (prefers-reduced-motion: reduce) {
  /* The script already declines to auto-advance; this covers the entrance. */
  .programs__switch.is-enhanced .programs__panel.is-active { animation: none; }
  .programs__tab-fill { transition: none; }
  .programs__tab .programs__tab-name,
  .programs__tab .programs__tab-num,
  .programs__tab .programs__tab-kicker { animation: none; }
}


/* Vanguard is its own section now, carrying the gradient the inset band used
   to. It was split out of the programs band when that went dark: nested there
   it picked up a treatment meant for something else, and the two together made
   one section more than twice the height of any other on the page. */
.vanguard-section { background: linear-gradient(160deg, var(--blue-50), var(--sand)); }

/*
 * The masterclass detail Vanguard's card links down to. An inset band
 * inside the same section rather than a full-bleed one: it is one program's
 * supporting detail, not a section in its own right, so it reads as part of
 * the grid above it rather than a new band of the page.
 */
/* The band's colour now fills the whole section, since the band IS the section.
   Everything it carried as a nested block is gone with it: the margin-top that
   separated it from the cards above, its own vertical padding, and the rounded
   inset edge. Left in place those sat on top of the section's own padding and
   made the gap above Vanguard roughly twice that between any other two
   sections. */
.vanguard {
  padding-block: 0;
}

.vanguard__head { max-width: 62ch; margin: 0 auto clamp(2rem, 4vw, 3rem); text-align: center; }

/* SPG + Vanguard as one lockup, not two words — the amber V is the only
   colour break, standing in for the wordmark's usual logotype treatment. */
.vanguard__wordmark {
  margin: 0 0 0.5rem;
  font-family: var(--font-sans);
  font-size: clamp(1.6rem, 4vw, 2.4rem);
  font-weight: 800;
  letter-spacing: 0.01em;
  color: var(--ink-900);
}
.vanguard__wordmark span { color: var(--amber-500); }

.vanguard__label {
  margin: 0.6rem 0 0;
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--slate-600);
}

.vanguard__heading {
  margin: 0.5rem 0 0;
  font-family: var(--font-display);
  font-size: var(--step-3);
  letter-spacing: -0.01em;
}

.vanguard__head .lede { margin: 0.75rem auto 0; }

/*
 * Flex, not grid: five cards at three per row leaves a trailing row of two.
 * Grid's justify-content centres the whole track, not an incomplete row
 * within it, so that trailing pair stayed pinned left under the empty third
 * slot. Flex-wrap centres each wrapped line independently, so a short last
 * row centres itself — this also means it stays centred at any card count,
 * not just five.
 */
.vanguard__list {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1.5rem;
}

/*
 * A photo card, title and text set into its bottom edge — not the icon-card
 * treatment the rest of the site uses. The client's reference shows each
 * masterclass as its own image (a lit bulb, a compass on a road, a seedling
 * in a glass globe); an icon badge would have competed with that rather
 * than needing one. Falls back to a plain dark gradient — still on-brand,
 * still readable — when a card has no image chosen yet.
 */
.vanguard__card {
  position: relative;
  flex: 1 1 300px;
  max-width: calc((100% - 3rem) / 3);
  aspect-ratio: 3 / 2;
  display: flex;
  align-items: flex-end;
  border-radius: var(--r-lg);
  overflow: hidden;
  background: linear-gradient(160deg, var(--ink-700), var(--ink-900)) center / cover no-repeat;
  box-shadow: var(--shadow-sm);
}

/* Scrim behind the text, not on the whole card, so the top of the photo
   stays clear. */
.vanguard__card::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(8, 17, 29, 0.88) 0%, rgba(8, 17, 29, 0.4) 55%, rgba(8, 17, 29, 0) 85%);
}

.vanguard__card-inner {
  position: relative;
  z-index: 1;
  padding: clamp(1.1rem, 2.5vw, 1.5rem);
}

.vanguard__card h4 {
  margin: 0 0 0.35rem;
  font-family: var(--font-sans);
  font-size: 0.92rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: #fff;
}
.vanguard__card p { font-size: 0.85rem; line-height: 1.45; color: rgba(255, 255, 255, 0.8); margin: 0; }

.vanguard__promise {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 1.5rem 2.5rem;
  margin: clamp(2.25rem, 4vw, 3rem) 0 0;
  padding-top: clamp(1.75rem, 3vw, 2.5rem);
  border-top: 1px solid var(--line-soft);
}

.vanguard__promise li {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 0.9rem;
  color: var(--slate-600);
}

.vanguard__promise svg { width: 20px; height: 20px; color: var(--blue-600); flex-shrink: 0; }
.vanguard__promise strong { color: var(--ink-900); }

@media (max-width: 900px) {
  .vanguard__card { max-width: calc((100% - 1.5rem) / 2); }
}

@media (max-width: 560px) {
  .vanguard__card { max-width: 100%; }
}

/* Pillar cards (Network / Learn / Grow) */
.pillar {
  position: relative;
  overflow: hidden;
  padding: clamp(1.8rem, 3vw, 2.6rem);
  border-radius: var(--r-lg);
  background: #fff;
  border: 1px solid var(--line-soft);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1rem;
  transition: transform 0.45s var(--ease), box-shadow 0.45s var(--ease);
}
.pillar .link-arrow { margin-top: auto; padding-top: 0.6rem; }
.pillar::after {
  content: "";
  position: absolute;
  left: 0; right: 0; top: 0;
  height: 3px;
  background: var(--accent-bar, var(--blue-500));
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.5s var(--ease);
}
.pillar:hover { transform: translateY(-6px); box-shadow: var(--shadow-lg); }
.pillar:hover::after { transform: scaleX(1); }
.pillar__index {
  font-family: var(--font-display);
  font-size: 3.4rem;
  line-height: 0.85;
  /* The source design used --sand-2 here, but that is a background tint: on the
     pillar's white card it came out at 1.16:1, effectively invisible. This is a
     numeral that carries the reading order, not decoration, so it has to be
     legible. --slate-400 gives 3.46:1, which clears the 3:1 bar because the type
     is large (54px) — do not reuse this token for body-size text, where the bar
     is 4.5:1 and it fails. */
  color: var(--slate-400);
  letter-spacing: -0.05em;
}
.pillar--blue  { --accent-bar: var(--blue-500); }
.pillar--amber { --accent-bar: var(--amber-500); }
.pillar--coral { --accent-bar: var(--coral-500); }

/* Feature row (alternating) */
.feature-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
.feature-row + .feature-row { margin-top: clamp(3.5rem, 6vw, 6rem); }
.feature-row:nth-child(even) > *:first-child { order: 2; }

.feature-visual {
  position: relative;
  border-radius: var(--r-xl);
  background: linear-gradient(150deg, var(--blue-50), var(--sand));
  border: 1px solid var(--line-soft);
  min-height: 340px;
  display: grid;
  place-items: center;
  padding: 2rem;
  overflow: hidden;
}
.feature-visual::before {
  content: "";
  position: absolute;
  width: 320px; height: 320px;
  border-radius: 50%;
  border: 1px dashed rgba(27, 106, 201, 0.25);
  animation: spin 40s linear infinite;
}

/* People */
.person {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.9rem;
  padding: 1.5rem;
  border-radius: var(--r-md);
  background: #fff;
  border: 1px solid var(--line);
  /* A resting shadow, not just the hover one — line-soft on its own at 6%
     opacity was too faint to read as a card edge against the section's own
     white background. */
  box-shadow: var(--shadow-sm);
  transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease);
}
.person:hover { transform: translateY(-5px); box-shadow: var(--shadow-md); }

.person__avatar {
  width: 74px;
  height: 74px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 600;
  color: #fff;
  letter-spacing: -0.02em;
  background: linear-gradient(140deg, var(--blue-500), var(--blue-700));
}
.person__avatar--amber { background: linear-gradient(140deg, var(--amber-400), #c98a06); }
.person__avatar--coral { background: linear-gradient(140deg, #f07a63, var(--coral-500)); }
.person__avatar--slate { background: linear-gradient(140deg, #64748b, var(--ink-700)); }
.person__name { font-family: var(--font-display); font-size: 1.1rem; font-weight: 600; letter-spacing: -0.02em; }
.person__role { font-size: 0.8rem; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; color: var(--blue-600); }
.person__bio { font-size: 0.92rem; color: var(--slate-500); }
.person__tags { display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: auto; padding-top: 0.3rem; }

.tag {
  padding: 0.28rem 0.66rem;
  border-radius: var(--r-full);
  background: var(--sand);
  font-size: 0.73rem;
  font-weight: 500;
  color: var(--slate-700);
  border: 1px solid var(--line-soft);
}
.surface-ink .tag { background: rgba(255, 255, 255, 0.07); color: rgba(255, 255, 255, 0.75); border-color: rgba(255, 255, 255, 0.12); }

/* Posts */
.post {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.9rem;
  padding: 1.6rem;
  border-radius: var(--r-lg);
  background: #fff;
  border: 1px solid var(--line-soft);
  transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease);
}
.post:hover { transform: translateY(-5px); box-shadow: var(--shadow-md); }
.post .link-arrow { margin-top: auto; padding-top: 0.4rem; }
.post__thumb {
  width: 100%;
  aspect-ratio: 16 / 10;
  border-radius: var(--r-md);
  background: linear-gradient(140deg, var(--blue-100), var(--sand));
  position: relative;
  overflow: hidden;
  display: grid;
  place-items: center;
}
.post__thumb span {
  font-family: var(--font-display);
  font-size: 2.4rem;
  color: rgba(27, 106, 201, 0.28);
  letter-spacing: -0.04em;
}
.post__meta { display: flex; gap: 0.6rem; font-size: 0.78rem; color: var(--slate-400); font-weight: 500; }
.post__title { font-size: 1.16rem; line-height: 1.28; }

/* Events */
.event {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: clamp(1.2rem, 3vw, 2.4rem);
  align-items: center;
  padding: clamp(1.4rem, 2.5vw, 2rem);
  border-radius: var(--r-lg);
  background: #fff;
  border: 1px solid var(--line-soft);
  transition: transform 0.4s var(--ease), box-shadow 0.4s var(--ease), border-color 0.3s ease;
}
.event:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: var(--blue-100); }
.event__date {
  display: grid;
  place-items: center;
  gap: 0.1rem;
  width: 92px;
  padding: 0.9rem 0.5rem;
  border-radius: var(--r-md);
  background: var(--ink-900);
  color: #fff;
  text-align: center;
}
.event__date .q {
  font-family: var(--font-display);
  font-size: 1.7rem;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.03em;
}
.event__date .y { font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase; color: rgba(255, 255, 255, 0.6); }
.event__date--amber { background: var(--amber-500); color: var(--ink-900); }
.event__date--amber .y { color: rgba(8, 17, 29, 0.6); }
.event__date--coral { background: var(--coral-500); }
.event__body { display: grid; gap: 0.5rem; }
.event__title { font-size: 1.32rem; }
.event__facts { display: flex; flex-wrap: wrap; gap: 0.4rem 1.1rem; font-size: 0.85rem; color: var(--slate-500); }
.event__facts span { display: inline-flex; align-items: center; gap: 0.4rem; }
.event__facts svg { width: 15px; height: 15px; color: var(--blue-600); flex-shrink: 0; }

/* When and where carry the decision when someone is scanning a list of events,
   so they are lifted out of the muted facts row. The mode stays quiet: it
   matters once you have picked an event, not while you are picking one. */
.event__fact--key { color: var(--ink-700); font-weight: 600; }

.event--featured {
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.85fr);
  align-items: stretch;
  padding: 0;
  overflow: hidden;
  border: 0;
  background: var(--ink-900);
  color: rgba(255, 255, 255, 0.8);
}
.event--featured:hover { transform: none; }
.event--featured .event__body { padding: clamp(2rem, 4vw, 3.4rem); align-content: center; gap: 1.1rem; }
.event--featured .event__title { color: #fff; font-size: var(--step-3); }
.event--featured .event__facts { color: rgba(255, 255, 255, 0.66); }
.event--featured .event__facts svg { color: var(--amber-400); }
.event--featured .event__fact--key { color: #fff; }

/* The source template coloured this eyebrow with an inline style; it is a class
   here so the child theme and Customizer can reach it. */
.eyebrow--amber { color: var(--amber-400); }

/* The card is dark, so the title link takes the card's colour rather than the
   global link blue, which would be unreadable on ink. */
.event--featured .event__title a { color: inherit; text-decoration: none; }
.event--featured .event__title a:hover,
.event--featured .event__title a:focus-visible { text-decoration: underline; text-underline-offset: 0.16em; }

.event--featured .event__excerpt { color: rgba(255, 255, 255, 0.72); max-width: 56ch; }
.event--featured .event__cta { margin-top: 0.4rem; }
.event__aside {
  position: relative;
  display: grid;
  place-content: center;
  gap: 0.6rem;
  padding: clamp(2rem, 4vw, 3rem);
  background: linear-gradient(150deg, var(--blue-700), var(--ink-800));
  text-align: center;
  overflow: hidden;
}
.event__aside::before {
  content: "";
  position: absolute;
  width: 260px; height: 260px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.16);
  animation: spin 34s linear infinite;
}
.event__aside .big {
  font-family: var(--font-display);
  font-size: clamp(3rem, 6vw, 4.6rem);
  line-height: 0.9;
  color: #fff;
  letter-spacing: -0.04em;
}
.event__aside .small { font-size: 0.82rem; letter-spacing: 0.16em; text-transform: uppercase; color: rgba(255, 255, 255, 0.66); }

/* --------------------------------------------------------------------------
   10. Stats, marquee, quote
   -------------------------------------------------------------------------- */
.stats {
  display: grid;
  /* auto-fit so the block reflows to 2×2 inside a half-width column */
  grid-template-columns: repeat(auto-fit, minmax(215px, 1fr));
  gap: 1px;
  background: var(--line-soft);
  border: 1px solid var(--line-soft);
  border-radius: var(--r-lg);
  overflow: hidden;
}
.stat { background: #fff; padding: clamp(1.4rem, 2.6vw, 2.2rem); display: grid; gap: 0.35rem; }
.surface-ink .stats { background: rgba(255, 255, 255, 0.12); border-color: rgba(255, 255, 255, 0.12); }
.surface-ink .stat { background: var(--ink-900); }
.stat__num {
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 2.6vw, 2.7rem);
  font-weight: 600;
  letter-spacing: -0.04em;
  line-height: 1;
  color: var(--ink-900);
}
.surface-ink .stat__num { color: #fff; }
.stat__label { font-size: 0.86rem; color: var(--slate-500); }

/* The number got its dark-surface colour but the label never did, so it kept the
   light-background slate and sat at 3.44:1 on the ink band. Same value as
   .surface-ink .lede, so the two read as one family. */
.surface-ink .stat__label { color: rgba(255, 255, 255, 0.74); }

.marquee {
  position: relative;
  overflow: hidden;
  padding-block: 1.4rem;
  border-block: 1px solid var(--line-soft);
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}
.marquee__track {
  display: flex;
  width: max-content;
  align-items: center;
  gap: 3.5rem;
  animation: marquee var(--marquee-duration, 34s) linear infinite;
}
.marquee:hover .marquee__track,
.marquee:focus-within .marquee__track { animation-play-state: paused; }
.marquee__item {
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--slate-400);
  white-space: nowrap;
  display: inline-flex;
  align-items: center;
  gap: 3.5rem;
}
.marquee__item::after { content: "◆"; font-size: 0.5rem; color: var(--amber-500); }

/* The track slides left by exactly one pass of its content. The number of
   passes is decided in PHP from how much content there is, so it is divided out
   here rather than assumed: a flat -50% is only correct when the track happens
   to be doubled, which it no longer always is. */
@keyframes marquee {
  to { transform: translateX(calc(-100% / var(--marquee-passes, 2))); }
}

/* --- logo strip ------------------------------------------------------------
   The band carries client logos with a line of text after every fourth. */

.marquee--logos { padding-block: clamp(1.5rem, 2.4vw, 2.25rem); }

/* The text between groups is a label, not another brand in the row.

   Left in the strip's display serif at logo size it sat in the same visual
   register as the logos and read as one of them — a wordmark among wordmarks.
   It is set instead in the theme's existing label language, the one .eyebrow
   uses: small, uppercase, widely letter-spaced sans in the accent colour. That
   is a different typographic register from any logo, so it reads as punctuation
   between the groups rather than a member of them.

   The rules either side make the separator role explicit, and replace the
   diamond the text-only strip uses to divide topics — with logos present, the
   logos already do that job and a diamond as well is clutter. */
.marquee--logos .marquee__item {
  gap: 0.75rem;
  font-family: var(--font-sans);
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--blue-600);
}

.marquee--logos .marquee__item::before,
.marquee--logos .marquee__item::after {
  content: "";
  flex: 0 0 auto;
  width: 20px;
  height: 2px;
  border-radius: 2px;
  /* Set explicitly rather than inherited: the base ::after is an amber diamond,
     and currentColor here would pick that up instead of the label's colour. */
  background: var(--blue-600);
  opacity: 0.4;
  font-size: 0;
}

.marquee__brand { display: inline-flex; align-items: center; justify-content: center; }

/* Logos arrive at whatever size and shape the client's own file happens to be.
   Normalising on HEIGHT is what makes a mixed set sit together — a wide wordmark
   and a square badge then carry the same visual weight, which equal widths would
   not achieve.

   Deliberately no max-width. Capping it looks harmless and is not: once a wide
   wordmark hits the cap, width becomes the binding constraint and the image
   shrinks to fit it, dropping its height below every other logo. Measured
   previously with a 190px cap, six logos meant to share one height painted
   between 24px and 38px — the widest mark coming out smallest, which is
   backwards. Letting an unusually wide logo take more of the strip is the
   lesser problem.

   min-width on the wrapper stops a square or tall mark sitting in a slot barely
   wider than itself; it changes spacing only, never proportions. */
.marquee__logo {
  display: block;
  /* --logo-scale is written per logo by the template from the mark's aspect, so
     a square badge and a wide wordmark carry comparable weight rather than
     merely a comparable height. It defaults to 1 if absent. */
  height: calc(clamp(26px, 3vw, 40px) * var(--logo-scale, 1));
  width: auto;
  /* Shown in their own colours, at the client's request. The usual greyscale
     treatment unifies a strip but flattens brands that people recognise by
     colour, and these are marks visitors know on sight. */
}

.marquee__brand { min-width: 72px; }

@media (prefers-reduced-motion: reduce) {
  /* The global reduced-motion rule collapses animations to 0.01ms, which parks
     this one at its END state — the track slid a full pass to the left, with
     content hanging off the side. Undo the transform and let the strip sit
     still, scrollable by hand instead. */
  .marquee__track {
    animation: none !important;
    transform: none !important;
  }
  .marquee { overflow-x: auto; mask-image: none; }
}

.quote {
  display: grid;
  gap: 1.8rem;
  padding: clamp(2rem, 4vw, 3.4rem);
  border-radius: var(--r-xl);
  background: #fff;
  border: 1px solid var(--line-soft);
  box-shadow: var(--shadow-sm);
}
.quote__text {
  font-family: var(--font-display);
  font-size: var(--step-2);
  line-height: 1.35;
  letter-spacing: -0.02em;
  color: var(--ink-900);
}
.quote__by { display: flex; align-items: center; gap: 0.9rem; }
.quote__mark { font-family: var(--font-display); font-size: 3.5rem; line-height: 0.6; color: var(--amber-500); }

/* --------------------------------------------------------------------------
   11. Accordion, tabs, table
   -------------------------------------------------------------------------- */
.accordion { display: grid; gap: 0.75rem; }
.acc {
  border: 1px solid var(--line-soft);
  border-radius: var(--r-md);
  background: #fff;
  overflow: hidden;
  transition: border-color 0.3s ease, box-shadow 0.3s ease;
}
.acc.is-open { border-color: var(--blue-100); box-shadow: var(--shadow-sm); }
.acc__btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.15rem 1.4rem;
  border: 0;
  background: transparent;
  font-family: var(--font-sans);
  font-size: 1.02rem;
  font-weight: 600;
  color: var(--ink-900);
  text-align: left;
  cursor: pointer;
}
.acc__icon {
  position: relative;
  flex-shrink: 0;
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--sand);
  display: grid;
  place-items: center;
  transition: background-color 0.3s ease, transform 0.35s var(--ease);
}
.acc__icon::before, .acc__icon::after {
  content: "";
  position: absolute;
  background: var(--ink-900);
  border-radius: 2px;
  transition: opacity 0.25s ease, background-color 0.25s ease;
}
.acc__icon::before { width: 11px; height: 1.8px; }
.acc__icon::after { width: 1.8px; height: 11px; }
.acc.is-open .acc__icon { background: var(--blue-600); transform: rotate(90deg); }
.acc.is-open .acc__icon::before { background: #fff; }
.acc.is-open .acc__icon::after { opacity: 0; }
.acc__panel { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 0.4s var(--ease); }
.acc.is-open .acc__panel { grid-template-rows: 1fr; }
.acc__inner { overflow: hidden; }
.acc__inner > div { padding: 0 1.4rem 1.4rem; color: var(--slate-500); font-size: 0.96rem; max-width: 68ch; }

/* flex-wrap + max-width: without them the pill group grows past a phone
   viewport and drags the whole page into horizontal scroll. These are
   filter controls, so wrapping beats scrolling — no option gets hidden. */
.tabs {
  display: inline-flex;
  flex-wrap: wrap;
  max-width: 100%;
  gap: 0.3rem;
  padding: 0.35rem;
  background: var(--sand);
  border-radius: var(--r-lg);
  /* Every use of this sits directly above the thing it filters, so the spacing
     belongs here rather than being re-stated at each call site — the events
     archive had none and its tabs touched the first card. */
  margin-bottom: clamp(1.5rem, 3vw, 2.25rem);
}

/* Single row is the common case; keep the full pill there. */
@media (min-width: 561px) {
  .tabs { border-radius: var(--r-full); }
}
.tab {
  padding: 0.6rem 1.15rem;
  border: 0;
  border-radius: var(--r-full);
  background: transparent;
  font-family: var(--font-sans);
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--slate-500);
  cursor: pointer;
  transition: background-color 0.25s ease, color 0.25s ease, box-shadow 0.25s ease;
}
.tab:hover { color: var(--ink-900); }
.tab.is-active { background: #fff; color: var(--ink-900); box-shadow: var(--shadow-xs); }

.plans { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 1.25rem; align-items: stretch; }
.plan {
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  padding: clamp(1.6rem, 2.6vw, 2.2rem);
  border-radius: var(--r-lg);
  background: #fff;
  border: 1px solid var(--line-soft);
}
.plan--featured {
  background: var(--ink-900);
  color: rgba(255, 255, 255, 0.76);
  border-color: transparent;
  box-shadow: var(--shadow-lg);
  transform: translateY(-8px);
}
.plan--featured h3, .plan--featured .plan__price { color: #fff; }
.plan--featured .plan__list li { color: rgba(255, 255, 255, 0.72); }
.plan--featured .plan__list svg { color: var(--amber-400); }
.plan__price { font-family: var(--font-display); font-size: 2.3rem; letter-spacing: -0.04em; line-height: 1; color: var(--ink-900); }
.plan__price small { font-family: var(--font-sans); font-size: 0.85rem; font-weight: 500; color: var(--slate-400); letter-spacing: 0; }
.plan__list { display: grid; gap: 0.7rem; }
.plan__list li { display: flex; gap: 0.65rem; font-size: 0.92rem; color: var(--slate-700); align-items: flex-start; }
.plan__list svg { width: 17px; height: 17px; flex-shrink: 0; margin-top: 3px; color: var(--blue-600); }
.plan .btn { margin-top: auto; }
.plan__badge {
  align-self: flex-start;
  padding: 0.28rem 0.7rem;
  border-radius: var(--r-full);
  background: var(--amber-500);
  color: var(--ink-900);
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   12. Forms
   -------------------------------------------------------------------------- */
.form { display: grid; gap: 1rem; }
.form__row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1rem; }
.field { display: grid; gap: 0.4rem; }
.field label { font-size: 0.82rem; font-weight: 600; color: var(--slate-700); }
.surface-ink .field label { color: rgba(255, 255, 255, 0.72); }
.field input, .field select, .field textarea {
  width: 100%;
  padding: 0.85rem 1rem;
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
  background: #fff;
  font-family: var(--font-sans);
  font-size: 0.95rem;
  color: var(--ink-900);
  transition: border-color 0.25s ease, box-shadow 0.25s ease;
}
.field input::placeholder, .field textarea::placeholder { color: var(--slate-400); }
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none;
  border-color: var(--blue-500);
  box-shadow: 0 0 0 4px var(--blue-100);
}
.field textarea { resize: vertical; min-height: 110px; }
.form__note { font-size: 0.8rem; color: var(--slate-400); }
.surface-ink .form__note { color: rgba(255, 255, 255, 0.5); }

.form-card {
  padding: clamp(1.75rem, 3vw, 2.6rem);
  border-radius: var(--r-xl);
  background: #fff;
  border: 1px solid var(--line-soft);
  box-shadow: var(--shadow-lg);
  display: grid;
  gap: 1.5rem;
}

/* --------------------------------------------------------------------------
   13. CTA band
   -------------------------------------------------------------------------- */
.cta-band {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-xl);
  padding: clamp(2.5rem, 5vw, 4.5rem);
  background: linear-gradient(135deg, var(--blue-700), var(--ink-900) 62%);
  color: rgba(255, 255, 255, 0.78);
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 0.8fr);
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: center;
}
.cta-band h2 { color: #fff; }
.cta-band::after {
  content: "";
  position: absolute;
  right: -8%;
  top: -40%;
  width: 460px; height: 460px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(242, 176, 30, 0.35), transparent 62%);
  pointer-events: none;
}
.cta-band__actions { display: grid; gap: 0.75rem; justify-items: start; position: relative; z-index: 1; }

/* --------------------------------------------------------------------------
   14. Page hero (inner pages)
   -------------------------------------------------------------------------- */
.page-hero {
  position: relative;
  padding-block: clamp(3rem, 6vw, 5.5rem) clamp(3rem, 5vw, 4.5rem);
  overflow: hidden;
}
/*
 * Hero rhythm.
 *
 * The gap that spaced these used to live on a .page-hero__inner wrapper, but no
 * template ever rendered one — every hero puts breadcrumbs, eyebrow, title and
 * lede straight into .container. So the spacing never applied and all eight
 * inner pages shipped with the eyebrow welded to the title and the title to the
 * lede. Spacing the children themselves fixes every hero at once, including the
 * five templates that hand-roll this markup instead of using the shared parts.
 *
 * Scoped to direct children so hero variants that nest their own layout inside
 * .container — the leader profile's portrait-and-stack row — keep their own
 * tighter spacing rather than being pushed apart by these.
 */
.page-hero > .container > .eyebrow { margin-block: 1.1rem 0.7rem; }
.page-hero > .container > h1 { margin-block: 0; }
.page-hero > .container > .lede { margin-block: 0.85rem 0; }

/*
 * Inner-page titles ran at --step-5, the same size as the front page's hero
 * title, which left every interior page shouting as loudly as the homepage.
 * --step-4 was still too loud once real page names replaced one-word labels:
 * "About SPG Leaders" at 62px filled the band on its own. Set below the scale
 * so an interior title leads its page without competing with the front page.
 */
.page-hero h1 { font-size: clamp(2rem, 1.5rem + 1.9vw, 3rem); }
.breadcrumb { display: flex; gap: 0.5rem; font-size: 0.82rem; color: var(--slate-400); }
.breadcrumb a:hover { color: var(--blue-600); }
.surface-ink .breadcrumb { color: rgba(255, 255, 255, 0.5); }
.surface-ink .breadcrumb a:hover { color: var(--amber-400); }

/* --------------------------------------------------------------------------
   15. Footer
   -------------------------------------------------------------------------- */
.site-footer { background: var(--ink-900); color: rgba(255, 255, 255, 0.62); padding-block: clamp(3.5rem, 6vw, 5.5rem) 2rem; }
.site-footer h4 { color: #fff; font-family: var(--font-sans); font-size: 0.78rem; font-weight: 700; letter-spacing: 0.15em; text-transform: uppercase; }
.footer__grid {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) repeat(3, minmax(0, 1fr));
  gap: clamp(2rem, 4vw, 3.5rem);
  padding-bottom: clamp(2.5rem, 4vw, 3.5rem);
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}
.footer__brand { display: grid; gap: 1.1rem; align-content: start; max-width: 34ch; }
.footer__brand .brand__name { color: #fff; }
.footer__list { display: grid; gap: 0.65rem; margin-top: 1.1rem; }
.footer__list a { font-size: 0.92rem; transition: color 0.2s ease, padding-left 0.25s var(--ease); }
.footer__list a:hover { color: #fff; padding-left: 4px; }
.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: space-between;
  align-items: center;
  padding-top: 1.8rem;
  font-size: 0.83rem;
}
.social { display: flex; gap: 0.5rem; }
.social a {
  display: grid;
  place-items: center;
  width: 38px; height: 38px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.14);
  transition: background-color 0.25s ease, border-color 0.25s ease, transform 0.3s var(--ease);
}
.social a:hover { background: var(--blue-600); border-color: var(--blue-600); transform: translateY(-2px); }
.social svg { width: 17px; height: 17px; color: #fff; }

/* --------------------------------------------------------------------------
   16. Reveal animation
   -------------------------------------------------------------------------- */
[data-reveal] {
  opacity: 0;
  transform: translateY(22px);
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
  transition-delay: var(--delay, 0ms);
}
[data-reveal].is-visible { opacity: 1; transform: none; }

/* --------------------------------------------------------------------------
   17. Responsive
   -------------------------------------------------------------------------- */
@media (max-width: 1080px) {
  .hero__grid { grid-template-columns: 1fr; }
  .hero__visual { max-width: 520px; margin-inline: auto; width: 100%; }
  .grid-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cta-band { grid-template-columns: 1fr; }
  .event--featured { grid-template-columns: 1fr; }
  .plans { grid-template-columns: 1fr; }
  .plan--featured { transform: none; }
  .footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 820px) {
  .grid-3 { grid-template-columns: 1fr; }
  .section-head--split { grid-template-columns: 1fr; align-items: start; }
  .feature-row { grid-template-columns: 1fr; }
  .feature-row:nth-child(even) > *:first-child { order: 0; }
  .event { grid-template-columns: auto minmax(0, 1fr); }
  .event > .btn { grid-column: 1 / -1; justify-self: start; }
}

@media (max-width: 620px) {
  .grid-2, .grid-4 { grid-template-columns: 1fr; }
  .form__row { grid-template-columns: 1fr; }
  /* The wordmark's left overhang is a fixed fraction of the ring, so once the
     visual stops being capped at 520px and starts tracking the viewport, the
     overhang lands outside the screen and clips the S — measured at 8px off the
     left edge on a 390px viewport. Easing the offset toward centre keeps the
     whole mark on screen; the logo's left bias still reads, just less far. */
  .hero__mark { left: 40%; }
  /* Stack the event row: a centred date chip beside a tall text column reads badly. */
  .event { grid-template-columns: 1fr; align-items: start; gap: 1rem; }
  .event__date {
    width: auto;
    justify-self: start;
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    padding: 0.55rem 1rem;
  }
  .event__date .q { font-size: 1.35rem; }

  .hero__panel--a { left: -2%; width: 168px; }
  .hero__panel--b { right: -2%; width: 180px; }
  .hero__panel--c { left: 8%; width: 165px; }
  .hero__panel { padding: 0.9rem 1rem; }
  .hero__panel .num { font-size: 1.5rem; }
  .footer__grid { grid-template-columns: 1fr; }
  .btn { width: 100%; }
  .cluster > .btn { width: auto; }
}

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

/* ==========================================================================
   v2 — imagery & scroll storytelling
   Skins the shared structural components in /assets/css/scroll.css.
   ========================================================================== */

/* Contour texture washed behind the hero, drifting on scroll */
.hero__texture {
  position: absolute;
  inset: 0;
  z-index: -1;
  opacity: .5;
  mask-image: radial-gradient(ellipse 75% 70% at 62% 42%, #000 20%, transparent 72%);
}
.hero__texture img { width: 100%; height: 100%; object-fit: cover; }

/* ---------------------------------------------------- pinned story section */
.story { background: var(--sand); }
.story__title { padding-top: var(--section); margin-bottom: 0.75rem; }
.story__stage { width: 100%; }
.story__grid {
  display: grid;
  grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr);
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
  width: 100%;
}
.story__kicker { display: flex; align-items: baseline; gap: .9rem; margin-bottom: 1.5rem; }
.story__num {
  font-family: var(--font-display);
  font-size: 3.4rem;
  line-height: .8;
  letter-spacing: -.05em;
  color: var(--blue-600);
}
/* slate-400 is 3.19:1 on the sand surface; slate-500 reaches 5.1:1. */
.story__of { font-size: .8rem; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; color: var(--slate-500); }
.story .step h3 { font-size: var(--step-3); margin-bottom: .9rem; }
.story .step p { color: var(--slate-600); font-size: var(--step-1); line-height: 1.55; max-width: 46ch; }

.story__vis {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: var(--r-xl);
  overflow: hidden;
  box-shadow: var(--shadow-lg);
  background: #fff;
}
.story__vis .layer img,
.story__vis .layer object { width: 100%; height: 100%; object-fit: cover; display: block; }
.story .pinbar { color: var(--ink-900); }

/* ------------------------------------------------------------- scrub band */
.scrubsec { background: var(--ink-900); color: #fff; }
.scrubsec .scrub__stage { background: var(--ink-900); }
/* Scrim between the scrubbing canvas and the copy, so the headline stays
   readable over whichever contours happen to be under it. */
.scrubsec .scrub__stage::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background:
    linear-gradient(100deg, rgba(8,17,29,.95) 0%, rgba(8,17,29,.82) 34%, rgba(8,17,29,.15) 62%, transparent 80%),
    linear-gradient(0deg, rgba(8,17,29,.6), transparent 45%);
}
.scrubsec__inner { width: 100%; }
.scrubsec h2 { color: #fff; max-width: 18ch; }
.scrubsec p { color: rgba(255, 255, 255, .72); max-width: 46ch; }
.scrubsec__readout {
  display: inline-flex;
  align-items: baseline;
  gap: .5rem;
  margin-top: 2rem;
  font-family: var(--font-display);
  font-size: 1rem;
  color: var(--amber-400);
}
.scrubsec__readout b {
  font-size: 3.2rem;
  line-height: .85;
  letter-spacing: -.04em;
  font-weight: 600;
}
.scrubsec__hint {
  position: absolute;
  left: 50%;
  bottom: 2.5rem;
  transform: translateX(-50%);
  z-index: 3;
  font-size: .74rem;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, .5);
  opacity: calc(1 - var(--p, 0) * 3);
}

/* --------------------------------------------------------- parallax band */
.bandimg {
  position: relative;
  overflow: hidden;
  border-radius: var(--r-xl);
  aspect-ratio: 21 / 9;
}
.bandimg__cap {
  position: absolute;
  left: clamp(1.25rem, 3vw, 2.5rem);
  bottom: clamp(1.25rem, 3vw, 2.5rem);
  z-index: 2;
  max-width: 34ch;
  color: #fff;
  font-family: var(--font-display);
  font-size: var(--step-2);
  letter-spacing: -.02em;
  line-height: 1.15;
  text-shadow: 0 2px 24px rgba(8, 17, 29, .5);
}

/* --------------------------------------------------- imagery inside cards */
.post__thumb { padding: 0; }
.post__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }

@media (max-width: 900px) {
  .story__grid { grid-template-columns: 1fr; gap: 1.75rem; }
  .story__vis { aspect-ratio: 16 / 10; }
  .story__num { font-size: 2.6rem; }
}

/* ==========================================================================
   v2 media pass 3 — real photography
   The imagery is now photographs rather than soft washes, so it is shown
   rather than blended away. Legibility comes from a directional scrim instead
   of from hiding the picture.
   ========================================================================== */

/* Scroll video: shown at near-full strength, slightly desaturated so it sits
   inside the palette rather than fighting it. */
.scrubsec .scrub__stage > video {
  opacity: .92;
  mix-blend-mode: normal;
  filter: saturate(.82) contrast(1.02);
}
/* Copy sits on the left; the scrim is heaviest there and clears to reveal the
   footage on the right. */
.scrubsec .scrub__stage::after {
  background:
    linear-gradient(100deg, rgba(8,17,29,.94) 0%, rgba(8,17,29,.86) 34%, rgba(8,17,29,.42) 60%, rgba(8,17,29,.12) 82%),
    linear-gradient(0deg, rgba(8,17,29,.55), transparent 40%);
}

/* Hero photograph stays a backdrop, not the subject, but readable: a hint of
   blur to soften it, and enough opacity that the photo shows. The radial mask on
   the base rule still fades it out towards the left, so the headline stays clear. */
.hero__texture { opacity: .6; filter: blur(.5px) saturate(.95); }

/* Once the layout stacks (1080px and under) the copy sits directly over the photo
   instead of beside it, so the photo eases back to keep the paragraph readable. */
@media (max-width: 1080px) {
  .hero__texture { opacity: .4; }
}

/* Focus-area photography (About → "Where we go deep") */
.focusmedia { position: relative; overflow: hidden; display: block; padding: 0; border: 0; }
.focusmedia img { width: 100%; height: 100%; object-fit: cover; display: block; }
.feature-visual.focusmedia { min-height: 0; aspect-ratio: 4/3; border-radius: var(--r-xl); background: none; padding: 0; }
.feature-visual.focusmedia::before { display: none; }

/* ==========================================================================
   Journey map — site structure and primary user journeys
   ========================================================================== */
.jm-grid { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 1rem; }
.jm-node {
  position: relative;
  display: flex; flex-direction: column; gap: .5rem;
  padding: 1.25rem 1.35rem;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  background: #fff;
}
.jm-node--built { border-color: var(--blue-100); box-shadow: var(--shadow-sm); }
.jm-node--planned { background: transparent; border-style: dashed; }
.jm-node__n {
  font-family: var(--font-display); font-size: .85rem; font-weight: 600;
  letter-spacing: .04em; color: var(--slate-400);
}
.jm-node h3 { font-size: 1.06rem; letter-spacing: -.02em; }
.jm-node p { font-size: .86rem; color: var(--slate-500); }
.jm-badge {
  align-self: flex-start; margin-top: .15rem;
  font-size: .66rem; font-weight: 700; letter-spacing: .11em; text-transform: uppercase;
  padding: .22rem .55rem; border-radius: var(--r-full);
}
.jm-badge--built { background: var(--blue-100); color: var(--blue-700); }
.jm-badge--planned { background: var(--sand-2); color: var(--slate-500); }
.jm-badge--parked { background: var(--coral-100); color: #b83a24; }

/* Journeys — numbered steps joined by a rule */
.jm-journey { border-top: 1px solid var(--line); padding-top: clamp(1.5rem,3vw,2.25rem); }
.jm-journey + .jm-journey { margin-top: clamp(2rem,4vw,3rem); }
.jm-journey__head { display: flex; align-items: baseline; gap: 1rem; margin-bottom: 1.5rem; }
.jm-journey__n {
  font-family: var(--font-display); font-size: 2.6rem; line-height: .8;
  letter-spacing: -.05em; color: var(--blue-600);
}
.jm-steps { display: grid; grid-template-columns: repeat(5, minmax(0,1fr)); gap: .75rem; }
.jm-step {
  position: relative;
  padding: 1rem 1.1rem;
  border-radius: var(--r-md);
  background: var(--sand);
  display: grid; gap: .3rem; align-content: start;
}
.jm-step__k {
  font-size: .66rem; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--blue-600);
}
.jm-step__t { font-family: var(--font-display); font-size: 1rem; letter-spacing: -.02em; color: var(--ink-900); }
.jm-step p { font-size: .8rem; color: var(--slate-500); }
.jm-step::after {
  content: "";
  position: absolute; right: -.55rem; top: 50%;
  width: .5rem; height: 1px; background: var(--line-strong, var(--line));
}
.jm-step:last-child::after { display: none; }

.jm-legend { display: flex; flex-wrap: wrap; gap: 1.25rem; font-size: .84rem; color: var(--slate-500); }
.jm-legend span { display: inline-flex; align-items: center; gap: .45rem; }
.jm-key { width: 22px; height: 10px; border-radius: 3px; border: 1px solid var(--line); }
.jm-key--built { background: var(--blue-100); border-color: var(--blue-100); }
.jm-key--planned { background: transparent; border-style: dashed; }
.jm-key--parked { background: var(--coral-100); border-color: var(--coral-100); }

@media (max-width: 1080px) { .jm-grid { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .jm-steps { grid-template-columns: repeat(2, minmax(0,1fr)); } .jm-step::after { display: none; } }
@media (max-width: 620px) { .jm-grid { grid-template-columns: 1fr; } .jm-steps { grid-template-columns: 1fr; } }

/* ==========================================================================
   Leader cards — Faculty & Expert Council layout
   ========================================================================== */

/* Bands: each group of leaders under its own heading. */
.leader-band + .leader-band { margin-top: clamp(2.5rem, 5vw, 4rem); }

.leader-band__title {
  display: flex;
  align-items: center;
  gap: 1rem;
  margin: 0 0 clamp(1.4rem, 3vw, 2rem);
  font-family: var(--font-display);
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-700);
  white-space: nowrap;
}

/* Rules either side, as the design has them. They are decoration, so they take
   no space in the accessibility tree and collapse rather than force overflow. */
.leader-band__title::before,
.leader-band__title::after {
  content: "";
  flex: 1 1 0;
  min-width: 0;
  height: 1px;
  background: linear-gradient(90deg, transparent, var(--amber-400), transparent);
}

/*
 * Portrait and name in a narrow left column, role and highlights in a wider
 * one beside it — two cards to a row leaves each about 460px wide, enough for
 * the text to sit beside the portrait rather than needing the full card width
 * stacked beneath it.
 */
.person__head {
  display: grid;
  grid-template-columns: minmax(110px, 150px) minmax(0, 1fr);
  align-items: start;
  column-gap: 1.75rem;
  width: 100%;
}

.person__id {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 0.9rem;
}

.person__body {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  min-width: 0;
}

/* 4:5, the same ratio the leader profile page's portrait uses, rather than
   this card's own circle. */
.person__photo {
  width: 120px;
  height: 150px;
  border-radius: var(--r-md);
  overflow: hidden;
  flex-shrink: 0;
}

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

.person__id .person__name { margin: 0; }

/* A short accent bar between the name and the role, standing in for the
   label the old layout put above the name instead. Amber, not the role's own
   blue — a second accent rather than a fainter repeat of the first, matching
   how .eyebrow already pairs the two elsewhere. */
.person__id .person__name::after {
  content: "";
  display: block;
  width: 32px;
  height: 3px;
  margin: 0.55rem auto;
  border-radius: 2px;
  background: var(--amber-500);
}

/* A caption to the name rather than the label above it the old layout used.
   Kept lighter than the name: these roles run to three lines, and at the name's
   weight they read as the louder of the two. */
.person__role {
  font-size: 0.76rem;
  font-weight: 500;
  line-height: 1.5;
  text-transform: none;
  letter-spacing: 0;
}

/* Normal flow, not grid: a grid container suppresses the list markers, and the
   bullets are the point of this list. */
.person__points {
  margin: 0;
  padding-left: 1.05rem;
  font-size: 0.92rem;
  line-height: 1.5;
  color: var(--slate-700);
}

/* The global `li { list-style: none }` reset sits on the li, not the list, so
   the marker has to be restored there too. */
.person__points li { list-style: disc; }
.person__points li + li { margin-top: 0.45rem; }
.person__points li::marker { color: var(--blue-500); }

/* The link that stands in for the highlights a card leaves out. It reads as the
   list's last line rather than a separate element: same type size and line height
   as the highlights, the same left edge as their text (the list's own indent), and
   the same gap between lines. Kept blue, at a regular weight, so it still says
   "link" without shouting. */
.person__more {
  display: inline-block;
  /* The card body puts a 0.75rem gap between its children, which would leave the
     link floating below the list. Taking that back out and adding the list's own
     0.45rem gives it exactly the spacing of another bullet. */
  margin-top: calc(0.45rem - 0.75rem);
  padding-left: 1.05rem;
  font-size: 0.92rem;
  line-height: 1.5;
  font-weight: 500;
  color: var(--blue-600);
  text-decoration: none;
}

.person__more:hover,
.person__more:focus-visible {
  text-decoration: underline;
  text-underline-offset: 0.2em;
}

/* Tags on a footer rule across the bottom, pinned there so cards in a row line
   up however uneven their bullets are. */
/*
 * On a leader card the tags read as one quiet line — "Partnerships · Growth ·
 * Leadership" — rather than the pill set used elsewhere: three pills wrap to two
 * rows in a quarter-width card and pull focus from the name. Scoped here, so
 * .tag keeps its pill form everywhere else it is used.
 */
.person .person__tags {
  width: 100%;
  margin-top: auto;
  padding-top: 0.85rem;
  border-top: 1px solid var(--line-soft);
  /* Text flow, not flex: as flex items the tags wrap individually and a
     separator can end up stranded at the start of the second line. */
  display: block;
  text-align: left;
  font-size: 0.78rem;
  line-height: 1.6;
  color: var(--slate-500);
}

.person .person__tags .tag {
  display: inline;
  padding: 0;
  border: 0;
  background: none;
  border-radius: 0;
  font-size: inherit;
  color: inherit;
}

.person .person__tags .tag + .tag::before {
  content: "·";
  margin: 0 0.45rem;
  color: var(--slate-400);
}

.person .person__avatar { width: 120px; height: 150px; border-radius: var(--r-md); font-size: 2.2rem; }

@media (max-width: 600px) {
  .leader-band__title { white-space: normal; }

  /* The 2-column head (portrait+name beside role+bullets) needs the width a
     2-up card has; a single stacked card here is a phone-width column, too
     narrow for both — back to one column, portrait and name above the rest,
     as the card had it before the 2-up grid. */
  .person__head { grid-template-columns: minmax(0, 1fr); }
}

/* ==========================================================================
   Leader profile page
   ========================================================================== */

/* Quote card and highlights stack in one right-hand column: the quote is the
   read, the highlights are the skim beneath it. */
.leader-profile__side {
  display: flex;
  flex-direction: column;
  gap: clamp(1.5rem, 3vw, 2.25rem);
}

.leader-quote__figure {
  margin: 0;
  background: var(--sand);
  border-radius: var(--r-lg);
  padding: clamp(1.75rem, 3vw, 2.5rem);
}

/* The quotation mark sits above the text rather than beside it, so the quote
   starts on the same edge as everything else in the column. */
.leader-quote__figure::before {
  content: "\201C";
  display: block;
  font-family: var(--font-display);
  font-size: 3.4rem;
  line-height: 0.55;
  margin-bottom: 0.1rem;
  color: var(--amber-400);
}

.leader-quote__text {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--step-2);
  line-height: 1.32;
  letter-spacing: -0.015em;
  color: var(--ink-900);
}

.leader-quote__by {
  margin-top: 1.1rem;
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--blue-600);
}

.leader-quote__context {
  display: block;
  margin-top: 0.2rem;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--slate-500);
}

.leader-brief__title {
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--slate-500);
  margin: 0 0 0.9rem;
}

/* Roomier than the same list on a card, which is packed into a quarter column. */
.leader-brief__list { font-size: 1rem; line-height: 1.6; }
