/* ==========================================================================
   MSJ Biology Club — Design System
   Style: restrained glassmorphism (nav + cards only)
   Type:  Crimson Pro (display) + Atkinson Hyperlegible (body/UI)
   ========================================================================== */

/* ---------- 1. Tokens ---------- */
:root {
  /* Brand ramp — biology green */
  --green-950: #0b2e1c;
  --green-900: #14532d;
  --green-800: #166534;
  --green-700: #15803d;
  --green-600: #16a34a;
  --green-500: #22c55e;
  --green-200: #bbf7d0;
  --green-100: #dcfce7;
  --green-50:  #f0fdf4;

  /* Accent — call to action */
  --amber-700: #b45309;
  --amber-600: #d97706;
  --amber-500: #f59e0b;
  --amber-100: #fef3c7;

  /* Logo purple — decorative use only, never for body text */
  --violet-700: #6b2585;
  --violet-600: #7c2d91;
  --violet-100: #f3e6f8;

  /* Brighter steps needed for legible accents on a dark ground */
  --green-400: #4ade80;
  --green-300: #86efac;
  --amber-400: #fbbf24;

  /* ---- Semantic: Deep Forest (dark) ----
     The brand and accent ramps above keep their true values; only these
     semantic tokens flip. Components read semantics, never raw ramp steps,
     which is why the dark bands and footer still work unchanged. */
  --color-bg:          #0a1710;
  --color-surface:     #12261a;
  --color-surface-alt: #0f1f15;
  --color-fg:          #e8fdf0;
  --color-fg-muted:    #9fc4ae;   /* 8.1:1 on --color-bg */
  --color-primary:     var(--green-400);
  --color-primary-ink: var(--green-300);
  --color-on-primary:  #052e16;
  --color-accent:      var(--amber-400);
  --color-on-accent:   #301a02;
  --color-border:      #1c3d29;
  --color-border-soft: rgba(255, 255, 255, 0.09);
  --color-ring:        var(--green-400);

  /* Surfaces that are dark in any theme */
  --color-band:        #12301f;
  --color-footer-bg:   #050f09;
  --color-header-glass: rgba(10, 23, 16, 0.82);
  --color-hover-wash:  rgba(255, 255, 255, 0.07);

  /* Ambient hero glows — tinted, never pale washes */
  --hero-glow-1: rgba(34, 197, 94, 0.14);
  --hero-glow-2: rgba(168, 85, 201, 0.12);

  /* Tinted chips, so small pills don't punch bright holes in a dark page */
  --chip-brand-bg:  rgba(74, 222, 128, 0.14);
  --chip-brand-fg:  var(--green-300);
  --chip-accent-bg: rgba(251, 191, 36, 0.15);
  --chip-accent-fg: var(--amber-400);
  --chip-violet-bg: rgba(192, 132, 252, 0.16);
  --chip-violet-fg: #d8b4fe;

  /* Spacing — density 4/10 (standard) */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-12: 3rem;
  --space-16: 4rem;
  --space-24: 6rem;

  /* Type */
  --font-display: "Crimson Pro", Georgia, "Times New Roman", serif;
  --font-body: "Atkinson Hyperlegible", system-ui, -apple-system, "Segoe UI", sans-serif;

  --text-xs:   0.8125rem;
  --text-sm:   0.9375rem;
  --text-base: 1.0625rem;
  --text-lg:   1.1875rem;
  --text-xl:   clamp(1.375rem, 1.2rem + 0.8vw, 1.75rem);
  --text-2xl:  clamp(1.75rem, 1.4rem + 1.6vw, 2.5rem);
  --text-3xl:  clamp(2.125rem, 1.6rem + 2.4vw, 3.25rem);
  --text-hero: clamp(2.5rem, 1.9rem + 3.6vw, 4.25rem);

  /* Radius */
  --r-sm: 8px;
  --r-md: 14px;
  --r-lg: 20px;
  --r-xl: 28px;
  --r-full: 999px;

  /* Elevation — black-based; green-tinted shadows vanish on a dark ground */
  --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.30), 0 1px 3px rgba(0, 0, 0, 0.22);
  --shadow-md: 0 4px 14px rgba(0, 0, 0, 0.38), 0 2px 5px rgba(0, 0, 0, 0.26);
  --shadow-lg: 0 20px 44px rgba(0, 0, 0, 0.50), 0 6px 14px rgba(0, 0, 0, 0.32);

  /* Motion — easeOutQuint. The long tail is what reads as "smooth": motion
     leaves quickly, then settles gently instead of stopping dead. */
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-inout: cubic-bezier(0.65, 0, 0.35, 1);
  --t-fast: 200ms;
  --t-base: 380ms;
  --t-slow: 640ms;

  --wrap: 1120px;
  --wrap-narrow: 760px;
}

/* ---------- 2. Reset & base ---------- */
*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-fg);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

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

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: -0.015em;
  margin: 0 0 var(--space-4);
  text-wrap: balance;
}

h1 { font-size: var(--text-3xl); }
h2 { font-size: var(--text-2xl); }
h3 { font-size: var(--text-xl); }
h4 { font-size: var(--text-lg); font-family: var(--font-body); font-weight: 700; }

p { margin: 0 0 var(--space-4); text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

a { color: var(--color-primary-ink); text-underline-offset: 3px;
    transition: color var(--t-fast) var(--ease); }
a:hover { color: var(--color-primary); }

strong { font-weight: 700; }

ul, ol { margin: 0 0 var(--space-4); padding-left: 1.25em; }
li { margin-bottom: var(--space-2); }

:focus-visible {
  outline: 3px solid var(--color-ring);
  outline-offset: 3px;
  border-radius: 4px;
}

button { font: inherit; }

.skip-link {
  position: absolute;
  left: var(--space-4);
  top: -100px;
  z-index: 200;
  background: var(--color-primary);
  color: var(--color-on-primary);
  padding: var(--space-3) var(--space-6);
  border-radius: var(--r-sm);
  font-weight: 700;
  text-decoration: none;
  transition: top var(--t-base) var(--ease);
}
.skip-link:focus { top: var(--space-4); color: var(--color-on-primary); }

.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;
}

/* ---------- 3. Layout ---------- */
.container {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--space-6);
}
/* Also centers when used on its own, not just alongside `.container`. */
.container-narrow { max-width: var(--wrap-narrow); margin-inline: auto; }

.section { padding-block: var(--space-16); }
.section-sm { padding-block: var(--space-12); }

@media (min-width: 768px) {
  .section { padding-block: var(--space-24); }
  .section-sm { padding-block: var(--space-16); }
}

.section-head { max-width: 60ch; margin-bottom: var(--space-8); }
.section-head.center { margin-inline: auto; text-align: center; }

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-primary);
  margin-bottom: var(--space-3);
}
.eyebrow::before {
  content: "";
  width: 22px; height: 2px;
  background: currentColor;
  border-radius: 2px;
}
/* The leading dash reads as a left-edge marker, so it is dropped wherever the
   block is centred — otherwise it pulls the label visibly off-centre. */
.section-head.center .eyebrow::before,
.page-hero-center .eyebrow::before { display: none; }

.lede {
  font-size: var(--text-lg);
  color: var(--color-fg-muted);
  max-width: 62ch;
}
.section-head.center .lede { margin-inline: auto; }

.grid { display: grid; gap: var(--space-6); }
.grid-2 { grid-template-columns: 1fr; }
.grid-3 { grid-template-columns: 1fr; }
.grid-4 { grid-template-columns: repeat(2, 1fr); }

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

/* ---------- 4. Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: 48px;
  padding: var(--space-3) var(--space-6);
  border: 1px solid transparent;
  border-radius: var(--r-full);
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 700;
  text-decoration: none;
  cursor: pointer;
  transition: background var(--t-base) var(--ease),
              color var(--t-base) var(--ease),
              border-color var(--t-base) var(--ease),
              transform var(--t-fast) var(--ease),
              box-shadow var(--t-base) var(--ease);
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }
.btn svg { width: 18px; height: 18px; flex: none; }

.btn-primary {
  background: var(--color-primary);
  color: var(--color-on-primary);
  box-shadow: var(--shadow-sm);
}
.btn-primary:hover {
  background: var(--green-800);
  color: var(--color-on-primary);
  box-shadow: var(--shadow-md);
}

.btn-accent {
  background: var(--color-accent);
  color: var(--color-on-accent);
  box-shadow: var(--shadow-sm);
}
.btn-accent:hover {
  background: var(--amber-700);
  color: var(--color-on-accent);
  box-shadow: var(--shadow-md);
}

.btn-outline {
  background: transparent;
  color: var(--color-primary-ink);
  border-color: var(--color-primary);
}
.btn-outline:hover {
  background: var(--color-primary);
  color: var(--color-on-primary);
}

.btn-on-dark {
  background: rgba(255, 255, 255, 0.12);
  color: #fff;
  border-color: rgba(255, 255, 255, 0.4);
  backdrop-filter: blur(6px);
}
.btn-on-dark:hover { background: rgba(255, 255, 255, 0.22); color: #fff; }

.btn-lg { min-height: 56px; padding: var(--space-4) var(--space-8); font-size: var(--text-base); }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--space-3); }
.btn-row.center { justify-content: center; }

/* ---------- 5. Header / nav ---------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  background: var(--color-header-glass);
  backdrop-filter: blur(14px) saturate(1.4);
  -webkit-backdrop-filter: blur(14px) saturate(1.4);
  border-bottom: 1px solid var(--color-border-soft);
}

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: 72px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3);
  text-decoration: none;
  color: var(--color-fg);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.25rem;
  letter-spacing: -0.01em;
  line-height: 1.1;
}
.brand:hover { color: var(--color-fg); }

/* Club name over the school name. The second line carries the same colour as the
   club name — the smaller size and lighter weight already set the hierarchy, so
   dimming it too made it read as greyed-out rather than secondary. Matches the
   footer lockup, which has always used the full-strength colour for both lines. */
.brand-text { display: flex; flex-direction: column; }
.brand-text small {
  font-family: var(--font-display);
  font-size: 0.8125rem;
  font-weight: 400;
  letter-spacing: 0.01em;
  color: var(--color-fg);
  margin-top: 1px;
  white-space: nowrap;
}
/* Phone widths leave the brand ~180px between the logo and the menu button.
   Tightening the size and tracking keeps the school name on one line rather
   than wrapping and pushing the header taller. */
@media (max-width: 520px) {
  .brand-text small { font-size: 0.75rem; letter-spacing: 0; }
}

.brand-mark {
  width: 44px;
  height: 44px;
  flex: none;
  border-radius: var(--r-full);
  object-fit: cover;
  background: var(--violet-600);
  box-shadow: var(--shadow-sm);
}
.brand-mark-fallback { padding: 0; }


.nav-links {
  display: none;
  align-items: center;
  gap: var(--space-1);
  list-style: none;
  margin: 0;
  padding: 0;
}
.nav-links li { margin: 0; }

.nav-link {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 var(--space-3);
  border-radius: var(--r-sm);
  font-size: var(--text-sm);
  font-weight: 700;
  text-decoration: none;
  color: var(--color-fg-muted);
  transition: color var(--t-base) var(--ease), background var(--t-base) var(--ease);
}
.nav-link:hover { color: var(--color-primary-ink); background: var(--color-hover-wash); }
.nav-link[aria-current="page"] { color: var(--color-primary-ink); background: var(--color-surface); box-shadow: var(--shadow-sm); }

.nav-cta { display: none; }

.nav-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border: 1px solid var(--color-border);
  border-radius: var(--r-sm);
  background: var(--color-surface);
  color: var(--color-fg);
  cursor: pointer;
  transition: background var(--t-base) var(--ease);
}
.nav-toggle:hover { background: var(--color-surface-alt); }
.nav-toggle svg { width: 22px; height: 22px; }
.nav-toggle .icon-close { display: none; }
.nav-toggle[aria-expanded="true"] .icon-close { display: block; }
.nav-toggle[aria-expanded="true"] .icon-menu { display: none; }

.mobile-menu {
  display: none;
  padding-bottom: var(--space-6);
  border-top: 1px solid var(--color-border-soft);
}
.mobile-menu.is-open { display: block; }
.mobile-menu ul { list-style: none; margin: 0; padding: var(--space-2) 0 0; }
.mobile-menu li { margin: 0; }
.mobile-menu li a {
  display: block;
  padding: var(--space-3) var(--space-2);
  min-height: 48px;
  font-weight: 700;
  text-decoration: none;
  color: var(--color-fg);
  border-bottom: 1px solid var(--color-border-soft);
}
.mobile-menu li a[aria-current="page"] { color: var(--color-primary); }
.mobile-menu .btn { width: 100%; margin-top: var(--space-4); }

@media (min-width: 940px) {
  .nav-links, .nav-cta { display: flex; }
  .nav-toggle { display: none; }
  .mobile-menu { display: none !important; }
}

/* ---------- 6. Hero ---------- */
.hero {
  position: relative;
  overflow: hidden;
  padding-block: var(--space-16) var(--space-16);
  background:
    radial-gradient(1000px 480px at 82% -8%, var(--hero-glow-1), transparent 62%),
    radial-gradient(720px 420px at 6% 104%, var(--hero-glow-2), transparent 60%),
    var(--color-bg);
}
@media (min-width: 768px) {
  .hero { padding-block: var(--space-24); }
}

/* The helix is confined to the hero. The rail fills the hero box, and .hero's own
   overflow:hidden clips the part that hangs off the right edge, so nothing here
   needs to position or clip <main>. assets/js/main.js slides the drawing inside
   the rail as the hero scrolls away, which reads as rotation.

   Section content sits at z-index 2 (see `main > section > .container` below),
   so the hero text stays above this. */
/* Anchored to the right edge of the centred content column, NOT to the viewport
   edge. With `right: -6%` the helix drifted further from the text every time the
   window got wider, ending up pinned to the far edge of a full-screen display.
   Tying it to the column keeps the same gap from the hero text at any width.

   The 157px is the offset that reproduces the old `right: -6%` at a 1280px
   window, which is where the spacing looked right; expressing it against the
   column instead of the viewport freezes that same spacing at every width.
   Below the column's max width the calc goes negative on its own, so the helix
   bleeds off the right the way it used to on smaller screens. */
.helix-rail {
  position: absolute;
  inset-block: 0;
  right: calc(50% - var(--wrap) / 2 - 157px);
  width: min(560px, 52%);
  pointer-events: none;
}
@media (max-width: 767px) { .helix-rail { right: -28%; } }

.hero-helix {
  width: 100%;
  height: 100%;
  color: var(--green-500);
  opacity: 0.16;
}
@media (max-width: 767px) { .hero-helix { opacity: 0.09; } }

/* Section content clears the helix rail. */
main > section > .container { position: relative; z-index: 2; }

.hero-inner { max-width: 68ch; }

.hero h1 { font-size: var(--text-hero); margin-bottom: var(--space-6); }
.hero h1 .accent { color: var(--color-primary); display: block; }

.hero-lede {
  font-size: var(--text-lg);
  color: var(--color-fg-muted);
  max-width: 56ch;
  margin-bottom: var(--space-4);
}

/* Continuation of the club description — a step down from the lede so the
   opening sentences still lead. */
.hero-body {
  font-size: var(--text-base);
  color: var(--color-fg-muted);
  max-width: 62ch;
  margin-bottom: var(--space-8);
}

.badge-row { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-6); }

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-1) var(--space-3);
  border-radius: var(--r-full);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  font-size: var(--text-xs);
  font-weight: 700;
  color: var(--color-primary-ink);
  box-shadow: var(--shadow-sm);
}
.badge svg { width: 14px; height: 14px; }
.badge-accent { background: var(--chip-accent-bg); border-color: var(--amber-500); color: var(--chip-accent-fg); }
.badge-violet { background: var(--chip-violet-bg); border-color: rgba(216,180,254,.4); color: var(--chip-violet-fg); }

/* Page hero (interior pages) */
.page-hero {
  position: relative;
  padding-block: var(--space-12);
  background:
    radial-gradient(900px 400px at 88% 0%, var(--hero-glow-1), transparent 60%),
    var(--color-bg);
}
@media (min-width: 768px) { .page-hero { padding-block: var(--space-16); } }
/* Decorative motif behind a page hero. Each page draws its own artwork from what
   that page is about: a gel on Activities, answer bubbles on USABO, a node
   network on Our Team, dividing cells on Join Us.

   The wrapper carries its own overflow:hidden rather than putting `overflow` on
   .page-hero, which every page uses. Section content sits at z-index 2 (see
   `main > section > .container`), so the motif stays behind it. */
.hero-motif {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}
.hero-motif svg {
  width: 100%;
  height: 100%;
  color: var(--green-500);
  opacity: 0.17;
  /* Cleared through the middle so centred titles never read over the artwork. */
  -webkit-mask-image: linear-gradient(90deg, #000 0%, transparent 32%, transparent 68%, #000 100%);
          mask-image: linear-gradient(90deg, #000 0%, transparent 32%, transparent 68%, #000 100%);
}

/* Gel (Activities) */
.hero-motif .gel-lane { stroke: currentColor; stroke-width: 0.75; opacity: 0.35; fill: none; }
.hero-motif .gel-well { opacity: 0.5; }

/* Answer bubbles (USABO), node network (Our Team), dividing cells (Join Us).
   All three are outlines with selected shapes filled, so one rule covers them. */
.hero-motif .motif-line {
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}
.hero-motif .motif-edge { stroke-width: 1.25; opacity: 0.45; }

/* Narrow screens crop the motif to its centre, which the mask would erase, so
   the mask is dropped and the whole thing dimmed instead. */
@media (max-width: 767px) {
  .hero-motif svg {
    opacity: 0.08;
    -webkit-mask-image: none;
            mask-image: none;
  }
}

/* Join Us reads as one unit: title then tiles. The usual hero-bottom plus
   section-top stack leaves them looking disconnected. */
.page-hero.is-tight-bottom { padding-bottom: var(--space-6); }
.section.is-tight-top { padding-top: var(--space-6); }
@media (min-width: 768px) {
  .page-hero.is-tight-bottom { padding-bottom: var(--space-8); }
  .section.is-tight-top { padding-top: var(--space-8); }
}

.page-hero h1 { margin-bottom: var(--space-4); }
.page-hero .lede { margin-bottom: 0; }

/* Photo-backed hero band */
.photo-hero {
  position: relative;
  min-height: 260px;
  display: grid;
  place-items: center;
  text-align: center;
  padding: var(--space-16) var(--space-6);
  background: var(--green-950);
  overflow: hidden;
}
.photo-hero .photo-hero-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0.42;
}
.photo-hero::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(11, 46, 28, 0.55), rgba(11, 46, 28, 0.78));
}
.photo-hero > .photo-hero-inner { position: relative; z-index: 2; }
.photo-hero h1 { color: var(--amber-500); font-size: var(--text-3xl); margin-bottom: var(--space-3); }
.photo-hero p { color: rgba(255, 255, 255, 0.9); max-width: 56ch; margin-inline: auto; }

/* ---------- 7. Cards ---------- */
.card {
  position: relative;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--r-lg);
  padding: var(--space-6);
  box-shadow: var(--shadow-sm);
  transition: transform var(--t-base) var(--ease), box-shadow var(--t-base) var(--ease), border-color var(--t-base) var(--ease);
}
.card h3 { margin-bottom: var(--space-2); }
.card p { color: var(--color-fg-muted); font-size: var(--text-sm); }

.card-link { text-decoration: none; color: inherit; display: block; }
.card-link:hover, .card-hover:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lg);
  border-color: var(--green-500);
  color: inherit;
}

.card-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  border-radius: var(--r-md);
  background: var(--color-surface-alt);
  color: var(--color-primary);
  margin-bottom: var(--space-4);
}
.card-icon svg { width: 24px; height: 24px; }
.card-icon.accent { background: var(--chip-accent-bg); color: var(--chip-accent-fg); }
.card-icon.violet { background: var(--chip-violet-bg); color: var(--chip-violet-fg); }

.card-more {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin-top: var(--space-4);
  font-size: var(--text-sm);
  font-weight: 700;
  color: var(--color-primary);
}
.card-more svg { width: 16px; height: 16px; transition: transform var(--t-base) var(--ease); }
.card-link:hover .card-more svg { transform: translateX(4px); }

/* ---------- 8. Bands ---------- */
.band {
  background: var(--color-surface);
  border-block: 1px solid var(--color-border-soft);
}
.band-alt { background: var(--color-surface-alt); }

.band-deep {
  background:
    radial-gradient(800px 400px at 90% 10%, rgba(34, 197, 94, 0.16), transparent 60%),
    var(--color-band);
  color: #fff;
}
.band-deep h2, .band-deep h3 { color: #fff; }
.band-deep p { color: rgba(255, 255, 255, 0.86); }
.band-deep .eyebrow { color: var(--green-500); }
.band-deep a:not(.btn) { color: var(--amber-500); }
.band-deep .lede { color: rgba(255, 255, 255, 0.86); }

.split {
  display: grid;
  gap: var(--space-8);
  align-items: center;
  grid-template-columns: 1fr;
}
@media (min-width: 900px) {
  .split { grid-template-columns: 1.15fr 0.85fr; gap: var(--space-12); }
  .split.reverse > :first-child { order: 2; }
}

.media-frame {
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--shadow-lg);
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
}
.media-frame img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }

/* Full-width banner variant — group shots are wide, so 4:3 would crop the
   people at the ends out of frame. The doubled class outranks the later
   `.media-frame.is-empty` rule, so the placeholder previews the true shape. */
.media-frame.media-frame-wide img { aspect-ratio: 16 / 7; }
.media-frame.media-frame-wide.is-empty { aspect-ratio: 16 / 7; }

.media-frame.is-empty {
  display: grid;
  place-items: center;
  aspect-ratio: 4 / 3;
  color: var(--color-fg-muted);
  font-size: var(--text-sm);
  text-align: center;
  padding: var(--space-6);
}

/* Drop-in placeholder captions: only visible while the real photo is missing. */
.placeholder-note { display: none; }
.is-empty > .placeholder-note { display: block; }
.placeholder-note code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.9em;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 4px;
  padding: 1px 5px;
}

/* ---------- 8b. Centred page title ---------- */
.page-hero-center { text-align: center; padding-block: var(--space-16); }
@media (min-width: 768px) { .page-hero-center { padding-block: var(--space-24); } }
.page-hero-center .lede { margin-inline: auto; }

.page-title-xl {
  font-size: var(--text-hero);
  margin: 0;
  letter-spacing: -0.02em;
  animation: titleIn 900ms var(--ease) both;
}
/* Accent rule grows out from the centre under the title. */
.page-title-xl::after {
  content: "";
  display: block;
  width: 0;
  height: 3px;
  margin: var(--space-6) auto 0;
  border-radius: 3px;
  background: linear-gradient(90deg, var(--green-500), var(--color-accent));
  animation: ruleGrow 1100ms var(--ease) 300ms both;
}
@keyframes titleIn {
  from { opacity: 0; transform: translateY(22px); }
  to   { opacity: 1; transform: none; }
}
@keyframes ruleGrow {
  from { width: 0; opacity: 0; }
  to   { width: 108px; opacity: 1; }
}

/* ---------- 9. Officers ----------
   Flex rather than grid so a final incomplete row centres itself,
   which is how the reference layout reads. */
.officer-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-12) var(--space-8);
}

.officer-card { width: 100%; }
@media (min-width: 560px) {
  .officer-card { width: calc((100% - var(--space-8)) / 2); }
}
@media (min-width: 900px) {
  .officer-card { width: calc((100% - 2 * var(--space-8)) / 3); }
}

/* Square photo, no card chrome — the photo itself is the object. */
.avatar {
  position: relative;
  width: 100%;
  aspect-ratio: 1;
  margin: 0 0 var(--space-4);
  background: linear-gradient(140deg, var(--green-600), var(--green-800));
  display: grid;
  place-items: center;
  overflow: hidden;
  border-radius: 3px;
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--t-base) var(--ease);
}

.avatar::before {
  content: attr(data-initials);
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 8vw, 4rem);
  font-weight: 700;
  color: #fff;
  letter-spacing: 0.02em;
}
.avatar img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center 22%;
}

/* Role sits above the name, both in the display face. */
/* The person leads the card, so the name is the heading and carries the size and
   the full-strength colour; the role sits under it as the supporting line. */
.officer-name {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.2;
  color: var(--color-fg);
  margin: 0;
}
.officer-role {
  font-family: var(--font-display);
  font-size: 1.0625rem;
  font-weight: 600;
  line-height: 1.25;
  color: var(--color-primary-ink);
  margin: var(--space-1) 0 0;
}
.officer-grade {
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 700;
  color: var(--color-fg-muted);
  margin: var(--space-4) 0 0;
}

/* ---------- 10. USABO components ---------- */
/* Exam breakdown bars */
.breakdown { display: grid; gap: var(--space-4); margin: 0; padding: 0; list-style: none; }
.breakdown li { margin: 0; }

.breakdown-row {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-2) var(--space-4);
  align-items: baseline;
  margin-bottom: var(--space-2);
}
.breakdown-label { font-weight: 700; font-size: var(--text-sm); }
.breakdown-value {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
  color: var(--color-primary);
  font-variant-numeric: tabular-nums;
}
.breakdown-track {
  height: 10px;
  border-radius: var(--r-full);
  background: var(--color-surface-alt);
  overflow: hidden;
  border: 1px solid var(--color-border);
}
.breakdown-fill {
  height: 100%;
  border-radius: var(--r-full);
  background: linear-gradient(90deg, var(--green-600), var(--green-500));
  width: 0;
  transition: width 1100ms var(--ease);
}
.breakdown li:nth-child(1) .breakdown-fill { background: linear-gradient(90deg, var(--green-800), var(--green-600)); }
.breakdown li:nth-child(2) .breakdown-fill { background: linear-gradient(90deg, var(--green-700), var(--green-500)); }

/* Award tiers */
.tier-list { display: grid; gap: var(--space-3); list-style: none; margin: 0; padding: 0; }
.tier {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-6);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-left: 5px solid var(--green-500);
  border-radius: var(--r-md);
  margin: 0;
  box-shadow: var(--shadow-sm);
}
.tier:nth-child(1) { border-left-color: var(--green-200); }
.tier:nth-child(2) { border-left-color: var(--green-500); }
.tier:nth-child(3) { border-left-color: var(--green-700); }
.tier:nth-child(4) { border-left-color: var(--amber-500); background: var(--chip-accent-bg); }
.tier-rank {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 700;
  white-space: nowrap;
  /* Wide enough for the longest rank ("Top 500") so every tier name starts on
     the same column instead of shifting row to row. */
  min-width: 8ch;
}
.tier-name { font-size: var(--text-sm); font-weight: 700; color: var(--color-fg-muted); }
.tier:nth-child(4) .tier-name { color: var(--chip-accent-fg); }

/* Pathway steps */
.pathway { display: grid; gap: var(--space-4); list-style: none; margin: 0; padding: 0; counter-reset: step; }
@media (min-width: 900px) { .pathway { grid-template-columns: repeat(4, 1fr); } }
.pathway li {
  position: relative;
  margin: 0;
  padding: var(--space-6);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
}
.pathway li::before {
  counter-increment: step;
  content: counter(step);
  display: grid;
  place-items: center;
  width: 34px; height: 34px;
  margin-bottom: var(--space-4);
  border-radius: var(--r-full);
  background: var(--color-primary);
  color: #fff;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.0625rem;
}
.pathway h3 { font-size: var(--text-lg); margin-bottom: var(--space-2); }
.pathway p { font-size: var(--text-sm); color: var(--color-fg-muted); }
.pathway .when {
  display: block;
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-accent);
  margin-bottom: var(--space-1);
}

/* Semifinalist roster */
.roster {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: var(--space-2);
  list-style: none;
  margin: 0;
  padding: 0;
}
.roster li {
  margin: 0;
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--r-md);
  font-size: var(--text-sm);
  font-weight: 700;
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.roster li svg { width: 15px; height: 15px; color: var(--color-primary); flex: none; }

.highlight-card {
  background: linear-gradient(140deg, var(--chip-accent-bg), var(--color-surface));
  border: 1px solid var(--amber-500);
  border-radius: var(--r-lg);
  padding: var(--space-8);
  box-shadow: var(--shadow-md);
}
.highlight-card .badge { background: var(--amber-400); color: var(--color-on-accent); border-color: var(--amber-600); }

/* Stat figures */
.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--space-6);
}
.stat { text-align: center; }
.stat-num {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 1.6rem + 2.6vw, 3.25rem);
  font-weight: 700;
  line-height: 1;
  color: var(--color-primary);
  font-variant-numeric: tabular-nums;
}
.band-deep .stat-num { color: var(--amber-500); }
.stat-label { font-size: var(--text-sm); color: var(--color-fg-muted); margin-top: var(--space-2); }
.band-deep .stat-label { color: rgba(255, 255, 255, 0.82); }

/* ---------- 10b. Exam content pie ---------- */
.pie-figure { margin: 0; }
.pie { width: 100%; height: auto; display: block; overflow: visible; }

/* Separators are the band colour, so the slices look cut out of the page. */
.pie-slices path {
  stroke: var(--color-surface-alt);
  stroke-width: 2.5;
}
/* Concentric rings sit the disc on the forest ground instead of floating on it. */
.pie-halo {
  fill: none;
  stroke: rgba(71, 184, 131, 0.16);
  stroke-width: 1.5;
}
.pie-halo-outer {
  stroke: rgba(71, 184, 131, 0.09);
  stroke-dasharray: 2 10;
  stroke-linecap: round;
}

.pie-item polyline {
  stroke-width: 1.6;
  stroke-linecap: round;
  opacity: 0.75;
}
.pie-name {
  font-family: var(--font-body);
  font-size: 17px;
  font-weight: 700;
  fill: var(--color-fg);
}
.pie-pct {
  font-family: var(--font-display);
  font-size: 22px;
  font-weight: 700;
}

/* ---- Scroll-triggered reveal ----
   The disc sweeps open clockwise, then each topic's label fades in at the
   moment the sweep clears its slice. Defaults are the finished state, so if
   the observer never fires (or motion is reduced) the chart just sits there
   fully drawn. */
.pie-wipe-arc { stroke-dashoffset: 0; }
.pie-figure.reveal .pie-wipe-arc { stroke-dashoffset: 534.07; }
/* Linear on purpose: at constant angular speed the --d delays below map
   straight onto each slice's share of the circle, so a label lands exactly
   when the sweep clears its wedge. */
.pie-figure.reveal.is-visible .pie-wipe-arc {
  animation: pieSweep 1200ms linear both;
}

.pie-figure.reveal .pie-item,
.pie-figure.reveal .pie-legend li { opacity: 0; }
.pie-figure.reveal.is-visible .pie-item,
.pie-figure.reveal.is-visible .pie-legend li {
  animation: pieLabelIn 520ms var(--ease) var(--d, 0ms) both;
}

@keyframes pieSweep {
  from { stroke-dashoffset: 534.07; }
  to   { stroke-dashoffset: 0; }
}
@keyframes pieLabelIn {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

/* Legend replaces the leader labels where the SVG gets too small to read. */
.pie-legend {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: var(--space-3) var(--space-6);
  list-style: none;
  margin: var(--space-8) 0 0;
  padding: 0;
  max-width: 620px;
  margin-inline: auto;
}
.pie-legend li {
  display: grid;
  grid-template-columns: 14px 1fr auto;
  align-items: center;
  gap: var(--space-3);
  margin: 0;
  font-size: var(--text-sm);
}
.pie-legend .swatch { width: 14px; height: 14px; border-radius: 4px; }
.pie-legend .legend-name { color: var(--color-fg); }
.pie-legend .legend-pct {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--text-base);
  color: var(--color-fg-muted);
  font-variant-numeric: tabular-nums;
}

/* Small screens: drop the leader lines, enlarge the pie, keep the legend. */
@media (max-width: 799px) {
  .pie-items { display: none; }
  .pie > g:first-of-type {
    transform: scale(1.42);
    transform-origin: 510px 290px;
    transform-box: view-box;
  }
}
@media (min-width: 800px) {
  .pie-legend { display: none; }
}

/* ---------- 10c. Plain name list ---------- */
.name-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: var(--space-3) var(--space-8);
  list-style: none;
  margin-inline: auto;
  margin-block: 0;
  padding: 0;
  max-width: 940px;
}
.name-list li {
  margin: 0;
  text-align: center;
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
  line-height: 1.4;
  color: var(--color-fg);
}

/* ---------- 10d. Uncropped photo frame ---------- */
/* Shows the whole image at its own aspect ratio — nothing cropped away. */
.media-frame.media-frame-full { background: transparent; border: 0; }
.media-frame.media-frame-full img {
  aspect-ratio: auto;
  height: auto;
  object-fit: contain;
  border-radius: var(--r-lg);
}
.media-frame.media-frame-full.is-empty { aspect-ratio: 16 / 7; }

/* ---------- 11. Books ---------- */
.book-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-6);
}
@media (min-width: 700px) { .book-grid { grid-template-columns: repeat(3, 1fr); } }

.book-card {
  display: flex;
  flex-direction: column;
  text-align: center;
  background: transparent;
  border: 0;
  padding: 0;
  transition: transform var(--t-base) var(--ease);
}
.book-card:hover { transform: translateY(-4px); }

.book-cover {
  position: relative;
  aspect-ratio: 3 / 4;
  border-radius: var(--r-sm);
  overflow: hidden;
  background: linear-gradient(150deg, var(--green-800), var(--green-950));
  display: grid;
  place-items: center;
  margin-bottom: var(--space-4);
  box-shadow: var(--shadow-md);
}
.book-cover img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.book-cover::before {
  content: attr(data-fallback);
  padding: var(--space-4);
  font-family: var(--font-display);
  font-size: var(--text-sm);
  font-weight: 700;
  color: rgba(255, 255, 255, 0.85);
  line-height: 1.3;
}
.book-title { font-size: var(--text-base); font-weight: 700; margin: 0; }
.book-note { font-size: var(--text-xs); color: var(--color-fg-muted); margin: 0; }
.book-order {
  display: inline-block;
  align-self: center;
  margin-bottom: var(--space-2);
  padding: 2px var(--space-2);
  border-radius: var(--r-full);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.book-order.start { background: var(--chip-brand-bg); color: var(--chip-brand-fg); }
.book-order.next { background: var(--chip-accent-bg); color: var(--chip-accent-fg); }
.book-order.advanced { background: var(--chip-violet-bg); color: var(--chip-violet-fg); }

/* ---------- 12. Activities ---------- */
.activity-card { display: flex; flex-direction: column; height: 100%; }
.activity-tags { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-top: var(--space-4); }
.tag {
  font-size: var(--text-xs);
  font-weight: 700;
  padding: 2px var(--space-3);
  border-radius: var(--r-full);
  background: var(--color-surface-alt);
  color: var(--color-primary-ink);
  border: 1px solid var(--color-border);
}

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

.gallery-item {
  position: relative;
  aspect-ratio: 4 / 3;
  border-radius: var(--r-md);
  overflow: hidden;
  border: 1px solid var(--color-border);
  background: var(--color-surface-alt);
  display: grid;
  place-items: center;
  padding: 0;
  cursor: pointer;
  color: var(--color-fg-muted);
  font-size: var(--text-xs);
  text-align: center;
  transition: transform var(--t-base) var(--ease), box-shadow var(--t-base) var(--ease);
}
.gallery-item:hover { transform: scale(1.02); box-shadow: var(--shadow-lg); }
.gallery-item img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.gallery-item .placeholder-note { padding: var(--space-4); }

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: none;
  place-items: center;
  padding: var(--space-6);
  background: rgba(11, 46, 28, 0.9);
  backdrop-filter: blur(6px);
}
.lightbox.is-open { display: grid; }
.lightbox img { max-width: min(1100px, 92vw); max-height: 86vh; border-radius: var(--r-md); box-shadow: var(--shadow-lg); }
.lightbox-close {
  position: absolute;
  top: var(--space-6);
  right: var(--space-6);
  width: 48px; height: 48px;
  border-radius: var(--r-full);
  border: 1px solid rgba(255, 255, 255, 0.35);
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
  cursor: pointer;
  display: grid;
  place-items: center;
}
.lightbox-close svg { width: 22px; height: 22px; }

/* ---------- 13a. Join tiles ---------- */
/* Three tiles, so it goes straight from one column to three — a two-column step
   would leave the third tile orphaned in a half-empty row. */
.join-tiles {
  display: grid;
  gap: var(--space-6);
  grid-template-columns: 1fr;
  max-width: 1040px;
  margin-inline: auto;
}
@media (min-width: 880px) {
  .join-tiles { grid-template-columns: repeat(3, 1fr); }
}

.join-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  min-height: 280px;
  padding: var(--space-12) var(--space-8);
  border-radius: var(--r-xl);
  text-decoration: none;
  text-align: center;
  color: #fff;
  box-shadow: var(--shadow-md);
  transition: transform var(--t-base) var(--ease), box-shadow var(--t-base) var(--ease);
}
.join-tile:hover {
  transform: translateY(-6px);
  box-shadow: var(--shadow-lg);
  color: #fff;
}

.join-tile-form {
  background: linear-gradient(145deg, var(--amber-500), var(--amber-700));
}
.join-tile-discord {
  background: linear-gradient(145deg, #6b7ce8, #4a58c4);
}
/* Instagram's brand ramp runs from the bottom-left corner, not top-down. */
.join-tile-instagram {
  background:
    radial-gradient(125% 125% at 12% 100%,
      #FEDA75 0%, #FA7E1E 24%, #D62976 52%, #962FBF 76%, #4F5BD5 100%);
}

.join-tile-icon {
  display: grid;
  place-items: center;
  width: 76px;
  height: 76px;
  border-radius: var(--r-full);
  background: rgba(255, 255, 255, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.3);
}
.join-tile-icon svg { width: 38px; height: 38px; }

.join-tile-title {
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 1.4rem + 1.2vw, 2.25rem);
  font-weight: 700;
  line-height: 1.15;
}

.join-tile-action {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--text-sm);
  font-weight: 700;
  padding: var(--space-2) var(--space-6);
  border-radius: var(--r-full);
  background: rgba(255, 255, 255, 0.18);
  border: 1px solid rgba(255, 255, 255, 0.35);
}
.join-tile-action svg { width: 16px; height: 16px; transition: transform var(--t-base) var(--ease); }
.join-tile:hover .join-tile-action svg { transform: translateX(4px); }

/* ---------- 12b. Alumni timeline ----------
   Each year is a marker on a continuous rail with its officers branching off,
   so the section reads as the club's history rather than a table. `--rail` is
   both the width of the year column and the x position of the rail, which keeps
   the dots centred on the line without any magic numbers. */
.alumni-roll {
  --rail: 6rem;
  position: relative;
  max-width: 640px;
  margin: var(--space-12) auto 0;
  display: grid;
  gap: var(--space-12);
}

/* Faded at both ends so the rail doesn't stop on a hard edge. */
.alumni-roll::before {
  content: "";
  position: absolute;
  left: var(--rail);
  top: 0.5em;
  bottom: 0.5em;
  width: 2px;
  margin-left: -1px;
  border-radius: 2px;
  background: linear-gradient(
    180deg,
    transparent,
    var(--color-border) 5%,
    var(--color-border) 95%,
    transparent
  );
}

.alumni-year {
  position: relative;
  display: grid;
  grid-template-columns: var(--rail) 1fr;
  align-items: start;
}

/* Marker dot, centred on the rail and aligned to the year label's first line.
   The ring is the band colour, so the dot reads as sitting on top of the rail. */
.alumni-year::before {
  content: "";
  position: absolute;
  left: var(--rail);
  top: 0.4em;
  width: 11px;
  height: 11px;
  margin-left: -5.5px;
  border-radius: var(--r-full);
  background: var(--color-accent);
  box-shadow:
    0 0 0 4px var(--color-surface-alt),
    0 0 14px rgba(245, 158, 11, 0.45);
}

.alumni-year-label {
  margin: 0;
  padding-right: var(--space-6);
  text-align: right;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--color-accent);
}

.alumni-list { list-style: none; margin: 0; padding: 0 0 0 var(--space-8); }
.alumni-list li {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-1) var(--space-4);
  margin: 0;
  padding-block: var(--space-3);
  border-bottom: 1px solid var(--color-border-soft);
}
.alumni-list li:first-child { padding-top: 0; }
.alumni-list li:last-child { border-bottom: 0; padding-bottom: 0; }

.alumni-name {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
  line-height: 1.25;
  color: var(--color-fg);
}
/* Pushed to the trailing edge so the roles form their own column. */
.alumni-role {
  margin-inline-start: auto;
  font-size: var(--text-sm);
  color: var(--color-fg-muted);
}

/* Phones: the rail moves to the far left and the year sits above its officers,
   so names get the full width instead of losing 6rem to a gutter. */
@media (max-width: 559px) {
  .alumni-roll { --rail: 0.4rem; gap: var(--space-8); }
  .alumni-year { grid-template-columns: 1fr; }
  .alumni-year-label {
    text-align: left;
    padding: 0 0 var(--space-3) var(--space-8);
  }
}

/* ---------- 13. Join / FAQ / steps ---------- */
.steps { display: grid; gap: var(--space-6); counter-reset: joinstep; list-style: none; margin: 0; padding: 0; }
@media (min-width: 800px) { .steps { grid-template-columns: repeat(3, 1fr); } }
.steps li {
  margin: 0;
  padding: var(--space-6);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-sm);
}
.steps li::before {
  counter-increment: joinstep;
  content: "Step " counter(joinstep);
  display: block;
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-accent);
  margin-bottom: var(--space-2);
}
.steps h3 { font-size: var(--text-lg); margin-bottom: var(--space-2); }
.steps p { font-size: var(--text-sm); color: var(--color-fg-muted); }

.cta-panel {
  text-align: center;
  padding: var(--space-12) var(--space-6);
  border-radius: var(--r-xl);
  background:
    radial-gradient(600px 300px at 50% 0%, rgba(34, 197, 94, 0.18), transparent 65%),
    var(--color-band);
  color: #fff;
  box-shadow: var(--shadow-lg);
}
.cta-panel h2 { color: #fff; }
.cta-panel p { color: rgba(255, 255, 255, 0.88); max-width: 52ch; margin-inline: auto; }
.cta-note { font-size: var(--text-xs); color: rgba(255, 255, 255, 0.7); margin-top: var(--space-4); }

.contact-grid { display: grid; gap: var(--space-4); grid-template-columns: 1fr; }
@media (min-width: 700px) { .contact-grid { grid-template-columns: repeat(3, 1fr); } }

.contact-card {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-6);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--r-lg);
  text-decoration: none;
  color: inherit;
  box-shadow: var(--shadow-sm);
  transition: transform var(--t-base) var(--ease), box-shadow var(--t-base) var(--ease), border-color var(--t-base) var(--ease);
}
.contact-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); border-color: var(--green-500); color: inherit; }
.contact-card .card-icon { margin-bottom: 0; }
.contact-label { font-size: var(--text-xs); text-transform: uppercase; letter-spacing: 0.08em; color: var(--color-fg-muted); font-weight: 700; }
.contact-value { font-weight: 700; font-size: var(--text-base); word-break: break-word; }

.faq { display: grid; gap: var(--space-3); }
.faq details {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}
.faq summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: 56px;
  padding: var(--space-4) var(--space-6);
  font-weight: 700;
  cursor: pointer;
  list-style: none;
  transition: background var(--t-base) var(--ease);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary:hover { background: var(--color-surface-alt); }
.faq summary::after {
  content: "";
  flex: none;
  width: 11px; height: 11px;
  border-right: 2.5px solid var(--color-primary);
  border-bottom: 2.5px solid var(--color-primary);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform var(--t-base) var(--ease-inout);
}
.faq details[open] summary::after { transform: rotate(-135deg) translate(-2px, -2px); }
.faq .faq-body { padding: 0 var(--space-6) var(--space-6); color: var(--color-fg-muted); font-size: var(--text-sm); }

/* ---------- 14. Announcements ---------- */
.announcements { display: grid; gap: var(--space-4); list-style: none; margin: 0; padding: 0; }
.announcement {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-4);
  align-items: start;
  margin: 0;
  padding: var(--space-5, 1.25rem) var(--space-6);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-sm);
}
.announcement-when {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--text-sm);
  color: var(--color-accent);
  white-space: nowrap;
  padding-top: 2px;
  min-width: 9ch;
}
.announcement-what { font-size: var(--text-sm); }
.announcement-what strong { display: block; font-size: var(--text-base); margin-bottom: 2px; }
.announcement-what span { color: var(--color-fg-muted); }

/* ---------- 15. Footer ---------- */
.site-footer {
  background: var(--color-footer-bg);
  color: rgba(255, 255, 255, 0.78);
  padding-block: var(--space-16) var(--space-8);
  font-size: var(--text-sm);
}
.footer-grid {
  display: grid;
  gap: var(--space-8);
  grid-template-columns: 1fr;
  padding-bottom: var(--space-8);
  border-bottom: 1px solid rgba(255, 255, 255, 0.12);
}
@media (min-width: 800px) { .footer-grid { grid-template-columns: 1.4fr 1fr 1fr; gap: var(--space-12); } }

.site-footer h4 {
  color: #fff;
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin-bottom: var(--space-4);
}
.site-footer ul { list-style: none; margin: 0; padding: 0; }
.site-footer li { margin-bottom: var(--space-2); }
.site-footer a { color: rgba(255, 255, 255, 0.78); text-decoration: none; }
.site-footer a:hover { color: var(--amber-500); text-decoration: underline; }

.footer-brand { display: inline-flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-4); }
.footer-brand .brand-mark { width: 52px; height: 52px; }
.footer-brand-name { font-family: var(--font-display); font-size: 1.375rem; font-weight: 700; color: #fff; line-height: 1.15; display: flex; flex-direction: column; }
/* School name under the club name — same serif and same white, set smaller so
   the club name stays the primary line. Mirrors the header lockup. */
.footer-brand-name small {
  font-family: var(--font-display);
  font-size: 0.8125rem;
  font-weight: 400;
  color: #fff;
  letter-spacing: 0.01em;
  margin-top: 2px;
}

.social-row { display: flex; gap: var(--space-3); margin-top: var(--space-4); }
.social-btn {
  display: inline-grid;
  place-items: center;
  width: 44px; height: 44px;
  border-radius: var(--r-full);
  border: 1px solid rgba(255, 255, 255, 0.22);
  background: rgba(255, 255, 255, 0.07);
  color: #fff;
  transition: background var(--t-base) var(--ease), transform var(--t-fast) var(--ease);
}
.social-btn:hover { background: rgba(255, 255, 255, 0.18); transform: translateY(-2px); color: #fff; }
.social-btn svg { width: 20px; height: 20px; }

.footer-bottom {
  padding-top: var(--space-6);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  justify-content: space-between;
  font-size: var(--text-xs);
  color: rgba(255, 255, 255, 0.55);
}

/* Fine print. Deliberately the smallest type on the site, but the colour is held
   at 0.42 alpha rather than dimmed further: any lower and it drops under the
   WCAG AA contrast the rest of the site is built to. */
/* flex-basis alone is not enough to force its own row: `ch` scales with the tiny
   font size, so a ch-based max-width shrinks the hypothetical size until it fits
   beside the copyright. Pinning the basis to 100% keeps it on its own line. */
.footer-note {
  flex: 0 0 100%;
  max-width: 100%;
  margin: 0;
  padding-top: var(--space-2);
  font-size: 0.625rem;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.42);
}

/* ---------- 16. Motion ---------- */
.reveal {
  opacity: 0;
  transform: translateY(16px) scale(0.99);
}
.reveal.is-visible {
  opacity: 1;
  transform: none;
  transition: opacity var(--t-slow) var(--ease), transform var(--t-slow) var(--ease);
  transition-delay: var(--reveal-delay, 0ms);
}

/* Officer cards travel further so the stagger reads as a wave across the
   grid rather than a flicker. */
.officer-card.reveal { transform: translateY(30px) scale(0.96); }
.officer-card.reveal.is-visible {
  transition: opacity 820ms var(--ease), transform 820ms var(--ease);
  transition-delay: var(--reveal-delay, 0ms);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .reveal, .officer-card.reveal { opacity: 1; transform: none; }
  .btn:hover, .card-hover:hover, .officer-card:hover, .book-card:hover, .gallery-item:hover { transform: none; }
  .page-title-xl { animation: none; }
  .page-title-xl::after { animation: none; width: 108px; opacity: 1; }
  /* The pie's stagger is delay-driven, and the global duration override above
     doesn't touch delays — cancel the animations outright so the finished
     chart is there immediately. */
  .pie-figure.reveal .pie-wipe-arc,
  .pie-figure.reveal.is-visible .pie-wipe-arc { animation: none; stroke-dashoffset: 0; }
  .pie-figure.reveal .pie-item,
  .pie-figure.reveal .pie-legend li,
  .pie-figure.reveal.is-visible .pie-item,
  .pie-figure.reveal.is-visible .pie-legend li { animation: none; opacity: 1; transform: none; }
}

/* ---------- 17. Utilities ---------- */
.mt-0 { margin-top: 0; }
.mt-6 { margin-top: var(--space-6); }
.mt-8 { margin-top: var(--space-8); }
.mb-0 { margin-bottom: 0; }
.mb-6 { margin-bottom: var(--space-6); }
.text-center { text-align: center; }
.text-sm { font-size: var(--text-sm); }
.text-muted { color: var(--color-fg-muted); }
.note {
  font-size: var(--text-xs);
  color: var(--color-fg-muted);
  font-style: italic;
}
