/* ==========================================================================
   DBPC Alumni Portal — Mission 17B, Phase 1: Design System Foundation
   --------------------------------------------------------------------------
   Reusable, OPT-IN UI foundation for the Revolut-inspired redesign.

   Scope (per docs/design/17B-redesign-spec.md):
     - role-based design tokens (surfaces / text / borders / accents / shadows)
     - dark theme default + light theme via [data-theme="light"]
     - glass / Mica / Acrylic effect tokens + utilities
     - adaptive performance (reduced motion, low-effect fallbacks, no-backdrop)
     - reusable component base classes (cards / tables / forms / buttons)

   IMPORTANT — this file does NOT redesign existing pages.
   It only declares custom properties (inert until consumed) and NEW class
   selectors. No legacy selector (.card, .navbar, body, .table, ...) is
   touched, so every current page renders identically. Pages adopt these
   utilities in later 17B phases. Loaded after app.css so it may reuse the
   --space-*, --radius-*, and --font-* tokens defined there.
   ========================================================================== */

/* Editorial serif for heritage/storytelling moments (Mission 19.2). Loaded
   here so the brand layer owns the typeface; functional UI stays sans-serif. */
@import url("https://fonts.googleapis.com/css2?family=Newsreader:ital,opsz,wght@0,6..72,400;0,6..72,500;0,6..72,600;0,6..72,700;1,6..72,400;1,6..72,500&display=swap");

/* ---- Brand identity (Mission 19.1) ------------------------------------- */
/* Raw heritage palette — the single source of truth for the DBPC identity.
   Role tokens below map to these per theme. Navy is the institutional anchor;
   gold is the ceremonial accent (used sparingly); paper/ink/stone are the
   warm-archival neutrals. Purple/blue are removed as the brand identity. */
:root {
  --brand-navy: #0E2A47;     /* primary identity — authority, school depth   */
  --brand-gold: #C8A24B;     /* ceremonial accent — legacy, recognition      */
  --brand-ink: #0B1520;      /* dark-theme base — depth, premium readability */
  --brand-paper: #FAF7F1;    /* light-theme base — warm archive, not white   */
  --brand-stone: #D8D0C2;    /* secondary surfaces / borders — heritage      */
  --brand-maroon: #6F1D1B;   /* solemn/ceremonial highlight (sparing)        */
  --brand-ash: #6B7280;      /* memorial restraint                           */
  --brand-orange: #E2542C;   /* Park Circus Unit accent (from the logo band) */

  /* Typeface roles (Mission 19.2) — editorial serif display + sans UI.
     --font-heading / --font-body are defined in app.css; we keep them for
     functional UI and add a serif display face for heritage moments. */
  --font-display: "Newsreader", Georgia, "Times New Roman", "Source Serif 4", serif;
  --font-ui: var(--font-body);
}

/* ---- Theme tokens: DARK (default) — ceremonial ink + navy + gold -------- */
:root {
  color-scheme: dark;

  /* Surfaces — ink base, navy-tinted raised panels */
  --surface-base: var(--brand-ink);   /* #0B1520 page background             */
  --surface-raised: #122236;          /* cards, panels (navy ink)            */
  --surface-overlay: #18304C;         /* dropdowns, popovers, modals (navy)  */
  --surface-sunken: #070E18;          /* wells, insets (deep ink)            */

  /* Text / foreground — warm off-white, not clinical white */
  --fg: #F1ECE1;
  --fg-muted: #B7C0CC;
  --fg-subtle: #87919F;
  --fg-on-accent: var(--brand-ink);   /* ink text reads on gold actions      */

  /* Borders — warm stone, low alpha */
  --border-subtle: rgba(216, 208, 194, 0.08);
  --border: rgba(216, 208, 194, 0.16);
  --border-strong: rgba(216, 208, 194, 0.28);

  /* Accents — gold is the visible ceremonial accent on ink;
     a restrained institutional steel-blue is the quiet secondary/info tone. */
  --accent: var(--brand-gold);        /* #C8A24B                             */
  --accent-strong: #B58B36;           /* deeper gold for hover / primary bg  */
  --accent-soft: rgba(200, 162, 75, 0.16);
  --accent-2: #6E93B8;                /* restrained steel-blue secondary     */
  --accent-2-strong: #4F77A0;

  /* Semantic — restrained, institutional (not neon) */
  --success: #4E8D6B;
  --warning: #C9952F;
  --danger: #B4453E;
  --info: #6E93B8;

  /* Elevation — deep, neutral shadows; subtle gold-tinted glow */
  --shadow-1: 0 1px 2px rgba(0, 0, 0, 0.50);
  --shadow-2: 0 6px 20px rgba(0, 0, 0, 0.50);
  --shadow-3: 0 18px 50px rgba(0, 0, 0, 0.60);
  --shadow-glow: 0 0 0 1px var(--accent-soft), 0 8px 30px rgba(200, 162, 75, 0.22);

  /* Glass / Mica / Acrylic — navy-tinted translucency */
  --glass-bg: rgba(18, 34, 54, 0.55);
  --glass-border: rgba(216, 208, 194, 0.14);
  --glass-blur: 16px;
  --glass-saturate: 130%;

  --mica-bg: rgba(11, 21, 32, 0.80);
  --mica-border: rgba(216, 208, 194, 0.08);
  --mica-blur: 30px;

  --acrylic-bg: rgba(20, 38, 60, 0.72);
  --acrylic-border: rgba(216, 208, 194, 0.14);
  --acrylic-blur: 24px;

  /* Opaque fallbacks used when backdrop-filter is unsupported or perf is low */
  --glass-solid: #13243B;
  --mica-solid: #0E1B2B;
  --acrylic-solid: #18304C;

  /* Motion */
  --motion-fast: 0.15s;
  --motion: 0.28s;
  --motion-slow: 0.5s;
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
}

/* ---- Theme tokens: LIGHT ([data-theme="light"]) — warm archival paper --- */
[data-theme="light"] {
  color-scheme: light;

  /* Surfaces — warm paper base, warm near-white panels (never clinical white) */
  --surface-base: var(--brand-paper);   /* #FAF7F1                            */
  --surface-raised: #FFFDF8;             /* cards on paper                     */
  --surface-overlay: #FFFDF8;            /* dropdowns, popovers, modals        */
  --surface-sunken: #F1EBDF;             /* wells, insets (paper/stone)        */

  /* Text / foreground — navy ink on paper */
  --fg: var(--brand-navy);               /* #0E2A47                           */
  --fg-muted: #44566B;
  --fg-subtle: #6B7888;
  --fg-on-accent: var(--brand-paper);    /* paper text reads on navy actions  */

  /* Borders — navy-tinted hairlines (stone available as --brand-stone) */
  --border-subtle: rgba(14, 42, 71, 0.07);
  --border: rgba(14, 42, 71, 0.14);
  --border-strong: rgba(14, 42, 71, 0.26);

  /* Accents — navy is the primary interactive colour on paper;
     gold is the ceremonial secondary (used sparingly). */
  --accent: var(--brand-navy);           /* #0E2A47                           */
  --accent-strong: #0A2038;              /* darker navy for hover / primary bg */
  --accent-soft: rgba(14, 42, 71, 0.10);
  --accent-2: var(--brand-gold);         /* ceremonial gold                    */
  --accent-2-strong: #A8842F;

  /* Semantic — restrained, warm */
  --success: #2E7D55;
  --warning: #B07A1E;
  --danger: #9B3A33;
  --info: #3E6E97;

  /* Elevation — soft, warm shadows; quiet navy glow */
  --shadow-1: 0 1px 2px rgba(14, 42, 71, 0.08);
  --shadow-2: 0 8px 24px rgba(14, 42, 71, 0.10);
  --shadow-3: 0 20px 50px rgba(14, 42, 71, 0.14);
  --shadow-glow: 0 0 0 1px var(--accent-soft), 0 10px 30px rgba(14, 42, 71, 0.12);

  /* Glass / Mica / Acrylic — warm paper translucency */
  --glass-bg: rgba(255, 253, 248, 0.62);
  --glass-border: rgba(14, 42, 71, 0.10);

  --mica-bg: rgba(250, 247, 241, 0.85);
  --mica-border: rgba(14, 42, 71, 0.06);

  --acrylic-bg: rgba(255, 253, 248, 0.80);
  --acrylic-border: rgba(14, 42, 71, 0.10);

  --glass-solid: #FFFDF8;
  --mica-solid: #F4EEE3;
  --acrylic-solid: #FFFDF8;
}

/* ==========================================================================
   Surface effect utilities — glass / Mica / Acrylic
   ========================================================================== */
.glass-card {
  background: var(--glass-bg);
  border: 1px solid var(--glass-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-2);
  color: var(--fg);
  padding: var(--space-24);
  -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
}

.mica-surface {
  background: var(--mica-bg);
  border: 1px solid var(--mica-border);
  color: var(--fg);
  -webkit-backdrop-filter: blur(var(--mica-blur)) saturate(120%);
  backdrop-filter: blur(var(--mica-blur)) saturate(120%);
}

.acrylic-panel {
  background: var(--acrylic-bg);
  border: 1px solid var(--acrylic-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-3);
  color: var(--fg);
  -webkit-backdrop-filter: blur(var(--acrylic-blur)) saturate(150%);
  backdrop-filter: blur(var(--acrylic-blur)) saturate(150%);
}

/* ==========================================================================
   Modern component base styles (token-driven; no hardcoded colors)
   ========================================================================== */

/* Dashboard shell surface */
.dashboard-surface {
  background: var(--surface-base);
  color: var(--fg);
  border-radius: var(--radius-lg);
  padding: var(--space-24);
}

/* Modern card */
.card-modern {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-1);
  color: var(--fg);
  overflow: hidden;
  transition: transform var(--motion-fast) var(--ease),
              box-shadow var(--motion-fast) var(--ease),
              border-color var(--motion-fast) var(--ease);
}
.card-modern:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-2);
  border-color: var(--border-strong);
}
.card-modern__header {
  padding: var(--space-16) var(--space-24);
  border-bottom: 1px solid var(--border-subtle);
}
.card-modern__body { padding: var(--space-24); }

/* Modern table (real data table — not a layout table) */
.table-modern {
  width: 100%;
  border-collapse: collapse;
  color: var(--fg);
  background: var(--surface-raised);
  border-radius: var(--radius-md);
  overflow: hidden;
}
.table-modern thead th {
  text-align: left;
  font-size: var(--text-small);
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--fg-subtle);
  background: var(--surface-overlay);
  padding: var(--space-12) var(--space-16);
  border-bottom: 1px solid var(--border);
}
.table-modern tbody td {
  padding: var(--space-12) var(--space-16);
  border-bottom: 1px solid var(--border-subtle);
}
.table-modern tbody tr { transition: background var(--motion-fast) var(--ease); }
.table-modern tbody tr:hover { background: var(--accent-soft); }
.table-modern tbody tr:last-child td { border-bottom: none; }

/* Mission 26.2 — "Continue as Guest" block below the login form, separated by a
   hairline rule. Reuses existing button styles; no inline CSS. */
.login-guest {
  margin-top: var(--space-24);
  padding-top: var(--space-24);
  border-top: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-12);
}
.login-guest__note { margin: 0; color: var(--fg-muted); }

/* Modern form controls (scoped to .form-modern so legacy forms are untouched) */
.form-modern .field-modern { margin-bottom: var(--space-24); }
.form-modern .label-modern {
  display: block;
  font-weight: 600;
  margin-bottom: var(--space-8);
  color: var(--fg);
}
.form-modern .input-modern,
.form-modern .select-modern,
.form-modern .textarea-modern {
  width: 100%;
  min-height: 44px;
  padding: var(--space-12) var(--space-16);
  font: inherit;
  color: var(--fg);
  background: var(--surface-sunken);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  transition: border-color var(--motion-fast) var(--ease),
              box-shadow var(--motion-fast) var(--ease);
}
.form-modern .input-modern::placeholder { color: var(--fg-subtle); }
.form-modern .input-modern:focus,
.form-modern .select-modern:focus,
.form-modern .textarea-modern:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accent-soft);
}
.form-modern .textarea-modern { min-height: 120px; }

/* ==========================================================================
   Animated button
   ========================================================================== */
.btn-animated {
  --btn-bg: var(--accent-strong);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-8);
  min-height: 44px;
  padding: var(--space-12) var(--space-24);
  font-family: var(--font-body);
  font-weight: 600;
  color: var(--fg-on-accent);
  background: var(--btn-bg);
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  text-decoration: none;
  cursor: pointer;
  transition: transform var(--motion-fast) var(--ease),
              box-shadow var(--motion-fast) var(--ease),
              filter var(--motion-fast) var(--ease);
}
.btn-animated:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-glow);
  filter: brightness(1.06);
}
.btn-animated:active { transform: translateY(0) scale(0.98); }
.btn-animated--ghost {
  --btn-bg: transparent;
  color: var(--fg);
  border-color: var(--border-strong);
}
.btn-animated--secondary { --btn-bg: var(--accent-2-strong); }
/* Arrow that slides on hover (paired with text, e.g. CTA links) */
.btn-animated__arrow {
  display: inline-block;
  transition: transform var(--motion-fast) var(--ease);
}
.btn-animated:hover .btn-animated__arrow { transform: translateX(4px); }

/* ==========================================================================
   Theme toggle button
   ========================================================================== */
.theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  color: var(--fg);
  background: var(--surface-raised);
  border: 1px solid var(--border);
  border-radius: var(--radius-full);
  cursor: pointer;
  transition: background var(--motion-fast) var(--ease),
              border-color var(--motion-fast) var(--ease),
              transform var(--motion-fast) var(--ease);
}
.theme-toggle:hover { border-color: var(--accent); transform: translateY(-1px); }
.theme-toggle__icon { line-height: 1; font-size: var(--text-body-lg); }
/* Show the icon for the action available in the CURRENT theme:
   dark theme -> offer "switch to light" (sun); light theme -> moon. */
.theme-toggle__icon--to-light { display: inline; }
.theme-toggle__icon--to-dark { display: none; }
[data-theme="light"] .theme-toggle__icon--to-light { display: none; }
[data-theme="light"] .theme-toggle__icon--to-dark { display: inline; }

/* ==========================================================================
   Reveal-on-scroll animation (progressive enhancement)
   Content is always visible without JS; only hidden once the runtime marks
   the document as JS-capable (html.js), then revealed by IntersectionObserver.
   ========================================================================== */
.js .reveal {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity var(--motion) var(--ease),
              transform var(--motion) var(--ease);
  will-change: opacity, transform;
}
.js .reveal.is-visible { opacity: 1; transform: none; }
.reveal--up { --reveal-from: translateY(24px); }
.reveal--left { --reveal-from: translateX(24px); }
.reveal--right { --reveal-from: translateX(-24px); }
.js .reveal--up,
.js .reveal--left,
.js .reveal--right { transform: var(--reveal-from); }

/* ==========================================================================
   Adaptive performance & accessibility
   - .perf-low / .low-effects : strip expensive effects, keep all content
   - .no-backdrop             : backdrop-filter unsupported (added by runtime)
   - @supports fallback        : opaque surfaces when backdrop-filter missing
   - prefers-reduced-motion    : neutralize new-layer motion
   ========================================================================== */

/* Opaque fallback when the browser lacks backdrop-filter support. */
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .glass-card { background: var(--glass-solid); }
  .mica-surface { background: var(--mica-solid); }
  .acrylic-panel { background: var(--acrylic-solid); }
}

/* Runtime-detected fallback (older engines that mis-report @supports). */
.no-backdrop .glass-card { background: var(--glass-solid); }
.no-backdrop .mica-surface { background: var(--mica-solid); }
.no-backdrop .acrylic-panel { background: var(--acrylic-solid); }

/* Low-effort mode: weak devices, Save-Data, or opt-in via .low-effects.
   Drops blur and heavy shadows; preserves layout, color, and all features. */
.perf-low .glass-card,
.perf-low .mica-surface,
.perf-low .acrylic-panel,
.low-effects .glass-card,
.low-effects .mica-surface,
.low-effects .acrylic-panel {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
.perf-low .glass-card,
.low-effects .glass-card { background: var(--glass-solid); box-shadow: var(--shadow-1); }
.perf-low .mica-surface,
.low-effects .mica-surface { background: var(--mica-solid); }
.perf-low .acrylic-panel,
.low-effects .acrylic-panel { background: var(--acrylic-solid); box-shadow: var(--shadow-2); }
.perf-low .card-modern,
.low-effects .card-modern { transition: none; }
.perf-low .card-modern:hover,
.low-effects .card-modern:hover { transform: none; box-shadow: var(--shadow-1); }
.perf-low .reveal,
.low-effects .reveal {
  opacity: 1 !important;
  transform: none !important;
  transition: none !important;
}

/* ==========================================================================
   Mission 17B Phase 2 — navigation surface theming
   Activates ONLY when a navigation surface opts into a Mica/Acrylic utility.
   Makes the chrome's text/links theme-aware (legible in dark default AND
   light) without touching page content or non-navigation elements.
   ========================================================================== */

/* Public / portal top navbar (Mica). Keep sticky positioning from app.css. */
.navbar.mica-surface {
  border: none;
  border-bottom: 1px solid var(--border);
}
.navbar.mica-surface .navbar__brand { color: var(--fg); }
.navbar.mica-surface .navbar__links a { color: var(--fg-muted); }
.navbar.mica-surface .navbar__links a:hover { color: var(--fg); }
.navbar.mica-surface .navbar__links a[aria-current="page"] {
  color: var(--accent);
  font-weight: 600;
}
.navbar.mica-surface .navbar__toggle,
.navbar.mica-surface .btn--icon,
.navbar.mica-surface .account-menu__summary { color: var(--fg); }

/* Theme toggle sits in the navbar action cluster. */
.navbar__cta .theme-toggle { background: transparent; }

/* Off-canvas mobile drawer (Acrylic — floating navigation). */
.drawer__panel.acrylic-panel {
  border-radius: 0;
  border: none;
  border-inline-end: 1px solid var(--border);
}
.drawer__panel.acrylic-panel a { color: var(--fg); }
.drawer__panel.acrylic-panel a:hover { background: var(--accent-soft); color: var(--fg); }
.drawer__panel.acrylic-panel .drawer__divider { border-top-color: var(--border); }

/* Public navbar "More" mega-menu (native <details>; Acrylic floating panel). */
.has-megamenu { position: relative; display: flex; align-items: center; }
.megamenu { position: relative; }
.megamenu__summary {
  list-style: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-8) var(--space-12);
  border-radius: var(--radius-md);
  color: var(--fg-muted);
}
.megamenu__summary::-webkit-details-marker { display: none; }
.megamenu__summary::marker { content: ""; }
.megamenu__summary:hover { color: var(--fg); }
.megamenu[open] > .megamenu__summary { color: var(--fg); }
.megamenu__caret { transition: transform var(--motion-fast) var(--ease); }
.megamenu[open] > .megamenu__summary .megamenu__caret { transform: rotate(180deg); }
.megamenu__panel {
  position: absolute;
  inset-inline-end: 0;
  top: calc(100% + var(--space-8));
  z-index: 120;
  display: grid;
  grid-template-columns: repeat(2, minmax(180px, 1fr));
  gap: var(--space-16) var(--space-24);
  min-width: 440px;
  padding: var(--space-16);
}
.megamenu__heading {
  margin: 0 0 var(--space-8);
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--fg-subtle);
}
.megamenu__panel ul { list-style: none; margin: 0; padding: 0; }
.megamenu__panel li { margin: 0; }
.megamenu__panel a {
  display: block;
  padding: var(--space-8) var(--space-12);
  border-radius: var(--radius-sm);
  text-decoration: none;
}
.megamenu__panel a:hover { background: var(--accent-soft); }

/* Admin sidebar (Mica). Already light-on-dark, so only soften the surface. */
.sidebar.mica-surface { border-inline-end: 1px solid var(--border); }
.sidebar__top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-8);
}

/* ==========================================================================
   Mission 17B Phase 3 — public homepage hero carousel
   Near-full-screen premium hero. Slides cross-fade; text sits in a glass
   panel for legibility over any gradient. Token-driven (dark + light),
   responsive, and reduced-motion aware. No real photography required yet.
   ========================================================================== */
.hero-carousel {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  min-height: clamp(520px, 82vh, 820px);
  background: var(--surface-base);
  color: var(--fg);
}
.hero-carousel:focus-visible { outline: none; box-shadow: var(--focus-ring); }
.hero-carousel__viewport { position: absolute; inset: 0; }

.hero-slide {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--motion-slow) var(--ease);
}
.hero-slide.is-active { opacity: 1; visibility: visible; }

/* Gradient backdrops composed from tokens (no fixed colors, theme-aware). */
.hero-slide__bg { position: absolute; inset: 0; z-index: -1; }
.hero-slide__bg--a {
  background:
    radial-gradient(120% 90% at 15% 10%, var(--accent-soft), transparent 60%),
    linear-gradient(135deg, var(--surface-sunken), var(--accent-strong));
}
.hero-slide__bg--b {
  background:
    radial-gradient(120% 90% at 85% 15%, var(--accent-soft), transparent 60%),
    linear-gradient(135deg, var(--surface-sunken), var(--accent-2-strong));
}
.hero-slide__bg--c {
  background:
    radial-gradient(110% 90% at 50% 0%, var(--accent-soft), transparent 55%),
    linear-gradient(135deg, var(--accent-strong), var(--accent-2-strong));
}

.hero-slide__inner { width: 100%; }
.hero-slide__content {
  /* Width/proportions live in the hero-layout block below (Mission 22.1.4);
     .hero-slide__panel supplies the frosted bg/blur/border/padding. */
  width: min(660px, 100%);
}
.hero-slide__eyebrow {
  margin: 0 0 var(--space-8);
  font-size: var(--text-small);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
}
.hero-slide__title {
  margin: 0 0 var(--space-16);
  font-family: var(--font-heading);
  font-weight: 700;
  line-height: 1.1;
  color: var(--fg);
  font-size: clamp(2rem, 5vw, var(--text-display));
}
.hero-slide__subtitle {
  margin: 0 0 var(--space-24);
  max-width: 52ch;
  font-size: var(--text-body-lg);
  color: var(--fg-muted);
}
.hero-slide__cta { gap: var(--space-12); }

/* Manual previous / next controls (Acrylic floating buttons). */
.hero-carousel__arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 3;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  padding: 0;
  font-size: var(--text-h2);
  line-height: 1;
  color: var(--fg);
  cursor: pointer;
  border-radius: var(--radius-full);
}
.hero-carousel__arrow:hover { color: var(--accent); }
.hero-carousel__arrow--prev { inset-inline-start: var(--space-16); }
.hero-carousel__arrow--next { inset-inline-end: var(--space-16); }

/* Progress indicators. */
.hero-carousel__dots {
  position: absolute;
  inset-inline: 0;
  bottom: var(--space-24);
  z-index: 3;
  display: flex;
  justify-content: center;
  gap: var(--space-8);
}
.hero-carousel__dot {
  width: 12px;
  height: 12px;
  padding: 0;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-full);
  background: var(--surface-overlay);
  cursor: pointer;
  transition: background var(--motion-fast) var(--ease),
              transform var(--motion-fast) var(--ease);
}
.hero-carousel__dot:hover { transform: scale(1.15); }
.hero-carousel__dot.is-active,
.hero-carousel__dot[aria-pressed="true"] {
  background: var(--accent);
  border-color: var(--accent);
}

@media (max-width: 767px) {
  .hero-carousel { min-height: clamp(460px, 78vh, 680px); }
  .hero-slide { align-items: flex-end; }
  .hero-slide__inner { padding-bottom: var(--space-64); }
  .hero-carousel__arrow { width: 40px; height: 40px; font-size: var(--text-h3); }
  .hero-carousel__arrow--prev { inset-inline-start: var(--space-8); }
  .hero-carousel__arrow--next { inset-inline-end: var(--space-8); }
}

/* ==========================================================================
   Mission 17B Phase 4 — homepage below-hero sections
   The .home-modern wrapper carries the theme onto the homepage content so the
   modernized sections read correctly in dark (default) AND light. Scoped to
   the homepage only; no other page or global element is affected.
   ========================================================================== */
.home-modern { background: var(--surface-base); color: var(--fg); }
.home-modern h2,
.home-modern h3,
.home-modern h4 { color: var(--fg); }
.home-modern .lead { color: var(--fg-muted); }
.home-modern .note { color: var(--fg-subtle); }
.home-modern .section--muted { background: var(--surface-sunken); }
.home-modern .stat__num { color: var(--accent); }
.home-modern .empty-state { color: var(--fg-muted); }

/* CTA band reworked as a token gradient (works in both themes). */
.home-modern .cta-band {
  background: linear-gradient(135deg, var(--accent-strong), var(--accent-2-strong));
  box-shadow: var(--shadow-2);
}

/* Mission 19.11 — CTA band contrast fix (light mode).
   The CTA gradient is deep in BOTH themes (accent-strong -> accent-2-strong is
   dark navy/ochre in light, deep gold/steel in dark), so its text must be light
   in both. In light mode the text previously inherited the dark navy --fg and
   became unreadable over the dark band. Pin an explicit light foreground on the
   band, its heading/paragraph, and the ghost button. Dark mode already rendered
   near-white text, so its appearance is preserved; the navy/gold identity and
   the section layout are unchanged. */
.cta-band {
  --cta-fg: var(--brand-paper);   /* #FAF7F1 — high contrast on the dark band */
  color: var(--cta-fg);
}
.cta-band h2,
.cta-band p { color: var(--cta-fg); }
.cta-band p { opacity: 0.92; }    /* supporting text stays clearly readable */
/* Ghost CTA button: light outline + label on the dark band, both themes. */
.cta-band .btn-animated--ghost {
  color: var(--cta-fg);
  border-color: rgba(250, 247, 241, 0.55);
}
.cta-band .btn-animated--ghost:hover { border-color: var(--cta-fg); }

/* Padded surface to compose with the mica/glass utilities. */
.surface-panel { border-radius: var(--radius-lg); padding: var(--space-32); }

/* Stat card: centered figure + label inside a glass-card. */
.stat-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-4);
}
.stat-card .stat__num { font-size: var(--text-h1); line-height: 1.1; }
.stat-card__label { color: var(--fg-muted); font-size: var(--text-small); }

/* ==========================================================================
   Mission 19.5 — photography & placeholder strategy
   Image-ready photo slots: intentional, branded institutional surfaces (crest
   watermark + frame) that look deliberate, not unfinished, and accept a real
   DBPC photograph later (set .photo-slot__img with no other markup change).
   Token-driven, theme-aware, responsive.
   ========================================================================== */
.photo-slot {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0;
  overflow: hidden;
  aspect-ratio: 4 / 3;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: radial-gradient(140% 120% at 50% 0%, var(--surface-overlay), var(--surface-sunken));
  color: var(--fg-subtle);
}
.photo-slot__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.photo-slot__mark { color: var(--accent); opacity: 0.32; line-height: 0; }
.photo-slot__mark .icon { width: 2.4em; height: 2.4em; }
.photo-slot__label {
  position: absolute;
  inset-inline: var(--space-12);
  bottom: var(--space-8);
  font-size: var(--text-small);
  color: var(--fg-muted);
}

/* Variants by image category (campus / archival / gallery / event / portrait /
   memorial). Each is an image-ready frame ready for real photography. */
.photo-slot--campus { aspect-ratio: 16 / 9; background: linear-gradient(160deg, var(--surface-overlay), var(--brand-ink)); }
.photo-slot--archival { background: linear-gradient(135deg, var(--surface-overlay), var(--surface-sunken)); }
.photo-slot--archival::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.5;
  background: repeating-linear-gradient(45deg, transparent 0 6px, var(--border-subtle) 6px 7px);
}
.photo-slot--gallery { aspect-ratio: 4 / 3; }
.photo-slot--event { aspect-ratio: 4 / 3; }
.photo-slot--portrait { aspect-ratio: 3 / 4; border-radius: var(--radius-lg); }
.photo-slot--memorial { background: linear-gradient(135deg, var(--surface-sunken), var(--surface-base)); }
.photo-slot--memorial .photo-slot__mark { color: var(--brand-ash); opacity: 0.30; }

/* Image-ready homepage hero media — a future cinematic DBPC campus photograph,
   or a sunrise/sunset-toned animation, can replace this gradient by setting a
   background-image on .hero-slide__bg (or applying --campus) with no markup
   change. The tone evokes a Park Circus sunrise: warm gold horizon under navy. */
.hero-slide__bg--campus {
  background:
    linear-gradient(180deg, transparent 38%, rgba(0, 0, 0, 0.50)),
    radial-gradient(120% 80% at 50% 112%, var(--accent-soft), transparent 52%),
    linear-gradient(180deg, var(--brand-ink) 0%, #14233A 46%, var(--accent-strong) 100%);
}

/* Phase 5 — homepage legacy preview helpers (gallery tiles, list meta). */
.preview-thumb {
  display: block;
  margin: 0;
  border-radius: var(--radius-md);
  overflow: hidden;
  border: 1px solid var(--border);
  background: var(--surface-overlay);
}
.preview-thumb img {
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}
.preview-thumb figcaption { padding: var(--space-8) var(--space-12); }
.preview-meta { color: var(--fg-subtle); font-size: var(--text-small); }

/* ==========================================================================
   Mission 17B Phase 6.5 — hero + navigation polish
   CSS-only refinement (plus the .hero-carousel__dots--capsule modifier class).
   No layout restructure, no behavior change; theme-aware (dark + light).
   ========================================================================== */

/* --- Public navbar: stronger frosted Mica + pill link states ------------- */
.navbar.mica-surface {
  -webkit-backdrop-filter: blur(22px) saturate(160%);
  backdrop-filter: blur(22px) saturate(160%);
}
.navbar.mica-surface .navbar__links a {
  transition: background var(--motion-fast) var(--ease),
              color var(--motion-fast) var(--ease),
              box-shadow var(--motion-fast) var(--ease);
}
/* Rounded hover/focus state around each nav link. */
.navbar.mica-surface .navbar__links a:hover {
  background: var(--accent-soft);
  color: var(--fg);
}
/* Accessible, theme-aware focus ring (keyboard); not hover-only. */
.navbar.mica-surface .navbar__links a:focus-visible {
  outline: none;
  background: var(--accent-soft);
  box-shadow: 0 0 0 2px var(--surface-base), 0 0 0 4px var(--accent);
}
/* Selected link pops: tinted pill + accent text + inset accent ring. */
.navbar.mica-surface .navbar__links a[aria-current="page"] {
  background: var(--accent-soft);
  color: var(--accent);
  box-shadow: inset 0 0 0 1px var(--accent);
}

/* --- Hero layout: spacing, proportions, card width ----------------------- */
.hero-slide__inner { padding-block: var(--space-48); }
/* Mission 22.1.4 — a deliberately generous, balanced hero panel.
   width: min() keeps it premium-wide on desktop yet fluid (never overflows) on
   tablet/mobile; padding is handled on .hero-slide__panel for the frosted card. */
.hero-slide__content {
  /* Mission 24.8 — a slightly narrower plaque so more of the photo shows and
     the panel reads as a premium plate, not a dominant block. */
  width: min(560px, 100%);
  max-width: none;
}
.hero-slide__title { margin-bottom: var(--space-12); }

/* --- Carousel arrows: refined Acrylic feel ------------------------------- */
.hero-carousel__arrow {
  transition: transform var(--motion-fast) var(--ease),
              color var(--motion-fast) var(--ease),
              box-shadow var(--motion-fast) var(--ease);
}
.hero-carousel__arrow:hover {
  transform: translateY(-50%) scale(1.06);
  box-shadow: var(--shadow-glow);
}

/* --- Capsule progress indicators ----------------------------------------- */
.hero-carousel__dots--capsule { gap: var(--space-8); }
.hero-carousel__dots--capsule .hero-carousel__dot {
  width: 10px;
  height: 10px;
  border-radius: var(--radius-full);
  transition: width var(--motion) var(--ease),
              background var(--motion-fast) var(--ease),
              border-color var(--motion-fast) var(--ease);
}
/* Active indicator stretches into a rounded capsule. */
.hero-carousel__dots--capsule .hero-carousel__dot.is-active,
.hero-carousel__dots--capsule .hero-carousel__dot[aria-pressed="true"] {
  width: 30px;
}

/* ==========================================================================
   Mission 17B Phase 6.75 — shared design-system refinement
   Reusable, OPT-IN interaction utilities only. No page body is restyled (every
   selector below is a NEW class), so existing pages are unchanged. Theme-aware
   (dark default + light); reduced-motion and low-performance respected.
   ========================================================================== */
:root { --motion-link: 0.2s; }   /* 180–220ms band for link micro-interactions */

/* --- Premium link hover (.link) ----------------------------------------- */
.link {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  color: var(--accent);
  text-decoration: none;
  /* left-to-right underline grow */
  background-image: linear-gradient(var(--accent), var(--accent));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 2px;
  transition: color var(--motion-link) var(--ease),
              filter var(--motion-link) var(--ease),
              background-size var(--motion-link) var(--ease),
              transform var(--motion-link) var(--ease);
}
.link:hover { filter: brightness(1.15); background-size: 100% 2px; }
.link:active { transform: translateY(1px); }      /* subtle press */
.link:focus-visible {
  outline: none;
  border-radius: var(--radius-sm);
  box-shadow: 0 0 0 2px var(--surface-base), 0 0 0 4px var(--accent);
}
.link__arrow { transition: transform var(--motion-link) var(--ease); }
.link:hover .link__arrow { transform: translateX(3px); }   /* icon shifts right */

/* Soft pill variant (rounded background instead of underline). */
.link--pill {
  padding: var(--space-4) var(--space-12);
  border-radius: var(--radius-full);
  background-image: none;
  transition: background var(--motion-link) var(--ease),
              color var(--motion-link) var(--ease),
              transform var(--motion-link) var(--ease);
}
.link--pill:hover { background: var(--accent-soft); filter: none; }

/* --- Button states (loading / disabled) --------------------------------- */
.btn-animated:disabled,
.btn-animated[aria-disabled="true"] {
  opacity: 0.5;
  cursor: not-allowed;
  transform: none;
  box-shadow: none;
  filter: none;
}
.btn-animated.is-loading,
.btn-animated[aria-busy="true"] {
  color: transparent;
  pointer-events: none;
  position: relative;
}
.btn-animated.is-loading::after,
.btn-animated[aria-busy="true"]::after {
  content: "";
  position: absolute;
  width: 1em;
  height: 1em;
  border: 2px solid var(--fg-on-accent);
  border-top-color: transparent;
  border-radius: var(--radius-full);
  animation: spin 0.6s linear infinite;
}

/* --- Generic hover lift (cards & surfaces) ------------------------------ */
.hover-lift {
  transition: transform var(--motion-fast) var(--ease),
              box-shadow var(--motion-fast) var(--ease);
}
.hover-lift:hover { transform: translateY(-3px); box-shadow: var(--shadow-2); }

/* --- Modern form: validation + helper text ------------------------------ */
.form-modern .input-modern[aria-invalid="true"],
.form-modern .select-modern[aria-invalid="true"],
.form-modern .textarea-modern[aria-invalid="true"] {
  border-color: var(--danger);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 25%, transparent);
}
.form-modern .input-modern.is-valid {
  border-color: var(--success);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--success) 22%, transparent);
}
.field-modern__help { margin-top: var(--space-4); font-size: var(--text-small); color: var(--fg-subtle); }
.field-modern__error { margin-top: var(--space-4); font-size: var(--text-small); color: var(--danger); }

/* --- Modern table: sticky header utility (row hover already defined) ----- */
.table-modern--sticky thead th { position: sticky; top: 0; z-index: 1; }

/* --- Typography scale utilities (sans UI headings) ---------------------- */
/* .t-display is defined in the Mission 19.2 editorial layer (serif). */
.t-h1 { font-family: var(--font-heading); font-size: var(--text-h1); line-height: 1.15; }
.t-h2 { font-family: var(--font-heading); font-size: var(--text-h2); line-height: 1.2; }
.t-h3 { font-family: var(--font-heading); font-size: var(--text-h3); line-height: 1.25; }
.t-body-lg { font-size: var(--text-body-lg); }
.t-body { font-size: var(--text-body); }
.t-small { font-size: var(--text-small); }
.t-xs { font-size: var(--text-xs); }
.t-bold { font-weight: 700; }
.t-semibold { font-weight: 600; }
.t-tight { line-height: 1.1; }
.t-eyebrow {
  font-size: var(--text-xs);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--fg-subtle);
}

/* --- Animation utilities (entrance) ------------------------------------- */
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes fade-up { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes fade-left { from { opacity: 0; transform: translateX(-16px); } to { opacity: 1; transform: none; } }
@keyframes fade-right { from { opacity: 0; transform: translateX(16px); } to { opacity: 1; transform: none; } }
@keyframes scale-in { from { opacity: 0; transform: scale(0.96); } to { opacity: 1; transform: none; } }

.fade-up { animation: fade-up var(--motion) var(--ease) both; }
.fade-left { animation: fade-left var(--motion) var(--ease) both; }
.fade-right { animation: fade-right var(--motion) var(--ease) both; }
.scale-in { animation: scale-in var(--motion) var(--ease) both; }

/* Stagger: sequence direct children's entrance. */
.stagger > * { animation: fade-up var(--motion) var(--ease) both; }
.stagger > *:nth-child(1) { animation-delay: 0ms; }
.stagger > *:nth-child(2) { animation-delay: 60ms; }
.stagger > *:nth-child(3) { animation-delay: 120ms; }
.stagger > *:nth-child(4) { animation-delay: 180ms; }
.stagger > *:nth-child(5) { animation-delay: 240ms; }
.stagger > *:nth-child(6) { animation-delay: 300ms; }
.stagger > *:nth-child(7) { animation-delay: 360ms; }
.stagger > *:nth-child(8) { animation-delay: 420ms; }

/* Reduced motion: neutralize the new motion, keep content fully visible. */
@media (prefers-reduced-motion: reduce) {
  .link, .link--pill, .link__arrow, .hover-lift { transition: none; }
  .link:hover { background-size: 100% 2px; }
  .link:active, .hover-lift:hover { transform: none; }
  .btn-animated.is-loading::after,
  .btn-animated[aria-busy="true"]::after { animation-duration: 1.2s; }
  .fade-up, .fade-left, .fade-right, .scale-in,
  .stagger > * { animation: none; opacity: 1; transform: none; }
}

/* Low-performance / opt-in low-effects: drop the new entrance/hover motion. */
.perf-low .link, .perf-low .hover-lift,
.low-effects .link, .low-effects .hover-lift { transition: none; }
.perf-low .fade-up, .perf-low .fade-left, .perf-low .fade-right,
.perf-low .scale-in, .perf-low .stagger > *,
.low-effects .fade-up, .low-effects .fade-left, .low-effects .fade-right,
.low-effects .scale-in, .low-effects .stagger > * {
  animation: none;
  opacity: 1;
  transform: none;
}

/* ==========================================================================
   Mission 17B Phase 7 — page redesign surface (first used by the About page)
   Reusable themed wrapper so a redesigned public page reads correctly in dark
   (default) and light. Scoped to pages that opt in via .page-modern; no global
   element or other page is affected.
   ========================================================================== */
.page-modern { background: var(--surface-base); color: var(--fg); }
.page-modern h1,
.page-modern h2,
.page-modern h3,
.page-modern h4 { color: var(--fg); }
.page-modern .lead { color: var(--fg-muted); }
.page-modern .note { color: var(--fg-subtle); }
.page-modern .section--muted { background: var(--surface-sunken); }
.page-modern .stat__num { color: var(--accent); }
.page-modern .empty-state { color: var(--fg-muted); }
.page-modern .cta-band {
  background: linear-gradient(135deg, var(--accent-strong), var(--accent-2-strong));
  box-shadow: var(--shadow-2);
}

/* Page hero/banner (non-carousel). Token gradient backdrop; glass content. */
.page-hero {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  padding-block: clamp(var(--space-48), 10vw, var(--space-96));
  color: var(--fg);
  background:
    radial-gradient(120% 90% at 15% 10%, var(--accent-soft), transparent 60%),
    linear-gradient(135deg, var(--surface-sunken), var(--accent-strong));
}
.page-hero__content { max-width: 720px; }
.page-hero__title {
  margin: 0 0 var(--space-16);
  font-family: var(--font-heading);
  font-weight: 700;
  line-height: 1.1;
  color: var(--fg);
  font-size: clamp(2rem, 5vw, var(--text-display));
}
.page-hero__subtitle {
  margin: 0 0 var(--space-24);
  max-width: 56ch;
  font-size: var(--text-body-lg);
  color: var(--fg-muted);
}

/* ==========================================================================
   Mission 19.4 — public page hero archetypes
   Four hero compositions so pages no longer share one identical hero. Each
   opts in via a .page-hero--* modifier; token-driven, theme-aware, responsive.
   ========================================================================== */

/* --- Archetype 1: Photographic / Institutional (image-ready) ------------- */
.page-hero--feature {
  min-height: clamp(440px, 60vh, 640px);
  display: flex;
  align-items: flex-end;
  padding-block: var(--space-48);
  background: var(--brand-ink);
}
/* Intentional image-ready surface (NOT placeholder.svg). A real DBPC photo
   can later be set on this element with no markup change. */
.page-hero__media {
  position: absolute;
  inset: 0;
  z-index: -2;
  background:
    radial-gradient(120% 85% at 18% 12%, var(--accent-soft), transparent 55%),
    linear-gradient(160deg, var(--surface-overlay), var(--surface-sunken) 55%, var(--brand-ink));
}
.page-hero__media::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.45), transparent 62%);
}
.page-hero--feature .page-hero__content { max-width: 760px; }
/* Mission 22.1: the feature-hero title uses the site's sans heading (matching
   every other page hero) rather than the editorial serif, for consistency. */

/* --- Archetype 2: Split Institutional ----------------------------------- */
.page-hero--split .page-hero__split {
  display: grid;
  grid-template-columns: 1.3fr 0.7fr;
  gap: var(--space-48);
  align-items: center;
}
.page-hero__panel {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-8);
  text-align: center;
  padding: var(--space-32) var(--space-24);
}
.page-hero__crest { color: var(--accent); line-height: 0; }
.page-hero__crest .icon { width: 3em; height: 3em; }
.page-hero__crest-name { margin: var(--space-8) 0 0; font-size: var(--text-h3); color: var(--fg); }
@media (max-width: 767px) {
  .page-hero--split .page-hero__split { grid-template-columns: 1fr; }
  .page-hero__panel { display: none; }   /* keep mobile lean; lead text leads */
}

/* --- Archetype 3: Compact Index ----------------------------------------- */
.page-hero--index {
  min-height: 0;
  padding-block: clamp(var(--space-32), 5vw, var(--space-48));
  background: linear-gradient(180deg, var(--surface-overlay), var(--surface-base));
}
.page-hero--index .page-hero__content { max-width: 760px; }
.page-hero--index .page-hero__title { font-size: clamp(1.75rem, 4vw, var(--text-h1)); }
.page-hero--index .page-hero__subtitle { margin-bottom: var(--space-16); font-size: var(--text-body-lg); }

/* --- Institutional identity mark (Mission 22.3) --------------------------
   A small, reusable branded unit — a medallion (page-specific icon OR the
   official logo) beside a label — that de-generics index-page hero eyebrows.
   The label keeps the .t-eyebrow kicker style; the card owns the spacing. */
.institution-card {
  display: inline-flex;
  align-items: center;
  gap: var(--space-12);
  margin: 0 0 var(--space-16);
}
.institution-card__icon,
.institution-card__logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  flex: none;
  border-radius: 50%;
  box-shadow: var(--shadow-1);
}
.institution-card__icon {
  color: var(--accent);
  background: var(--surface-raised);
  border: 1px solid var(--border-strong);
}
.institution-card__icon .icon { width: 22px; height: 22px; }
.institution-card__logo {
  background: var(--brand-paper);
  padding: 3px;
  overflow: hidden;
}
.institution-card__logo img { width: 100%; height: 100%; object-fit: contain; border-radius: 50%; }
/* The label carries .t-eyebrow already; neutralise its own bottom margin so the
   card controls the spacing and the medallion + label stay vertically centred. */
.institution-card__label { margin: 0; }

/* --- Archetype 4: Quiet Editorial --------------------------------------- */
.page-hero--quiet {
  background: var(--surface-base);
  padding-block: clamp(var(--space-48), 9vw, var(--space-96));
  text-align: center;
}
.page-hero--quiet .page-hero__content { margin-inline: auto; max-width: 60ch; }
.page-hero--quiet .page-hero__title {
  font-family: var(--font-display);
  font-weight: 500;
}
.page-hero--quiet .page-hero__subtitle { margin-inline: auto; }
/* Memorial — especially restrained: ash tones, no accent, generous calm. */
.page-hero--memorial {
  background: var(--surface-sunken);
  border-bottom: 1px solid var(--border);
}
.page-hero--memorial .t-eyebrow { color: var(--brand-ash); }
.page-hero--memorial .page-hero__title { color: var(--fg); font-weight: 400; }

/* ==========================================================================
   Mission 19.6 — public page personality
   Per-page body identity hooks + a distinctive treatment per page, so pages
   share one brand but no longer read as the same template. Token-driven,
   theme-aware, responsive; glass stays selective.
   ========================================================================== */

/* Lead statement — a large, confident introduction.
   Mission 19.10: unified to the primary UI/sans font. A page intro is body
   voice, not an editorial moment, so the serif display was over-applied here
   and clashed with the surrounding UI (most visibly on the homepage welcome).
   Size, weight and tracking carry the emphasis; the serif is reserved for
   genuine editorial constructs (pull quotes, History longform, Memorial). */
.lede-statement {
  font-family: var(--font-ui);
  font-weight: 600;
  font-size: clamp(1.4rem, 3.2vw, 2.1rem);
  line-height: 1.3;
  letter-spacing: -0.01em;
  color: var(--fg);
  max-width: 30ch;
  margin: 0 0 var(--space-24);
}

/* Membership — ceremonial tier cards (gold rule, not a pricing table). */
.membership-tier { border-top: 3px solid var(--brand-gold); }
.membership-tier__seal { color: var(--brand-gold); line-height: 0; }
.membership-tier__seal .icon { width: 1.6em; height: 1.6em; }

/* Events — date-led event card with a prominent date block. */
.event-card { display: grid; grid-template-columns: 104px 1fr; gap: var(--space-16); align-items: stretch; }
.event-card__date {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  padding: var(--space-12);
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--surface-overlay);
  color: var(--accent);
}
.event-card__date .icon { width: 1.4em; height: 1.4em; }
.event-card__date-text {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-small);
  line-height: 1.2;
  text-align: center;
  color: var(--fg);
  font-variant-numeric: tabular-nums;
}
.event-card__body { min-width: 0; }
@media (max-width: 479px) {
  .event-card { grid-template-columns: 1fr; }
}

/* Gallery — image-led bento grid (first photo dominates). */
.gallery-grid-led { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-12); }
.gallery-grid-led > :first-child { grid-column: span 2; grid-row: span 2; }
@media (max-width: 767px) {
  .gallery-grid-led { grid-template-columns: repeat(2, 1fr); }
  .gallery-grid-led > :first-child { grid-column: span 2; grid-row: auto; }
}

/* Committee — official, image-ready portrait slot (pending feels intentional). */
.committee-portrait { width: 96px; margin-inline: auto; }

/* Memorial — quiet treatment: serif, calm surfaces, no elevation. */
.page-memorial h2,
.page-memorial h3 { font-family: var(--font-display); font-weight: 500; }
.page-memorial .glass-card { box-shadow: none; background: var(--surface-sunken); }

/* ==========================================================================
   Mission 19.7 — contextual page endings
   Replace the repeated gradient CTA band + identical "Explore more" rows with
   two reusable patterns: a horizontal contextual next-step, and a distinctive
   ceremonial membership invitation. Token-driven, theme-aware, responsive.
   ========================================================================== */

/* Contextual next-step — a quiet horizontal bar, not a loud gradient band. */
.next-step {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-16) var(--space-24);
  padding: var(--space-24) var(--space-32);
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  background: var(--surface-raised);
}
.next-step__title { margin: 0; }
.next-step__actions { display: flex; flex-wrap: wrap; gap: var(--space-12); align-items: center; }
/* Calm "help" variant: no accent fill, gentle surface. */
.next-step--help { background: var(--surface-sunken); }

/* Ceremonial membership invitation — gold seal, distinct from any CTA band. */
.cta-invitation {
  position: relative;
  text-align: center;
  padding: var(--space-48) var(--space-32);
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  border-top: 3px solid var(--brand-gold);
  background: linear-gradient(180deg, var(--surface-raised), var(--surface-base));
  box-shadow: var(--shadow-2);
}
.cta-invitation__seal { color: var(--brand-gold); line-height: 0; }
.cta-invitation__seal .icon { width: 2.4em; height: 2.4em; }
/* Mission 22.3 — ceremonial seal now carries the official logo medallion. */
.cta-invitation__logo { width: 76px; height: 76px; margin: 0 auto; }
.cta-invitation__title {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(1.6rem, 3.6vw, var(--text-h1));
  margin: var(--space-12) 0 var(--space-8);
  color: var(--fg);
}
.cta-invitation__text { margin: 0 auto; max-width: 52ch; color: var(--fg-muted); }

@media (max-width: 599px) {
  .next-step { flex-direction: column; align-items: flex-start; }
}

/* ==========================================================================
   Mission 19.8 — institutional footer
   A "yearbook back cover": a consistent navy→ink closing band (both themes)
   with a gold crest seal, serif identity, a warm closing statement, and
   organized link groups. No sitemap feel, no social placeholders.
   ========================================================================== */
.footer--institutional {
  background: linear-gradient(180deg, var(--brand-navy), var(--brand-ink));
  color: rgba(241, 236, 225, 0.78);
  border-top: 3px solid var(--brand-gold);
  padding-block: var(--space-64) var(--space-32);
  margin-top: var(--space-48);
}
.footer--institutional a { color: rgba(241, 236, 225, 0.80); text-decoration: none; }
.footer--institutional a:hover { color: #fff; }
.footer--institutional a:focus-visible {
  outline: none;
  border-radius: var(--radius-sm);
  box-shadow: 0 0 0 2px var(--brand-ink), 0 0 0 4px var(--brand-gold);
}

/* Identity / crest seal */
.footer__identity { max-width: 54ch; margin: 0 auto var(--space-48); text-align: center; }
.footer__seal {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  margin-bottom: var(--space-16);
  border-radius: var(--radius-full);
  border: 2px solid var(--brand-gold);
  color: var(--brand-gold);
}
.footer__seal .icon { width: 1.6em; height: 1.6em; }
.footer__name {
  margin: 0;
  font-family: var(--font-display);
  font-size: var(--text-h2);
  color: #fff;
}
.footer__assoc {
  margin: 0 0 var(--space-16);
  font-family: var(--font-display);
  font-style: italic;
  color: var(--brand-gold);
}
.footer__closing { margin: 0; color: rgba(241, 236, 225, 0.72); }

/* Organized link groups */
.footer--institutional .footer__cols {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--space-32);
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  padding-top: var(--space-32);
}
.footer--institutional .footer__cols strong {
  display: block;
  margin-bottom: var(--space-12);
  font-family: var(--font-display);
  color: #fff;
}
.footer--institutional .footer__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--space-8);
}
.footer--institutional .footer__list a:hover { text-decoration: underline; text-underline-offset: 3px; }
.footer__email { display: inline-flex; align-items: center; gap: var(--space-8); }
.footer__email-icon { color: var(--brand-gold); line-height: 0; }

.footer--institutional .footer__bottom {
  margin-top: var(--space-32);
  padding-top: var(--space-16);
  border-top: 1px solid rgba(255, 255, 255, 0.12);
  font-size: var(--text-small);
  color: rgba(241, 236, 225, 0.6);
}
.footer--institutional .footer__bottom p { margin: 0; }

@media (max-width: 1023px) {
  .footer--institutional .footer__cols { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 599px) {
  .footer--institutional .footer__cols { grid-template-columns: 1fr; }
}

/* Two-column media + text block (stacks on mobile). */
.media-split {
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: var(--space-32);
  align-items: center;
}
@media (max-width: 767px) {
  .media-split { grid-template-columns: 1fr; }
}

/* ==========================================================================
   Mission 17B Phase 9 — History story timeline
   A centerpiece vertical timeline: glass cards alternate left/right on desktop
   around a central connector, and stack into a single left-aligned rail on
   mobile. Token-driven (dark default + light); pairs with .reveal.
   ========================================================================== */
.story-timeline { list-style: none; margin: 0; padding: 0; position: relative; }
/* Central connector line. */
.story-timeline::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 2px;
  background: linear-gradient(var(--accent), var(--accent-2));
  transform: translateX(-50%);
}
.story-timeline__item {
  position: relative;
  width: 50%;
  padding: var(--space-24) var(--space-48);
  box-sizing: border-box;
}
/* Alternate sides on desktop. */
.story-timeline__item:nth-child(odd) { left: 0; }
.story-timeline__item:nth-child(even) { left: 50%; }
/* Node where each card meets the connector. */
.story-timeline__marker {
  position: absolute;
  top: var(--space-32);
  width: 16px;
  height: 16px;
  border-radius: var(--radius-full);
  background: var(--accent);
  border: 3px solid var(--surface-base);
  box-shadow: 0 0 0 1px var(--accent);
}
.story-timeline__item:nth-child(odd) .story-timeline__marker { right: -8px; }
.story-timeline__item:nth-child(even) .story-timeline__marker { left: -8px; }
.story-timeline__year { margin: 0 0 var(--space-8); color: var(--accent); }
/* Optional historical photograph slot inside a card. */
.story-timeline__media {
  margin: var(--space-16) 0 0;
  border-radius: var(--radius-md);
  overflow: hidden;
  border: 1px solid var(--border);
}
.story-timeline__media img { display: block; width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }

/* Mobile: single left rail, cards stacked full width. */
@media (max-width: 767px) {
  .story-timeline::before { left: 8px; }
  .story-timeline__item,
  .story-timeline__item:nth-child(odd),
  .story-timeline__item:nth-child(even) {
    width: 100%;
    left: 0;
    padding-left: var(--space-32);
    padding-right: 0;
  }
  .story-timeline__item:nth-child(odd) .story-timeline__marker,
  .story-timeline__item:nth-child(even) .story-timeline__marker {
    left: 0;
    right: auto;
  }
}

/* ==========================================================================
   Mission 17B Phase 12 — gallery page: theme the legacy filter chips so they
   read correctly on the redesigned (dark default + light) surface. Scoped to
   .page-modern; the chips elsewhere are untouched.
   ========================================================================== */
.page-modern .chip {
  background: var(--surface-raised);
  border: 1px solid var(--border);
  color: var(--fg-muted);
  transition: background var(--motion-fast) var(--ease),
              color var(--motion-fast) var(--ease),
              border-color var(--motion-fast) var(--ease);
}
.page-modern .chip:hover { border-color: var(--accent); color: var(--fg); }
.page-modern .chip[aria-pressed="true"] {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--fg-on-accent);
}
/* Gallery tile: link wraps the image; caption + category badge below. */
.page-modern .preview-thumb a { display: block; }

/* ==========================================================================
   Mission 17B Phase 15 — public site visual consistency
   Theme-aware refinements only: bring the remaining legacy components used
   inside redesigned pages (breadcrumb, timeline, accordion, alert) onto the
   dark-default/light token system so spacing, colour, and contrast are
   consistent across every public page. No structural or content changes.
   ========================================================================== */

/* Breadcrumb sits on the gradient page-hero — make it legible in both themes. */
.page-hero .breadcrumb,
.page-hero .breadcrumb a { color: var(--fg-muted); }
.page-hero .breadcrumb a:hover { color: var(--fg); }
.page-hero .breadcrumb li + li::before { color: var(--fg-subtle); }
.page-hero .breadcrumb [aria-current="page"] { color: var(--fg); }

/* Legacy step timeline used inside redesigned pages (e.g. membership). */
.page-modern .timeline { border-left-color: var(--border); }
.page-modern .timeline__year { color: var(--accent); }
.page-modern .timeline__item::before { background: var(--accent); }

/* Legacy accordion inside redesigned pages (membership FAQ). */
.page-modern .accordion details {
  border-color: var(--border);
  background: var(--surface-raised);
}

/* Notice / alert boxes: themed surface with a semantic accent border so they
   match the surrounding page instead of reading as light callouts. */
.page-modern .alert {
  background: var(--surface-raised);
  border-color: var(--border);
  color: var(--fg);
}
.page-modern .alert--info { border-inline-start: 3px solid var(--accent-2); }
.page-modern .alert--success { border-inline-start: 3px solid var(--success); }
.page-modern .alert--warning { border-inline-start: 3px solid var(--warning); }
.page-modern .alert--error { border-inline-start: 3px solid var(--danger); }

/* Eyebrow label hugs its heading consistently across all pages. */
.t-eyebrow { margin: 0 0 var(--space-8); }

/* Safety net: media and grids never force horizontal overflow on mobile. */
.page-modern img,
.home-modern img { max-width: 100%; height: auto; }

/* ==========================================================================
   Mission 18 — public website experience enhancement
   Interaction polish only (no structure/content changes). Every effect is
   theme-aware and gated for reduced-motion and low-performance.
   ========================================================================== */

/* Consistent, theme-aware focus ring across interactive elements. */
.btn-animated:focus-visible,
.theme-toggle:focus-visible,
.chip:focus-visible,
.hero-carousel__arrow:focus-visible,
.hero-carousel__dot:focus-visible,
.megamenu__summary:focus-visible {
  outline: none;
  box-shadow: 0 0 0 2px var(--surface-base), 0 0 0 4px var(--accent);
}

/* Mega-menu: animate the Acrylic panel in when opened. */
@keyframes menu-in { from { opacity: 0; transform: translateY(-6px); } to { opacity: 1; transform: none; } }
.megamenu[open] > .megamenu__panel { animation: menu-in var(--motion-fast) var(--ease) both; }

/* Mobile drawer: smoother easing for panel + overlay. */
.drawer__panel { transition: transform var(--motion) var(--ease); }
.drawer__overlay { transition: opacity var(--motion) var(--ease); }

/* Hero transition polish: a subtle Ken Burns drift on the active slide. */
@keyframes kenburns { from { transform: scale(1); } to { transform: scale(1.06); } }
.hero-slide.is-active .hero-slide__bg { animation: kenburns 14s ease-out both; }

/* Subtle page-in feel for the main content (opacity only — no layout shift). */
@keyframes page-in { from { opacity: 0; } to { opacity: 1; } }

/* In-page anchors clear the sticky navbar. */
.page-modern :is(h1, h2, h3)[id],
.home-modern :is(h1, h2, h3)[id] { scroll-margin-top: 80px; }

/* Footer polish. */
.footer strong { display: inline-block; margin-bottom: var(--space-12); font-family: var(--font-heading); }
.footer__list { display: grid; gap: var(--space-8); }
.footer__list a {
  text-decoration: none;
  background-image: linear-gradient(currentColor, currentColor);
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 1px;
  transition: background-size var(--motion-link) var(--ease), color var(--motion-fast) var(--ease);
}
.footer__list a:hover { background-size: 100% 1px; color: #fff; }
.footer .muted { color: rgba(255, 255, 255, 0.6); }

@media (prefers-reduced-motion: no-preference) {
  .js main { animation: page-in 0.35s var(--ease) both; }
}

/* Low-performance: drop the most expensive ambient motion, keep everything. */
.perf-low .hero-slide.is-active .hero-slide__bg,
.low-effects .hero-slide.is-active .hero-slide__bg { animation: none; }
.perf-low .megamenu[open] > .megamenu__panel,
.low-effects .megamenu[open] > .megamenu__panel { animation: none; }
.perf-low main, .low-effects main { animation: none; }

/* ==========================================================================
   Mission 19.2 — editorial typography layer
   An OPT-IN serif/editorial system for heritage and storytelling moments.
   Functional UI keeps the sans (--font-heading / --font-ui). No page layout
   changes here; later phases apply these where each page's mood calls for it.
   Theme-aware, responsive (clamp), and accessible line-heights.
   ========================================================================== */

/* Inline SVG icon system (Mission 19.3). Icons inherit text colour via
   currentColor and scale with the surrounding type (em-based). */
.icon {
  display: inline-block;
  width: 1.25em;
  height: 1.25em;
  vertical-align: -0.18em;
  flex-shrink: 0;
  fill: none;
  stroke: currentColor;
}
.icon--sm { width: 1em; height: 1em; }
.icon--md { width: 1.25em; height: 1.25em; }
.icon--lg { width: 1.5em; height: 1.5em; }
.icon--xl { width: 2em; height: 2em; }

/* Opt any element into the editorial serif. */
.t-serif { font-family: var(--font-display); }

/* Editorial display headings (serif). .t-display is upgraded from the earlier
   sans definition; .t-display-xl is the true hero/editorial size. */
.t-display {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.08;
  letter-spacing: -0.01em;
  font-size: clamp(2.25rem, 5vw, var(--text-display));
}
.t-display-xl {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.04;
  letter-spacing: -0.015em;
  font-size: clamp(2.75rem, 7vw, 4.5rem);
}

/* Institutional section heading (serif, measured) — an alternative to the
   sans .t-h2 so section titles are no longer all identical. */
.t-section {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.005em;
  font-size: clamp(1.5rem, 3.2vw, var(--text-h1));
}

/* Pull quote — editorial serif italic with a ceremonial accent rule. */
.pull-quote {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.25rem, 3vw, 1.75rem);
  line-height: 1.4;
  color: var(--fg);
  max-width: 42ch;
  margin: var(--space-32) 0;
  padding-inline-start: var(--space-24);
  border-inline-start: 3px solid var(--accent);
}
.pull-quote__attr {
  display: block;
  margin-top: var(--space-12);
  font-family: var(--font-ui);
  font-style: normal;
  font-size: var(--text-small);
  letter-spacing: 0.02em;
  color: var(--fg-subtle);
}

/* Long-form reading — editorial measure + comfortable rhythm for stories. */
.longform { max-width: 68ch; }
.longform p {
  font-size: var(--text-body-lg);
  line-height: 1.75;
  margin-bottom: var(--space-24);
}
.longform--serif p { font-family: var(--font-display); }
.longform--serif h2,
.longform--serif h3 { font-family: var(--font-display); }

/* Drop cap for the opening of a story section. */
.drop-cap::first-letter {
  float: left;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 3.4em;
  line-height: 0.78;
  padding-inline-end: var(--space-8);
  color: var(--accent);
}

/* Stat / numeric treatment — large, tabular numerals, tight tracking. */
.t-stat {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2rem, 5vw, 3.25rem);
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--fg);
  font-variant-numeric: tabular-nums lining-nums;
  font-feature-settings: "tnum" 1, "lnum" 1;
}
.t-stat__label {
  display: block;
  margin-top: var(--space-4);
  font-family: var(--font-ui);
  font-size: var(--text-small);
  color: var(--fg-muted);
}
/* Apply tabular numerals to existing legacy stat figures too. */
.stat__num { font-variant-numeric: tabular-nums lining-nums; }

/* Caption / kicker — small supporting type for images and metadata. */
.t-caption {
  font-family: var(--font-ui);
  font-size: var(--text-small);
  line-height: 1.45;
  color: var(--fg-subtle);
}

/* Honor the OS reduced-motion preference for this layer's motion. */
@media (prefers-reduced-motion: reduce) {
  .megamenu[open] > .megamenu__panel { animation: none; }
  .hero-slide.is-active .hero-slide__bg { animation: none; }
  .drawer__panel, .drawer__overlay { transition: none; }
  .js main { animation: none; }
  .footer__list a { transition: none; }
  .navbar.mica-surface .navbar__links a { transition: none; }
  .hero-carousel__arrow { transition: none; }
  .hero-carousel__arrow:hover { transform: translateY(-50%); }
  .hero-carousel__dots--capsule .hero-carousel__dot { transition: none; }
  .hero-slide { transition: none; }
  .hero-carousel__dot { transition: none; }
  .card-modern,
  .btn-animated,
  .btn-animated__arrow,
  .theme-toggle,
  .table-modern tbody tr,
  .form-modern .input-modern { transition: none; }
  .js .reveal,
  .js .reveal--up,
  .js .reveal--left,
  .js .reveal--right {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .btn-animated:hover { transform: none; }
}

/* ==========================================================================
   Mission 21.12 — design-system demo utilities (CSP enforcement prep)
   Small classes that replace the inline styles previously used only on the
   /design-system and /demo-components reference pages, so a strict CSP (no
   'unsafe-inline' in style-src) can be enforced. These are demo-only helpers.
   ========================================================================== */
.mt-48 { margin-top: var(--space-48); }

.ds-type-display { font-size: var(--text-display); font-family: var(--font-heading); line-height: 1.1; }
.ds-type-lead { font-size: var(--text-body-lg); }
.ds-form { margin-inline: 0; }
.ds-kpi { font-size: var(--text-h2); margin: 0; }

/* Fixed palette swatches for the design-system reference page. */
.swatch--primary-900 { background: #062544; }
.swatch--primary-700 { background: #0b3d6e; }
.swatch--primary-500 { background: #1a6fb5; }
.swatch--primary-100 { background: #e3eef8; }
.swatch--accent-600 { background: #b97b05; }
.swatch--accent-500 { background: #e2a106; }
.swatch--accent-100 { background: #fbefd2; }
.swatch--neutral-900 { background: #111827; }
.swatch--neutral-500 { background: #6b7280; }
.swatch--neutral-100 { background: #f3f4f6; }
.swatch--success { background: #15803d; }
.swatch--error { background: #b91c1c; }

/* ==========================================================================
   Mission 22 — logo-aligned brand, real hero photography, compact account menu
   Uses local static assets only (no remote URLs). Photos load under a
   readability scrim; the account menu keeps the logged-in navbar compact.
   ========================================================================== */

/* --- Official logo in the header / footer --- */
.navbar__logo {
  width: 36px;
  height: 36px;
  object-fit: contain;
  flex: none;
}
.navbar__wordmark {
  display: inline-flex;
  flex-direction: column;
  justify-content: center;
  font-family: var(--font-display);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1;
  white-space: nowrap;
}
/* Mission 24.2 — compact two-line brand wordmark (primary + unit subline). The
   longer organisation name is abbreviated to "DBAA Kolkata" so the header stays
   balanced; the unit label sits on a small second line without wrapping. */
.navbar__wordmark-primary {
  font-size: var(--text-body);
  line-height: 1.05;
}
.navbar__wordmark-unit {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--text-xs);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--fg-muted);
  line-height: 1.1;
}
/* Membership card unit label under the formal association name (Mission 24.2). */
.member-card__unit {
  margin: 0;
  font-size: var(--text-small);
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--fg-muted);
}
/* Mission 22.1.1 — compact, no-wrap header actions with consistent sizing. */
.navbar__brand { gap: var(--space-8); }
.navbar__cta .btn,
.navbar__login,
.navbar__join { white-space: nowrap; flex: none; }
.account-menu__summary { white-space: nowrap; flex: none; }
/* Mission 22.1.3 — Sign in button reads via theme tokens in BOTH themes.
   The legacy .btn--secondary hardcodes navy (#0b3d6e) text/border, which
   vanishes on the dark navbar. Bind it to --fg / --border-strong / --accent
   instead so contrast is strong in dark (paper text on ink) and light (navy
   on paper) alike. Selector doubles specificity so it wins over app.css. */
.navbar__cta .navbar__login.btn--secondary {
  color: var(--fg);
  background: transparent;
  border-color: var(--border-strong);
}
.navbar__cta .navbar__login.btn--secondary:hover {
  color: var(--fg);
  background: var(--surface-raised);
  border-color: var(--accent);
}
.navbar__cta .navbar__login.btn--secondary:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}
.footer__logo {
  width: 72px;
  height: 72px;
  object-fit: contain;
  margin: 0 auto var(--space-16);
  display: block;
}

/* --- Homepage hero: real photograph under a theme-aware scrim --- */
.hero-slide__bg { overflow: hidden; }
.hero-slide__photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
/* Mission 22.2 — slide-specific crop art direction. The photos are full-bleed
   and cover-cropped; these object-position hints keep each slide's subject
   framed as the aspect ratio changes across desktop/tablet/mobile:
   - building: bias slightly up so the central facade / signage stays in frame
   - wheels:   centred so the vehicle/banner isn't clipped on either side
   - members:  bias up so faces are not cut off when the base is cropped away */
.hero-slide__photo--building { object-position: center 35%; }
.hero-slide__photo--wheels   { object-position: center 50%; }
.hero-slide__photo--members  { object-position: center 28%; }
/* Mission 24.8 — a lighter, left-localised scrim so the photograph reads more
   openly. Text readability is carried by the frosted .hero-slide__panel (its
   own translucent bg + blur), so the scrim only needs to steady the left/text
   region; the right ~third of the image is revealed (fades to transparent). */
.hero-slide__bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg,
    rgba(11, 21, 32, 0.60) 0%, rgba(11, 21, 32, 0.28) 40%,
    rgba(11, 21, 32, 0.06) 72%, rgba(11, 21, 32, 0) 100%);
}
[data-theme="light"] .hero-slide__bg::after {
  background: linear-gradient(90deg,
    rgba(11, 21, 32, 0.42) 0%, rgba(11, 21, 32, 0.18) 40%,
    rgba(11, 21, 32, 0.03) 72%, rgba(11, 21, 32, 0) 100%);
}
/* Hero text follows the theme-aware panel tokens (Mission 22.1.1). */
.hero-slide__content { color: var(--hero-panel-fg); }
.hero-slide__title { color: var(--hero-panel-fg); }
.hero-slide__subtitle { color: var(--hero-panel-muted); }
.hero-slide__eyebrow { color: var(--accent); }

/* --- Feature page hero: real photograph (About) --- */
.page-hero__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  z-index: -1;
}
/* Keep the existing gradient scrim above the photo for title legibility. */
.page-hero__media { overflow: hidden; }

/* --- Compact account menu (logged-in public navbar) --- */
.account-menu { position: relative; }
.account-menu__summary {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-8);
  border-radius: var(--radius-pill, 999px);
  border: 1px solid var(--border);
  background: var(--surface-overlay);
  color: var(--fg);
  cursor: pointer;
  list-style: none;
}
.account-menu__summary::-webkit-details-marker { display: none; }
.account-menu__summary::marker { content: ""; }
.account-menu__avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--brand-orange);
  color: #fff;
  font-weight: 700;
  font-size: var(--text-small);
}
.account-menu__panel {
  position: absolute;
  right: 0;
  top: calc(100% + var(--space-8));
  min-width: 220px;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-12);
  border-radius: var(--radius-md);
  z-index: 40;
}
.account-menu__email {
  margin: 0 0 var(--space-4);
  font-size: var(--text-small);
  color: var(--fg-muted);
  word-break: break-all;
}
.account-menu__panel a {
  padding: var(--space-8);
  border-radius: var(--radius-sm);
  color: var(--fg);
  text-decoration: none;
}
.account-menu__panel a:hover { background: var(--surface-overlay); }
.account-menu__signout { margin: var(--space-4) 0 0; }
.account-menu__signout-btn {
  width: 100%;
  padding: var(--space-8);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--fg);
  cursor: pointer;
  text-align: left;
}
.account-menu__signout-btn:hover { background: var(--surface-overlay); }

/* ==========================================================================
   Mission 22.1 — visual QA: polished round logo, solid hero panel, About
   readability. Reusable logo medallion + higher-contrast hero/About panels.
   ========================================================================== */

/* --- Reusable polished logo medallion --- */
.brand-logo { display: block; object-fit: contain; }
.brand-logo--round {
  border-radius: 50%;
  background: var(--brand-paper);
  padding: 5px;
  border: 1px solid rgba(11, 21, 32, 0.10);
  box-shadow: 0 2px 12px rgba(11, 21, 32, 0.22);
}
.brand-logo--footer {
  width: 88px;
  height: 88px;
  margin: 0 auto var(--space-16);
}
.brand-logo--hero-card {
  width: 120px;
  height: 120px;
  margin: 0 auto var(--space-12);
}
/* Header medallion keeps the 44px footprint but gains the round frame. */
.navbar__logo.brand-logo--round { padding: 3px; }

/* --- Homepage hero: solid institutional text panel (not a frosted card) --- */
.hero-slide__photo {
  /* Mission 24.8 — subtle grade for cohesion, but brightness lifted close to
     full so the photograph is clearly visible (was brightness(0.9)). */
  filter: saturate(1.06) contrast(1.04) brightness(0.98);
}
/* Mission 22.1.1 / 22.1.2 — theme-aware FROSTED (Mica) hero content panel.
   Translucent, blurred glass — not a solid block — with AA-level text contrast.
   Dark (default): frosted ink panel + warm paper text.
   Light: frosted warm-paper panel + navy text.
   Each background has an rgba() fallback first, then a color-mix() that
   browsers which support it use instead (both translucent). */
:root {
  --hero-panel-bg: rgba(11, 21, 32, 0.46);
  --hero-panel-bg: color-mix(in srgb, var(--brand-ink) 58%, transparent);
  --hero-panel-fg: #F7F3EA;
  --hero-panel-muted: rgba(247, 243, 234, 0.86);
  --hero-panel-border: rgba(247, 243, 234, 0.22);
  /* Mica edge: a faint inner highlight over the soft outer shadow. */
  --hero-panel-edge: inset 0 1px 0 rgba(247, 243, 234, 0.22);
}
[data-theme="light"] {
  --hero-panel-bg: rgba(250, 247, 241, 0.56);
  --hero-panel-bg: color-mix(in srgb, var(--brand-paper) 60%, transparent);
  --hero-panel-fg: var(--brand-navy);
  --hero-panel-muted: rgba(14, 42, 71, 0.82);
  --hero-panel-border: rgba(255, 255, 255, 0.55);
  --hero-panel-edge: inset 0 1px 0 rgba(255, 255, 255, 0.65);
}
.hero-slide__panel {
  background: var(--hero-panel-bg);
  color: var(--hero-panel-fg);
  border: 1px solid var(--hero-panel-border);
  border-radius: var(--radius-lg);
  /* Mission 24.8 — a touch less vertical padding so the plaque is shorter and
     less dominant, keeping generous horizontal breathing room. Defined space
     tokens only. */
  padding: clamp(var(--space-24), 4vw, var(--space-32)) clamp(var(--space-32), 4vw, var(--space-48));
  box-shadow: var(--hero-panel-edge), var(--shadow-2);
  backdrop-filter: blur(24px) saturate(1.7);
  -webkit-backdrop-filter: blur(24px) saturate(1.7);
}
/* No backdrop support / low-perf: fall back to a nearly-opaque (but not fully
   flat) tinted panel so text stays readable without the blur. */
.no-backdrop .hero-slide__panel,
.low-effects .hero-slide__panel {
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  background: rgba(11, 21, 32, 0.94);
}
[data-theme="light"] .no-backdrop .hero-slide__panel,
[data-theme="light"] .low-effects .hero-slide__panel {
  background: rgba(250, 247, 241, 0.94);
}

/* ==========================================================================
   Member portal dashboard — Mission 23
   Institutional, theme-aware shell: welcome header, read-only membership card,
   honest account-setup indicator, and a navigable section hub. Token-driven;
   reuses .glass-card / .institution-card__icon / .badge / .status-dot.
   ========================================================================== */
.portal-dash { gap: var(--space-32); }

/* Preview banner + real sign-out states use a text label, never colour alone. */
.status-dot--info { background: var(--accent-2); }
.status-dot--wait { background: var(--brand-gold); }
.portal-preview-note {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  margin: 0;
  color: var(--fg-muted);
  font-size: var(--text-small);
}

/* Welcome header */
.portal-welcome {
  display: flex;
  align-items: center;
  gap: var(--space-16);
}
.portal-welcome__avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  flex: none;
  border-radius: 50%;
  background: var(--accent);
  color: var(--fg-on-accent);
  font-family: var(--font-heading);
  font-size: var(--text-h3);
  font-weight: 700;
}
.portal-welcome__title { margin: 0; }
.portal-welcome__meta { margin: var(--space-4) 0 0; color: var(--fg-muted); font-size: var(--text-small); }

/* Membership card */
.member-card { display: flex; flex-direction: column; gap: var(--space-16); }
.member-card__head { display: flex; align-items: center; gap: var(--space-16); }
.member-card__logo { flex: none; line-height: 0; }
.member-card__logo img { width: 56px; height: 56px; }
.member-card__title { margin: 0; }
.member-card__org { margin: var(--space-4) 0 0; color: var(--fg-muted); font-size: var(--text-small); }
.member-card__fields {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-16);
  margin: 0;
}
.member-field { margin: 0; }
.member-field__label {
  margin: 0;
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fg-subtle);
}
.member-field__value { margin: var(--space-4) 0 0; font-weight: 600; color: var(--fg); display: flex; align-items: center; gap: var(--space-8); }
.member-field__value--pending { color: var(--fg-subtle); font-weight: 500; font-style: italic; }

/* Account-setup card */
.setup-card { display: flex; flex-direction: column; gap: var(--space-12); }
.setup-card__title { margin: 0; }
.setup-steps { list-style: none; margin: var(--space-8) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-8); }
.setup-step { display: flex; align-items: center; gap: var(--space-12); }
.setup-step__mark { line-height: 0; flex: none; }
.setup-step__mark--done { color: var(--accent); }
.setup-step__mark--todo { color: var(--fg-subtle); }
.setup-step__label { flex: 1; }
.setup-step__state { font-size: var(--text-small); color: var(--fg-muted); }

/* Section hub */
.portal-section-heading { margin: var(--space-8) 0 0; }
.portal-tile {
  display: flex;
  align-items: flex-start;
  gap: var(--space-16);
  text-decoration: none;
  color: var(--fg);
}
.portal-tile__icon { flex: none; }
.portal-tile__body { display: flex; flex-direction: column; gap: var(--space-4); flex: 1; }
.portal-tile__title { font-weight: 700; }
.portal-tile__desc { color: var(--fg-muted); font-size: var(--text-small); }
.portal-tile__cta { display: inline-flex; align-items: center; gap: var(--space-8); flex: none; }
.portal-tile__arrow { color: var(--accent); }
.portal-tile__status {
  font-size: var(--text-xs);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 2px var(--space-8);
  border-radius: var(--radius-full);
}
.portal-tile__status--open { color: var(--accent); background: var(--accent-soft); }
.portal-tile__status--planned { color: var(--fg-subtle); background: var(--surface-sunken); border: 1px solid var(--border); }
/* "Live"/"Enforced" pill for genuinely implemented admin tools (Mission 24). */
.portal-tile__status--live {
  color: var(--success);
  background: color-mix(in srgb, var(--success) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--success) 40%, transparent);
}

/* Admin shell — logo brand + Security section (Mission 24). */
.sidebar__brand {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  text-decoration: none;
  color: var(--fg);
}
.sidebar__logo { width: 32px; height: 32px; flex: none; }
.sidebar__wordmark {
  display: inline-flex;
  flex-direction: column;
  font-family: var(--font-display);
  font-weight: 700;
  white-space: nowrap;
  color: var(--fg);
}
.sidebar__heading {
  margin: 0 0 var(--space-8);
  padding-inline: var(--space-8);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--fg-muted);
}
/* Mission 24.1 — theme-aware sidebar contrast. The legacy .sidebar styles are
   light-on-dark (#cdd9e7 links, #fff text) which wash out on the light Mica
   surface; bind the brand + links to the theme tokens like the public navbar. */
.sidebar.mica-surface { color: var(--fg); }
.sidebar__top {
  padding-bottom: var(--space-12);
  margin-bottom: var(--space-8);
  border-bottom: 1px solid var(--border);
}
.sidebar.mica-surface a { color: var(--fg-muted); }
.sidebar.mica-surface a:hover {
  background: var(--accent-soft);
  color: var(--fg);
}
.sidebar.mica-surface a[aria-current="page"] {
  background: var(--accent-soft);
  color: var(--fg);
  font-weight: 600;
  box-shadow: inset 3px 0 0 var(--accent);
}
.sidebar.mica-surface .sidebar__brand { color: var(--fg); }
.sidebar.mica-surface .sidebar__brand:hover { background: transparent; }
.sidebar__divider { border-top-color: var(--border); }
/* Admin content sits on the same themed surface as the sidebar (was a fixed
   light neutral, which read as disconnected in light mode and broke dark mode). */
.admin-main { background: var(--surface-base); }
.admin-dash { gap: var(--space-32); }
.portal-tile--planned { opacity: 0.82; }
a.portal-tile:hover .portal-tile__title { color: var(--accent); }

/* Real CSRF sign-out inside the mobile drawer, styled like the other links. */
.drawer__signout { margin: 0; }
.drawer__signout-btn {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  padding: var(--space-12) var(--space-16);
  font: inherit;
  color: var(--fg);
  cursor: pointer;
  border-radius: var(--radius-sm);
}
.drawer__panel.acrylic-panel .drawer__signout-btn:hover { background: var(--accent-soft); }

/* Alumni Directory / member search — future-ready preview (disabled skeleton) */
/* Mission 26.1 — dashboard Alumni Directory entry point. A simple navigation
   card (icon + copy + CTA) linking to /portal/directory. No search/filter/list
   UI lives on the dashboard; those belong only on the directory page. */
.directory-cta {
  display: flex;
  align-items: center;
  gap: var(--space-16);
  flex-wrap: wrap;
}
.directory-cta__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  flex: none;
  border-radius: var(--radius-md);
  color: var(--accent-strong);
  background: var(--accent-soft, var(--surface-2));
}
.directory-cta__body { flex: 1; min-width: 12rem; }
.directory-cta__title { margin: 0; }
.directory-cta__desc { margin: var(--space-4) 0 0; color: var(--fg-muted); }
.directory-cta__action { flex: none; }
.directory-search { display: flex; gap: var(--space-8); align-items: stretch; }
.directory-search__field { flex: 1; display: block; }
.directory-search__input { width: 100%; }
.directory-filters {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--space-12);
}
/* Mission 24.5 — the four directory filters (pass-out year / registration year /
   leaving class / sort by) sit in one clean row on desktop; two-up on tablet;
   stacked on mobile. Options are short, so they fit without wrapping awkwardly. */
.directory-filters--four { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 900px) {
  .directory-filters--four { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.directory-filter { display: flex; flex-direction: column; gap: var(--space-4); }
.directory-filter__label {
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--fg-subtle);
}
.directory-preview__note { margin: 0; }
/* Mission 26.1 — directory result count + honest scope note, and an empty state
   that pairs the message with a reset link when filters are active. */
.directory-count__scope {
  display: block;
  margin-top: var(--space-4);
  font-size: var(--text-small);
  color: var(--fg-subtle);
}
.directory-empty {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-12);
}
.directory-results { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-12); }
.directory-result {
  display: flex;
  align-items: center;
  gap: var(--space-16);
  padding: var(--space-16);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
}
.directory-result__avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  flex: none;
  border-radius: 50%;
  background: var(--surface-raised);
  border: 1px solid var(--border-strong);
  color: var(--fg-subtle);
}
.directory-result__body { flex: 1; display: flex; flex-direction: column; gap: var(--space-8); min-width: 0; }
.directory-result__line { display: block; margin: 0; }
.directory-result__line--name { width: 45%; height: 1.1rem; }
.directory-result__meta { display: flex; flex-wrap: wrap; gap: var(--space-8); }
.directory-result__tag {
  font-size: var(--text-xs);
  color: var(--fg-subtle);
  background: var(--surface-overlay);
  border-radius: var(--radius-full);
  padding: 2px var(--space-8);
}
.directory-result__contact { font-size: var(--text-small); color: var(--fg-subtle); font-style: italic; }

/* Sub-page header (title + honest status pill) and planned-feature rows. */
.portal-subhead {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-16);
  flex-wrap: wrap;
}
.planned-list { list-style: none; margin: var(--space-16) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-12); }
.planned-list li {
  display: flex;
  align-items: center;
  gap: var(--space-16);
  padding: var(--space-12) var(--space-16);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--surface-sunken);
}
.planned-list__icon { flex: none; }
.planned-list__label { flex: 1; min-width: 0; }

@media (max-width: 640px) {
  .member-card__fields { grid-template-columns: 1fr; }
  .directory-filters { grid-template-columns: 1fr; }
}

/* ==========================================================================
   Mission 24.6 — Portal / Admin theme consistency & dark-mode contrast
   The authenticated areas mixed the theme design system (glass-card, tokens)
   with legacy app.css components that hard-code light neutrals — so on the
   dark-by-default surfaces text rendered dark-on-dark and some panels stayed
   light. Two fixes:
     1) make the page <body> background/foreground theme-aware globally (public
        pages already paint --surface-base via their .page-modern wrappers, so
        this is a no-op there and simply gives portal/admin the dark surface);
     2) bind the legacy component classes to theme tokens *inside the
        authenticated shells only* (.app-shell on <body>), so light mode is
        untouched and dark mode is readable.
   Token-driven → correct in BOTH dark (default) and light.
   ========================================================================== */
body { background: var(--surface-base); color: var(--fg); }

/* --- Text / typography inside the authenticated shells --- */
.app-shell { color: var(--fg); }
/* Mission 24.6.1 — headings follow the theme foreground token instead of the
   fixed navy (app.css h1..h4 = --color-primary-900), which was unreadable on the
   dark surfaces. --fg = warm paper in dark (default), navy in light — so dark
   mode headings become readable and light mode keeps its navy (no regression).
   Covers page titles, card headings (member/setup card <h2>), and section
   headings across portal + admin. */
.app-shell h1,
.app-shell h2,
.app-shell h3,
.app-shell h4 { color: var(--fg); }
.app-shell .section-intro { color: var(--fg-muted); }
.app-shell .muted { color: var(--fg-muted); }
.app-shell .note { color: var(--fg-subtle); }
/* Mission 26.1.1 — admin admin-completion notice as a readable, responsive
   callout. The explanation is a normal paragraph (wraps naturally) and the
   "Edit the record" action is a separate button below it, so the link never
   breaks mid-sentence on narrow/medium widths. */
.completion-callout {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-12);
  padding: var(--space-16);
  border: 1px solid var(--border);
  border-left: 3px solid var(--accent-strong);
  border-radius: var(--radius-md);
  background: var(--accent-soft);
}
.completion-callout__text { margin: 0; color: var(--fg-muted); }
.completion-callout__action { flex: none; }
.app-shell .field__label { color: var(--fg); }
.app-shell .field__help { color: var(--fg-muted); }
.app-shell .detail-list dt { color: var(--fg-muted); }
.app-shell .detail-list dd { color: var(--fg); }
.app-shell .completeness__pct { color: var(--accent); }
.app-shell .completeness__label { color: var(--fg-muted); }
.app-shell .kpi__value { color: var(--accent); }
.app-shell .kpi__note { color: var(--fg-muted); }
.app-shell .timeline { border-inline-start-color: var(--border); }
.app-shell .timeline__year { color: var(--accent); }
.app-shell .list-rows li { border-bottom-color: var(--border); }

/* --- Surfaces: legacy card / welcome / tables --- */
.app-shell .card {
  background: var(--surface-raised);
  border-color: var(--border);
  color: var(--fg);
}
.app-shell .welcome { background: var(--surface-raised); color: var(--fg); }
.app-shell .table th,
.app-shell .table td { border-bottom-color: var(--border); color: var(--fg); }
.app-shell .table thead th { background: var(--surface-sunken); color: var(--fg-muted); }
.app-shell .table tbody tr:nth-child(even) { background: var(--surface-sunken); }
.app-shell .admin-main .table { background: transparent; }

/* --- Form controls: readable + legibly disabled in both themes --- */
.app-shell .input,
.app-shell .select,
.app-shell .textarea {
  background: var(--surface-raised);
  color: var(--fg);
  border-color: var(--border);
}
.app-shell .input::placeholder { color: var(--fg-subtle); }
.app-shell .input:disabled,
.app-shell .select:disabled,
.app-shell .textarea:disabled {
  background: var(--surface-sunken);
  color: var(--fg-muted);
  cursor: not-allowed;
}

/* --- Buttons: theme-token secondary/tertiary; disabled looks disabled but
   stays legible (the legacy navy text vanished on the dark shells). --- */
.app-shell .btn--secondary {
  color: var(--fg);
  background: transparent;
  border-color: var(--border-strong);
}
.app-shell .btn--secondary:hover { background: var(--surface-raised); }
.app-shell .btn--tertiary { color: var(--fg); }
.app-shell .btn--tertiary:hover { background: var(--surface-raised); }
.app-shell .btn:disabled,
.app-shell .btn[disabled],
.app-shell .btn[aria-disabled="true"] { opacity: 0.6; }

/* --- Info alert: dark-tinted panel in the shells (was a bright light island) --- */
.app-shell .alert--info {
  background: var(--accent-soft);
  border-color: var(--accent);
  color: var(--fg);
}
/* --- Neutral chip: theme surface so it isn't a bright island (coloured
   badge variants keep their semantic tint). --- */
.app-shell .badge { background: var(--surface-overlay); color: var(--fg-muted); }
.app-shell .badge--success,
.app-shell .badge--info,
.app-shell .badge--warning,
.app-shell .badge--error { color: inherit; }
