/* ============================================================
   OVERFLOW CHURCH — EDITORIAL MINIMALISM
   "Still Waters" — Playfair Display + Hanken Grotesk
   Mobile-first. Dark/light via CSS variables only.
   Full-width layout. Transparent auto-hiding header.
   ============================================================ */

/* ----------------------------------------------------------
   RESET & BASE
   ---------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; overflow-y: scroll; }
body {
  margin: 0;
  font-family: var(--font-sans);
  color: var(--color-ink);
  background: var(--color-bg);
  line-height: 1.65;
  font-size: 1rem;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
}
h1, h2, h3, h4 {
  font-family: var(--font-display);
  line-height: 1.12;
  font-weight: 400;
  color: var(--color-ink);
}
img { max-width: 100%; height: auto; display: block; }
a { color: var(--color-primary); }
address { font-style: normal; }

/* ----------------------------------------------------------
   LAYOUT UTILITIES
   ---------------------------------------------------------- */

/* Full-width wrapper with responsive side padding */
.full-width {
  width: 100%;
  padding-inline: clamp(1.25rem, 4vw, 4rem);
}

/* Container — centers content with responsive gutters */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: clamp(1.25rem, 4vw, 4rem);
}

/* Container that breaks out to full edge within a section that already has padding
   Use when the section itself manages padding-inline */
.container-flush {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
}

/* Body text limiter — keeps long-form prose readable on wide screens */
.prose-limit {
  max-width: 68ch;
}

.skip-link {
  position: absolute; left: -999px; top: 0;
  background: var(--color-deep); color: #fff;
  padding: var(--space-1) var(--space-2);
  font-family: var(--font-sans);
  font-size: 0.9rem;
  z-index: 200;
}
.skip-link:focus { left: var(--space-2); }

/* Section typography helpers */
.section-label {
  font-family: var(--font-sans);
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  /* one accent per section, resolved by ground (blue on light, gold on dark);
     matches the heading-emphasis word below so the two never clash */
  color: var(--section-accent);
  margin-bottom: var(--space-2);
}
.section-label--light { color: rgba(255,255,255,0.7); }

.section-heading {
  font-size: clamp(1.9rem, 5vw, 3rem);
  font-weight: 400;
  margin: 0 0 var(--space-3);
  text-align: center;
  max-width: 68ch;
}
.section-heading em {
  font-style: italic;
  color: var(--section-accent);
}
.section-heading--left { text-align: left; }

/* Mobile heading wrap control.
   Every display heading on the site is written as a plain phrase followed by an
   italic accent phrase in <em>, and that <em> is the authored split point. Left
   to itself the browser ignores it and breaks wherever the line runs out, which
   orphans the tail ("Come as you are this / Sunday") and, worse, lands in a
   different place on a 390px phone than on a 430px one. Keeping the accent
   phrase unbreakable moves it to the next line whole, so the break always falls
   where the writing turns and is identical on every phone. Headings that
   already fit on one line are unaffected. */
@media (max-width: 47.99rem) {
  .section-heading em,
  .page-title-heading em,
  .page-hero-title em,
  .convictions__heading em { white-space: nowrap; }

  /* "How you grow once you are in" is long enough that even a clean break looks
     thin on its first line, so it scales down to hold one line instead, capped
     at the size it already uses so it never grows on wider phones. */
  .nightfall__heading { font-size: min(1.9rem, 6.2vw); }
}

.section-sub {
  color: var(--color-muted);
  font-size: 1.05rem;
  max-width: 48ch;
  margin: 0 0 var(--space-4);
  text-align: center;
}
.section-sub--left { text-align: left; }

/* Centered section heads/labels/subs (opt-in) */
.section-label--center { text-align: center; }
.section-heading--center { text-align: center; margin-inline: auto; }
.section-sub--center { text-align: center; margin-inline: auto; }

/* Fully centered section: centers heading, label, sub, prose, cards and button
   rows inside. Used on supplemental CTA / intro sections. */
.section-center { text-align: center; }
.section-center .section-label { text-align: center; }
.section-center .section-heading { text-align: center; margin-inline: auto; }
.section-center .section-sub { text-align: center; margin-inline: auto; }
.section-center .prose-body,
.section-center .visit-cta-card { margin-inline: auto; }
.section-center .visit-cta-card > div { justify-content: center; }
.section-center .fivefold-badges { justify-content: center; }

/* Full-width body measure — content fills the container so the left and right
   page gaps are equal (no narrow right-hand gutter). Higher specificity than
   .prose-body so it wins regardless of source order. */
.prose-body.prose-wide,
.prose-wide { max-width: none; }

/* ----------------------------------------------------------
   BUTTONS
   ---------------------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0.85rem 1.75rem;
  font-family: var(--font-sans);
  font-size: 0.95rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-decoration: none;
  min-height: 44px;
  border: none;
  cursor: pointer;
  transition: opacity 150ms ease, transform 150ms ease, background-color 150ms ease;
  border-radius: var(--radius);
}
.btn:hover { opacity: 0.88; transform: translateY(-1px); }

.btn-primary-solid {
  background: var(--color-accent);
  color: #fff;
}
.btn-outline-white {
  background: transparent;
  color: #fff;
  box-shadow: inset 0 0 0 1.5px rgba(255,255,255,0.55);
}
.btn-outline-white:hover {
  background: rgba(255,255,255,0.1);
  opacity: 1;
}
.btn-teal {
  background: var(--color-primary);
  color: #fff;
}
/* Dark theme flips --color-primary to the lighter #4aa9e6, which left white
   label text at 2.59:1 on the site's most-used call to action across nine
   pages. The fill stays bright (it is what makes the CTA read as primary on a
   dark page); the label goes to deep ink instead, measured 6.66:1. */
:root[data-theme="dark"] .btn-teal { color: var(--color-deep); }
.btn-give {
  background: #fff;
  color: var(--color-deep);
  font-weight: 700;
}
.btn-give:hover { opacity: 0.92; }

/* ----------------------------------------------------------
   PLACEHOLDER BADGE
   ---------------------------------------------------------- */
.placeholder-badge {
  display: inline-block;
  font-size: 0.67rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  font-family: var(--font-sans);
  background: #fff3cc;
  color: #7a5200;
  border: 1px dashed #d4a017;
  padding: 0.1rem 0.45rem;
  border-radius: 2px;
  vertical-align: middle;
  margin-inline: 0.15rem;
}
.hero .placeholder-badge {
  background: rgba(255,255,255,0.12);
  color: rgba(255,255,255,0.85);
  border-color: rgba(255,255,255,0.35);
  margin-bottom: var(--space-2);
  display: block;
  width: fit-content;
}

/* ----------------------------------------------------------
   SCROLL REVEAL
   ---------------------------------------------------------- */
/* Hiding is gated on .js (set by the inline script in base.njk, and dropped
   again if main.js never checks in). Without JavaScript running there is no
   observer to add .is-visible, so an ungated .reveal would hide the content
   permanently. Keep the .js prefix on every rule that hides. */
.js .reveal {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.75s ease, transform 0.75s ease;
}
.reveal.is-visible { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1; transform: none; transition: none; }
  .btn { transition: none; }
}

/* ----------------------------------------------------------
   HEADER — transparent over hero, solid on scroll
   ---------------------------------------------------------- */
.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  height: var(--header-h);
  /* Start transparent over the hero */
  background: transparent;
  border-bottom: 1px solid transparent;
  /* Only the slide animates; background/border switch instantly so the header
     never flashes a color while hiding (it stays transparent as it slides up) */
  transition: transform 300ms ease;
}

/* Solid state — activated via JS when scrolled past hero */
.site-header.is-solid {
  background: var(--color-bg);
  border-bottom-color: var(--color-line);
  box-shadow: 0 1px 12px rgba(0,0,0,0.06);
}

/* Hidden state — slide up out of view */
.site-header.is-hidden {
  transform: translateY(-100%);
}

/* When is-hidden and is-solid are both set, the slide-up still applies */
.site-header.is-solid.is-hidden {
  transform: translateY(-100%);
}

/* Header inner — full-width with responsive padding */
.header-inner {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  height: var(--header-h);
  padding-inline: clamp(1.25rem, 4vw, 4rem);
  gap: var(--space-3);
  width: 100%;
}

/* Logo / wordmark — flush left */
.brand {
  display: flex;
  align-items: center;
  text-decoration: none;
  flex-shrink: 0;
  /* Push the nav, hamburger, and toggle as a group to the far right */
  margin-right: auto;
}
.brand-logo {
  display: block;
  height: 2.125rem; /* 34px in a 64px bar */
  width: auto;
}
/* White logo over the hero (transparent header, any theme); the full-color
   logo on the solid header in both light and dark mode. */
.brand-logo--color { display: none; }
.site-header.is-solid .brand-logo--white { display: none; }
.site-header.is-solid .brand-logo--color { display: block; }

/* Desktop inline nav */
.primary-nav { display: none; }

.nav-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  align-items: stretch;   /* items fill the bar height so dropdowns hang from its bottom edge */
  height: 100%;
  gap: clamp(var(--space-1), 1vw, var(--space-2));
}
.nav-item { position: relative; display: flex; }
.nav-link {
  display: flex;
  align-items: center;
  height: 100%;            /* fill the bar so the hover tab can reach the dropdown */
  position: relative;
  font-size: clamp(0.95rem, 1.05vw, 1.08rem);
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--header-text, #fff);
  text-decoration: none;
  padding: 0.4rem 0.7rem;
  white-space: nowrap;
  transition: color 120ms ease, background-color 120ms ease, opacity 120ms ease;
  /* Full opacity at rest: the old 0.9 dimmed the halo as well as the word, which
     is exactly the wrong trade over a bright hero. Hover still reads clearly —
     it swaps in a solid white tab, a far stronger cue than a 10% fade. */
  opacity: 1;
  /* Dark halo so the white nav words stay legible over bright or video heroes.
     The left-hand items land on the blown-out center of the home carousel, where
     a soft single shadow washed out — so this stacks near-opaque contact layers
     with widening blooms to build a real dark aura around each word. Removed on
     the solid header and on hover, where the word sits on a solid background. */
  text-shadow:
    0 0 3px rgba(0, 0, 0, 0.95),
    0 1px 3px rgba(0, 0, 0, 0.9),
    0 0 8px rgba(0, 0, 0, 0.85),
    0 0 16px rgba(0, 0, 0, 0.65),
    0 0 30px rgba(0, 0, 0, 0.5);
}
/* Solid header (scrolled past hero): words are dark on a light bar, so the
   over-hero halo would smudge them — drop it. */
.site-header.is-solid .nav-link { text-shadow: none; }
/* Hover / focus / open: a white tab grows behind the word and joins the dropdown
   below it, so the word stays readable even over the hero image. */
.nav-item:hover > .nav-link,
.nav-item:focus-within > .nav-link,
.nav-link:hover,
.nav-link:focus-visible {
  opacity: 1;
  color: var(--color-primary);
  background: var(--color-bg);
  border-radius: var(--radius) var(--radius) 0 0;
  z-index: 101;   /* sit above the panel so the seam is covered */
  text-shadow: none;   /* solid tab behind the word; halo not needed here */
}
/* Plain top-level links (Visit, Events, Watch, Give) have no panel below, so
   the hover tab rounds on all four corners instead of squaring off to meet one. */
.nav-item:not(.has-dropdown) > .nav-link:hover,
.nav-item:not(.has-dropdown) > .nav-link:focus-visible {
  border-radius: var(--radius);
}
/* Dropdown affordance: a small chevron marks the items that open a submenu
   (About, Connect, Outreach), so the mixed model reads as intentional next to
   the plain links. Flips up while the panel is open. */
.nav-item.has-dropdown > .nav-link::after {
  content: "";
  width: 0.38em;
  height: 0.38em;
  margin-left: 0.45em;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  transform: translateY(-0.14em) rotate(45deg);
  opacity: 0.85;
  transition: transform 120ms ease;
  /* The chevron is drawn with borders, which text-shadow does not reach, so it
     carries its own matching halo — otherwise it fades out over a bright hero
     while the word beside it stays sharp. */
  filter:
    drop-shadow(0 0 2px rgba(0, 0, 0, 0.9))
    drop-shadow(0 1px 3px rgba(0, 0, 0, 0.75))
    drop-shadow(0 0 8px rgba(0, 0, 0, 0.5));
}
/* Solid header and hover put the chevron on a solid background — halo off, to
   match the word. */
.site-header.is-solid .nav-item.has-dropdown > .nav-link::after,
.nav-item.has-dropdown:hover > .nav-link::after,
.nav-item.has-dropdown:focus-within > .nav-link::after {
  filter: none;
  opacity: 0.7;
}
.nav-item.has-dropdown:hover > .nav-link::after,
.nav-item.has-dropdown:focus-within > .nav-link::after {
  transform: translateY(0.06em) rotate(225deg);
}

/* Desktop dropdown panel — revealed on hover/focus of its nav-item */
.nav-dropdown {
  position: absolute;
  top: 100%;
  left: 0;
  width: max-content;   /* box hugs its widest item; shorter items leave space on the right */
  background: var(--color-bg);
  border-radius: 0 var(--radius) var(--radius) var(--radius);   /* top-left square to meet the tab */
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.12), 0 1px 6px rgba(0, 0, 0, 0.06);
  padding: 0.3rem;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  /* No slide: the panel sits flush under the tab and fades in on the same
     120ms as the tab, so the tab + panel read as one piece appearing at once. */
  transition: opacity 120ms ease, visibility 0s 120ms;
  z-index: 100;
}
.nav-item.has-dropdown:hover > .nav-dropdown,
.nav-item.has-dropdown:focus-within > .nav-dropdown,
.nav-dropdown.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  transition: opacity 120ms ease;
}
.nav-dropdown-list { list-style: none; margin: 0; padding: 0; }
.nav-dropdown-link {
  display: block;
  white-space: nowrap;
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--color-ink-soft);
  text-decoration: none;
  padding: 0.4rem 0.55rem;
  transition: color 140ms ease;
}
.nav-dropdown-link:hover,
.nav-dropdown-link:focus-visible {
  color: var(--color-primary);   /* word turns blue, no row pill */
}

/* When solid, update header text to ink */
.site-header.is-solid {
  --header-text: var(--color-ink-soft);
}

/* Header actions — sits with the nav, grouped to the far right.
   The brand's margin-right:auto pushes this whole cluster right; no auto
   margin here (that would strand the nav in the middle). */
.header-actions {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  flex-shrink: 0;
}

/* ----------------------------------------------------------
   THEME TOGGLE — sliding pill switch
   ---------------------------------------------------------- */
.theme-toggle {
  position: relative;
  width: 68px;
  height: 32px;
  min-height: 44px;
  padding: 6px 0;
  border: none;
  background: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.theme-toggle:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
  border-radius: var(--radius-pill);
}

/* The pill track */
.theme-toggle-track {
  position: relative;
  display: flex;
  align-items: center;
  width: 56px;
  height: 28px;
  border-radius: var(--radius-pill);
  /* Over hero: semi-transparent white track; solid: theme-matched */
  background: rgba(255,255,255,0.22);
  border: 1.5px solid rgba(255,255,255,0.4);
  transition: background 280ms ease, border-color 280ms ease;
  padding: 0 5px;
}
.site-header.is-solid .theme-toggle-track {
  background: var(--color-bg-soft);
  border-color: var(--color-line);
}

/* Sun / moon glyphs — each centered in the pill half the knob is NOT covering,
   and only the exposed one shows: moon on the right in light mode, sun on the
   left in dark mode. Absolute so we can center in the open space rather than
   pin to the very end. */
.theme-toggle-sun,
.theme-toggle-moon {
  position: absolute;
  top: 50%;
  font-size: 0.9rem;
  line-height: 1;
  color: rgba(255,255,255,0.9);
  transition: color 280ms ease, opacity 220ms ease;
  user-select: none;
  pointer-events: none;
}
.site-header.is-solid .theme-toggle-sun,
.site-header.is-solid .theme-toggle-moon {
  color: var(--color-muted);
}
/* Light mode (default): knob left, moon centered in the open right half. */
.theme-toggle-sun  { left: 32%; transform: translate(-50%, -50%); opacity: 0; }
.theme-toggle-moon { left: 68%; transform: translate(-50%, -50%); opacity: 1; }
/* Dark mode: knob right, sun centered in the open left half. */
[data-theme="dark"] .theme-toggle-sun  { opacity: 1; }
[data-theme="dark"] .theme-toggle-moon { opacity: 0; }
/* Phones: a touch smaller still. */
@media (max-width: 47.99rem) {
  .theme-toggle-sun,
  .theme-toggle-moon { font-size: 0.8rem; }
}

/* Sliding knob */
.theme-toggle-knob {
  position: absolute;
  left: 3px;
  top: 50%;
  transform: translateY(-50%);
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 1px 4px rgba(0,0,0,0.2);
  transition: left 260ms cubic-bezier(0.34, 1.56, 0.64, 1), background 280ms ease, box-shadow 280ms ease;
}
.site-header.is-solid .theme-toggle-knob {
  background: var(--color-ink);
  box-shadow: 0 1px 4px rgba(0,0,0,0.15);
}

/* Dark theme: knob slides right */
[data-theme="dark"] .theme-toggle-knob {
  left: calc(100% - 23px);
}
[data-theme="dark"] .site-header.is-solid .theme-toggle-knob {
  background: var(--color-accent-light);
}

/* ----------------------------------------------------------
   HAMBURGER toggle — three-bar, ALL widths
   ---------------------------------------------------------- */
.nav-toggle {
  display: inline-flex;
  flex-direction: column;
  gap: 5px;
  justify-content: center;
  width: 44px;
  height: 44px;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0 10px;
  border-radius: var(--radius);
  transition: background 150ms ease;
  flex-shrink: 0;
}
.nav-toggle:hover { background: rgba(255,255,255,0.12); }
.site-header.is-solid .nav-toggle:hover { background: var(--color-bg-soft); }
.nav-toggle:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}
/* Single SVG icon — the three bars are drawn in one rasterization pass, so they
   stay even and crisp even on scaled/HiDPI displays that round per-element hairlines. */
.nav-toggle-icon {
  display: block;
  width: 24px;
  height: 18px;
  overflow: visible; /* let the rotated X arms show */
}
.nav-toggle-bar {
  fill: var(--header-text, #fff);
  transform-box: fill-box;
  transform-origin: center;
  transition: transform 250ms ease, opacity 200ms ease, fill 280ms ease;
}
/* Open state: X — top and bottom bars meet in the middle and cross; middle fades */
[aria-expanded="true"] .nav-toggle-bar--top { transform: translateY(8px) rotate(45deg); }
[aria-expanded="true"] .nav-toggle-bar--mid { opacity: 0; }
[aria-expanded="true"] .nav-toggle-bar--bot { transform: translateY(-8px) rotate(-45deg); }

/* ----------------------------------------------------------
   MEGA MENU
   ---------------------------------------------------------- */
.mega-menu {
  position: fixed;
  top: var(--header-h);
  left: 0;
  right: 0;
  background: var(--color-bg);
  border-bottom: 1px solid var(--color-line);
  z-index: 99;
  transform: translateY(-8px);
  opacity: 0;
  visibility: hidden;
  transition: opacity 250ms ease, transform 250ms ease, visibility 0s 250ms;
  box-shadow: 0 8px 32px rgba(0,0,0,0.08);
  /* Cap the panel to the space below the header and scroll inside it, so a menu
     taller than the screen (small phones) keeps its bottom items reachable.
     100dvh tracks the mobile browser's dynamic chrome; 100vh is the fallback. */
  max-height: calc(100vh - var(--header-h));
  max-height: calc(100dvh - var(--header-h));
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}
.mega-menu.is-open {
  opacity: 1;
  transform: translateY(0);
  visibility: visible;
  transition: opacity 250ms ease, transform 250ms ease;
}

.mega-menu-inner {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-4) var(--space-5);
  padding-block: var(--space-4);
  padding-bottom: var(--space-5);
  padding-inline: clamp(1.25rem, 4vw, 4rem);
}

.mega-col {}

.mega-col-heading {
  display: block;
  font-family: var(--font-sans);
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-accent);
  text-decoration: none;
  margin-bottom: var(--space-2);
  padding-bottom: var(--space-1);
  border-bottom: 1px solid var(--color-line);
}
.mega-col-heading:hover { color: var(--color-primary); }

.mega-col-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.mega-link {
  display: flex;
  align-items: center;
  font-size: 0.95rem;
  color: var(--color-ink-soft);
  text-decoration: none;
  padding: 0.55rem 0;
  min-height: 44px;
  border-bottom: 1px solid transparent;
  transition: color 150ms ease;
}
.mega-link:hover { color: var(--color-ink); }

.mega-close {
  position: absolute;
  top: var(--space-1);
  right: var(--space-1);
  width: 44px;
  height: 44px;
  background: none;
  border: 1px solid var(--color-line);
  border-radius: 50%;
  cursor: pointer;
  font-size: 1.4rem;
  color: var(--color-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 150ms ease, color 150ms ease;
}
.mega-close:hover { background: var(--color-bg-soft); color: var(--color-ink); }
.mega-close:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.mega-overlay {
  display: none;
  position: fixed;
  inset: var(--header-h) 0 0 0;
  background: rgba(0,0,0,0.3);
  z-index: 98;
  backdrop-filter: blur(2px);
}
.mega-overlay.is-active { display: block; }

/* ----------------------------------------------------------
   HERO — full-bleed to the top, starts behind transparent header
   ---------------------------------------------------------- */
.hero {
  position: relative;
  overflow: hidden;
  /* Extend to very top of page — header overlays it */
  min-height: 100svh;
  display: flex;
  align-items: center;
  color: #fff;
  /* No top margin — hero goes edge-to-edge */
}

/* Layered background: brand-blue gradient mesh — no photo required.
   Pinned to the viewport so it (and the video over it) stays put while the
   .page-flow sheet scrolls up over it. Negative z-index keeps it behind every
   opaque section; only the transparent hero region lets it show through. */
.hero-bg {
  position: fixed;
  inset: 0;
  z-index: -3;
}
.hero-bg-mesh {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 80% 60% at 15% 35%, #1772c2 0%, transparent 60%),
    radial-gradient(ellipse 60% 80% at 85% 70%, #0a3a66 0%, transparent 55%),
    radial-gradient(ellipse 50% 50% at 50% 10%, #4dc4e8 0%, transparent 50%),
    linear-gradient(170deg, #082742 0%, #0e4f86 45%, #061d33 100%);
}
/* SVG noise grain for depth */
.hero-bg-grain {
  position: absolute;
  inset: 0;
  opacity: 0.04;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='1'/%3E%3C/svg%3E");
  background-size: 200px 200px;
}

/* ----------------------------------------------------------
   HERO — full-bleed looping river video
   ---------------------------------------------------------- */
.hero-video {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Sits just above the gradient fallback, still behind all opaque content */
  z-index: -2;
  pointer-events: none;
  /* Crossfade duration must match FADE in main.js's hero-loop logic */
  opacity: 1;
  transition: opacity 1.5s linear;
}
/* The inactive copy in the crossfade pair fades to reveal the other */
.hero-video.is-hidden { opacity: 0; }

/* Scrim for headline legibility over the moving video (light touch — the panel
   carries most of the contrast now) */
.hero-scrim {
  /* Absolute within the hero so it scrolls up WITH the hero copy over the
     pinned video. Above the fixed video (z-2), below the opaque page sheet. */
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    linear-gradient(105deg, rgba(6,20,33,0.42) 0%, rgba(6,20,33,0.14) 42%, rgba(6,20,33,0) 70%),
    linear-gradient(to top, rgba(6,20,33,0.28) 0%, rgba(6,20,33,0) 45%);
}

/* Frosted panel behind the hero copy — keeps text legible over the moving video */
.hero-panel {
  width: fit-content;
  max-width: 100%;
  padding: clamp(1.5rem, 3.5vw, 2.75rem);
  border-radius: 18px;
  background: rgba(6, 20, 33, 0.16);
  border: 1px solid rgba(255, 255, 255, 0.08);
  -webkit-backdrop-filter: blur(4px);
          backdrop-filter: blur(4px);
}

/* Reduced motion: no video — fall back to the calm gradient-mesh hero */
@media (prefers-reduced-motion: reduce) {
  .hero-video { display: none; }
}

.hero-inner {
  position: relative;
  z-index: 4;
  width: 100%;
  padding-inline: clamp(1.25rem, 4vw, 4rem);
  /* Top padding clears the transparent fixed header */
  padding-top: calc(var(--header-h) + var(--space-6));
  padding-bottom: var(--space-7);
  /* Wide enough that "Overflow Church" stays on one line inside the panel */
  max-width: 72rem;
}

.hero-eyebrow {
  font-family: var(--font-sans);
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.92);
  margin: 0 0 var(--space-3);
  /* Crisp + soft shadow keeps small text readable over bright video */
  text-shadow: 0 1px 3px rgba(6,20,33,0.7), 0 1px 12px rgba(6,20,33,0.4);
}

/* Bigger, bolder, editorial hero headline. Lower clamp floor so "Overflow Church"
   stays on one line down through phone widths (it needs ~39px at 390px). */
.hero-title {
  font-family: var(--font-display);
  font-size: clamp(2.2rem, 9vw, 6.5rem);
  font-weight: 700;
  line-height: 1.02;
  margin: 0 0 var(--space-3);
  color: #fff;
  /* No max-width cap — let "Overflow Church" stay on one line where there's room */
  max-width: none;
  /* Soft halo lifts the headline off the bright, moving video */
  text-shadow: 0 2px 20px rgba(6, 20, 33, 0.45);
}
.hero-title em {
  font-style: italic;
  font-weight: 400;
  /* Brighter brand blue (was the darker primary) for legibility over the video */
  color: var(--color-accent-light);
}

.hero-sub {
  font-size: clamp(1rem, 2.5vw, 1.2rem);
  font-weight: 400;
  color: #fff;
  /* No width cap — one line on desktop; wraps naturally on small screens */
  max-width: none;
  margin: 0 0 var(--space-3);
  line-height: 1.6;
  text-shadow: 0 1px 3px rgba(6,20,33,0.7), 0 1px 12px rgba(6,20,33,0.4);
}

.hero-cta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-4);
}

/* Scroll-down cue at the foot of the hero. Centered with margin (not transform)
   so the .reveal entrance animation can own the element's transform. */
.hero-scroll {
  position: absolute;
  z-index: 4;
  left: 0;
  right: 0;
  bottom: clamp(0.9rem, 3vh, 2rem);
  margin-inline: auto;
  width: fit-content;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  padding: 0.5rem 0.9rem;
  color: rgba(255, 255, 255, 0.85);
  text-decoration: none;
}
.hero-scroll:hover { color: #fff; }
.hero-scroll:focus-visible {
  outline: 2px solid #fff;
  outline-offset: 4px;
  border-radius: 8px;
}
.hero-scroll-chevron {
  width: 38px;
  height: 38px;
  filter: drop-shadow(0 1px 6px rgba(6, 20, 33, 0.5));
  animation: hero-scroll-bounce 2s ease-in-out infinite;
}
@keyframes hero-scroll-bounce {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(6px); }
}
@media (prefers-reduced-motion: reduce) {
  .hero-scroll-chevron { animation: none; }
}

/* The page below the hero rides up over the pinned hero backdrop (gradient +
   video, position:fixed at negative z-index). page-flow itself is TRANSPARENT
   and sits above the video (z-index:1); each section paints its own opaque
   background to cover the video, EXCEPT the Convictions section, which is left
   transparent so the river shows through as the one mid-page video reveal.
   Keeping the cover on each section (not on this wrapper) is what lets a single
   section punch through to the video. */
.page-flow {
  position: relative;
  z-index: 1;
}
/* Each opaque section sets its own background (see the cinematic-home block
   below). The Convictions section deliberately does NOT, so the river shows
   through it. The give band keeps its own blue. */

/* Land below the fixed header when the cue is clicked */
#welcome-next { scroll-margin-top: var(--header-h); }

/* Staggered delay for reveal animations */
[data-delay="0"] { transition-delay: 0ms; }
[data-delay="80"] { transition-delay: 80ms; }
[data-delay="160"] { transition-delay: 160ms; }
[data-delay="240"] { transition-delay: 240ms; }
[data-delay="320"] { transition-delay: 320ms; }
[data-delay="200"] { transition-delay: 200ms; }
[data-delay="400"] { transition-delay: 400ms; }
[data-delay="600"] { transition-delay: 600ms; }
[data-delay="800"] { transition-delay: 800ms; }
@media (prefers-reduced-motion: reduce) {
  [data-delay] { transition-delay: 0ms !important; }
}

/* A more pronounced, graceful reveal for the visit panel and the conviction
   tiles — slower rise so the stagger is clearly perceptible (the default 0.75s
   with tight delays was too quick to read). Use the duration LONGHAND so it does
   not reset the transition-delay set by [data-delay]. */
.invite__panel.reveal,
.conviction.reveal {
  transition-duration: 0.95s;
}

/* ----------------------------------------------------------
   VISIT INVITE (Section 2)
   ---------------------------------------------------------- */
.visit-invite {
  padding-block: var(--space-6);
  border-bottom: 1px solid var(--color-line);
  /* Section spans full width; .container inside handles side padding */
}
.visit-inner {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: 1fr;
}
.visit-detail-list {
  list-style: none;
  margin: 0 0 var(--space-4);
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
}
.visit-detail {
  display: grid;
  grid-template-columns: 8rem 1fr;
  gap: var(--space-2);
  padding: 0.9rem 0;
  border-bottom: 1px solid var(--color-line);
  align-items: baseline;
}
.visit-detail-label {
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-muted);
  white-space: nowrap;
}
.visit-detail-value {
  font-size: 0.98rem;
  color: var(--color-ink);
}
/* On phones the 8rem label column plus an unbreakable value (the contact email
   is 28 characters and will not wrap) sets a min-content floor wider than the
   screen, which scrolled the whole page sideways. Stacking the label over the
   value removes the floor and gives the value the full width, so the email
   stays on one line rather than being broken across two. */
@media (max-width: 47.99rem) {
  .visit-detail {
    grid-template-columns: 1fr;
    gap: 0.25rem;
  }
}
.visit-inner > * { min-width: 0; }
.visit-lead {
  font-size: 1.08rem;
  line-height: 1.7;
  color: var(--color-ink-soft);
  margin: 0 0 var(--space-4);
  max-width: 54ch;
}
/* Home "Plan Your Visit" photo (scoped to .visit-invite so it doesn't affect
   the Visit page, which reuses .visit-aside for a text box). */
.visit-invite .visit-aside {
  border-radius: var(--radius);
  overflow: hidden;
  aspect-ratio: 4 / 3;
  align-self: center;
}
.visit-photo {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* Visit page "What to Expect" text aside */
.visit-aside-card {
  padding: var(--space-4);
  border-left: 3px solid var(--color-accent);
  background: var(--color-bg-tint);
}
.visit-aside-text {
  font-size: 1.05rem;
  line-height: 1.7;
  color: var(--color-ink-soft);
  margin: 0;
  max-width: 56ch;
}

/* ----------------------------------------------------------
   INLINE LINK (shared utility)
   ---------------------------------------------------------- */
/* The small arrow link used inside cards and section bodies site-wide. Card
   families that need it pinned to the bottom edge (so links align across a row)
   set margin-top: auto on it themselves; see .connect-hub-card. */
.inline-link {
  font-size: 0.9rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--link-ink);
  text-decoration: none;
}
.inline-link:hover { text-decoration: underline; }

/* ----------------------------------------------------------
   WATCH (Section 5)
   ---------------------------------------------------------- */
.watch-section {
  padding-block: var(--space-6);
  background: var(--color-bg-soft);
  border-bottom: 1px solid var(--color-line);
}
.watch-inner {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
  align-items: center;
}
/* YouTube facade: thumbnail + play button until clicked, then swapped for the
   real player by main.js. Keeps the landing page from loading the YT player. */
.yt-facade {
  position: relative;
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  aspect-ratio: 16/9;
  border-radius: var(--radius);
  background-color: var(--color-deep);
  background-size: cover;
  background-position: center;
  cursor: pointer;
  overflow: hidden;
  transition: opacity 200ms ease;
}
.yt-facade::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.18);
  transition: background 200ms ease;
}
.yt-facade:hover::after,
.yt-facade:focus-visible::after { background: rgba(0, 0, 0, 0.05); }
.yt-facade-play {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 4.25rem;
  height: 4.25rem;
  padding-left: 0.35rem;
  font-size: 1.6rem;
  color: #fff;
  background: rgba(0, 0, 0, 0.55);
  border-radius: 50%;
  transition: background 200ms ease, transform 200ms ease;
}
.yt-facade:hover .yt-facade-play,
.yt-facade:focus-visible .yt-facade-play {
  background: var(--color-teal, rgba(0, 0, 0, 0.75));
  transform: translate(-50%, -50%) scale(1.06);
}
/* The injected iframe fills the same 16:9 box. */
.watch-thumb iframe {
  display: block;
  width: 100%;
  aspect-ratio: 16/9;
  border: 0;
  border-radius: var(--radius);
}

/* ----------------------------------------------------------
   EVENTS (Section 6)
   ---------------------------------------------------------- */
.events-section {
  padding-block: var(--space-6);
  border-bottom: 1px solid var(--color-line);
}
.events-section .section-label,
.events-section .section-heading {
  text-align: left;
  display: block;
}
.events-inner {
  /* inner container applied via .container in template */
}
.events-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
.event-card {
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  gap: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--color-line);
  background: var(--color-bg-soft);
  align-items: start;
  transition: border-color 200ms ease;
}
.event-card:hover { border-color: var(--color-accent); }
.event-card-date {
  display: flex;
  flex-direction: column;
  align-items: center;
  border-right: 1px solid var(--color-line);
  padding-right: var(--space-3);
}
.event-month {
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-accent);
}
.event-day {
  font-family: var(--font-display);
  font-size: 2rem;
  font-weight: 400;
  color: var(--color-ink);
  line-height: 1;
}
.event-title {
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 400;
  margin: 0 0 0.35rem;
  color: var(--color-ink);
}
.event-meta {
  font-size: 0.85rem;
  color: var(--color-muted);
  margin: 0;
}
.events-footer { margin-top: var(--space-2); }

/* ----------------------------------------------------------
   GIVE BAND (Section 7)
   ---------------------------------------------------------- */
.give-band {
  --section-accent: var(--section-accent-on-dark); /* dark ground: the readable blue shade */
  background:
    radial-gradient(ellipse 70% 80% at 100% 50%, #1772c2 0%, transparent 60%),
    linear-gradient(135deg, #082742 0%, #0e4f86 100%);
  color: #fff;
  padding-block: var(--space-6);
}

/* A content section painted with the give-band blue (used on About > Our
   Pillars). Flip the heading, labels, and accordion chrome to light so
   everything stays readable on the deep gradient. */
.section-deep-band {
  --section-accent: var(--section-accent-on-dark); /* dark ground: the readable blue shade */
  background:
    radial-gradient(ellipse 70% 80% at 100% 50%, #1772c2 0%, transparent 60%),
    linear-gradient(135deg, #082742 0%, #0e4f86 100%);
  color: #fff;
}
.section-deep-band .section-heading { color: #fff; }
.section-deep-band .accordion-list { border-top-color: rgba(255, 255, 255, 0.28); }
.section-deep-band .accordion-item { border-bottom-color: rgba(255, 255, 255, 0.28); }
.section-deep-band .accordion-summary-text { color: #fff; }
/* Open accordion: title + chevron flip from white to the band's link cyan. */
.section-deep-band details[open] .accordion-summary-text { color: var(--color-accent-light); }
.section-deep-band .accordion-caret::before { border-color: rgba(255, 255, 255, 0.75); }
.section-deep-band details[open] .accordion-caret::before { border-color: var(--color-accent-light); }
.section-deep-band .accordion-body,
.section-deep-band .accordion-body p { color: rgba(255, 255, 255, 0.9); }
.section-deep-band .accordion-body a { color: var(--color-accent-light); }
.section-deep-band .value-block-name { color: #fff; }
.section-deep-band .value-block-tagline { color: rgba(255, 255, 255, 0.85); }
.give-inner {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
  align-items: center;
}
.give-content { min-width: 0; }
.give-verse {
  margin: 0;
}
.give-verse-text {
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.55rem, 3.8vw, 2.4rem);
  line-height: 1.35;
  color: #fff;
  margin: 0 0 var(--space-3);
}
.give-verse-ref {
  display: block;
  font-family: var(--font-sans);
  font-style: normal;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--section-accent);
}
.give-heading {
  font-family: var(--font-display);
  font-size: clamp(1.8rem, 5vw, 3rem);
  font-weight: 400;
  margin: 0 0 var(--space-3);
  color: #fff;
  max-width: 22ch;
}
.give-heading em {
  font-style: italic;
  color: var(--section-accent);
}
.give-sub {
  font-size: 1.05rem;
  color: rgba(255,255,255,0.65);
  max-width: 44ch;
  margin: 0 0 var(--space-4);
  line-height: 1.65;
}
.give-band .placeholder-badge {
  background: rgba(255,255,255,0.12);
  color: rgba(255,255,255,0.85);
  border-color: rgba(255,255,255,0.35);
}

/* ----------------------------------------------------------
   FOOTER
   ---------------------------------------------------------- */
.site-footer {
  background: var(--color-footer);
  color: rgba(255,255,255,0.62);
  font-size: 0.9rem;
}
.footer-inner {
  display: grid;
  gap: var(--space-5);
  padding-block: var(--space-6) var(--space-3);
  grid-template-columns: 1fr;
}
.site-footer a { color: rgba(255,255,255,0.7); text-decoration: none; }
.site-footer a:hover { color: #fff; }

.footer-address {
  line-height: 1.9;
}
.footer-address p { margin: 0; }
.footer-heading {
  font-family: var(--font-sans);
  font-size: 0.8rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  /* the footer is always dark, on every page: the dark-ground blue */
  color: var(--section-accent-on-dark);
  margin: 0 0 var(--space-3);
}
.footer-col ul { list-style: none; margin: 0; padding: 0; }
.footer-col li { margin-bottom: 0.65rem; }
/* Nav columns: brighter links so Explore / Resources stand out from the address */
.footer-col--nav a { color: rgba(255,255,255,0.88); }
.footer-col--nav a:hover { color: var(--color-accent); }
.footer-copy {
  margin: var(--space-4) 0 0;
  /* 0.78rem at 40% white measured 3.80:1 on the footer's near-black. Raised to
     60% (7.27:1) and up a step in size. Still clearly the quietest text on the
     page, now readable. */
  font-size: 0.85rem;
  color: rgba(255,255,255,0.60);
}

/* Oversized brand wordmark (the logo lockup) spanning the full width at the
   very bottom of the footer. Shown whole, sitting large near the bottom edge. */
.footer-wordmark-band {
  padding-top: var(--space-3);
  /* No bottom padding so the wordmark sits flush with the bottom of the page. */
  padding-bottom: 0;
  /* Inset to the same gutter as the rest of the footer so the wordmark sits
     intentionally rather than bleeding off the screen edges. */
  padding-inline: clamp(1.25rem, 4vw, 4rem);
}
.footer-wordmark-giant {
  display: block;
  width: 100%;
  /* Preserve the wordmark's native proportions (2028 x 343) now that the
     element is a recolorable masked box rather than an <img>. */
  aspect-ratio: 2028 / 343;
  /* Fill the element and use the PNG's alpha as a mask. Uses the site's signature
     brand blue (--color-primary, same as the give band above) rather than the
     cyan accent, which read slightly green/teal down here in the dark footer. */
  background-color: var(--color-primary);
  -webkit-mask: url("/images/Overflow.png") center / contain no-repeat;
          mask: url("/images/Overflow.png") center / contain no-repeat;
  opacity: 0.2;
  user-select: none;
  pointer-events: none;
}

/* Center both nav columns (heading + links) so they read symmetrically */
.footer-col--nav { text-align: center; }
/* Explore: two columns of links under the centered heading */
.footer-col--explore ul {
  column-count: 2;
  column-gap: calc(var(--space-5) / 2);
}
.footer-col--explore li { break-inside: avoid; }

/* ----------------------------------------------------------
   DESKTOP BREAKPOINTS (48rem+)
   ---------------------------------------------------------- */
@media (min-width: 48rem) {

  /* Desktop inline nav with hover dropdowns replaces the hamburger here */
  .primary-nav { display: block; }
  .nav-toggle { display: none; }

  /* Mega menu grid: more columns on desktop */
  .mega-menu-inner {
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-5) var(--space-6);
    padding-block: var(--space-5);
  }

  /* Visit section 2-col */
  .visit-inner {
    grid-template-columns: 1fr 1fr;
    align-items: start;
  }
  /* Times & Location: words keep the original half-width column (so the detail
     text breathes and doesn't wrap awkwardly); the map is vertically centered
     against them. Horizontal placement of the map is handled in the wide-screen
     block below. */
  .visit-inner--location {
    grid-template-columns: 1fr 1fr;
    align-items: center;
  }
  .visit-inner--location .visit-map-wrap {
    aspect-ratio: 3 / 2;
  }
  /* Home Plan Your Visit: intro + details stacked on the left, photo on the
     right spanning both (vertically centered). On mobile (below this query) the
     three blocks simply stack in source order: intro, photo, details. */
  .visit-invite .visit-inner {
    grid-template-areas:
      "intro photo"
      "details photo";
  }
  .visit-invite .visit-intro { grid-area: intro; }
  .visit-invite .visit-aside { grid-area: photo; }
  .visit-invite .visit-details { grid-area: details; }

  /* Watch 2-col */
  .watch-inner { grid-template-columns: 1fr 1fr; }

  /* Events 2-col */
  .events-row { grid-template-columns: repeat(2, 1fr); }

  /* Give band: content pinned to the page-container left edge, verse extends
     right into the full-width band with a generous gap. */
  /* Content + verse sit as one block, centered in the band with equal margins
     to both screen edges, while keeping the same column widths (and verse
     width) as before. Splitting the container slack in four puts an equal
     margin on each side. */
  .give-inner {
    width: auto;
    max-width: none;
    margin-inline: max(0px, calc((100% - var(--container)) / 4));
    grid-template-columns: minmax(26rem, 34rem) minmax(0, 1fr);
    gap: var(--space-6);
  }

  /* Footer 3-col */
  .footer-inner { grid-template-columns: 2fr 1fr 1fr; }
}

@media (min-width: 64rem) {
  /* Mega menu: all 7 sections on one row (tighter column gap so they fit) */
  .mega-menu-inner { grid-template-columns: repeat(7, minmax(0, 1fr)); column-gap: var(--space-3); }
  .mega-col-list { gap: 0; }
}

/* ----------------------------------------------------------
   FOCUS STYLES (accessibility)
   ---------------------------------------------------------- */
:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 3px;
  border-radius: 2px;
}
a:focus-visible,
button:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 3px; }

/* ----------------------------------------------------------
   REDUCED MOTION — skip header slide animation
   ---------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  .site-header {
    transition: none;
  }
  .site-header.is-hidden {
    /* Still hide but without animation */
    transform: translateY(-100%);
    transition: none;
  }
}

/* ----------------------------------------------------------
   INTERIOR PAGE HERO — lighter variant for inner pages
   Shares brand-blue DNA with the home hero but at ~40vh height.
   ---------------------------------------------------------- */
.page-hero {
  position: relative;
  overflow: hidden;
  min-height: 36vh;
  display: flex;
  align-items: flex-end;
  color: #fff;
  padding-bottom: var(--space-6);
}
.page-hero-bg {
  position: absolute;
  inset: 0;
  z-index: 0;
}
.page-hero-mesh {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 70% 80% at 10% 40%, #1772c2 0%, transparent 55%),
    radial-gradient(ellipse 55% 70% at 90% 60%, #0a3a66 0%, transparent 50%),
    radial-gradient(ellipse 40% 50% at 60% 0%, #4dc4e8 0%, transparent 45%),
    linear-gradient(160deg, #082742 0%, #0e4f86 55%, #061d33 100%);
}
/* Visit page: real church photo behind the hero, with a dark gradient so the
   white title stays legible over the lower (building) portion of the image. */
.page-hero--photo {
  min-height: 48vh;
}
.page-hero--photo .page-hero-mesh {
  background-color: #061d33;
  background-image:
    linear-gradient(to bottom, rgba(6,21,38,0.30) 0%, rgba(6,21,38,0.48) 52%, rgba(6,21,38,0.9) 100%),
    url("/images/visit-hero.webp");
  background-image:
    linear-gradient(to bottom, rgba(6,21,38,0.30) 0%, rgba(6,21,38,0.48) 52%, rgba(6,21,38,0.9) 100%),
    image-set(url("/images/visit-hero.avif") type("image/avif"), url("/images/visit-hero.webp") type("image/webp"));
  background-size: cover;
  background-position: center 40%;
  background-repeat: no-repeat;
}
/* Section photo header — image-only banner up top (the photo breathes, tied to
   the home hero by the shared grain), with the page title/intro below on the page
   background. The banner's lower edge fades into --color-bg so the image melts
   into the page. One image per top-level section, shared by its child pages. */
.page-banner {
  position: relative;
  overflow: hidden;
  min-height: 44vh;
}
/* Shared treatment: crop, position, and the overlay (a top nav-darken plus a
   bottom fade that melts the image into the page via --banner-fade: full melt in
   dark, gentle on white in light). Each section overrides only its photo below. */
.page-banner .page-hero-mesh {
  background-color: #0b2c49;
  background-size: cover;
  background-position: center 40%;
  background-repeat: no-repeat;
}
.page-banner--about .page-hero-mesh {
  background-image:
    linear-gradient(to bottom, rgba(6,21,38,0.45) 0%, rgba(6,21,38,0.10) 20%, rgba(6,21,38,0) 52%, rgba(6,21,38,0) var(--banner-fade-start), var(--banner-fade) 100%),
    url("/images/headers/stream5.webp");
  background-image:
    linear-gradient(to bottom, rgba(6,21,38,0.45) 0%, rgba(6,21,38,0.10) 20%, rgba(6,21,38,0) 52%, rgba(6,21,38,0) var(--banner-fade-start), var(--banner-fade) 100%),
    image-set(url("/images/headers/stream5.avif") type("image/avif"), url("/images/headers/stream5.webp") type("image/webp"));
}
.page-banner--contact .page-hero-mesh {
  background-image:
    linear-gradient(to bottom, rgba(6,21,38,0.45) 0%, rgba(6,21,38,0.10) 20%, rgba(6,21,38,0) 52%, rgba(6,21,38,0) var(--banner-fade-start), var(--banner-fade) 100%),
    url("/images/headers/stream2.webp");
  background-image:
    linear-gradient(to bottom, rgba(6,21,38,0.45) 0%, rgba(6,21,38,0.10) 20%, rgba(6,21,38,0) 52%, rgba(6,21,38,0) var(--banner-fade-start), var(--banner-fade) 100%),
    image-set(url("/images/headers/stream2.avif") type("image/avif"), url("/images/headers/stream2.webp") type("image/webp"));
}
.page-banner--connect .page-hero-mesh {
  background-image:
    linear-gradient(to bottom, rgba(6,21,38,0.45) 0%, rgba(6,21,38,0.10) 20%, rgba(6,21,38,0) 52%, rgba(6,21,38,0) var(--banner-fade-start), var(--banner-fade) 100%),
    url("/images/headers/stream7.webp");
  background-image:
    linear-gradient(to bottom, rgba(6,21,38,0.45) 0%, rgba(6,21,38,0.10) 20%, rgba(6,21,38,0) 52%, rgba(6,21,38,0) var(--banner-fade-start), var(--banner-fade) 100%),
    image-set(url("/images/headers/stream7.avif") type("image/avif"), url("/images/headers/stream7.webp") type("image/webp"));
}
.page-banner--outreach .page-hero-mesh {
  background-image:
    linear-gradient(to bottom, rgba(6,21,38,0.45) 0%, rgba(6,21,38,0.10) 20%, rgba(6,21,38,0) 52%, rgba(6,21,38,0) var(--banner-fade-start), var(--banner-fade) 100%),
    url("/images/headers/stream6.webp");
  background-image:
    linear-gradient(to bottom, rgba(6,21,38,0.45) 0%, rgba(6,21,38,0.10) 20%, rgba(6,21,38,0) 52%, rgba(6,21,38,0) var(--banner-fade-start), var(--banner-fade) 100%),
    image-set(url("/images/headers/stream6.avif") type("image/avif"), url("/images/headers/stream6.webp") type("image/webp"));
}
.page-banner--events .page-hero-mesh {
  background-image:
    linear-gradient(to bottom, rgba(6,21,38,0.45) 0%, rgba(6,21,38,0.10) 20%, rgba(6,21,38,0) 52%, rgba(6,21,38,0) var(--banner-fade-start), var(--banner-fade) 100%),
    url("/images/headers/stream3.webp");
  background-image:
    linear-gradient(to bottom, rgba(6,21,38,0.45) 0%, rgba(6,21,38,0.10) 20%, rgba(6,21,38,0) 52%, rgba(6,21,38,0) var(--banner-fade-start), var(--banner-fade) 100%),
    image-set(url("/images/headers/stream3.avif") type("image/avif"), url("/images/headers/stream3.webp") type("image/webp"));
}
.page-banner--watch .page-hero-mesh {
  background-image:
    linear-gradient(to bottom, rgba(6,21,38,0.45) 0%, rgba(6,21,38,0.10) 20%, rgba(6,21,38,0) 52%, rgba(6,21,38,0) var(--banner-fade-start), var(--banner-fade) 100%),
    url("/images/headers/stream4.webp");
  background-image:
    linear-gradient(to bottom, rgba(6,21,38,0.45) 0%, rgba(6,21,38,0.10) 20%, rgba(6,21,38,0) 52%, rgba(6,21,38,0) var(--banner-fade-start), var(--banner-fade) 100%),
    image-set(url("/images/headers/stream4.avif") type("image/avif"), url("/images/headers/stream4.webp") type("image/webp"));
  /* stream4's water is low in the frame; shift this section's crop down so the
     stream shows (overrides the shared center 40%). */
  background-position: center 60%;
}
.page-banner--visit .page-hero-mesh {
  background-image:
    linear-gradient(to bottom, rgba(6,21,38,0.45) 0%, rgba(6,21,38,0.10) 20%, rgba(6,21,38,0) 52%, rgba(6,21,38,0) var(--banner-fade-start), var(--banner-fade) 100%),
    url("/images/visit-hero.webp");
  background-image:
    linear-gradient(to bottom, rgba(6,21,38,0.45) 0%, rgba(6,21,38,0.10) 20%, rgba(6,21,38,0) 52%, rgba(6,21,38,0) var(--banner-fade-start), var(--banner-fade) 100%),
    image-set(url("/images/visit-hero.avif") type("image/avif"), url("/images/visit-hero.webp") type("image/webp"));
}
/* Policies and Resources reuse the Contact section's forest/stream image
   (stream2) for now, per Ryan 2026-07-24. Their own modifiers let a distinct
   image drop in later without touching Contact. */
.page-banner--policies .page-hero-mesh,
.page-banner--resources .page-hero-mesh {
  background-image:
    linear-gradient(to bottom, rgba(6,21,38,0.45) 0%, rgba(6,21,38,0.10) 20%, rgba(6,21,38,0) 52%, rgba(6,21,38,0) var(--banner-fade-start), var(--banner-fade) 100%),
    url("/images/headers/stream2.webp");
  background-image:
    linear-gradient(to bottom, rgba(6,21,38,0.45) 0%, rgba(6,21,38,0.10) 20%, rgba(6,21,38,0) 52%, rgba(6,21,38,0) var(--banner-fade-start), var(--banner-fade) 100%),
    image-set(url("/images/headers/stream2.avif") type("image/avif"), url("/images/headers/stream2.webp") type("image/webp"));
}
.page-title {
  text-align: center;
  padding: clamp(4.5rem, 10vw, 9rem) 0 clamp(1rem, 3vw, 1.75rem);
}
.page-title-heading {
  font-family: var(--font-display);
  font-size: clamp(2rem, 6vw, 3.8rem);
  font-weight: 600;
  line-height: 1.06;
  margin: 0 auto var(--space-2);
  max-width: 22ch;
  color: var(--color-ink);
}
.page-title-heading em {
  font-style: italic;
  font-weight: 400;
  /* page titles over photo banners are a dark ground, so their emphasis word
     takes the same --section-accent as everything else on that ground */
  color: var(--section-accent);
}
.page-title-sub {
  font-size: clamp(1.05rem, 2vw, 1.25rem);
  color: var(--color-ink-soft);
  /* All page-header subtitles share the Missional Communities width (92ch) so
     they read as one system site-wide. See the --wide note below. */
  max-width: 92ch;
  margin: 0 auto;
}
/* Retained for markup that still opts in; now equal to the base width above. */
.page-title-sub--wide { max-width: 92ch; }

/* Serve page: foundation scripture as a large, centered display pull quote.
   Italic Playfair in brand blue (theme-aware --color-primary), matching the
   site's blue italic accent words. Sized to sit on two lines on desktop. */
.serve-scripture {
  margin: 0 auto;
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.6rem, 3.3vw, 2.5rem);
  font-weight: 400;
  line-height: 1.3;
  color: var(--color-primary);
  max-width: 60ch;
  text-align: center;
}
.serve-scripture p { margin: 0; }
.serve-scripture-ref {
  display: block;
  margin-top: var(--space-3);
  font-family: var(--font-sans);
  font-style: normal;
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-primary);
}

/* Subtle divider between sub-sections (e.g., Upcoming vs Previous events) */
.section-divider {
  border: 0;
  border-top: 1px solid var(--color-line);
  margin: var(--space-6) 0;
}

/* Event listing (Send Her upcoming / previous gatherings) */
.event-list {
  list-style: none;
  margin: var(--space-5) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}
.event-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  border: 1px solid var(--color-line);
  background: var(--color-bg-soft);
  padding: var(--space-4);
}
.event-card__media { flex: 0 0 auto; }
.event-card__media img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius);
}
.event-card__body { flex: 1 1 auto; }
.event-card__date {
  font-family: var(--font-sans);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-primary);
  margin: 0 0 var(--space-1);
}
.event-card__title {
  font-family: var(--font-display);
  font-size: 1.6rem;
  font-weight: 400;
  margin: 0 0 var(--space-2);
  color: var(--color-ink);
}
.event-card__where {
  color: var(--color-muted);
  line-height: 1.6;
  margin: 0 0 var(--space-3);
}
@media (min-width: 40rem) {
  .event-card { flex-direction: row; align-items: center; gap: var(--space-5); }
  .event-card__media { flex: 0 0 260px; }
}
.page-hero-grain {
  position: absolute;
  inset: 0;
  opacity: 0.04;
  background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='1'/%3E%3C/svg%3E");
  background-size: 200px 200px;
}
.page-hero-inner {
  position: relative;
  z-index: 1;
  width: 100%;
  padding-inline: clamp(1.25rem, 4vw, 4rem);
  padding-top: calc(var(--header-h) + var(--space-5));
  max-width: var(--container);
  margin-inline: auto;
  text-align: center;
}
/* Hidden on the supplementary pages: the eyebrow just restated the page title,
   which read oddly. Kept in the markup for structure/breadcrumb context. */
.page-hero-eyebrow {
  display: none;
}
.page-hero-title {
  font-family: var(--font-display);
  font-size: clamp(2rem, 6vw, 3.8rem);
  font-weight: 600;
  line-height: 1.06;
  margin: 0 auto var(--space-2);
  color: #fff;
  max-width: 24ch;
}
.page-hero-title em {
  font-style: italic;
  font-weight: 400;
  color: var(--color-accent);
}
.page-hero-sub {
  font-size: clamp(0.95rem, 2vw, 1.1rem);
  font-weight: 300;
  color: rgba(255,255,255,0.72);
  max-width: 48ch;
  margin: 0 auto;
  line-height: 1.6;
}

/* ----------------------------------------------------------
   INTERIOR CONTENT SECTIONS
   ---------------------------------------------------------- */

/* Generic padded section */
.content-section {
  padding-block: var(--section-pad);
  border-bottom: 1px solid var(--color-line);
}
.content-section:last-child { border-bottom: none; }
.content-section--no-rule { border-bottom: none; }

/* Prose section — constrained measure */
.prose-section {
  padding-block: var(--section-pad);
  border-bottom: 1px solid var(--color-line);
}
.prose-section:last-child { border-bottom: none; }
.prose-body {
  max-width: 68ch;
  font-size: 1.05rem;
  line-height: 1.75;
  color: var(--color-ink-soft);
}
.prose-body p { margin: 0 0 var(--space-3); }
.prose-body p:last-child { margin-bottom: 0; }
.prose-body ul {
  margin: 0 0 var(--space-3);
  padding-left: 1.4em;
}
.prose-body li { margin-bottom: 0.5rem; line-height: 1.65; }
.prose-body strong { color: var(--color-ink); font-weight: 600; }
.prose-body a { color: var(--color-primary); }
.prose-body a:hover { text-decoration: underline; }

/* ----------------------------------------------------------
   ACCORDION (details / summary — native HTML, no JS)
   ---------------------------------------------------------- */
.accordion-list {
  list-style: none;
  margin: var(--space-4) 0 0;
  padding: 0;
  border-top: 1px solid var(--color-line);
}
.accordion-item {
  border-bottom: 1px solid var(--color-line);
}
.accordion-item details {
  /* Removes native disclosure marker fully in most browsers */
}
.accordion-item summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  list-style: none;
  cursor: pointer;
  padding: var(--space-3) 0;
  gap: var(--space-3);
  min-height: 44px;
  user-select: none;
}
/* Hide the native marker in WebKit */
.accordion-item summary::-webkit-details-marker { display: none; }
/* Hide in Firefox */
.accordion-item summary::marker { display: none; }

.accordion-summary-text {
  font-family: var(--font-display);
  font-size: clamp(1.2rem, 2.5vw, 1.5rem);
  font-weight: 400;
  color: var(--color-ink);
  line-height: 1.2;
  transition: color 200ms ease;
}
/* Clean minimal chevron (a thin "v"), no circle */
.accordion-caret {
  flex-shrink: 0;
  position: relative;
  width: 18px;
  height: 18px;
  color: transparent;
  font-size: 0;
  transition: transform 280ms ease;
}
.accordion-caret::before {
  content: "";
  position: absolute;
  top: 35%;
  left: 50%;
  width: 11px;
  height: 11px;
  transform: translate(-50%, -50%) rotate(45deg);
  border-right: 2px solid var(--color-muted);
  border-bottom: 2px solid var(--color-muted);
  transition: border-color 200ms ease;
}
details[open] .accordion-caret {
  transform: rotate(180deg);
}
details[open] .accordion-caret::before {
  border-color: var(--color-accent);
}
.accordion-body {
  padding: 0 0 var(--space-4);
  max-width: none;
}
.accordion-body p {
  font-size: 1.02rem;
  line-height: 1.75;
  color: var(--color-ink-soft);
  margin: 0 0 var(--space-3);
}
.accordion-body p:last-child { margin-bottom: 0; }
.accordion-body a { color: var(--color-primary); }
.accordion-body a:hover { text-decoration: underline; }

/* Core value blocks (full text inside the About accordion) */
.value-block { margin-bottom: var(--space-4); }
.value-block:last-child { margin-bottom: 0; }
.value-block-name {
  font-family: var(--font-display);
  font-size: 1.3rem;
  margin: 0 0 var(--space-1);
  color: var(--color-ink);
}
.value-block-tagline {
  font-weight: 600;
  color: var(--color-primary);
  margin: 0 0 var(--space-1);
}

/* Belief topic list (summary on the About accordion) */
.belief-topic-list {
  margin: var(--space-2) 0 var(--space-3);
  padding-left: 1.1rem;
  columns: 2;
  color: var(--color-ink-soft);
}
.belief-topic-list li { margin-bottom: 0.3rem; }

/* Full-vision lead sentence */
.vision-lead {
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 2.5vw, 1.7rem);
  line-height: 1.4;
  color: var(--color-ink);
  margin: 0 0 var(--space-4);
}

/* ----------------------------------------------------------
   VISIT PAGE — location block + map
   ---------------------------------------------------------- */
.visit-map-wrap {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 7;
  background: var(--color-bg-soft);
  border: 1px solid var(--color-line);
  border-radius: var(--radius);
  overflow: hidden;
}
.visit-map-wrap iframe {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}
/* Wide screens: widen the map's cell so it reaches the viewport's right edge,
   then center the fixed-size map within that band — i.e. centered horizontally
   between the right edge of the words and the right edge of the screen. The cell
   lands exactly at the viewport edge (no horizontal scroll); max-width keeps the
   map from overflowing the band on the narrow end of this range. */
@media (min-width: 72rem) {
  .visit-inner--location > div:last-child {
    min-width: 0;
    width: calc(100% + (100vw - var(--container)) / 2 + clamp(1.25rem, 4vw, 4rem));
    display: flex;
    align-items: center;
    justify-content: center;
  }
  .visit-inner--location .visit-map-wrap {
    width: 42.5rem;
    max-width: 100%;
    /* The cell's band starts a column-gap in from the words' right edge; this
       margin re-centers the map on the words' true right edge (shifts it left by
       half the gap) so it isn't a touch too far right. */
    margin-right: var(--space-5);
  }
}
/* Large screens: shift the When & Where left column into the left page margin so
   the heading ("Come as you are this Sunday") fits on one line — its natural
   width is wider than the half column. The shift is clamped so it never reaches
   the viewport edge or collides with the centered map. */
@media (min-width: 90rem) {
  .visit-inner--location > div:first-child {
    margin-left: calc(-1 * clamp(0rem, (100vw - var(--container)) / 2 - 2rem, 12rem));
  }
  .visit-location-heading {
    white-space: nowrap;
  }
}
/* Decorative cross-line flourish under page headers. A cross spacer, so it
   carries the site's gold: brass on light grounds (visible on white and over
   photo banners without needing text contrast), bright gold on dark. The
   membership nightfall flourish keeps its own blue (a gold spacer would clash
   with the gold constellation name right below it), so it is excluded. */
.expect-flourish {
  display: block;
  width: clamp(14rem, 38vw, 22rem);
  aspect-ratio: 764 / 35;
  margin: var(--space-3) auto var(--space-4);
  background-color: var(--color-gold);
  -webkit-mask: url("/images/cross-line.webp") center / contain no-repeat;
          mask: url("/images/cross-line.webp") center / contain no-repeat;
}
:root[data-theme="dark"] .expect-flourish:not(.nightfall__flourish) {
  background-color: var(--color-gold-bright);
}
/* What to Expect: deep-blue band matching the home page Give section, fixed in
   both light and dark themes. Text/accent flip to light so they read on the
   dark ground. */
.expect-band {
  --section-accent: var(--section-accent-on-dark); /* dark ground: the readable blue shade */
  background:
    radial-gradient(ellipse 70% 80% at 100% 50%, #1772c2 0%, transparent 60%),
    linear-gradient(135deg, #082742 0%, #0e4f86 100%);
  color: #fff;
  /* Keep the blue band at its original size; only the standard (non-band)
     sections take the larger --section-pad. */
  padding-block: var(--space-6);
}
.expect-band .section-heading { color: #fff; }
.expect-band .section-heading em { color: var(--section-accent); }
.expect-band .section-sub { color: rgba(255, 255, 255, 0.82); }
.expect-band .expect-flourish { background-color: var(--color-gold-bright); }
.visit-cta-card {
  background: var(--color-bg-tint);
  border: 1px solid var(--color-line);
  padding: var(--space-4);
  margin-top: var(--space-4);
}
.visit-cta-card p {
  font-size: 1.05rem;
  color: var(--color-ink-soft);
  line-height: 1.7;
  margin: 0 0 var(--space-3);
}
.visit-cta-card p:last-child { margin-bottom: 0; }

/* ----------------------------------------------------------
   VISIT PAGE — community heat map
   ---------------------------------------------------------- */
.heatmap-wrap {
  position: relative;
  width: 100%;
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: 0 2px 16px rgba(0,0,0,0.12);
  margin-top: var(--space-4);
}
.heatmap-img {
  display: block;
  width: 100%;
  height: auto;
}
/* Default: show light image via <picture>, hide theme-dark img */
.heatmap-img--theme-dark {
  display: none;
}
/* When site dark theme is active via data-theme="dark" on <html> */
:root[data-theme="dark"] .heatmap-img--default {
  display: none;
}
:root[data-theme="dark"] .heatmap-img--theme-dark {
  display: block;
}
/* Driven purely by the site theme (data-theme is always set on load), so the
   light map shows on the light site and the dark map on the dark site,
   regardless of the OS color preference. */
:root[data-theme="light"] .heatmap-img--default {
  display: block;
}
:root[data-theme="light"] .heatmap-img--theme-dark {
  display: none;
}

/* ----------------------------------------------------------
   STAFF / TEAM GRID
   ---------------------------------------------------------- */
.team-grid {
  list-style: none;
  margin: var(--space-5) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-3);
}
.team-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  /* Mobile: one card per row so the names/titles get the full width */
  flex: 0 1 100%;
  border: 1px solid var(--color-line);
  background: var(--color-bg-soft);
  padding: var(--space-4) var(--space-3);
  transition: border-color 200ms ease;
}
/* Tablet: a few across */
@media (min-width: 48rem) {
  .team-card { flex: 0 1 160px; }
}
/* Exactly five across on desktop; partial last row stays centered */
@media (min-width: 64rem) {
  .team-card { flex: 0 0 calc((100% - 4 * var(--space-3)) / 5 - 2px); }
  /* Break the grid out of the 72rem container so the five cards get wider
     (~1/3) using the otherwise-empty side space. Viewport-aware cap avoids
     horizontal scroll on smaller laptops. */
  .team-grid {
    width: min(84rem, 94vw);
    max-width: none;
    margin-left: 50%;
    transform: translateX(-50%);
  }
}
.team-card:hover { border-color: var(--color-accent); }
.team-avatar {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  background: var(--color-primary);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: 1.6rem;
  font-weight: 400;
  color: #fff;
  margin-bottom: var(--space-3);
  flex-shrink: 0;
}
/* Staff portraits are wrapped in <picture> to offer a WebP fallback alongside
   the AVIF (Safari cannot decode AVIF before iPadOS 16). Take the wrapper out
   of the layout so the <img> stays the direct flex item and the percentage
   widths below keep resolving against the card rather than an inline wrapper. */
.team-card picture,
.staff-bio-aside picture {
  display: contents;
}
.team-photo {
  width: 132px;
  height: 132px;
  border-radius: 50%;
  object-fit: cover;
  object-position: center top;
  background: var(--color-bg-soft);
  margin-bottom: var(--space-3);
  flex-shrink: 0;
}
/* Desktop: photo scales with the wider card so the gap between the circle and
   the card edge stays constant (100% = card content box via .team-link). */
@media (min-width: 64rem) {
  .team-photo {
    width: calc(100% - 4px);
    height: auto;
    aspect-ratio: 1 / 1;
    max-width: 210px;
  }
}
.team-contact-email {
  display: inline-block;
  font-family: var(--font-sans);
  font-size: 1.25rem;
  font-weight: 600;
  color: var(--color-accent);
  text-decoration: none;
  word-break: break-word;
}
.team-contact-email:hover { text-decoration: underline; }

/* Script-style accent link — Playfair italic in accent blue, sized like a small
   display line. Closes supplemental CTA sections in place of a button pair
   (Connect, Care, Outreach). The [data-cta-pending] variant is an inert holder
   (e.g. Request C.A.R.E.) until its form exists; JS blocks its default. */
.cta-script-link {
  display: inline-block;
  margin-top: 0;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  /* Sized to sit visually level with the 1.2rem subtitle above it. Playfair
     italic reads a touch smaller than the Hanken body, so the number runs a
     hair larger to match by eye. Colour matches the heading em ("to begin")
     via --color-primary, which is theme-aware. */
  font-size: 1.3rem;
  line-height: 1.4;
  color: var(--color-primary);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.15em;
  transition: opacity 150ms ease;
}
.cta-script-link:hover {
  opacity: 0.82;
}
.cta-script-link[data-cta-pending] { cursor: pointer; }
.team-name {
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 400;
  color: var(--color-ink);
  margin: 0 0 0.3rem;
}
.team-title {
  /* Was --color-accent (#4dc4e8), measured 1.85:1 on the light card ground.
     The design system already records that this cyan is never text on a light
     ground; this had drifted back in. --section-accent resolves by ground:
     4.55:1 light, and the lighter blue on dark. */
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--section-accent);
  margin: 0;
  line-height: 1.5;
}

/* Clickable staff card → bio page */
.team-link {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  text-decoration: none;
  color: inherit;
}
.team-card:hover .team-name { color: var(--color-primary); }
.team-link:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 4px;
  border-radius: 8px;
}

/* ----------------------------------------------------------
   STAFF BIO PAGE (/about/staff/<slug>/)
   ---------------------------------------------------------- */
.staff-bio {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: 1fr;
  align-items: start;
}
@media (min-width: 48rem) {
  .staff-bio { grid-template-columns: 280px 1fr; }
}
.staff-bio-aside {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-3);
}
@media (min-width: 48rem) {
  .staff-bio-aside {
    position: sticky;
    top: calc(var(--header-h) + var(--space-3));
  }
}
.staff-bio-photo {
  width: 100%;
  max-width: 280px;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  object-position: center top;
  border-radius: 12px;
  background: var(--color-bg-soft);
}
.staff-bio-subhead {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 400;
  color: var(--color-ink);
  margin: var(--space-5) 0 var(--space-2);
}
.staff-bio-pending {
  color: var(--color-muted);
  font-style: italic;
}

/* ----------------------------------------------------------
   CONNECT PAGE — full hub cards
   ---------------------------------------------------------- */
/* "Our Story" heritage animation (self-contained React piece at
   /media/legacy-video/). Full-bleed and transparent so it reads as part of the
   page: the rail spans the full viewport width and the page background (light or
   dark) shows through. Plays once, holds the final frame.
   Two canvases: desktop renders the original 1280x720 (16/9 box); mobile/tablet
   renders a 1280x1280 square canvas (1/1 box below) so type can be large with
   real space between the content and the timeline rail. The media query is the
   exact complement of the scroll-pin query, matching the JS branch in
   overflow-video.jsx. */
.legacy-video {
  position: relative;
  width: 100vw;
  left: 50%;
  margin-left: -50vw;
  aspect-ratio: 16 / 9;
  overflow: hidden;
}
@media not all and (min-width: 64rem) and (pointer: fine) {
  /* PAIRED WITH MOB.H in docs/legacy-video-src/overflow-video.jsx. The mobile
     canvas is 1280 wide by MOB.H tall; this box must be the same ratio or the
     piece letterboxes or crops. MOB.H went 1280 -> 1380 to add room at the
     BOTTOM of the canvas for the Next control, so this is no longer 1/1.
     Change one, change the other. */
  .legacy-video { aspect-ratio: 1280 / 1380; }
}
.legacy-video iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
  background: transparent;
  z-index: 0;
}
/* Fade the top edge into the page background above (the "Who We Are" header),
   the same way the animation's own dark gradient melts into the section below,
   so there is no stark line. --color-bg matches the adjacent background on both
   the light and dark site themes. */
.legacy-video::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  /* Short, subtle top blend only. The animation's own ground already matches the
     page background (light or dark), so a long fade isn't needed for a seamless
     edge; a tall fade instead dimmed the scene titles that sit near the top on
     mobile. Kept small so titles read at full strength. */
  height: 6%;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(to bottom, var(--color-bg) 0%, var(--color-bg) 5%, transparent 100%);
}

/* -------------------------------------------------------------
   Desktop scroll-pin for the "Our Story" animation.
   .story-scroll is a tall track; its sticky stage pins to the top of the
   viewport and holds the animation there, centered and covering the screen,
   for ~1 screen of scrolling before releasing. So as you scroll into it, the
   timeline locks dead-center, plays for a beat, then scrolls on. Desktop +
   fine-pointer only; phones/tablets keep the normal in-flow piece.
   ------------------------------------------------------------- */
@media (min-width: 64rem) and (pointer: fine) {
  .story-scroll {
    height: 200vh;          /* ~1 screen of held scroll before release; raise for a longer hold */
    padding: 0;
  }
  .story-scroll__stage {
    position: sticky;
    top: 0;
    height: 100vh;
    overflow: hidden;
    background: #0a1520;    /* the animation's own dark ground, so any edge blends */
  }
  .story-scroll__stage .legacy-video {
    position: absolute;
    top: 50%;
    left: 50%;
    /* The rail sits low in the canvas (~76%) with a faint ghost year up top, so a
       pure center reads bottom-heavy. Lift ~4% so the words + rail land centered.
       Tune the second value (-54%) if the balance needs a nudge. */
    transform: translate(-50%, -54%);
    margin: 0;
    width: 100vw;
    height: 56.25vw;        /* 16:9 */
    min-width: 177.7778vh;  /* cover the viewport, no letterbox bands */
    min-height: 100vh;
    aspect-ratio: auto;
  }
  .story-scroll__stage .legacy-video::before { display: none; } /* box-level fade is clipped in cover mode; use the stage fade below */
  /* Top-edge fade, recreated at the STAGE edge so the animation still melts into
     the dark section above as you scroll into the pin (the box-level fade gets
     clipped once the box covers the viewport). Fixed dark #0a1520 = the
     animation's own ground, so it matches the dark section above during the
     scroll-in and stays invisible once pinned (dark over dark), on both themes. */
  .story-scroll__stage::before {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 24%;
    z-index: 1;
    pointer-events: none;
    background: linear-gradient(to bottom, #0a1520 0%, #0a1520 5%, transparent 100%);
  }
}

.connect-hub-grid {
  list-style: none;
  margin: var(--space-5) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
  /* Every row matches the tallest card, not just the cards within one row.
     Grid already stretches siblings across a row, so a 3-up grid with 5 cards
     gave a 301px first row and a 277px second one, which read as a mistake.
     This also lets card copy vary in length without changing card size, which
     is what makes it safe to name a ministry's sub-areas inside its blurb. */
  grid-auto-rows: 1fr;
}
.connect-hub-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--color-line);
  background: var(--color-bg-soft);
  padding: var(--space-4);
  transition: transform 200ms ease, box-shadow 200ms ease, border-color 200ms ease;
}
/* Hover: accent the border, turn the title blue, and lift the card on a soft
   shadow. A restrained 3px lift, matching the hover language used across the
   site's other card families. */
.connect-hub-card:hover {
  border-color: var(--color-accent);
  transform: translateY(-3px);
  box-shadow: 0 14px 34px rgba(8, 39, 66, 0.12);
}
/* Dark mode: the drop shadow above is invisible against the dark ground, so the
   lift reads as almost nothing and the hover collapses to a border tint. Restore
   it with the same even blue glow the home page's .plug-card uses, so the hover
   language matches across themes: shadow in light, glow in dark. No offset, so
   the bloom is even on all sides.
   Scoped to exclude .connect-hub-grid--static (serve), where the hover
   affordance is deliberately stripped because those nine cards are
   informational rather than clickable. */
:root[data-theme="dark"] .connect-hub-grid:not(.connect-hub-grid--static) .connect-hub-card:hover {
  box-shadow: 0 0 32px 1px rgba(56, 150, 224, 0.18);
}
/* Push each card's CTA (link or button) to the bottom so they align across a row */
.connect-hub-card .inline-link,
.connect-hub-card .btn { margin-top: auto; }
.connect-hub-number {
  font-family: var(--font-display);
  font-size: 2.5rem;
  font-weight: 400;
  color: var(--color-line);
  line-height: 1;
  margin-bottom: var(--space-2);
}
.connect-hub-title {
  font-family: var(--font-display);
  font-size: 1.35rem;
  font-weight: 400;
  margin: 0 0 var(--space-2);
  color: var(--color-ink);
  transition: color 180ms ease;
}
.connect-hub-text {
  font-size: 0.97rem;
  color: var(--color-muted);
  margin: 0 0 var(--space-3);
  line-height: 1.6;
  max-width: 52ch;
}
/* Hover text uses --color-primary, not --color-accent. The accent cyan (#4dc4e8)
   measures 1.85:1 against the card ground (#f2f5f8) in light mode, well under the
   4.5:1 AA floor for the 21.6px title; it only ever looked fine because on a dark
   ground the same cyan is 8.37:1. --color-primary is 4.55:1 light / 6.54:1 dark.
   Affects the card grids on care, classes, ministries, outreach, resources, and
   contact. Do not revert to --color-accent for text on a light ground. */
.connect-hub-card:hover .connect-hub-number {
  color: var(--color-primary);
  transition: color 180ms ease;
}
.connect-hub-card:hover .connect-hub-title { color: var(--color-primary); }

@media (min-width: 48rem) {
  .connect-hub-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (min-width: 64rem) {
  .connect-hub-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

/* Classes page: all cards on one row on large screens. Keeps the card size by
   letting the row run wider than the 72rem text container (Ryan, Jul 22: same
   box size, one line, use more of the screen on big displays). */
@media (min-width: 64rem) {
  .connect-hub-grid--four {
    grid-template-columns: repeat(4, 1fr);
    width: min(94rem, 92vw);
    margin-left: 50%;
    transform: translateX(-50%);
  }
}

/* ----------------------------------------------------------
   C.A.R.E. framework (Connect landing) + care-page taglines
   .care-tagline: the verbatim Overflow tagline under each heading.
   .care-links: a wrapping row of destination links (wayfinding).
   ---------------------------------------------------------- */
.care-tagline {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.15rem;
  color: var(--color-accent);
  margin: 0 0 var(--space-3);
}
.care-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  margin-top: var(--space-4);
}

/* ----------------------------------------------------------
   FEATURE ROW — reusable interior-page editorial pattern
   A wide two-column row: an oversized serif initial (or figure) on one side,
   copy on the other, the side alternating with --flip. One continuous ground
   (no background banding), a hairline connector between rows so a sequence
   reads as one journey. This is the default way to lay out a run of sections
   on interior pages, replacing stacked full-width bands and the old
   light/dark zebra. First used for C.A.R.E. on /connect/.
   ---------------------------------------------------------- */
/* The group carries a full section-pad like any other section, so it breathes
   from its neighbours (intro above, CTA below) on the same rhythm as the rest of
   the site. The first/last row zero their outer edge padding so that section-pad
   is not doubled by row padding at the ends. Between rows the gap is two row
   paddings, tuned close to the site's inter-section rhythm. */
.feature-rows {
  padding-block: var(--section-pad);
}
.feature-row {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.6fr);
  align-items: center;
  gap: clamp(1.5rem, 5vw, 5rem);
  padding-block: clamp(4rem, 7.5vw, 7rem);
}
.feature-row:first-child { padding-top: 0; }
.feature-row:last-child { padding-bottom: 0; }
.feature-row + .feature-row {
  border-top: 1px solid var(--color-line);
}
/* Both items are pinned to grid-row 1. The initial comes first in the markup;
   on flipped rows it is placed in column 2 while the copy takes column 1, which
   runs "backward" relative to source order. Without an explicit row, Grid's
   sparse auto-placement drops the copy onto a second row instead of beside the
   initial, so a flipped row would stack diagonally instead of centering. */
.feature-row__figure { grid-column: 1; grid-row: 1; }
.feature-row__body   { grid-column: 2; grid-row: 1; }
/* Flip: copy sits on the left, the initial/figure on the right */
.feature-row--flip {
  grid-template-columns: minmax(0, 1.6fr) minmax(0, 0.85fr);
}
.feature-row--flip .feature-row__figure { grid-column: 2; grid-row: 1; }
.feature-row--flip .feature-row__body   { grid-column: 1; grid-row: 1; }

/* The initial hugs the copy side of its column (not floating dead-centre) so
   each initial/copy pair reads as one intentional unit. */
.feature-row__figure {
  display: flex;
  align-items: center;
  justify-content: flex-end;
}
.feature-row--flip .feature-row__figure { justify-content: flex-start; }
.feature-row__initial {
  font-family: var(--font-display);
  font-size: clamp(6rem, 13vw, 12.5rem);
  /* Full line box (>= 1) so the whole glyph sits inside the element's box. With a
     tighter line-height the round bottom of letters like C overshoots the box,
     and because background-clip:text paints the fill only INSIDE that box, the
     overshoot renders transparent and the letter looks cut off at the bottom. */
  line-height: 1;
  font-weight: 400;
  color: var(--section-accent);
  user-select: none;
}
/* Layer 2: fill each initial with the page's own stream imagery, blue-toned so
   the letters read as brand-coloured "windows" onto the photo rather than flat
   glyphs. Guarded by @supports so any browser without background-clip:text
   simply keeps the solid-blue fallback set above. */
@supports ((-webkit-background-clip: text) or (background-clip: text)) {
  .feature-row__initial {
    color: transparent;
    -webkit-text-fill-color: transparent;
    background-image:
      linear-gradient(150deg, rgba(23, 114, 194, 0.42) 0%, rgba(8, 39, 66, 0.72) 100%),
      image-set(
        url("/images/headers/stream7.avif") type("image/avif"),
        url("/images/headers/stream7.webp") type("image/webp"));
    /* Zoom in so each letter shows only a PORTION of the scene (cover shows
       almost the whole image, which is why the letters looked identical), then
       sample a different horizontal spot per letter (nth-child rules below), all
       within the same vertical band the header crops to (~20%). Static fill;
       Ryan found the fixed-attachment scroll reveal too busy at this letter size. */
    background-repeat: no-repeat;
    /* Two layers, sized independently: the tint gradient fills the whole glyph
       box (100% 100%); the photo is sized by HEIGHT (auto 130%) so it always
       covers the tall, narrow glyph. Sizing the photo by WIDTH made its height
       fall short of the glyph, leaving the bottom of each letter with no photo
       and exposing the flat tint as a hard blue band. Height-sizing guarantees
       full coverage while still leaving room to pan horizontally per letter. */
    background-size: 100% 100%, auto 130%;
    background-position: 50% 20%;
    -webkit-background-clip: text;
    background-clip: text;
  }
  /* Horizontal spread across the header's scene: C at the left through E at the
     right, so each initial reads as a different area of the same photo. */
  .feature-rows .feature-row:nth-child(1) .feature-row__initial { background-position: 12% 20%; }
  .feature-rows .feature-row:nth-child(2) .feature-row__initial { background-position: 40% 20%; }
  .feature-rows .feature-row:nth-child(3) .feature-row__initial { background-position: 62% 20%; }
  .feature-rows .feature-row:nth-child(4) .feature-row__initial { background-position: 88% 20%; }
}
/* On the dark ground the letters should stay luminous, so lighten the tint. */
:root[data-theme="dark"] .feature-row__initial {
  background-image:
    linear-gradient(150deg, rgba(125, 214, 239, 0.30) 0%, rgba(23, 114, 194, 0.55) 100%),
    image-set(
      url("/images/headers/stream7.avif") type("image/avif"),
      url("/images/headers/stream7.webp") type("image/webp"));
}
/* Title lockup: the movement's NAME is the big heading (the giant initial beside
   it supplies the letter), the evocative phrase is the deck beneath it. */
.feature-row__title { margin-top: 0; margin-bottom: var(--space-2); }
.feature-row__deck {
  font-family: var(--font-display);
  font-size: clamp(1.2rem, 2.4vw, 1.6rem);
  line-height: 1.3;
  color: var(--color-ink-soft);
  margin: 0 0 var(--space-3);
  max-width: 42ch;
}
.feature-row__deck em { font-style: italic; color: var(--section-accent); }
.feature-row__body .prose-body p:last-child { margin-bottom: 0; }

@media (max-width: 48rem) {
  .feature-row,
  .feature-row--flip {
    grid-template-columns: 1fr;
    gap: var(--space-2);
    padding-block: var(--space-5);
  }
  /* Stack the giant initial ABOVE the copy (figure row 1, body row 2). Without an
     explicit grid-row both stay pinned to row 1 from the base rules and overlap in
     one cell, so align-items:center floats the letter into the middle of the body. */
  .feature-row__figure,
  .feature-row--flip .feature-row__figure { grid-column: 1; grid-row: 1; }
  .feature-row__body,
  .feature-row--flip .feature-row__body { grid-column: 1; grid-row: 2; }
  .feature-row__figure { justify-content: flex-start; }
  /* Mobile: full line box (avoid the clip), and static attachment since iOS
     ignores fixed and it costs paint performance while scrolling. */
  .feature-row__initial { font-size: clamp(4.5rem, 22vw, 7rem); line-height: 1; background-attachment: scroll; }
}

/* ----------------------------------------------------------
   WHOLE-CARD CLICKABLE
   These promo cards each hold exactly one link, so we stretch that
   link across the whole card: a tap anywhere navigates, while the real
   <a> and its text stay in the DOM for screen readers (announced as a
   normal link). The pointer cursor follows the stretched link, so the
   whole card reads as clickable. Only safe on single-destination cards;
   never apply where a card holds two links (e.g. outreach partner rows).
   ---------------------------------------------------------- */
.connect-hub-card,
.plug-card { position: relative; }

.connect-hub-card .inline-link::after,
.plug-card .inline-link::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
}
/* Reinforce the affordance: hovering anywhere on the card underlines the link. */
.connect-hub-card:hover .inline-link,
.plug-card:hover .inline-link { text-decoration: underline; }

/* Keyboard focus: lift the card border and ring the link so the target is
   obvious when tabbing through. */
.connect-hub-card:focus-within { border-color: var(--color-accent); }
.connect-hub-card .inline-link:focus-visible,
.plug-card .inline-link:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 4px;
}

/* ----------------------------------------------------------
   MISSIONAL COMMUNITIES — full-width directory rows
   ---------------------------------------------------------- */
.mc-list {
  list-style: none;
  margin: var(--space-5) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.mc-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  border: 1px solid var(--color-line);
  background: var(--color-bg-soft);
  padding: var(--space-4);
  transition: border-color 200ms ease;
}
.mc-card:hover { border-color: var(--color-accent); }
/* Top row: name + schedule on the left, CTA on the right, the CTA vertically
   centered against the title/schedule block (not the whole card). */
.mc-card-head {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.mc-card-id { flex: 1 1 auto; }
.mc-card-title {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 400;
  margin: 0 0 var(--space-1);
  color: var(--color-ink);
}
.mc-card-meta {
  font-size: 0.95rem;
  color: var(--color-muted);
  margin: 0;
  line-height: 1.5;
}
.mc-card-meta strong { color: var(--color-ink); font-weight: 600; }
.mc-card-cta { flex: 0 0 auto; }
/* Compact button for these rows — the default .btn reads too large here. */
.mc-card .btn {
  padding: 0.58rem 1.3rem;
  font-size: 0.85rem;
  min-height: 40px;
}
.mc-card-desc {
  font-size: 0.97rem;
  color: var(--color-muted);
  line-height: 1.7;
}
.mc-card-desc p { margin: 0 0 var(--space-2); }
.mc-card-desc p:last-child { margin-bottom: 0; }

/* ----------------------------------------------------------
   MISSIONAL PARTNERS — alternating logo + text rows
   ---------------------------------------------------------- */
.partner-list {
  margin-top: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}
.partner-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.partner-media { flex: 0 0 auto; }
.partner-logo-frame {
  background: #fff;
  border: 1px solid var(--color-line);
  border-radius: 14px;
  padding: var(--space-4);
  min-height: 170px;
  display: flex;
  align-items: center;
  justify-content: center;
}
.partner-logo-frame img {
  max-width: 100%;
  max-height: 120px;
  width: auto;
  height: auto;
  object-fit: contain;
}
.partner-logo-frame--placeholder {
  background: var(--color-bg-soft);
  border-style: dashed;
  color: var(--color-muted);
  font-family: var(--font-display);
  font-size: 1rem;
  text-align: center;
}
.partner-name {
  font-family: var(--font-display);
  font-size: clamp(1.55rem, 3vw, 2.05rem);
  font-weight: 400;
  margin: 0 0 var(--space-1);
  color: var(--color-ink);
}
.partner-lead {
  font-weight: 500;
  color: var(--color-ink);
  margin: 0 0 var(--space-2);
  line-height: 1.55;
}
.partner-body p {
  color: var(--color-muted);
  line-height: 1.7;
  margin: 0 0 var(--space-2);
}
.partner-aims {
  margin: 0 0 var(--space-2);
  padding-left: 1.2em;
  color: var(--color-muted);
  line-height: 1.7;
}
.partner-aims li { margin-bottom: var(--space-1); }
.partner-links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1) var(--space-4);
  margin-top: var(--space-1);
}

@media (min-width: 56rem) {
  .partner-row {
    flex-direction: row;
    align-items: center;
    gap: var(--space-6);
  }
  .partner-row:nth-child(even) { flex-direction: row-reverse; }
  .partner-media { flex: 0 0 280px; }
  .partner-text { flex: 1 1 auto; }
}

/* ----------------------------------------------------------
   BELIEFS / LONG-FORM DOC — belief items
   ---------------------------------------------------------- */
.beliefs-list {
  list-style: none;
  margin: var(--space-4) 0 0;
  padding: 0;
  display: grid;
  gap: var(--space-4);
  grid-template-columns: 1fr;
}
.belief-item {
  border-left: 3px solid var(--color-accent);
  padding-left: var(--space-3);
}
.belief-heading {
  font-family: var(--font-display);
  font-size: 1.6rem;
  font-weight: 400;
  margin: 0 0 var(--space-2);
  color: var(--color-ink);
}
.belief-text {
  font-size: 1.1rem;
  line-height: 1.7;
  color: var(--color-ink-soft);
  margin: 0;
}

/* Single full-width column so each statement spans the page; shorter rows */
.beliefs-list {
  grid-template-columns: 1fr;
}

/* ----------------------------------------------------------
   ABOUT PAGE FIVE-FOLD TEASER
   ---------------------------------------------------------- */
.fivefold-teaser {
  padding: var(--space-4);
  border: 1px solid var(--color-line);
  background: var(--color-bg-tint);
  border-top: 3px solid var(--color-primary);
  margin-top: var(--space-4);
}
.fivefold-teaser p {
  font-size: 1.02rem;
  line-height: 1.7;
  color: var(--color-ink-soft);
  margin: 0 0 var(--space-2);
}
.fivefold-badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  margin: var(--space-2) 0 var(--space-3);
}
.fivefold-badge {
  display: inline-block;
  font-size: 0.85rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 0.3rem 0.75rem;
  border: 1.5px solid var(--color-accent);
  border-radius: var(--radius-pill);
  color: var(--color-accent);
  background: transparent;
}
/* Per-grace pill colours — outline and label match that grace's temple pillar. */
/* Border keeps the true brand colour; the LABEL uses the readable -ink variant.
   Borders are not held to a text contrast ratio, so the pill still reads as the
   right grace colour while the word inside it is legible in both themes. */
.fivefold-badge--apostolic    { border-color: var(--fold-apostolic);    color: var(--fold-apostolic-ink); }
.fivefold-badge--prophetic    { border-color: var(--fold-prophetic);    color: var(--fold-prophetic-ink); }
.fivefold-badge--evangelistic { border-color: var(--fold-evangelistic); color: var(--fold-evangelistic-ink); }
.fivefold-badge--shepherding  { border-color: var(--fold-shepherding);  color: var(--fold-shepherding-ink); }
.fivefold-badge--teaching     { border-color: var(--fold-teaching);     color: var(--fold-teaching-ink); }

/* ----------------------------------------------------------
   MOBILE-ONLY ADJUSTMENTS (below 48rem)
   ---------------------------------------------------------- */
@media (max-width: 47.99rem) {
  /* Home header eyebrow: stack on three lines, drop the separator dot */
  .hero-eyebrow .he-dot { display: none; }
  .hero-eyebrow .he-part { display: block; }

  /* Tighten the gap above and below the Plan Your Visit photo on mobile */
  .visit-invite .visit-inner { gap: var(--space-3); }

  /* Smaller Give verse on mobile */
  .give-verse-text { font-size: 1.25rem; }

  /* Five-fold badges: compact enough to wrap 3 + 2 (no orphaned single row) */
  .fivefold-badges { gap: 0.3rem; }
  .fivefold-badge {
    font-size: 0.6rem;
    letter-spacing: 0.03em;
    padding: 0.24rem 0.4rem;
  }
}

/* ----------------------------------------------------------
   THE FIVE GRACES — interactive temple of pillars
   ---------------------------------------------------------- */
.fold-temple-section {
  position: relative;
  background: #082742;            /* lighter navy blue band */
  color: #fff;
  padding-top: var(--space-5);
  padding-bottom: var(--space-5);  /* match the gap above the temple (hint margin) */
  overflow: hidden;
}
.fold-temple-intro {
  font-family: var(--font-display);
  font-weight: 400;
  text-align: center;
  color: #fff;
  font-size: clamp(1.9rem, 5vw, 3rem);   /* match the other section headings */
  margin: 0 0 0.35rem;
}
.fold-temple-intro em { font-style: italic; color: var(--color-primary); }
.fold-temple-hint {
  text-align: center; color: rgba(255,255,255,0.7);
  font-size: 0.9rem; letter-spacing: 0.02em; margin: 0 0 var(--space-5);
}

/* Per-fold color hooks */
.fold--apostolic    { --fold-self: var(--fold-apostolic);    --fold-cap-c: var(--fold-apostolic-cap); }
.fold--prophetic    { --fold-self: var(--fold-prophetic);    --fold-cap-c: var(--fold-prophetic-cap); }
.fold--evangelistic { --fold-self: var(--fold-evangelistic); --fold-cap-c: var(--fold-evangelistic-cap); }
.fold--shepherding  { --fold-self: var(--fold-shepherding);  --fold-cap-c: var(--fold-shepherding-cap); }
.fold--teaching     { --fold-self: var(--fold-teaching);     --fold-cap-c: var(--fold-teaching-cap); }

/* Temple — pillars stay wide; roof/steps are sized to the pillar block (--span)
   plus a small overhang, so they sit just outside the pillars (not the screen edge).
   The blue band itself is full width. */
.fold-temple {
  --span: min(1200px, 92vw);     /* width of the pillar block (the wide look) */
  --over-in: 44px;               /* inner bars: just outside the pillars */
  --over-out: 96px;              /* outer bars: a little farther */
  max-width: calc(var(--span) + var(--over-out));
  margin-inline: auto;
}
.fold-roof { position: relative; display: flex; flex-direction: column; align-items: center; }
.fold-pediment {
  width: calc(var(--span) + var(--over-in)); height: clamp(56px, 8vw, 132px);
  background: #eef3f7; clip-path: polygon(50% 0, 100% 100%, 0 100%);
}
/* Cross set into the pediment */
.fold-cross {
  position: absolute; left: 50%; top: clamp(8px, 1.4vw, 22px);
  transform: translateX(-50%); z-index: 1;
  width: clamp(10px, 1.13vw, 15px); height: clamp(43px, 5.75vw, 83px);
  background: #082742; border-radius: 2px;
}
.fold-cross::before {
  content: ""; position: absolute; left: 50%; top: 36%;
  transform: translate(-50%, -50%);
  width: clamp(33px, 4vw, 58px); height: clamp(10px, 1.13vw, 15px);
  background: #082742; border-radius: 2px;
}
.fold-entablature { width: calc(var(--span) + var(--over-out)); height: 22px; margin-top: 9px; background: #eef3f7; border-radius: 3px; }
.fold-entablature--thin { width: calc(var(--span) + var(--over-in)); height: 16px; }

.fold-colonnade {
  width: var(--span); margin-inline: auto;
  display: flex; align-items: flex-end; justify-content: center;
  gap: clamp(12px, 2.4vw, 44px);
  padding: clamp(14px, 2vw, 22px) 0;
}
.fold-pillar {
  position: relative;
  flex: 1 1 0; max-width: 230px; min-width: 0;
  display: flex; flex-direction: column; align-items: stretch;
  background: none; border: 0; padding: 0; margin: 0; font: inherit; color: #fff;
  cursor: pointer;
}
.fold-pillar::before {
  content: ""; position: absolute; inset: -26px -16px; z-index: 0;
  background: radial-gradient(ellipse at center, rgba(255,255,255,0.30), transparent 72%);
  opacity: 0; transition: opacity 0.3s ease; pointer-events: none;
}
.fold-pillar:hover::before, .fold-pillar:focus-visible::before { opacity: 1; }
.fold-pillar:focus-visible { outline: 2px solid #fff; outline-offset: 4px; }
.fold-pillar > * { position: relative; z-index: 1; }

.fold-cap { height: 34px; background: var(--fold-cap-c); border-radius: 3px 3px 0 0; }
.fold-shaft {
  position: relative; width: 84%; margin-inline: auto;
  height: clamp(180px, 21vw, 300px); background: var(--fold-self);
  display: flex; align-items: center; justify-content: center;
}
.fold-disc {
  width: clamp(82px, 9vw, 126px); aspect-ratio: 1; border-radius: 50%;
  border: 6px solid #fff; display: flex; align-items: center; justify-content: center;
}
.fold-icon { width: 70%; height: 70%; object-fit: contain; }
.fold--shepherding .fold-icon { transform: rotate(20deg) scale(1.16); }

.fold-base { height: 52px; background: var(--fold-cap-c); border-radius: 0 0 3px 3px; display: flex; align-items: center; justify-content: center; }
/* Navy sits on the five pillar caps, whose lightness varies by grace. Against
   the apostolic cap (#c57371, the darkest of them) --color-deep measured
   4.40:1, just under the floor; the other four passed. One step deeper clears
   all five (4.94:1 worst, on apostolic) and is imperceptible against the
   original navy, so the pillars keep their look. */
.fold-label {
  font-family: var(--font-display); font-weight: 600; color: #061d31;
  font-size: clamp(1rem, 1.45vw, 1.32rem); letter-spacing: 0.01em; line-height: 1;
}
.fold-label-m { display: none; }

.fold-steps { display: flex; flex-direction: column; align-items: center; gap: 8px; }
.fold-step { width: calc(var(--span) + var(--over-in)); height: 18px; background: #eef3f7; border-radius: 3px; }   /* top step (just below pillars) */
.fold-step--thin { width: calc(var(--span) + var(--over-out)); height: 22px; }                                     /* very bottom step — wider, same height as the cornice */

/* Overlay reveal — frosted glass card (matches the hero panel effect) */
.fold-overlay {
  position: fixed; inset: 0; z-index: 200;
  display: none; align-items: center; justify-content: center; padding: 24px;
  background: rgba(6, 20, 33, 0.45);
}
.fold-overlay.is-open { display: flex; animation: foldOverlayIn 0.25s ease; }
@keyframes foldOverlayIn { from { opacity: 0; } to { opacity: 1; } }
.fold-overlay-card {
  position: relative; width: min(560px, 92%); max-height: 86vh; overflow-y: auto;
  background: rgba(26, 36, 48, 0.55);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.12);
  color: #fff;
  border-radius: 14px; padding: clamp(30px, 4vw, 46px); text-align: center;
  box-shadow: 0 20px 60px rgba(0,0,0,0.4);
}
.fold-overlay-name {
  font-family: var(--font-display); font-style: italic; font-weight: 400;
  color: var(--fold-current, #fff);     /* match the clicked pillar's color */
  font-size: clamp(1.7rem, 3.6vw, 2.3rem); margin: 0 0 0.45rem;
}
.fold-overlay-tagline { font-family: var(--font-display); font-size: clamp(1.1rem, 2vw, 1.35rem); margin: 0 0 0.8rem; color: var(--color-accent-light); }
.fold-overlay-body { color: rgba(255,255,255,0.9); line-height: 1.65; margin: 0; font-size: 1.02rem; }
.fold-overlay-close {
  position: absolute; top: 8px; right: 14px;
  background: none; border: 0; cursor: pointer; font-size: 1.9rem; line-height: 1; color: rgba(255,255,255,0.7);
}
.fold-overlay-close:hover { color: #fff; }

/* Scroll frame + swipe hint (frame is a passthrough on desktop) */
.fold-temple-frame { position: relative; }
.fold-swipe-hint { display: none; }

/* ---- Mobile: roof + floor stay fixed; pillars snap-scroll through the slots (3 per view) ---- */
@media (max-width: 720px) {
  .fold-temple { --span: 100%; max-width: 520px; margin-inline: auto; }
  .fold-temple-scroll { overflow: visible; }

  /* fixed structure (does not scroll); roof keeps its height, the 4 bars are slimmer */
  .fold-pediment { width: 90%; }
  .fold-entablature { width: 96%; height: 14px; }
  .fold-entablature--thin { width: 90%; height: 10px; }
  .fold-step { width: 90%; height: 12px; }
  .fold-step--thin { width: 96%; height: 14px; }

  /* pillars: clean 3-up snap carousel inside the fixed frame */
  .fold-colonnade {
    width: 86%; margin-inline: auto;
    justify-content: flex-start;       /* start on Apostolic, not the centered middle */
    overflow-x: auto; overflow-y: hidden;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    gap: 12px; padding-block: 14px;
  }
  .fold-colonnade::-webkit-scrollbar { display: none; }
  .fold-pillar {
    flex: 0 0 calc((100% - 24px) / 3);   /* exactly three per view (two 12px gaps) */
    max-width: none; scroll-snap-align: start;
  }
  .fold-pillar::before { display: none; }   /* no hover glow on touch */

  /* proportional sizing so three sit cleanly */
  .fold-cap { height: 22px; }
  .fold-shaft { height: 152px; }
  .fold-disc { width: 72px; border-width: 5px; }
  .fold-icon { width: 72%; height: 72%; }
  .fold-base { height: 36px; }
  .fold-label { font-size: 0.82rem; font-weight: 700; }

  /* swipe affordance */
  .fold-swipe-hint {
    display: block; text-align: center; margin-top: var(--space-3);
    color: rgba(255,255,255,0.66); font-family: var(--font-sans);
    font-size: 0.8rem; letter-spacing: 0.08em; text-transform: uppercase;
  }
  .fold-swipe-arrow { display: inline-block; animation: foldSwipeNudge 1.6s ease-in-out infinite; }
  .fold-swipe-arrow:last-child { animation-delay: 0.8s; }
}
@keyframes foldSwipeNudge {
  0%, 100% { transform: translateX(0); opacity: 0.5; }
  50%      { transform: translateX(4px); opacity: 1; }
}

/* ---- Reduced motion ---- */
@media (prefers-reduced-motion: reduce) {
  .fold-pillar::before { transition: none; }
  .fold-overlay.is-open { animation: none; }
}

/* Scroll lock for the Five Graces overlay: pin the page in place. The html
   element keeps overflow-y: scroll, so the scrollbar stays put and nothing
   reflows (no shift, no empty gutter strip). `top` is set inline to the
   saved scroll position. */
.fold-lock { position: fixed; left: 0; right: 0; width: 100%; }

/* While a pillar card is open the site menu steps out of the way — it is chrome
   competing with a modal, and it reads straight through the card's scrim.
   Higher specificity than .site-header.is-hidden so it wins whatever state the
   header held when the card opened; the shared transform transition carries it. */
body.fold-lock .site-header { transform: translateY(-100%); pointer-events: none; }

/* ============================================================
   HOME — CINEMATIC RESHAPE (2026-06)
   Photo-rich, asymmetric, video revealed at hero + convictions only.
   Rhythm comes from layout and scale, not alternating background bands.
   New sections use fresh class names; the old .visit-/.values/.connect-/
   .watch-/.events- rules are superseded and can be retired.
   Retired so far (2026-07-28): the whole .values-/.value-card and home .connect-
   card set. Still outstanding: .visit-, .watch-, .events- (all confirmed unused
   by any template, but not yet removed).
   ============================================================ */

/* ---- Photo frame + aspect-agnostic placeholder ----------------------------
   .frame sets the cinematic crop. Drop in <img class="frame__img"> later and it
   covers the frame at any source ratio. Until then .frame__ph stands in. */
.frame {
  position: relative;
  overflow: hidden;
  background: var(--color-deep);
}
.frame__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.frame__ph {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background:
    radial-gradient(120% 100% at 50% 0%, rgba(23,114,194,0.45) 0%, transparent 62%),
    linear-gradient(158deg, #0e3d68 0%, #082742 58%, #061d33 100%);
}
.frame__ph::before {
  content: "";
  position: absolute;
  inset: 0;
  background: url("/images/fish-watermark.svg") center / clamp(72px, 22%, 168px) no-repeat;
  opacity: 0.10;
}
.frame__ph-label {
  position: relative;
  font-family: var(--font-sans);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.6);
  padding: 0.45em 1em;
  border: 1px solid rgba(255,255,255,0.22);
  border-radius: var(--radius-pill);
}

/* ---- Section 2: Come As You Are (asymmetric, photo bleeds right) ----------- */
.invite {
  position: relative;
  background: var(--color-bg);
  padding-block: var(--section-pad);
}
.invite__grid {
  display: grid;
  grid-template-columns: 1.1fr 1fr;
  align-items: start;
}
/* Church photo bleeds to the LEFT screen edge */
.invite__media {
  grid-column: 1;
  height: clamp(28rem, 46vw, 44rem);
}
.invite__media .frame { height: 100%; }
/* Floating navy panel: kicked down and left so it overlaps the photo's
   bottom-right area and overhangs the photo's bottom edge. White hairline
   border + soft drop shadow read as lifted. margin-top (not transform) so the
   section grows to contain the overhang and never collides with the carousel. */
.invite__panel {
  --section-accent: var(--section-accent-on-dark); /* dark ground: the readable blue shade */
  grid-column: 2;
  z-index: 2;
  margin-left: clamp(-9rem, -10vw, -4rem);
  margin-right: var(--page-pad);
  margin-top: clamp(5rem, 11vw, 9rem);
  padding: clamp(1.75rem, 3vw, 2.75rem);
  color: #fff;
  background:
    radial-gradient(130% 100% at 85% 0%, rgba(23,114,194,0.5) 0%, transparent 62%),
    linear-gradient(150deg, #0e3d68 0%, #082742 55%, #061d33 100%);
  /* Border matches the section background in each theme (near-white in light,
     dark navy in dark) — it reads as a clean cut-out line against the photo. */
  border: 2px solid var(--color-bg);
  border-radius: var(--radius);
  box-shadow: 0 36px 72px -26px rgba(6, 20, 33, 0.7);
}
.invite__panel .section-heading { color: #fff; text-align: left; }
.invite__lead {
  font-size: clamp(1rem, 1.4vw, 1.15rem);
  line-height: 1.7;
  color: rgba(255, 255, 255, 0.9);
  margin: 0 0 var(--space-4);
}
.invite__details {
  list-style: none;
  margin: 0 0 var(--space-4);
  padding: 0;
  display: grid;
  gap: var(--space-3);
}
.invite__detail {
  display: grid;
  gap: 0.15rem;
  padding-bottom: var(--space-3);
  border-bottom: 1px solid rgba(255, 255, 255, 0.16);
}
.invite__detail:last-child { border-bottom: 0; padding-bottom: 0; }
.invite__detail-label {
  font-family: var(--font-sans);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--section-accent);
}
.invite__detail-value { color: rgba(255, 255, 255, 0.92); }
/* Dark theme (desktop only): the dark drop shadow disappears against the dark
   background, so give the panel a brand-blue glow so it still reads as lifted.
   Offset down-right with a negative spread so the glow sits only on the right
   and bottom (against the dark area) and not on the top/left (over the photo). */
:root[data-theme="dark"] .invite__panel {
  box-shadow: 40px 42px 55px -20px rgba(56, 150, 224, 0.1);
}
@media (max-width: 48rem) {
  :root[data-theme="dark"] .invite__panel { box-shadow: none; }
}
/* Church photo: mirror the panel's lift so the image also reads as sitting out,
   but at half strength (alpha halved: light 0.7 -> 0.35, dark glow 0.1 -> 0.05).
   Same offsets/blur/spread as .invite__panel, so the effect matches "the same
   way" (light: sides + bottom; dark glow: right + bottom), just softer. */
.invite__media .frame {
  box-shadow: 0 36px 72px -26px rgba(6, 20, 33, 0.35);
}
:root[data-theme="dark"] .invite__media .frame {
  box-shadow: 40px 42px 55px -20px rgba(56, 150, 224, 0.05);
}
@media (max-width: 48rem) {
  :root[data-theme="dark"] .invite__media .frame { box-shadow: none; }
}
@media (max-width: 64rem) {
  .invite__grid { grid-template-columns: 1fr; }
  .invite__media { grid-column: 1; height: 15rem; }
  .invite__panel {
    grid-column: 1;
    margin: -3rem var(--page-pad) 0;
  }
}

/* ---- Section 3: What's Happening (single centered card, crossfade) --------- */
.happenings {
  background: var(--color-bg);
  /* Bottom gap doubled vs top so the white below the dots visually matches the
     white above the kicker (which is padded by the section above it too),
     leaving the carousel block centered in its white space. */
  padding-block: clamp(3.5rem, 8vw, 6.5rem) clamp(7rem, 16vw, 13rem);
  text-align: center;
  /* Contain the full-bleed (100vw) wave backdrop — no horizontal scroll. */
  overflow: clip;
}
.happenings .section-heading { margin-bottom: clamp(1.75rem, 4vw, 2.75rem); }
/* Holds the card + the wave band so the waves stay anchored behind the card
   regardless of the section's (asymmetric) padding. */
.happenings__stagewrap { position: relative; }
/* Wave band image, bleeding the full viewport width behind the card and
   centered on it. width:100% + height:auto means it always spans edge to edge
   (no side cropping); its rendered height follows the image's aspect ratio.
   The section clips the overflow. Static by design. */
.happenings__waves {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 100vw;
  /* translateZ(0) keeps the big wave image on its own compositor layer, so it
     rasterizes once and is only composited (not repainted) while scrolling. */
  transform: translate(-50%, -50%) translateZ(0);
  z-index: 0;
  pointer-events: none;
}
.happenings__waves img { display: block; width: 100%; height: auto; }
/* Theme-specific wave art: the dark set has a non-white backdrop so the waves
   read right on the dark theme. Light shows by default; dark swaps in. (Display
   lives on the --img class, not `picture`, so the theme rules below outrank it.) */
.happenings__waves-img { display: block; }
.happenings__waves-img--dark { display: none; }
:root[data-theme="dark"] .happenings__waves-img--light { display: none; }
:root[data-theme="dark"] .happenings__waves-img--dark { display: block; }
/* One centered stage; slides are stacked and crossfade in place (no scrolling,
   so the page is never pulled here). aspect-ratio reserves the card height. */
.happenings__stage {
  position: relative;
  z-index: 1;
  width: min(100%, 54rem);
  margin-inline: auto;
  aspect-ratio: 16 / 8;
}
/* On phones the 16:8 card is short, so the overlaid caption reads oversized
   relative to it. A taller card (~50% more height) gives the caption room and
   matches the desktop proportions without shrinking the type. */
@media (max-width: 48rem) {
  .happenings__stage { aspect-ratio: 4 / 3; }
  /* No wave backdrop on phones (both themes); the card spans nearly full width
     so there's little room for it. Lazy images in a hidden box don't load. */
  .happenings__waves { display: none; }
}
.happenings__slides { list-style: none; margin: 0; padding: 0; }
/* Instant swap — no crossfade. A fade would briefly show the wave backdrop
   through the slides; a hard cut keeps it clean (one out, next immediately in). */
.happenings__slide {
  position: absolute;
  inset: 0;
  opacity: 0;
  visibility: hidden;
  text-align: left;
}
.happenings__slide.is-active {
  opacity: 1;
  visibility: visible;
}
.happenings__slide .frame {
  position: absolute;
  inset: 0;
  border-radius: var(--radius);
}
.happenings__caption {
  position: absolute;
  inset: auto 0 0 0;
  z-index: 1;
  padding: clamp(1.25rem, 3vw, 2.25rem);
  color: #fff;
  background: linear-gradient(to top, rgba(6,20,33,0.86) 0%, rgba(6,20,33,0.32) 55%, transparent 100%);
}
.happenings__eyebrow {
  font-family: var(--font-sans);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-accent-light);
  /* Soft dark halo so the light eyebrow stays legible where it sits over a
     brighter part of a slide photo, without darkening the accent color. */
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5), 0 0 10px rgba(0, 0, 0, 0.35);
}
.happenings__title {
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 3vw, 2.1rem);
  font-weight: 500;
  margin: 0.25rem 0 0.4rem;
  color: #fff;
}
.happenings__meta { margin: 0; color: rgba(255,255,255,0.85); font-size: 0.95rem; }

/* ---- "Reconstructing Dad" series lockup (home carousel middle slide) --------
   Mirrors the book cover: a red pen-script "Re" tucked into heavy block-cap
   CONSTRUCTING, an oversized DAD beneath, and a thin tracked all-caps subtitle.
   It rides the same dark caption gradient as every slide, so the red-and-white
   lockup reads identically in the site's light and dark themes. */
.happenings__title--series {
  font-family: "Montserrat", var(--font-sans), sans-serif;
  line-height: 1;
  /* Negative top margin trims the tall empty band above the all-caps letters
     so the eyebrow-to-title gap matches the mixed-case serif slides. */
  margin: -0.35rem 0 0.5rem;
}
/* One line: RECONSTRUCTING DAD, all block caps at one size, with the red
   script "Re" leading it. DAD is not oversized (we don't fully mirror the
   cover's stacked lockup; readers recognize it from "Reconstructing Dad"). */
.rd {
  display: inline-flex;
  align-items: baseline;
  flex-wrap: wrap;
  font-family: "Montserrat", var(--font-sans), sans-serif;
  font-weight: 800;
  font-size: clamp(1.15rem, 4.6vw, 2.05rem);
  letter-spacing: 0.005em;
  line-height: 1.05;
  color: #fff;
}
/* Pen-script "Re", a touch larger than the caps and set just left of the C
   with a clear gap (no overlap). */
.rd__re {
  font-family: "Caveat", cursive;
  font-weight: 700;
  font-size: 1.45em;
  color: #c72321;
  margin-right: 0.1em;
}
/* Subtitle: bold tracked caps (already uppercased at build via the | upper
   filter, so no runtime text-transform). */
.happenings__meta--caps {
  font-family: "Montserrat", var(--font-sans), sans-serif;
  font-weight: 700;
  letter-spacing: 0.14em;
  font-size: clamp(0.64rem, 1.9vw, 0.8rem);
  color: rgba(255, 255, 255, 0.9);
  margin-top: 0.4rem;
}

.happenings__dots {
  display: flex;
  justify-content: center;
  gap: 0.6rem;
  margin-top: clamp(1.25rem, 3vw, 1.75rem);
}
.happenings__dot {
  width: 9px; height: 9px;
  border-radius: var(--radius-pill);
  border: 0;
  background: var(--color-line);
  padding: 0;
  cursor: pointer;
  transition: background-color 150ms ease, transform 150ms ease;
}
.happenings__dot.is-active { background: var(--color-primary); transform: scale(1.25); }
.happenings__dot:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 3px; }

/* ---- Section 4: Four Convictions (still river + photo tiles) ---------------- */
.convictions {
  position: relative;
  /* Transparent so the pinned hero river video (position:fixed, paused to a
     still frame this far down) shows through — "fixed to the background": the
     river stays put at all times while this section scrolls over it. No
     background-attachment:fixed (which repaints every scroll frame and lagged),
     and a transparent section has no navy padding band at the top. */
  background: transparent;
  color: #fff;
  padding-block: clamp(3.5rem, 8vw, 6.5rem) 0;
  overflow: clip;
}
/* Scrim over the revealed river: lighter at the very top so the river reads
   there, deeper behind the heading and tiles for legibility. */
.convictions::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(130% 80% at 50% 40%, rgba(23,114,194,0.26) 0%, transparent 62%),
    linear-gradient(180deg, rgba(6,20,33,0.28) 0%, rgba(6,20,33,0.52) 42%, rgba(6,20,33,0.82) 100%);
}
.convictions > * { position: relative; z-index: 1; }
.convictions__intro {
  text-align: center;
  /* Wide enough that "A people shaped by four convictions" stays on one line on
     desktop (accounting for the container's 4rem side padding on wide screens);
     it wraps naturally only on narrow viewports. */
  max-width: 66rem;
  margin: 0 auto clamp(2rem, 5vw, 3.5rem);
}
.convictions__heading {
  font-family: var(--font-display);
  font-size: clamp(2rem, 5.5vw, 3.4rem);
  font-weight: 400;
  line-height: 1.08;
  margin: 0 0 var(--space-3);
  color: #fff;
}
.convictions__heading em { font-style: italic; color: var(--color-accent-light); }
.convictions__lead {
  font-size: clamp(1rem, 2vw, 1.18rem);
  line-height: 1.7;
  color: rgba(255,255,255,0.82);
  /* Keep the lead at a readable width even though the intro is now wider */
  max-width: 42rem;
  margin: 0 auto;
}
.convictions__band {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(4px, 0.6vw, 10px);  /* thin seams let the river glimmer between tiles */
  list-style: none;
  margin: 0;
  padding: 0;
}
.conviction { position: relative; }
.conviction__frame { height: clamp(24rem, 40vw, 34rem); }
.conviction__overlay {
  position: absolute;
  inset: auto 0 0 0;
  z-index: 1;
  /* extra top padding gives the oversized index number room to breathe */
  padding: clamp(2.75rem, 7vw, 4.5rem) clamp(1rem, 2vw, 1.6rem) clamp(1rem, 2vw, 1.6rem);
  background: linear-gradient(to top, rgba(5,14,24,0.94) 0%, rgba(5,14,24,0.5) 58%, transparent 100%);
}
/* Oversized, translucent, brand-blue numeral layered BEHIND the name + tagline,
   sitting flush to the bottom-left of the tile. */
.conviction__index {
  position: absolute;
  left: clamp(0.5rem, 1.4vw, 1.1rem);
  /* Sit fully inside the tile (was clipped at the bottom edge before) */
  bottom: clamp(0.6rem, 1.4vw, 1.1rem);
  z-index: 0;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 500;
  font-size: clamp(3.6rem, 7.5vw, 6rem);
  line-height: 0.8;
  color: var(--color-accent-light);
  opacity: 0.22;
  pointer-events: none;
}
.conviction__name {
  position: relative;
  z-index: 1;
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 2vw, 1.7rem);
  font-weight: 500;
  margin: 0 0 0.3em;
  color: #fff;
}
.conviction__tagline {
  position: relative;
  z-index: 1;
  font-size: 0.92rem;
  line-height: 1.55;
  color: rgba(255,255,255,0.86);
  margin: 0;
}
@media (max-width: 64rem) {
  .convictions__band { grid-template-columns: repeat(2, 1fr); }
  .conviction__frame { height: clamp(18rem, 52vw, 26rem); }
}
@media (max-width: 36rem) {
  .convictions__band { grid-template-columns: 1fr; }
  .conviction__frame { height: 16rem; }
}

/* ---- Section 5: Latest Message (flipped, cinematic) ------------------------ */
.message {
  background: var(--color-bg);
  /* Top gap doubled: the convictions tiles now run flush to this section, so
     the heading needs breathing room above. Bottom unchanged (white-on-white
     into Get Plugged In). */
  padding-block: clamp(7rem, 16vw, 13rem) clamp(3.5rem, 8vw, 7rem);
}
.message__grid {
  display: grid;
  grid-template-columns: 1.12fr 0.88fr;
  align-items: center;
  gap: clamp(2rem, 5vw, 4.5rem);
}
.message__media { position: relative; }
.message__media .yt-facade,
.message__media .yt-frame {
  width: 100%;
  aspect-ratio: 16 / 9;
  border-radius: var(--radius);
}
/* The injected player keeps the facade's footprint instead of collapsing to
   the browser's default 300x150 iframe size when playback starts. */
.yt-frame {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border: 0;
}
.message__copy { max-width: 34rem; }
@media (max-width: 64rem) {
  .message__grid { grid-template-columns: 1fr; }
  .message__media { order: -1; }
}

/* ---- Section 6: Get Plugged In (image-topped cards) ------------------------ */
.plug {
  position: relative;
  isolation: isolate;
  background: var(--color-bg);
  padding-block: var(--section-pad);
}
/* Faint fish watermark behind the section to cap off the page. Raised so its
   top sits up near the heading; saturate() nudges the slate-blue art a touch
   more blue (it washes toward grey at this low opacity). */
.plug::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: url("/images/fish-watermark.svg") center calc(25% + 25px) / min(100%, 80rem) auto no-repeat;
  opacity: 0.12;
  filter: saturate(1.6);
  pointer-events: none;
}
/* On phones the cards stack, so the section is much taller and 25% drops the
   fish low. Pull it near the top (behind the heading) like on desktop. */
@media (max-width: 48rem) {
  .plug::before { background-position: center calc(1.5rem + 165px); }
}
/* The grid breaks out wider than the centered header so the four cards stretch
   further across the screen (≈30% larger than the 72rem container). */
.plug__grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(1.1rem, 2vw, 1.75rem);
  list-style: none;
  width: min(100% - 2 * var(--page-pad), 94rem);
  margin: clamp(2rem, 4vw, 3rem) auto 0;
  padding: 0;
}
.plug-card {
  display: flex;
  flex-direction: column;
  background: var(--color-bg-soft);
  border: 1px solid var(--color-line);
  border-radius: var(--radius);
  overflow: hidden;
  transition: transform 200ms ease, box-shadow 200ms ease;
}
.plug-card:hover { transform: translateY(-4px); box-shadow: 0 14px 34px rgba(8,39,66,0.12); }
/* Dark theme: the default dark hover shadow is invisible on the dark background,
   so on hover give the cards a subtle blue glow. No offset so it's even on all
   sides (a downward offset to clear the top made the bottom read brighter). */
:root[data-theme="dark"] .plug-card:hover {
  box-shadow: 0 0 32px 1px rgba(56, 150, 224, 0.18);
}
.plug-card__media { aspect-ratio: 4 / 3.2; }
.plug-card__body {
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  flex: 1;
  padding: clamp(1.25rem, 1.8vw, 1.7rem);
}
.plug-card__title {
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 1.6vw, 1.45rem);
  font-weight: 500;
  margin: 0;
}
.plug-card__text { font-size: 1rem; line-height: 1.55; color: var(--color-ink-soft, inherit); margin: 0; }
.plug-card__body .inline-link { margin-top: auto; }
@media (max-width: 64rem) { .plug__grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 36rem) { .plug__grid { grid-template-columns: 1fr; } }

/* ============================================================
   WATCH PAGE — recent messages grid
   ============================================================ */
.watch-grid {
  list-style: none;
  margin: var(--space-5) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
}
.watch-card { display: flex; }
.watch-card__link {
  display: flex;
  flex-direction: column;
  width: 100%;
  border: 1px solid var(--color-line);
  background: var(--color-bg-soft);
  text-decoration: none;
  color: inherit;
  overflow: hidden;
  transition: border-color 200ms ease;
}
.watch-card__link:hover { border-color: var(--color-accent); }
.watch-card__thumb {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: var(--color-bg-tint);
}
.watch-card__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.watch-card__play {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2.4rem;
  color: #fff;
  text-shadow: 0 2px 12px rgba(0, 0, 0, 0.5);
  opacity: 0.85;
  transition: opacity 180ms ease, transform 180ms ease;
}
.watch-card__link:hover .watch-card__play { opacity: 1; transform: scale(1.08); }
.watch-card__title {
  font-size: 0.97rem;
  color: var(--color-ink);
  margin: 0;
  padding: var(--space-2) var(--space-3) var(--space-3);
  line-height: 1.45;
}
@media (min-width: 48rem) { .watch-grid { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 64rem) { .watch-grid { grid-template-columns: repeat(3, 1fr); } }

/* ============================================================
   EVENTS — upcoming events list (native, from the PCO Calendar API)
   ============================================================ */
.events-list {
  list-style: none;
  margin: var(--space-4) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}
.event-card {
  display: flex;
  gap: var(--space-4);
  padding: var(--space-4);
  border: 1px solid var(--color-line);
  background: var(--color-bg-soft);
  transition: border-color 200ms ease;
}
.event-card:hover { border-color: var(--color-accent); }
.event-when {
  flex: 0 0 8.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}
.event-when-date {
  font-family: var(--font-display);
  font-size: 1.15rem;
  color: var(--color-ink);
  line-height: 1.2;
}
.event-when-time {
  font-size: 0.9rem;
  color: var(--color-muted);
}
.event-body { flex: 1 1 auto; }
.event-name {
  font-family: var(--font-display);
  font-size: 1.3rem;
  font-weight: 600;
  margin: 0;
  line-height: 1.25;
}
.event-name a {
  color: var(--color-ink);
  text-decoration: none;
  transition: color 200ms ease;
}
.event-name a:hover { color: var(--color-accent); }
.event-recurrence {
  margin: 0.35rem 0 0;
  font-size: 0.8rem;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--color-accent);
}
.event-location {
  margin: 0.35rem 0 0;
  font-size: 0.95rem;
  color: var(--color-muted);
}
/* No max-width here on purpose. A 60ch cap used to stop the summary ~283px
   short of the card's right edge while .event-name and .event-location ran the
   full width, so the summary was the one ragged element in the card and read
   as broken rather than as a reading measure. Card width is already bounded by
   the page container, which keeps the line length sane. */
.event-summary {
  margin: 0.5rem 0 0;
  font-size: 0.97rem;
  color: var(--color-ink-soft);
}
.events-cta { margin-top: var(--space-5); }

@media (max-width: 40rem) {
  .event-card { flex-direction: column; gap: var(--space-2); }
  .event-when {
    flex-basis: auto;
    flex-direction: row;
    gap: var(--space-2);
    align-items: baseline;
  }
}

/* ============================================================
   RESOURCES — print/free resource rows (cover left, details right)
   ============================================================ */
.resource-list {
  list-style: none;
  margin: var(--space-5) 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}
.resource-row {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: var(--space-5);
  align-items: start;
}
.resource-row__cover { display: flex; justify-content: center; }
.resource-row__cover img {
  width: 100%;
  max-width: 220px;
  height: auto;
  display: block;
  box-shadow: 0 12px 32px rgba(8, 39, 66, 0.18);
}
.resource-row__content { display: flex; flex-direction: column; }
.resource-row__title {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3vw, 2rem);
  font-weight: 400;
  line-height: 1.15;
  margin: 0 0 0.35rem;
  color: var(--color-ink);
}
.resource-row__author {
  font-size: 0.9rem;
  color: var(--color-muted);
  margin: 0 0 var(--space-3);
}
.resource-row__desc {
  font-size: 1rem;
  color: var(--color-ink-soft);
  line-height: 1.7;
  margin: 0 0 var(--space-4);
}
.resource-row__foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-top: auto;
}
.resource-row__price-label {
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-muted);
  margin: 0 0 0.25rem;
}
.resource-row__price {
  font-size: 1.6rem;
  font-weight: 700;
  color: var(--color-ink);
  margin: 0;
}
@media (max-width: 48rem) {
  .resource-row { grid-template-columns: 1fr; gap: var(--space-4); }
  .resource-row__cover { justify-content: flex-start; }
  .resource-row__cover img { max-width: 160px; }
  .resource-row__foot { align-items: flex-start; }
}

/* ==========================================================================
   STANDALONE PAGE TITLE — interior page with no photo banner (membership).
   Clears the fixed header; main.js keeps the header solid at scroll-top on
   these pages since there is no dark banner behind the white logo.
   ========================================================================== */
.page-title--standalone {
  padding-top: calc(var(--header-h) + clamp(3rem, 7vw, 6rem));
}

/* ==========================================================================
   NIGHTFALL / CONSTELLATION — membership "Get Plugged In" night-sky section.
   Visuals ported from docs/prototypes/membership-constellation-prototype.html
   (design locked v37 + unison breathing, commit e327774). Do not retune.
   The section is committed-dark in both site themes.

   Wrapper modes (set by constellation.js):
     .nightfall--pin   desktop: 250vh wrapper, sticky viewport stage, scroll
                       drives --nf-* progress channels (dusk veil, night veil,
                       sky fade, text color, intro rise)
     .nightfall--flat  mobile / reduced motion / no-JS fallback: dusk band +
                       full-height stage in normal flow
   ========================================================================== */
.nightfall {
  --text: #eaf1ff;
  --muted: #9fb0cc;
  --cyan: #8fd3ea;
  position: relative;
  color: var(--text);
  font-family: var(--font-sans);
  -webkit-font-smoothing: antialiased;
}

/* Desktop pin: tall wrapper, sticky viewport stage. The height buys two things:
   the transition itself, and then a long stretch of held scroll after the scene
   has fully arrived. That dwell is deliberate. Without it, the natural "is this
   locked in place?" scroll immediately pushes the finished scene off screen
   before you have looked at it. */
.nightfall--pin { height: 360vh; }
.nightfall--pin .nightfall__sticky {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  background: var(--color-bg);
}
/* Flat mode: normal flow, dusk band above the stage. The intro sits after the
   stage in the DOM (pin mode overlays it), so flex order pulls it up front. */
.nightfall--flat .nightfall__sticky {
  position: relative;
  display: flex;
  flex-direction: column;
}
.nightfall--flat .nightfall__intro { order: -1; }

.nightfall__veil {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: var(--nf-dusk, 0);
}
.nightfall__veil--dusk {
  background: linear-gradient(180deg, #2a3a5e 0%, #16233f 55%, #0a1224 100%);
}
/* Dark theme: the page is already deep navy, so dusk must only DEEPEN toward
   night (the light-mode twilight stops are lighter than the dark page bg and
   read as a wrong brighten-then-darken bump). */
:root[data-theme="dark"] .nightfall__veil--dusk {
  background: linear-gradient(180deg, #0a1520 0%, #071022 55%, #04060e 100%);
}
.nightfall__veil--night {
  background: #04060e;
  opacity: var(--nf-night, 0);
}
.nightfall--flat .nightfall__veil { display: none; }

/* The stage (sky + water + constellation) */
.nightfall .stage {
  position: relative;
  width: 100%;
  overflow: hidden;
  isolation: isolate;
}
.nightfall--pin .stage {
  position: absolute;
  inset: 0;
  opacity: var(--nf-sky, 0);
}
.nightfall--flat .stage {
  height: 100vh;
  height: 100svh; /* stable against mobile URL-bar show/hide */
  min-height: 560px;
  background: #04060e;
}

/* Intro copy: overlays the stage while day turns to night (pin mode) */
.nightfall--pin .nightfall__intro {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  text-align: center;
  /* the block is taller now (message + star plate); the bottom padding lifts
     the whole composition just above dead centre so it does not sit low */
  padding: 0 var(--page-pad) 7vh;
  pointer-events: none;
  /* contains the watermark's z-index: -1 so it sits behind this block's copy
     without escaping behind the veils (the intro's own opacity only creates a
     stacking context once it drops below 1, which is too late) */
  isolation: isolate;
  /* The copy stays locked in place (no drift) and crossfades against the sky:
     its opacity is exactly the inverse of the stage's, so one ramps out
     precisely as the other ramps in (Ryan, Jul 18). */
  opacity: calc(1 - var(--nf-sky, 0));
}
.nightfall__heading,
.nightfall__sub {
  color: color-mix(in oklab, var(--color-ink), #eaf1ff calc(var(--nf-text, 0) * 100%));
}
/* This section owns a gold already (the Northern Cross star plate), so its
   eyebrow and emphasis word stay the water blue rather than taking the
   dark-ground gold — two golds would compete. */
.nightfall__label,
.nightfall__heading em {
  color: var(--color-primary);
}
/* Runs on one line on desktop (deliberate: it reads as a single instruction).
   Narrow screens still wrap it, where one line is not possible. */
.nightfall__sub {
  max-width: none;
  margin: var(--space-2) auto 0;
  font-size: 1.05rem;
  line-height: 1.6;
}
@media (max-width: 60rem) {
  .nightfall__sub { max-width: 46ch; }
}
/* Flat mode: intro sits on its own dusk band in light text */
/* The gradient must reach night BEFORE the copy starts, or the light text sits
   on a light background at the top of the band. */
.nightfall--flat .nightfall__intro {
  position: relative;
  text-align: center;
  padding: var(--space-6) var(--page-pad) var(--space-5);
  background: linear-gradient(180deg, var(--color-bg) 0%, #16233f 20%, #04060e 52%);
}
/* Dark theme: deepen only, never brighten (see the dusk veil note above) */
:root[data-theme="dark"] .nightfall--flat .nightfall__intro {
  background: linear-gradient(180deg, var(--color-bg) 0%, #071022 20%, #04060e 52%);
}
.nightfall--flat .nightfall__heading,
.nightfall--flat .nightfall__sub { color: #eaf1ff; }

/* --- Stage layers (ported verbatim from the prototype) --- */
.nightfall #nebula { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 0; display: block; }
.nightfall #starfield { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1; display: block; }

.nightfall .sea { position: absolute; left: 0; right: 0; bottom: 0; height: 34%; z-index: 2; }
.nightfall #water { position: absolute; inset: 0; width: 100%; height: 100%; display: block;
  -webkit-mask-image: linear-gradient(180deg, rgba(0,0,0,0) 0%, #000 10%);
  mask-image: linear-gradient(180deg, rgba(0,0,0,0) 0%, #000 10%); }
.nightfall .sea__fallback { position: absolute; inset: 0; background: linear-gradient(180deg, #0a1830 0%, #071022 55%, #040912 100%); display: none; }

.nightfall .constellation { position: absolute; left: 0; right: 0; top: 0; bottom: 34%; z-index: 5; }
.nightfall .lines { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.nightfall .lines line { stroke: rgba(170,196,238,0.34); stroke-width: 1.2; stroke-linecap: round; vector-effect: non-scaling-stroke; stroke-dasharray: var(--L,1); stroke-dashoffset: var(--L,1); animation: lineDraw var(--ldur,1.35s) ease forwards; animation-delay: var(--ld,0s); transition: stroke 1.4s ease, stroke-width 1.4s ease; }
.nightfall .lines.is-complete line { stroke: rgba(255,214,150,0.48); stroke-width: 2.4; }
@keyframes lineDraw { to { stroke-dashoffset: 0; } }

.nightfall .star { position: absolute; transform: translate(-50%,-50%) scale(0.4); opacity: 0; width: 48px; height: 48px; display: grid; place-items: center; text-decoration: none; color: var(--text); -webkit-tap-highlight-color: transparent; animation: kindle .7s cubic-bezier(.2,.7,.3,1.15) forwards; animation-delay: var(--sd,0s); }
@keyframes kindle { to { opacity: 1; transform: translate(-50%,-50%) scale(1); } }
.nightfall .star.is-open { z-index: 10; }
.nightfall .star__dot { position: relative; width: 15px; height: 15px; border-radius: 50%; border: 1.5px solid rgba(226,236,255,0.55); background: transparent; transition: transform .35s ease, border-color .35s ease; }
/* the star inside the ring is drawn on the starfield canvas, identical to the background stars */
.nightfall .star__dot::after { content: none; }
/* gold = visited: once touched, a star keeps its gold */
.nightfall .star.is-visited .star__dot { border-color: rgba(255,222,170,0.85); }
.nightfall .star.is-open .star__dot { border-color: rgba(255,222,170,0.95); }

.nightfall .star__label { position: absolute; top: 50%; left: calc(50% + 17px); transform: translate(6px,-50%); white-space: nowrap; font-size: 0.9rem; letter-spacing: 0.02em; color: var(--text); background: radial-gradient(120% 160% at 0% 50%, rgba(6,12,26,0.94), rgba(6,12,26,0) 84%); padding: 6px 15px 6px 4px; opacity: 0; pointer-events: none; transition: opacity .3s ease, transform .3s ease; text-shadow: 0 1px 6px #000, 0 0 12px rgba(0,0,0,0.85); }
.nightfall .star__label::before { content: ""; position: absolute; top: 50%; right: 100%; width: 16px; height: 1px; transform: translateY(-50%); background: linear-gradient(90deg, rgba(150,190,255,0), rgba(190,215,255,0.75)); }
.nightfall .star[data-side="left"] .star__label { left: auto; right: calc(50% + 17px); transform: translate(-6px,-50%); padding: 6px 4px 6px 15px; background: radial-gradient(120% 160% at 100% 50%, rgba(6,12,26,0.94), rgba(6,12,26,0) 84%); }
.nightfall .star[data-side="left"] .star__label::before { right: auto; left: 100%; background: linear-gradient(270deg, rgba(150,190,255,0), rgba(190,215,255,0.75)); }

.nightfall .star:hover .star__label, .nightfall .star__hit:focus-visible .star__label { opacity: 1; transform: translate(0,-50%); }
.nightfall .star[data-side="left"]:hover .star__label { transform: translate(0,-50%); }
.nightfall .star:hover .star__dot, .nightfall .star__hit:focus-visible .star__dot, .nightfall .star.is-open .star__dot { transform: scale(1.3); }
.nightfall .star__hit { appearance: none; background: none; border: 0; padding: 0; margin: 0; width: 100%; height: 100%; display: grid; place-items: center; cursor: pointer; color: inherit; font: inherit; }
.nightfall .star__hit:focus-visible { outline: none; }
.nightfall .star__hit:focus-visible .star__dot { outline: 2px solid rgba(200,220,255,0.95); outline-offset: 6px; }
/* scripture card, opened on click */
.nightfall .star__card { position: absolute; top: 50%; left: calc(50% + 22px); transform: translate(10px,-50%); width: 272px; text-align: left;
  background: linear-gradient(180deg, rgba(9,17,36,0.93), rgba(6,12,26,0.95));
  border: 1px solid rgba(160,190,240,0.28); border-radius: 12px; padding: 14px 16px;
  opacity: 0; pointer-events: none; transition: opacity .35s ease, transform .35s ease;
  box-shadow: 0 10px 40px rgba(0,0,0,0.5); }
.nightfall .star[data-side="left"] .star__card { left: auto; right: calc(50% + 22px); transform: translate(-10px,-50%); }
.nightfall .star.is-open .star__card { opacity: 1; pointer-events: auto; transform: translate(0,-50%); }
.nightfall .star__card h3 { margin: 0 0 6px; font-size: 0.95rem; color: #ffe9c6; font-weight: 600; letter-spacing: 0.02em; }
.nightfall .star__card p { margin: 0 0 8px; font-size: 0.8rem; line-height: 1.55; color: var(--muted); }
.nightfall .star__card .star__verse { font-family: Georgia, "Iowan Old Style", serif; font-style: italic; color: rgba(207,224,255,0.82); }
.nightfall .star__card .star__verse span { font-style: normal; color: rgba(159,176,204,0.7); font-size: 0.72rem; white-space: nowrap; }
.nightfall .star__card a { display: inline-block; font-size: 0.78rem; color: var(--cyan); text-decoration: none; border-bottom: 1px solid rgba(143,211,234,0.4); padding-bottom: 1px; }
.nightfall .star__card a:hover, .nightfall .star__card a:focus-visible { color: #fff; border-color: #fff; outline: none; }
.nightfall .star.is-open .star__label { opacity: 0 !important; }

@media (max-width: 640px) {
  /* Stars centre via negative margins instead of transform here: a transformed
     ancestor would become the containing block for the card's position:fixed,
     trapping the bottom panel inside the 58px star box. Kindle keeps its fade
     (scale pop needs transform, so it is desktop-only). !important beats the
     instant-render inline transform set by constellation.js. */
  .nightfall .star {
    width: 58px;
    height: 58px;
    margin: -29px 0 0 -29px;
    transform: none !important;
    animation-name: kindleFade;
  }
  /* Labels start hidden on mobile: tapping a star shows its name (and the
     bottom card); tapping off hides both. Overrides the desktop rule that
     hides the label while a card is open, hence the !important. */
  .nightfall .star__label { opacity: 0; transform: translate(0,-50%); font-size: 0.8rem; }
  .nightfall .star[data-side="left"] .star__label { transform: translate(0,-50%); }
  .nightfall .star.is-open .star__label { opacity: 1 !important; }
  /* Prayer rides the right edge: its label starts closer to the ring and sits
     raised above the arm so it stays on-screen and clear of Spiritual Gifts */
  .nightfall .star[data-label="Prayer"] .star__label {
    left: calc(50% + 8px);
    top: calc(50% - 15px);
  }
  /* Side cards cannot fit beside a star on a phone: the open card becomes a
     bottom-anchored panel instead */
  .nightfall .star__card,
  .nightfall .star[data-side="left"] .star__card {
    position: fixed;
    left: 16px;
    right: 16px;
    top: auto;
    bottom: 16px;
    width: auto;
    transform: translateY(10px);
    z-index: 30;
  }
  .nightfall .star.is-open .star__card,
  .nightfall .star[data-side="left"].is-open .star__card { transform: none; }
}
@keyframes kindleFade { to { opacity: 1; } }
@media (prefers-reduced-motion: reduce) {
  .nightfall .star { animation: none; opacity: 1; transform: translate(-50%,-50%); }
  .nightfall .lines line { animation: none; stroke-dashoffset: 0; }
}

/* Cross watermark behind the copy, in the same slate blue as the fish
   watermark on the home page (#52708e). That colour is a mid tone, so it needs
   no light/dark inversion: it sits darker than the near-white page at the start
   of the transition and lighter than the night sky at the end. Only the
   strength differs per theme, so the mark carries the same weight on both
   grounds. Masked rather than dropped in as an image so it can be tinted at
   all. It lives inside the intro, so the intro's crossfade carries it away with
   the copy. Angle and strength are tokens; they are what is worth tuning. */
.nightfall__intro {
  /* 14deg, not 45: this artwork is built from many fine parallel strokes, and
     at 45 they read as diagonal scratches and the shape reads as an X rather
     than a cross. A gentle tilt keeps it legible as a cross and echoes the
     constellation's own lean in the scene below. */
  --cross-angle: 14deg;
  /* tuned so the mark carries equal weight against each ground: the same slate
     blue needs more presence on the dark page than on the near-white one */
  --cross-strength: 0.13;
}
:root[data-theme="dark"] .nightfall__intro { --cross-strength: 0.22; }
.nightfall__intro::before {
  content: "";
  position: absolute;
  z-index: -1;
  /* Sized so the WHOLE cross fits inside the section. The painted cross spans
     ~0.98 of its box height once tilted (head ~0.488 above centre, foot ~0.489
     below), so anything past ~840px on a 900px viewport gets its head cut flat
     at the section's top edge, which reads as a chopped cross floating under
     the section above rather than a watermark. Height and `top` move together:
     `top` is set to hold the foot on its line while the head stays clear of
     the boundary. */
  top: 53%;
  left: 50%;
  height: min(93vh, 840px);
  aspect-ratio: 2481 / 3594.49;
  transform: translate(-50%, -50%) rotate(var(--cross-angle));
  opacity: var(--cross-strength);
  background-color: #52708e;
  -webkit-mask: url("/images/cross-mark.svg") center / contain no-repeat;
          mask: url("/images/cross-mark.svg") center / contain no-repeat;
  pointer-events: none;
}
.nightfall--flat .nightfall__intro::before {
  /* same rule: the whole cross sits inside the band, head and foot both clear */
  top: 50%;
  height: 94%;
}
.nightfall--flat .nightfall__intro { overflow: hidden; isolation: isolate; }

/* Star plate: the constellation's name and what it is, sitting under the
   message as the caption on an old star chart would. The gold ripens as the
   page darkens (it must read on near-white at the start of the transition and
   on night sky at the end) and plants the colour the cross takes on completion. */
.nightfall__flourish {
  background-color: color-mix(in oklab, var(--color-primary), #93b2e8 calc(var(--nf-text, 0) * 100%));
  margin: var(--space-4) auto var(--space-3);
  width: clamp(9rem, 20vw, 13rem);
}
.nightfall__name {
  font-family: "Great Vibes", cursive;
  font-size: clamp(2.4rem, 5.5vw, 3.9rem);
  line-height: 1.1;
  margin: 0;
  /* the script's descenders need room; its cap height sits high in the em box */
  padding-bottom: 0.12em;
  /* Ripens with the transition: a deep gold on the near-white start (legible on
     white, where bright #ffdaa0 washed out at ~1.3:1) brightening to the bright
     completed-cross gold as night falls, driven by the same --nf-text channel.
     One continuous gold, only its luma tracks the background. */
  color: color-mix(in oklab, #a8791e, #ffdaa0 calc(var(--nf-text, 0) * 100%));
}
/* Flat mode (mobile / reduced motion) has no scroll driver, so --nf-text stays
   0; but its name sits on the dark dusk band, where the bright gold reads. */
.nightfall--flat .nightfall__name { color: #ffdaa0; }
.nightfall__note {
  max-width: 52ch;
  margin: var(--space-1) auto 0;
  font-size: 0.95rem;
  line-height: 1.6;
  color: color-mix(in oklab, var(--color-muted), #9fb0cc calc(var(--nf-text, 0) * 100%));
}
.nightfall--flat .nightfall__note { color: #9fb0cc; }
.nightfall--flat .nightfall__flourish { background-color: #93b2e8; }
@media (max-width: 640px) {
  .nightfall__note { font-size: 0.88rem; }
}

/* =========================================================================
   MISSIONS GLOBE — /outreach/missions "Where we serve" section.
   Line-art orthographic Earth rendered by assets/js/missions-globe.js. The
   canvas reads these --g-* tokens so it follows the site's light/dark theme.
   ========================================================================= */
:root {
  --g-ocean: #e9f1f8; --g-graticule: #d4dee7; --g-land: #e2e8ee; --g-border: #a6b3c0;
  --g-mission: rgba(23, 114, 194, 0.18); --g-mission-stroke: #1772c2;
  --g-marker: #1772c2; --g-glow: rgba(23, 114, 194, 0.50); --g-core: #ffffff;
  --g-sensitive: rgba(23, 114, 194, 0.30); --g-edge: #c1cbd6;
  /* Selected-location gold. --g-gold is the bright Northern Cross gold (FED99F);
     --g-gold-ink is the readable "brass" gold used for text/lines on light
     grounds (the bright gold washes out on white). */
  --g-gold: #FED99F; --g-gold-fill: rgba(199, 147, 58, 0.34);
  --g-gold-glow: rgba(254, 217, 159, 0.5); --g-gold-ink: #c9933a;
  /* --g-gold-ink is right for borders, dots and rings, but as small uppercase
     TEXT it measured 2.49:1 on the page ground, well under AA. This is the same
     brass taken deeper purely for those labels, so the globe's gold line work
     is untouched. */
  --g-gold-text: #8a631c;
}
:root[data-theme="dark"] {
  --g-ocean: #0c1a28; --g-graticule: #17293a; --g-land: #14283a; --g-border: #37506a;
  --g-mission: rgba(74, 169, 230, 0.22); --g-mission-stroke: #4aa9e6;
  --g-marker: #4aa9e6; --g-glow: rgba(74, 169, 230, 0.55); --g-core: #e8f3fb;
  --g-sensitive: rgba(74, 169, 230, 0.34); --g-edge: #274257;
  --g-gold: #FED99F; --g-gold-fill: rgba(254, 217, 159, 0.20);
  --g-gold-glow: rgba(254, 217, 159, 0.6); --g-gold-ink: #FED99F;
  /* On the dark ground the bright gold already clears AA, so text tracks it. */
  --g-gold-text: var(--g-gold-ink);
}

/* Typography for this section uses the site's own .section-label /
   .section-heading / .section-sub classes (see missions.njk) so the fonts,
   weights, and sizes match every other section. */

.mg-stage {
  position: relative; width: 100%; height: clamp(340px, 62vh, 560px);
  display: flex; align-items: center; justify-content: center;
}
/* While a marker is focused the stage breaks out to the full viewport width so
   the zoomed globe can reach the left and right edges (top/bottom stay framed
   by the surrounding content). The section clips the 100vw overflow so no
   horizontal scrollbar appears, matching the site's .legacy-video full-bleed. */
.mg-section { overflow-x: clip; }
.mg-stage--wide { width: 100vw; left: 50%; margin-left: -50vw; }
#mg-globe { touch-action: none; cursor: grab; display: block; }
#mg-globe:active { cursor: grabbing; }
.mg-stage[data-globe-failed] #mg-globe,
.mg-stage[data-globe-failed] .mg-hint,
.mg-stage[data-globe-failed] .mg-spin { display: none; }

.mg-hint {
  position: absolute; left: 50%; bottom: 8px; transform: translateX(-50%);
  font-family: var(--font-sans); font-size: 0.8rem; font-weight: 600;
  white-space: nowrap; text-align: center; color: var(--color-primary);
  background: color-mix(in srgb, var(--color-primary) 10%, var(--color-bg));
  border: 1px solid color-mix(in srgb, var(--color-primary) 32%, transparent);
  border-radius: var(--radius-pill);
  padding: 0.35rem 0.95rem; transition: opacity 0.5s ease; pointer-events: none;
}
.mg-hint.is-gone { opacity: 0; }

.mg-spin {
  position: absolute; top: 6px; right: 6px; display: inline-flex; align-items: center;
  gap: 0.45rem; font-family: var(--font-sans); font-size: 0.8rem; color: var(--color-muted);
  background: color-mix(in srgb, var(--color-bg) 86%, transparent);
  border: 1px solid var(--color-line); border-radius: var(--radius-pill);
  padding: 0.35rem 0.8rem; cursor: pointer;
}
.mg-spin:hover { border-color: var(--color-primary); color: var(--color-ink); }
.mg-spin-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--color-primary); }
.mg-spin[aria-pressed="false"] .mg-spin-dot { background: var(--color-muted); }

.mg-card {
  /* 320px, one width for every card so they stay consistent. Sized off the
     longest region eyebrow, "Haiti and the Dominican Republic": 235px of text
     + 14.4px close-button clearance + 43.2px padding = 293px minimum, so this
     leaves ~11% headroom rather than sitting on the wrap point, where a font
     swap could push "Republic" onto a second line. */
  position: absolute; width: 320px; max-width: calc(100% - 16px);
  background: var(--color-bg); border: 1px solid var(--color-line);
  border-radius: var(--radius); box-shadow: 0 18px 46px -18px rgba(8, 39, 66, 0.5);
  padding: 1.25rem 1.35rem 1.35rem;
  opacity: 0; visibility: hidden; transform: translateY(6px) scale(0.98);
  transition: opacity 0.18s ease, transform 0.18s ease; z-index: 5;
}
.mg-card.is-open { opacity: 1; visibility: visible; transform: none; }
.mg-close {
  position: absolute; top: 0.4rem; right: 0.55rem; background: none; border: none;
  color: var(--color-muted); font-size: 1.4rem; line-height: 1; cursor: pointer; padding: 0.25rem;
}
.mg-close:hover { color: var(--color-ink); }
.mg-region {
  font-family: var(--font-sans); font-size: 0.72rem; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--g-gold-text); margin: 0 0 0.35rem;
  padding-right: 0.9rem;  /* clear the close button, as .mg-name does: long
                             region names ("Haiti and the Dominican Republic")
                             otherwise run underneath it */
}
.mg-name {
  font-family: var(--font-display); font-weight: 500; font-size: 1.3rem; line-height: 1.15;
  color: var(--color-ink); margin: 0 0 0.6rem; padding-right: 0.9rem;
}
.mg-body { color: var(--color-muted); font-size: 0.95rem; line-height: 1.55; margin: 0; }
.mg-note {
  font-family: var(--font-sans); font-size: 0.78rem; color: var(--color-muted);
  margin: 0.8rem 0 0; padding-top: 0.8rem; border-top: 1px solid var(--color-line);
  display: flex; gap: 0.4rem;
}
.mg-note::before { content: "🔒"; }
.mg-link {
  display: inline-block; margin-top: 0.9rem; font-size: 0.95rem; font-weight: 600;
  color: var(--color-primary); text-decoration: none;
}
.mg-link:hover { text-decoration: underline; }

.mg-list-head { margin: var(--space-5) 0 var(--space-2); }
.mg-list-title {
  font-family: var(--font-display); font-weight: 500; font-size: 1.35rem;
  color: var(--color-ink); margin: 0 0 0.35rem;
}
.mg-list-sub { color: var(--color-muted); font-size: 0.95rem; margin: 0; max-width: 60ch; }
.mg-list {
  list-style: none; margin: 0; padding: 0; display: grid;
  grid-template-columns: repeat(2, 1fr); gap: 0.7rem;
}
.mg-place {
  display: flex; align-items: center; gap: 0.8rem; background: var(--color-bg-soft);
  border: 1px solid var(--color-line); border-radius: var(--radius);
  padding: 0.8rem 0.95rem; cursor: pointer;
  transition: border-color 0.14s ease, transform 0.14s ease;
}
.mg-place:hover { border-color: var(--color-primary); transform: translateY(-1px); }
.mg-place.is-active { border-color: var(--g-gold-ink); box-shadow: inset 0 0 0 1px var(--g-gold-ink); }
.mg-place-dot {
  width: 11px; height: 11px; border-radius: 50%; flex: none;
  background: var(--color-primary); box-shadow: 0 0 0 4px var(--color-bg-tint);
}
.mg-place-dot.is-sensitive {
  background: transparent; box-shadow: 0 0 0 3px color-mix(in srgb, var(--color-primary) 34%, transparent);
}
/* Selected place: dot + ring go gold to match the globe. */
.mg-place.is-active .mg-place-dot {
  background: var(--g-gold-ink); box-shadow: 0 0 0 4px color-mix(in srgb, var(--g-gold-ink) 22%, transparent);
}
.mg-place.is-active .mg-place-dot.is-sensitive {
  background: transparent; box-shadow: 0 0 0 3px color-mix(in srgb, var(--g-gold-ink) 45%, transparent);
}
.mg-place-text { display: flex; flex-direction: column; }
.mg-place-name { font-weight: 600; font-size: 0.98rem; color: var(--color-ink); }
.mg-place-region { font-family: var(--font-sans); font-size: 0.78rem; color: var(--color-muted); }

@media (prefers-reduced-motion: reduce) { .mg-place:hover { transform: none; } }
@media (max-width: 640px) {
  .mg-list { grid-template-columns: 1fr; }
  .mg-card {
    position: fixed; left: 8px !important; right: 8px; bottom: 8px; top: auto !important;
    width: auto; max-width: none;
  }
}
