/* ==========================================================================
   Aspire Education Group
   Built from shared/hive/aspire-design-system.md (verified 26 Aug 2026).
   Every token below is traceable to that document.
   ========================================================================== */

/* Cascade layers. `context` holds every rule that colours links or inherited
   text by container. Components (buttons especially) stay UNLAYERED, and
   unlayered rules beat layered ones no matter how specific the layered
   selector is. That is what stops a container rule repainting a button. */
@layer context;

/* --- Tokens ------------------------------------------------------------- */
:root {
  /* Neutrals */
  --rich-black:  #12161A;
  --gunmetal:    #2A2E33;
  --outer-space: #474C51;
  --gray:        #8E939B;   /* non-text only, 2.93:1 fails AA */
  --powder:      #C7C9CD;
  --platinum:    #EEF0F1;
  --frost:       #F6F7F8;
  --ice-fog:     #F8F9FA;   /* the page canvas */
  --sea-salt:    #FAFBFD;

  /* Primary teal ramp, monochromatic, 191–194° */
  --midnight:    #0F3B45;
  --deep-teal:   #124754;
  --ocean-blue:  #106276;   /* primary action */
  --sky-blue:    #1895B4;
  --moonstone:   #61BAD1;
  --soft-sky:    #AADFEE;
  --azure:       #D9EEF4;
  --pale-blue:   #E9F3F6;

  /* Accents, outside the ramp, used sparingly */
  --signature-teal:      #00A19A;
  --signature-teal-deep: #006B67;
  --mustard:             #FEDE6A;
  --mustard-deep:        #8A6910;

  /* Spacing scale, 8px base */
  --s-1: 4px;   --s-2: 8px;   --s-3: 16px;  --s-4: 24px;
  --s-5: 32px;  --s-6: 40px;  --s-7: 48px;  --s-8: 64px;
  --s-9: 80px;  --s-10: 96px; --s-11: 120px; --s-12: 160px;

  /* Layout */
  --content-max: 1296px;
  --gutter: 24px;
  --grid-gap: 24px;
  --nav-h: 72px;
  --section-gap: 96px;
  --band-pad: 64px;

  /* Radius, only two */
  --r-sm: 4px;
  --r-lg: 16px;

  --ease: 150ms ease-out;
}

@media (min-width: 640px)  { :root { --gutter: 32px; --section-gap: 120px; --band-pad: 80px; } }
@media (min-width: 1024px) { :root { --gutter: 48px; --nav-h: 80px; --section-gap: 160px; --band-pad: 96px; } }
@media (min-width: 1440px) { :root { --gutter: 72px; } }

/* --- Reset -------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--ice-fog);
  color: var(--rich-black);
  font-family: "Lato", -apple-system, system-ui, sans-serif;
  font-weight: 300;
  font-size: 20px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
/* Belt and braces against any bleed overflow. `clip` contains it without breaking
   position:sticky the way `hidden` would. */
body { overflow-x: clip; }
ul { margin: 0; padding: 0; list-style: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition: none !important; animation: none !important; }
}

/* --- Typography --------------------------------------------------------- */
h1, h2, h3, h4, .display {
  font-family: "Urbanist", "Inter Tight", system-ui, sans-serif;
  font-weight: 400;              /* never bold, size carries emphasis */
  letter-spacing: -0.02em;
  line-height: 1.1;
  text-wrap: balance;
  margin: 0;
  color: var(--rich-black);
}
h1 { font-size: clamp(56px, 5.6vw, 80px); }   /* Display L  80 / 56 */
h2 { font-size: clamp(40px, 3.9vw, 56px); }   /* Heading L  56 / 40 */
h3 { font-size: clamp(24px, 2.2vw, 32px); }   /* Heading S  32 / 24 */
h4 { font-size: clamp(20px, 1.6vw, 24px); }

p { margin: 0; }
.lede   { font-size: clamp(24px, 1.9vw, 28px); font-weight: 300; color: var(--outer-space); }
.body-m { font-size: clamp(18px, 1.4vw, 20px); font-weight: 300; color: var(--outer-space); }
.body-s { font-size: 16px; font-weight: 400; color: var(--outer-space); }
.eyebrow {
  font-size: 16px; font-weight: 400; letter-spacing: 0.12em;
  text-transform: uppercase; color: var(--ocean-blue);
}
.measure { max-width: 62ch; }

@layer context {
  a:not(.btn) { color: var(--ocean-blue); text-decoration-thickness: 1px; text-underline-offset: 3px; }
  a:not(.btn):hover { color: var(--deep-teal); text-decoration-thickness: 2px; }
  a:not(.btn):visited { color: var(--midnight); }
}

:focus-visible {
  outline: 2px solid var(--ocean-blue);
  outline-offset: 2px;
  border-radius: var(--r-sm);
}
.on-dark :focus-visible { outline-color: var(--soft-sky); }

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--ocean-blue); color: var(--sea-salt);
  padding: var(--s-3) var(--s-4); border-radius: 0 0 var(--r-sm) 0;
}
.skip:focus { left: 0; }

/* --- Layout ------------------------------------------------------------- */
.wrap {
  width: 100%;
  max-width: calc(var(--content-max) + (var(--gutter) * 2));
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.stack > * + * { margin-top: var(--s-4); }

/* Vertical rhythm belongs to the wrapper gap. Sections carry no vertical padding
   of their own, except filled bands, which need it so the fill has something to
   extend around. This is the rule from the design system; applying padding AND a
   gap is what produced the 328px compounding in the source Figma. */
main {
  display: flex;
  flex-direction: column;
  gap: var(--section-gap);
  padding-block: var(--s-9) var(--section-gap);
}
main > section { padding-block: 0; scroll-margin-top: calc(var(--nav-h) + var(--s-5)); }
main > section.band { padding-block: var(--band-pad); }
/* Two filled bands in a row sit flush: the wrapper gap between them would show
   the canvas as a confusing empty strip. A negative margin equal to the gap
   cancels it, so band meets band directly. */
main > section.band + section.band { margin-top: calc(-1 * var(--section-gap)); }
.band-pale { background: var(--pale-blue); }
.band-frost { background: var(--frost); }

.grid { display: grid; gap: var(--grid-gap); }
@media (min-width: 640px)  { .cols-2 { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1024px) { .cols-3 { grid-template-columns: repeat(3, 1fr); }
                             .cols-4 { grid-template-columns: repeat(4, 1fr); } }

.split { display: grid; gap: var(--s-7); align-items: start; }
.hero .split { align-items: center; }
@media (min-width: 1024px) { .split { grid-template-columns: 1fr 1fr; gap: var(--s-8); } }
@media (min-width: 1024px) { .split-wide { grid-template-columns: 5fr 7fr; } }

.section-head { display: flex; flex-direction: column; gap: var(--s-4); margin-bottom: var(--s-8); }

/* --- Navigation --------------------------------------------------------- */
.nav {
  height: var(--nav-h);
  background: var(--ice-fog);
  border-bottom: 1px solid var(--platinum);
  position: sticky; top: 0; z-index: 50;
}
.nav.is-scrolled { box-shadow: 0 1px 12px rgba(18,22,26,.06); }
.nav .wrap { height: 100%; display: flex; align-items: center; justify-content: space-between; gap: var(--s-4); }
.nav-logo img { height: 40px; width: auto; }
.nav-links { display: none; align-items: center; gap: var(--s-5); }
@media (min-width: 1024px) { .nav-links { display: flex; } }
@layer context {
  .nav-links a:not(.btn) {
    font-size: 16px; font-weight: 400; color: var(--rich-black); text-decoration: none;
    padding-block: var(--s-2); border-bottom: 2px solid transparent; transition: color var(--ease), border-color var(--ease);
  }
  .nav-links a:not(.btn):hover,
  .nav-links a:not(.btn)[aria-current="page"] { color: var(--ocean-blue); border-bottom-color: var(--ocean-blue); }
}
.nav-links .ext::after { content: " ↗"; font-size: 0.85em; }

.nav-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; background: none; border: 1px solid var(--powder);
  border-radius: var(--r-sm); cursor: pointer; color: var(--rich-black);
}
@media (min-width: 1024px) { .nav-toggle { display: none; } }
.nav-drawer { display: none; border-bottom: 1px solid var(--platinum); background: var(--ice-fog); }
.nav-drawer.open { display: block; }
@media (min-width: 1024px) { .nav-drawer { display: none !important; } }
.nav-drawer ul { display: flex; flex-direction: column; padding-block: var(--s-3); }
@layer context {
  .nav-drawer a:not(.btn) {
    display: block; padding: var(--s-3) 0; font-size: 18px; color: var(--rich-black); text-decoration: none;
    border-bottom: 1px solid var(--platinum);
  }
  .nav-drawer a:not(.btn):hover { color: var(--ocean-blue); }
}

/* --- Buttons ------------------------------------------------------------ */
/* ==========================================================================
   BUTTONS
   Deliberately NOT inside a cascade layer. Unlayered rules beat every layered
   rule regardless of specificity, so a context rule such as `.nav-links a`
   can never repaint a button label. This is the structural guarantee that
   dark text never lands on a dark button.

   Colour comes from three tokens per variant, so there is exactly one place
   to change it. Never set `color` or `background` on a button outside these
   declarations; re-point the tokens instead.
   ========================================================================== */
.btn {
  --btn-fg: var(--sea-salt);
  --btn-bg: var(--ocean-blue);
  --btn-bd: transparent;

  display: inline-flex; align-items: center; gap: var(--s-2);
  font-family: "Lato", system-ui, sans-serif; font-size: 16px; font-weight: 400;
  padding: 14px 20px; min-height: 48px; border-radius: var(--r-sm);
  cursor: pointer; text-decoration: none;
  transition: background-color var(--ease), color var(--ease), border-color var(--ease);

  color: var(--btn-fg);
  background: var(--btn-bg);
  border: 1px solid var(--btn-bd);
}
.btn:visited { color: var(--btn-fg); }

/* Primary: light label on a teal ground. Hover darkens the ground and shifts
   the label to pale blue. Sea Salt on Ocean Blue 6.69:1, Soft Sky on Deep
   Teal 7.06:1, Soft Sky on Midnight 8.37:1. All AA or better. */
.btn-primary          { --btn-fg: var(--sea-salt);  --btn-bg: var(--ocean-blue); }
.btn-primary:hover    { --btn-fg: var(--soft-sky);  --btn-bg: var(--deep-teal); }
.btn-primary:active   { --btn-fg: var(--soft-sky);  --btn-bg: var(--midnight); }

/* Secondary: dark label on a light ground, so dark text is correct here. */
.btn-secondary        { --btn-fg: var(--rich-black); --btn-bg: transparent; --btn-bd: var(--rich-black); }
.btn-secondary:hover  { --btn-fg: var(--rich-black); --btn-bg: var(--pale-blue); }
.btn-secondary:active { --btn-fg: var(--rich-black); --btn-bg: var(--azure); }

/* On dark bands the polarity inverts: light ground, dark label. */
.btn-on-dark          { --btn-fg: var(--midnight); --btn-bg: var(--sea-salt); }
.btn-on-dark:hover    { --btn-fg: var(--midnight); --btn-bg: var(--soft-sky); }

/* Light outline, for dark grounds only. Sea Salt on Signature Teal Deep 6.15:1. */
.btn-ghost-light        { --btn-fg: var(--sea-salt); --btn-bg: transparent; --btn-bd: var(--sea-salt); }
.btn-ghost-light:hover  { --btn-fg: var(--signature-teal-deep); --btn-bg: var(--sea-salt); --btn-bd: var(--sea-salt); }
.btn-ghost-light:active { --btn-fg: var(--signature-teal-deep); --btn-bg: var(--azure); --btn-bd: var(--azure); }

.btn:disabled, .btn[aria-disabled="true"] {
  --btn-fg: var(--outer-space); --btn-bg: var(--powder); --btn-bd: var(--powder);
  cursor: not-allowed;
}
.btn-row { display: flex; flex-wrap: wrap; gap: var(--s-4); align-items: center; }

.link-arrow { display: inline-flex; align-items: center; gap: var(--s-2); font-size: 16px; text-decoration: none; font-weight: 400; }
.link-arrow::after { content: "→"; transition: transform var(--ease); }
.link-arrow:hover::after { transform: translateX(3px); }

/* --- Cards -------------------------------------------------------------- */
.card {
  background: var(--sea-salt); border: 1px solid var(--platinum); border-radius: var(--r-sm);
  padding: var(--s-5); display: flex; flex-direction: column; gap: var(--s-3);
  transition: border-color var(--ease);
}
.card:hover { border-color: var(--ocean-blue); }
.grid > .card { height: 100%; }
.card > .link-arrow { margin-top: auto; padding-top: var(--s-2); }
.card h3, .card h4 { margin: 0; }

.media-card { border: none; background: none; padding: 0; gap: var(--s-4); }
.media-card .thumb { overflow: hidden; border-radius: var(--r-sm); aspect-ratio: 3 / 2; }
.media-card.portrait .thumb { aspect-ratio: 4 / 5; }
/* A card that also carries an image: keep the border and padding, but let the
   image sit flush to the top edge. */
.card.media-card:has(> .thumb:first-child):not(.portrait) {
  border: 1px solid var(--platinum); background: var(--sea-salt);
  padding: 0; overflow: hidden; gap: 0;
}
.card.media-card:has(> .thumb:first-child):not(.portrait) > .thumb:first-child + * { margin-top: var(--s-5); }
.card.media-card:has(> .thumb:first-child):not(.portrait) > *:not(.thumb) { padding-inline: var(--s-5); }
.card.media-card:has(> .thumb:first-child):not(.portrait) > *:last-child { padding-bottom: var(--s-5); }

/* --- People --------------------------------------------------------------
   One component, two scales. The leadership pair and the wider team use the
   same card structure and the same portrait crop; only the column width and
   type size differ. Using a single component keeps the two tiers reading as
   one section rather than two unrelated blocks.
   -------------------------------------------------------------------------- */
.person-card { display: flex; flex-direction: column; }
.person-card .thumb {
  aspect-ratio: 4 / 5; overflow: hidden; border-radius: var(--r-sm);
  background: var(--frost);
}
/* `backface-visibility` keeps the image on its own stable compositing layer.
   Without it, a lazy image that decodes after GSAP tears down the card's
   transform layer can paint blank until something else forces a repaint. */
.person-card .thumb img {
  width: 100%; height: 100%; object-fit: cover; object-position: center 15%;
  transition: transform 400ms ease-out;
  backface-visibility: hidden;
}
.person-card:hover .thumb img { transform: scale(1.03); }
.person-card .name {
  font-family: "Urbanist", system-ui, sans-serif; font-weight: 400;
  letter-spacing: -0.02em; color: var(--rich-black); margin-top: var(--s-4);
}
.person-card .role {
  color: var(--ocean-blue); font-size: 16px; letter-spacing: 0.02em; margin-top: 2px;
}
.person-card .bio { color: var(--outer-space); margin-top: var(--s-3); }

/* Leadership */
.people-lead { display: grid; gap: var(--s-7); max-width: 900px; }
@media (min-width: 700px) { .people-lead { grid-template-columns: repeat(2, 1fr); } }
.people-lead .name { font-size: clamp(26px, 2.2vw, 32px); }
.people-lead .bio  { font-size: 17px; }

/* Wider team: same card, narrower column, quieter type */
.people-team { display: flex; flex-wrap: wrap; gap: var(--s-7); }
.people-team .person-card { flex: 0 1 260px; }
.people-team .name { font-size: 21px; }
.people-team .role { font-size: 15px; }
.people-team .bio  { font-size: 15px; }

.people-divider {
  max-width: 900px; margin-top: var(--s-9); margin-bottom: var(--s-6);
  padding-top: var(--s-5); border-top: 1px solid var(--powder);
}

.media-card .thumb img { width: 100%; height: 100%; object-fit: cover; transition: transform 300ms ease-out; }
.media-card:hover .thumb img { transform: scale(1.02); }

.stat { display: flex; flex-direction: column; gap: var(--s-2); }
.stat .n {
  font-family: "Urbanist", system-ui, sans-serif; font-weight: 400;
  font-size: clamp(40px, 3.6vw, 56px); letter-spacing: -0.02em; line-height: 1;
  color: var(--ocean-blue);
}
.stat .l { font-size: 16px; color: var(--outer-space); }

.chip {
  display: inline-block; font-size: 14px; font-weight: 400; letter-spacing: 0.04em;
  padding: 6px 12px; border-radius: var(--r-sm);
  background: var(--azure); color: var(--deep-teal);
}
.chip-mustard { background: var(--mustard); color: var(--rich-black); }   /* fill + dark ink */
.chip-live { background: var(--signature-teal); color: var(--rich-black); }

/* --- Feature: one initiative given a full band ---------------------------- */
.feature { display: grid; gap: var(--s-7); align-items: center; }
@media (min-width: 900px) { .feature { grid-template-columns: 1.15fr 1fr; gap: var(--s-9); } }
.feature-copy { display: flex; flex-direction: column; gap: var(--s-4); }
.feature-copy h2 { margin: 0; }
.feature-copy .lede { margin: 0; }
.feature-copy .btn-row { margin-top: var(--s-2); }
.feature-img { border-radius: var(--r-sm); overflow: hidden; aspect-ratio: 4 / 5; }
@media (min-width: 900px) { .feature-img { aspect-ratio: 5 / 6; } }
.feature-img img { width: 100%; height: 100%; object-fit: cover; object-position: center 25%; backface-visibility: hidden; }

/* Head-office marker in the footer office list */
.hq {
  display: inline-block; margin-left: var(--s-2); padding: 1px 8px;
  border-radius: 999px; background: var(--signature-teal-deep); color: var(--sea-salt);
  font-size: 12px; letter-spacing: .06em; text-transform: uppercase; vertical-align: 1px;
}

/* --- Initiatives: four cards, one of them special ------------------------
 * Future Ed is one of the four white cards, not a section of its own. It is
 * distinguished, not removed from the row: a teal top-rule and a mustard chip
 * mark it as Aspire's own while it keeps the same white card body as the rest.
 */
.initiative-cards .card { position: relative; }
.initiative-cards .card .link-arrow { margin-top: auto; padding-top: var(--s-3); }
.card-feature {
  border-color: var(--signature-teal-deep);
  border-top: 3px solid var(--signature-teal-deep);
}

/* --- Slideshow ------------------------------------------------------------
 * Default (no JS): a plain stacked gallery. Every photograph is visible and the
 * controls are hidden, because nothing can drive them. `is-live` is added by
 * assets/js/slideshow.js and collapses the stack into one crossfading frame.
 */
.slideshow { display: flex; flex-direction: column; gap: var(--s-3); }
/* <figure> carries a UA margin of 1em 40px, which inset every photograph inside
   its frame and showed the frame's ground as a letterbox. */
.slideshow .slide { margin: 0; border-radius: var(--r-sm); overflow: hidden; }
.slideshow .slide img { width: 100%; height: 100%; object-fit: cover; display: block; backface-visibility: hidden; }
.slideshow-controls { display: none; }
.slideshow-status { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

.slideshow.is-live { display: block; position: relative; }
.slideshow.is-live .frame {
  position: relative; aspect-ratio: 3 / 2;
  border-radius: var(--r-sm); overflow: hidden; background: var(--midnight);
}
.slideshow.is-live .slide {
  position: absolute; inset: 0; border-radius: 0;
  opacity: 0; transition: opacity 700ms ease-in-out; pointer-events: none;
}
.slideshow.is-live .slide.is-current { opacity: 1; pointer-events: auto; }
.slideshow.is-reduced .slide { transition: none; }

.slideshow.is-live .slideshow-controls {
  display: flex; align-items: center; gap: var(--s-3);
  margin-top: var(--s-3); justify-content: space-between;
}

/* Arrows and dots sit on the band, not on the photograph, so they never fight
   the image for contrast. Both palettes are declared: the component is used on
   the Signature Teal Deep band today but must not break on a light one. */
.slideshow-prev, .slideshow-next {
  --dot-ink: var(--ocean-blue);
  appearance: none; background: transparent; cursor: pointer;
  border: 1px solid var(--dot-ink); color: var(--dot-ink);
  border-radius: 999px; width: 40px; height: 40px; line-height: 1;
  font-size: 16px; display: grid; place-items: center;
  transition: background-color var(--ease), color var(--ease);
}
.slideshow-prev:hover, .slideshow-next:hover { background: var(--dot-ink); color: var(--sea-salt); }

.slideshow-arrows { display: flex; gap: var(--s-2); }
.slideshow-dots { display: flex; gap: var(--s-2); align-items: center; }
.slideshow-dot {
  --dot-ink: var(--ocean-blue);
  appearance: none; padding: 0; cursor: pointer;
  width: 8px; height: 8px; border-radius: 999px;
  border: 1px solid var(--dot-ink); background: transparent;
  transition: background-color var(--ease), transform var(--ease);
}
.slideshow-dot[aria-selected="true"] { background: var(--dot-ink); transform: scale(1.4); }

/* Tap targets: the dot is 8px but the hit area must clear 44px. */
.slideshow-dot { position: relative; }
.slideshow-dot::after { content: ""; position: absolute; inset: -18px; }

/* On the Future Ed band the ink inverts. */
.on-dark .slideshow-prev, .on-dark .slideshow-next, .on-dark .slideshow-dot { --dot-ink: var(--sea-salt); }
.on-dark .slideshow-prev:hover, .on-dark .slideshow-next:hover { color: var(--signature-teal-deep); }

.slideshow-caption { font-size: 15px; opacity: .85; }
@media (prefers-reduced-motion: reduce) {
  .slideshow.is-live .slide { transition: none; }
}

/* --- Hero --------------------------------------------------------------- */
.hero .split { align-items: center; }
.hero-copy { display: flex; flex-direction: column; gap: var(--s-5); }
.hero-img { border-radius: var(--r-lg); overflow: hidden; aspect-ratio: 3 / 2; }
.hero-img img { width: 100%; height: 100%; object-fit: cover; }

/* Figma hero treatment: the image is 970x648 placed at x=842 in a 1440 frame, so it
   runs off the right edge. Reproduced here as a portrait-ish crop that bleeds to the
   viewport edge, with the 8px radius the Figma uses (not the 16px card radius). */
.hero-bleed { border-radius: 8px; overflow: hidden; aspect-ratio: 3 / 2; }
/* The hero file is the full 3:2 frame of the source photograph, the widest view
   of the student available. Frames are kept close to 3:2 so almost nothing is
   cropped away; the horizontal bias keeps her in shot where the frame is
   narrower than the file. */
.hero-bleed img { width: 100%; height: 100%; object-fit: cover; object-position: 4% center; }
@media (min-width: 1024px) {
  /* Narrow the image column so the frame reads like the Figma's tall right-edge
     window onto the photo. Because the photo is 3:2 (wider than any box here),
     object-fit:cover is height-driven: the student's on-screen size depends only
     on the box HEIGHT, not its width. So narrowing the column while holding the
     height keeps her exactly the same size, no zoom, just a narrower window that
     crops more off the sides. The portrait aspect-ratio below is chosen to keep
     the box height where it was at the old 4/3 frame. */
  .hero-figma { grid-template-columns: 1.8fr 1fr; align-items: start; }
  .hero-bleed {
    aspect-ratio: 0.86;
    /* Reaches the viewport edge at the 1440 design width (1296 + 2x72) and rests at
       the container edge above that. Avoids 100vw, which counts the scrollbar. */
    margin-right: calc(-1 * var(--gutter));
    border-radius: 8px 0 0 8px;
  }
}

/* About hero: heading and supporting copy side by side, then a full-width image below */
.hero-stacked { display: flex; flex-direction: column; gap: var(--s-8); }
.hero-stacked .intro { display: grid; gap: var(--s-5); align-items: start; }
@media (min-width: 1024px) { .hero-stacked .intro { grid-template-columns: 6fr 5fr; gap: var(--s-8); } }
.hero-stacked .wide-img { border-radius: 8px; overflow: hidden; aspect-ratio: 21 / 9; }
.hero-stacked .wide-img img { width: 100%; height: 100%; object-fit: cover; }
@media (max-width: 1023px) { .hero-stacked .wide-img { aspect-ratio: 3 / 2; } }

/* --- Dark bands --------------------------------------------------------- */
.on-dark { background: var(--deep-teal); color: var(--soft-sky); }
.on-dark h1, .on-dark h2, .on-dark h3, .on-dark h4 { color: var(--sea-salt); }
.on-dark .eyebrow { color: var(--soft-sky); }
.on-dark .body-m, .on-dark .body-s, .on-dark p { color: var(--soft-sky); }
@layer context { .on-dark a:not(.btn) { color: var(--sea-salt); } }
.on-dark .stat .n { color: var(--mustard); }     /* 7.72:1 on Deep Teal */
.on-dark .stat .l { color: var(--soft-sky); }

/* Reserved for Future Ed, the one initiative Aspire owns outright. Uses the deep
   partner of the logo teal rather than Deep Teal, so it reads as a different kind
   of band from the stat band. Declared after .on-dark so it wins on background.
   Soft Sky measures only 4.4:1 here, so body copy steps up to Sea Salt (6.15:1)
   and the eyebrow takes Mustard (4.81:1). The logo teal itself (#00A19A) tops out
   at 3.09:1 against Sea Salt and cannot carry text at all. */
.on-dark.band-teal { background: var(--signature-teal-deep); color: var(--sea-salt); }
.on-dark.band-teal .body-m,
.on-dark.band-teal .body-s,
.on-dark.band-teal .lede,
.on-dark.band-teal p { color: var(--sea-salt); }
.on-dark.band-teal .eyebrow { color: var(--mustard); }

/* --- CTA card ----------------------------------------------------------- */
.cta {
  background: var(--soft-sky); border-radius: var(--r-lg);
  padding: var(--s-10) var(--s-5); text-align: center;
  display: flex; flex-direction: column; align-items: center; gap: var(--s-4);
}
.cta h2 { color: var(--rich-black); }
.cta p { color: var(--outer-space); max-width: 52ch; }

/* --- Forms -------------------------------------------------------------- */
.field { display: flex; flex-direction: column; gap: var(--s-2); }
.field label { font-size: 16px; font-weight: 400; color: var(--rich-black); }
.field input, .field textarea, .field select {
  font-family: inherit; font-size: 18px; font-weight: 300; color: var(--rich-black);
  background: var(--sea-salt); border: 1px solid var(--powder); border-radius: var(--r-sm);
  padding: 14px 16px; min-height: 48px; width: 100%;
  transition: border-color var(--ease), box-shadow var(--ease);
}
.field textarea { min-height: 160px; resize: vertical; }
.field input::placeholder, .field textarea::placeholder { color: var(--outer-space); opacity: 1; }
.field input:hover, .field textarea:hover { border-color: var(--outer-space); }
.field input:focus-visible, .field textarea:focus-visible {
  border-color: var(--ocean-blue); outline: 2px solid var(--ocean-blue); outline-offset: 1px;
}
.field .hint { font-size: 14px; color: var(--outer-space); }
.field .error { font-size: 14px; color: #B3261E; }
.field.is-error input, .field.is-error textarea { border-color: #B3261E; }

/* --- FAQ ---------------------------------------------------------------- */
.faq { border-top: 1px solid var(--platinum); }
.faq details { border-bottom: 1px solid var(--platinum); }
.faq summary {
  cursor: pointer; list-style: none; padding: var(--s-4) 0;
  font-family: "Urbanist", system-ui, sans-serif; font-size: 20px; letter-spacing: -0.01em;
  display: flex; justify-content: space-between; gap: var(--s-4); align-items: center;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; color: var(--ocean-blue); font-size: 24px; line-height: 1; }
.faq details[open] summary::after { content: "–"; }
.faq details > p { padding-bottom: var(--s-4); color: var(--outer-space); }

/* --- Article ------------------------------------------------------------ */
.article-body { max-width: 68ch; margin-inline: auto; }
.article-body > * + * { margin-top: var(--s-4); }
.article-body h2 { margin-top: var(--s-8); font-size: clamp(32px, 2.6vw, 40px); }
.article-body h3 { margin-top: var(--s-6); }
.article-body p { font-size: 20px; font-weight: 300; color: var(--outer-space); line-height: 1.7; }
.article-body ul { list-style: disc; padding-left: 1.3em; color: var(--outer-space); font-weight: 300; }
.article-body li + li { margin-top: var(--s-2); }
.article-body blockquote {
  margin: var(--s-7) 0; padding: var(--s-5); background: var(--azure);
  border-left: 3px solid var(--ocean-blue); border-radius: 0 var(--r-sm) var(--r-sm) 0;
}
.article-body blockquote p { color: var(--rich-black); font-size: 22px; }
.article-meta { display: flex; flex-wrap: wrap; gap: var(--s-2) var(--s-4); font-size: 16px; color: var(--outer-space); }

/* --- Footer ------------------------------------------------------------- */
.footer { background: var(--deep-teal); color: var(--soft-sky); padding-block: var(--band-pad); }
.footer h4 { color: var(--sea-salt); font-size: 18px; margin-bottom: var(--s-3); }
@layer context {
  .footer a:not(.btn) { color: var(--soft-sky); text-decoration: none; }
  .footer a:not(.btn):hover { color: var(--sea-salt); text-decoration: underline; }
}
.footer-grid { display: grid; gap: var(--s-8); }
@media (min-width: 640px)  { .footer-grid { grid-template-columns: 1fr 1fr; } }
@media (min-width: 1024px) { .footer-grid { grid-template-columns: 2fr 1fr 1fr 1fr; } }
.footer-logo { background: var(--sea-salt); padding: var(--s-3); border-radius: var(--r-sm); display: inline-block; }
.footer-logo img { height: 36px; width: auto; }
.footer ul { display: flex; flex-direction: column; gap: var(--s-2); font-size: 16px; }
.footer-bottom {
  margin-top: var(--s-8); padding-top: var(--s-5);
  border-top: 1px solid rgba(170, 223, 238, 0.25);
  display: flex; flex-wrap: wrap; gap: var(--s-3) var(--s-5); justify-content: space-between;
  font-size: 16px;
}

/* --- Utilities ---------------------------------------------------------- */
.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.rule { height: 1px; background: var(--platinum); border: 0; margin: 0; }
