/* ==========================================================================
   Right Start Ministries — style.css
   Right Start Radio with Pastor Jim Custer

   A warm "dawn over night" theme (deep navy → sunrise gold/orange), tied to the
   morning radio broadcast. Slab-serif headings for scholarly warmth; generous,
   high-contrast type for an older, traditional audience.

   Conventions followed (see PROJECT-CONTEXT.md):
     - Design tokens in :root  - overflow-x: clip backstop  - page fade-in
     - .reveal / .reveal-scale / .stagger scroll animations (paired with script.js)
     - Mobile breakpoints at 900 / 768 / 480; prefers-reduced-motion honored
     - Admin styles live in the separate admin.css; this file only adds the
       sticky-header admin-mode offset and defines the CSS vars admin.css reads.
   Section index:
     1 Reset & base      6 Hero              11 Subscribe / stations
     2 Design tokens     7 Sections/cards    12 Contact form
     3 Typography        8 Split / bio       13 Footer
     4 Buttons/util      9 Episodes/audio    14 Reveal animations
     5 Header / nav     10 CTA / donate      15 Mobile
   ========================================================================== */

/* -----------------------------------------------
   1. Reset & Base
----------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

html {
  scroll-behavior: smooth;
  /* Backstop against horizontal scroll. `clip` (not `hidden`) so it doesn't
     break position: sticky on the header. */
  overflow-x: clip;
  scroll-padding-top: 96px; /* so #anchor jumps clear the sticky header */
}

body {
  font-family: 'Inter', system-ui, -apple-system, sans-serif;
  font-size: 17px;
  line-height: 1.7;
  color: var(--body);
  background: #fff;
  -webkit-font-smoothing: antialiased;
  opacity: 0;
  transition: opacity 0.5s ease;
  max-width: 100%;
  overflow-x: clip;
}
body.page-visible { opacity: 1; }

/* Set by script.js immediately before the bfcache-restore reload, to blank the
   restored (stale) frame instead of letting the visitor see it flash. !important
   and transition:none on purpose: this has to beat both the 0.5s fade above and
   the reduced-motion `body { opacity: 1 }` below, or the stale page either fades
   out slowly or never hides at all. */
body.page-reloading { opacity: 0 !important; transition: none !important; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto !important; }
  body { opacity: 1; transition: none; }
  /* Global backstop so any animation added later is covered automatically —
     the per-component reduced-motion blocks further down stay as they are. */
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

img { max-width: 100%; height: auto; display: block; }
a { color: var(--sunrise-700); text-decoration: none; }
a:hover { text-decoration: underline; }
ul { list-style: none; }
address { font-style: normal; }
p { margin-bottom: 1rem; }
p:last-child { margin-bottom: 0; }

:focus { outline: none; }
/* Focus ring uses the orange accent (not gold) so it stays visible on light backgrounds. */
:focus-visible { outline: 3px solid var(--sunrise-600); outline-offset: 2px; border-radius: 3px; }
a, button { -webkit-tap-highlight-color: transparent; }

/* Skip link (WCAG 2.4.1) — first focusable element on the page, injected at the top
   of partials.js's headerHTML and pointing at each page's <main id="main">. Parked
   off-screen until keyboard-focused; z-index clears the sticky header and alert bar. */
.skip-link {
  position: fixed;
  top: -100px;
  left: 16px;
  z-index: 300;
  background: var(--navy-800, #1a2740);
  color: #fff;
  font-weight: 600;
  padding: 12px 20px;
  border-radius: 0 0 8px 8px;
  transition: top 0.15s ease;
}
.skip-link:hover { text-decoration: none; }
.skip-link:focus-visible { top: 0; }

/* Screen-reader-only text — visually hidden but still read aloud and searchable. */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* -----------------------------------------------
   2. Design Tokens
----------------------------------------------- */
:root {
  /* Night → dawn palette */
  --navy-950: #0c1322;
  --navy-900: #101a2e;
  --navy-800: #1a2740;   /* primary brand navy */
  --navy-700: #26374f;
  --navy-600: #35496552;

  /* Accent = the logo's sunrise orange (#f08030). -500 is the true logo hue for
     decorative use (icons, gradients, glows, underline); -600/-700 are deepened
     for interactive backgrounds and text so they keep readable contrast. */
  --sunrise-700: #a94f0c;  /* deep — text on light (links, eyebrows): ~5.5:1 */
  --sunrise-600: #cf6415;  /* interactive background (buttons) */
  --sunrise-500: #f08030;  /* the logo orange — icons, gradients, accents */
  --sunrise-400: #f79a4e;
  /* One gold everywhere: unified to the home-hero eyebrow color (#f3ca7d)
     per request. The three steps are kept as names but hold the same value. */
  --gold-500:   #f3ca7d;
  --gold-400:   #f3ca7d;
  --gold-300:   #f3ca7d;

  /* Neutrals (warm) */
  --ink:    #1b2436;   /* headings / dark text */
  --body:   #3f4a5c;   /* body text */
  --muted:  #6c7686;   /* secondary text */
  --cream:  #faf6ef;   /* warm off-white alt background */
  --cream-200: #f3ebe0;
  --line:   #e8ddce;   /* warm hairline border */

  /* Admin.css reads these (with its own fallbacks) — keep them defined */
  --primary:    var(--sunrise-600);
  --border:     #e5e7eb;
  --bg-page:    #f7f4ee;
  --text-dark:  #1b2436;
  --text-muted: #6c7686;

  /* Shadows / radii */
  --shadow-sm: 0 1px 3px rgba(20,30,50,0.07);
  --shadow-md: 0 6px 24px rgba(20,30,50,0.10);
  --shadow-lg: 0 18px 50px rgba(20,30,50,0.16);
  --r-sm: 8px;
  --r-md: 14px;
  --r-lg: 22px;
  --r-full: 9999px;

  --ease: 0.2s ease;
  --maxw: 1160px;
  --header-h: 76px;
}

/* -----------------------------------------------
   3. Typography
----------------------------------------------- */
h1, h2, h3, h4, h5 {
  font-family: 'Bitter', Georgia, 'Times New Roman', serif;
  font-weight: 700;
  color: var(--ink);
  line-height: 1.18;
  letter-spacing: -0.01em;
}
h1 { font-size: clamp(2.1rem, 4.6vw, 3.35rem); font-weight: 800; }
h2 { font-size: clamp(1.7rem, 3.2vw, 2.5rem); }
h3 { font-size: clamp(1.25rem, 2vw, 1.55rem); }
h4 { font-size: 1.1rem; }

.section-label,
.eyebrow {
  display: inline-block;
  font-family: 'Inter', sans-serif;
  font-size: 0.78rem;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--sunrise-700);
  margin-bottom: 0.9rem;
}
.section-title { margin-bottom: 0.6rem; }
.section-intro { font-size: 1.12rem; color: var(--muted); max-width: 60ch; }
.lead { font-size: 1.18rem; color: var(--ink); }
.highlight { color: var(--sunrise-700); }

/* -----------------------------------------------
   4. Buttons & Utilities
----------------------------------------------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font-family: 'Inter', sans-serif;
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.2;
  padding: 0.85rem 1.7rem;
  border-radius: var(--r-full);
  border: 2px solid transparent;
  cursor: pointer;
  transition: transform var(--ease), background var(--ease), color var(--ease), box-shadow var(--ease), border-color var(--ease);
  text-align: center;
  white-space: nowrap;
}
.btn:hover { text-decoration: none; transform: translateY(-2px); }
.btn:active { transform: translateY(0); }
.btn svg { width: 1.1em; height: 1.1em; flex-shrink: 0; }

.btn-primary {
  background: var(--sunrise-600);
  color: #fff;
  box-shadow: 0 6px 18px rgba(207,100,21,0.30);
}
.btn-primary:hover { background: var(--sunrise-700); color: #fff; }

.btn-secondary {
  background: var(--navy-800);
  color: #fff;
}
.btn-secondary:hover { background: var(--navy-700); color: #fff; }

.btn-outline {
  background: transparent;
  color: var(--navy-800);
  border-color: var(--navy-800);
}
.btn-outline:hover { background: var(--navy-800); color: #fff; }

.btn-white {
  background: #fff;
  color: var(--navy-800);
  box-shadow: var(--shadow-md);
}
.btn-white:hover { background: var(--gold-300); color: var(--navy-900); }

.btn-outline-white {
  background: transparent;
  color: #fff;
  border-color: rgba(255,255,255,0.55);
}
.btn-outline-white:hover { background: rgba(255,255,255,0.12); color: #fff; border-color: #fff; }

.btn-gold { background: var(--gold-500); color: var(--navy-900); }
.btn-gold:hover { background: var(--gold-400); color: var(--navy-900); }

/* Touch devices keep :hover "stuck" after a tap, which left buttons (e.g. Load
   more episodes) recolored after the first press. Reset hover styling to base
   where there's no true hover pointer. */
@media (hover: none) {
  .btn:hover { transform: none; }
  .btn-primary:hover { background: var(--sunrise-600); color: #fff; }
  .btn-secondary:hover { background: var(--navy-800); color: #fff; }
  .btn-outline:hover { background: transparent; color: var(--navy-800); }
  .btn-white:hover { background: #fff; color: var(--navy-800); }
  .btn-outline-white:hover { background: transparent; color: #fff; border-color: rgba(255,255,255,0.55); }
  .btn-gold:hover { background: var(--gold-500); color: var(--navy-900); }
}

.btn-lg { font-size: 1.08rem; padding: 1rem 2.1rem; }
.btn-block { width: 100%; }

/* Mobile: let long labels wrap instead of overflowing */
.btn { }
@media (max-width: 768px) { .btn { white-space: normal; max-width: 100%; } }

.container { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 24px; }
.container--narrow { max-width: 820px; }
.text-center { text-align: center; }
.mt-sm { margin-top: 0.75rem; }
.mt-md { margin-top: 1.5rem; }
.mt-lg { margin-top: 2.5rem; }

.section { padding: clamp(3.5rem, 7vw, 6rem) 0; }
.section--alt { background: var(--cream); }
.section--dark { background: var(--navy-800); color: #e9edf4; }
.section--dark h1, .section--dark h2, .section--dark h3 { color: #fff; }
.section--dark .section-label { color: var(--gold-400); }
/* Left-aligned by default so a heading lines up with the full-width content
   it heads; .text-center re-centers the block for hero-style intros. */
.section-header { max-width: 680px; margin: 0 0 2.75rem; }
.section-header.text-center { margin-left: auto; margin-right: auto; }

/* -----------------------------------------------
   5. Header / Nav
----------------------------------------------- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 200;
  background: rgba(255,255,255,0.94);
  backdrop-filter: saturate(150%) blur(10px);
  border-bottom: 1px solid var(--line);
  transition: box-shadow var(--ease), background var(--ease), border-color var(--ease);
}
.site-header.scrolled {
  background: rgba(255,255,255,0.98);
  border-bottom-color: transparent;
  box-shadow: var(--shadow-md);
}
.admin-mode .site-header { top: 34px; }

/* Signature: a thin band of first light across the top edge of the bar — the
   "Right Start" dawn, echoed from the logo's sunrise. */
.header-dawn {
  position: absolute;
  top: 0; left: 0; right: 0;
  height: 3px;
  background: linear-gradient(90deg,
    var(--navy-800) 0%, var(--sunrise-600) 38%,
    var(--sunrise-500) 60%, var(--gold-400) 100%);
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  min-height: var(--header-h);
}
.logo { display: inline-flex; align-items: center; }
.logo:hover { text-decoration: none; }
.logo-img {
  height: 46px; width: auto;
  transition: height var(--ease);
}
.site-header.scrolled .logo-img { height: 42px; }

.main-nav ul { display: flex; align-items: center; gap: 0.1rem; }
.main-nav a {
  position: relative;
  display: inline-block;
  padding: 0.5rem 0.95rem;
  font-family: 'Inter', system-ui, sans-serif;
  font-weight: 600;
  font-size: 1.02rem;
  color: var(--navy-800);
  border-radius: var(--r-sm);
  transition: color var(--ease);
}
.main-nav a:not(.btn-nav):hover { color: var(--sunrise-700); text-decoration: none; }
.main-nav a.active:not(.btn-nav) { color: var(--ink); }
/* Underline "first light" — a warm sunrise-to-gold rule that grows from the
   center on hover and stays lit on the active page. Absolute so it never
   nudges the link's height in the flex row. */
.main-nav a:not(.btn-nav)::after {
  content: ''; position: absolute; left: 0.95rem; right: 0.95rem; bottom: 4px;
  height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, var(--sunrise-500), var(--gold-500));
  transform: scaleX(0); transform-origin: center;
  opacity: 0;
  transition: transform var(--ease), opacity var(--ease);
}
.main-nav a:not(.btn-nav):hover::after,
.main-nav a.active:not(.btn-nav)::after { transform: scaleX(1); opacity: 1; }
.main-nav a:focus-visible { outline: 2px solid var(--sunrise-600); outline-offset: 2px; border-radius: var(--r-sm); }

/* Give — the one loud element: a warm pill, set apart from the text links by a
   hairline divider so it reads as an action, not another destination. */
.nav-cta-item {
  margin-left: 0.65rem;
  padding-left: 0.9rem;
  border-left: 1px solid var(--line);
}
.main-nav a.btn-nav,
.btn-nav {
  background: var(--sunrise-600);
  color: #fff !important;
  padding: 0.58rem 1.4rem;
  border-radius: var(--r-full);
  box-shadow: 0 4px 14px rgba(207,100,21,0.28);
  transition: background var(--ease), transform var(--ease), box-shadow var(--ease);
}
.btn-nav:hover {
  background: var(--sunrise-700); color: #fff !important;
  transform: translateY(-1px);
  box-shadow: 0 6px 18px rgba(169,79,12,0.34);
}
.btn-nav:active { transform: translateY(0); }
.btn-nav.active::after { display: none; }

.nav-toggle {
  display: none;
  flex-direction: column;
  align-items: center; justify-content: center;
  gap: 5px;
  width: 44px; height: 44px;
  padding: 10px;
  background: none; border: none; cursor: pointer;
}
.nav-toggle span {
  display: block; height: 2.5px; width: 100%;
  background: var(--navy-800); border-radius: 2px;
  transition: transform var(--ease), opacity var(--ease);
}
.nav-toggle.open span:nth-child(1) { transform: translateY(7.5px) rotate(45deg); }
.nav-toggle.open span:nth-child(2) { opacity: 0; }
.nav-toggle.open span:nth-child(3) { transform: translateY(-7.5px) rotate(-45deg); }

/* -----------------------------------------------
   6. Hero (home)
----------------------------------------------- */
.hero {
  position: relative;
  color: #eef2f8;
  background:
    radial-gradient(120% 120% at 80% -10%, rgba(227,161,51,0.28), transparent 55%),
    radial-gradient(130% 110% at -10% 120%, rgba(240,128,48,0.30), transparent 55%),
    linear-gradient(160deg, var(--navy-900) 0%, var(--navy-800) 55%, var(--navy-700) 100%);
  overflow: hidden;
}
.hero::after {
  /* soft "sunrise" glow along the bottom */
  content: ''; position: absolute; left: 0; right: 0; bottom: -40%;
  height: 80%; pointer-events: none;
  background: radial-gradient(60% 100% at 50% 100%, rgba(243,202,125,0.20), transparent 70%);
}
.hero-inner {
  position: relative; z-index: 1;
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  align-items: center;
  gap: clamp(2rem, 5vw, 4rem);
  padding: clamp(3.5rem, 8vw, 6.5rem) 0 clamp(3.5rem, 8vw, 6rem);
}
.hero-eyebrow {
  display: inline-flex; align-items: center; gap: 0.6rem; flex-wrap: wrap;
  font-size: 0.8rem; font-weight: 700; letter-spacing: 0.13em; text-transform: uppercase;
  color: var(--gold-300); margin-bottom: 1.4rem;
}
.hero-eyebrow-dot { width: 5px; height: 5px; border-radius: 50%; background: var(--sunrise-400); }
.hero-title { color: #fff; margin-bottom: 1.4rem; }
.hero-desc { font-size: 1.2rem; color: #d3dbe8; max-width: 42ch; }
/* margin-top (not the desc's margin-bottom) sets this gap — the desc is the last
   <p> in its group, so `p:last-child { margin-bottom: 0 }` would zero it. */
.hero-actions { display: flex; flex-wrap: wrap; gap: 1rem; margin-top: 2.25rem; }
.hero-meta {
  margin-top: 2.5rem; padding-top: 2rem;
  border-top: 1px solid rgba(255,255,255,0.14);
  display: flex; gap: 2.75rem; flex-wrap: wrap;
}
/* Each value is centered over its own label. Below 900px the whole hero is
   already text-align: center, so this only changes the desktop layout. */
.hero-meta .stat { text-align: center; }
.hero-meta .stat strong { display: block; font-family: 'Bitter', serif; font-size: 1.55rem; line-height: 1.1; color: var(--gold-400); margin-bottom: 0.15rem; }
.hero-meta .stat span { font-size: 0.85rem; color: #b7c1d2; }

.hero-art { display: flex; justify-content: center; }
.hero-art-frame {
  position: relative;
  width: min(340px, 78vw);
  border-radius: 20px;
  overflow: hidden;
  box-shadow: 0 30px 60px rgba(0,0,0,0.45);
  border: 6px solid rgba(255,255,255,0.10);
  rotate: 2deg;
}
.hero-art-frame img { width: 100%; display: block; }

/* Page hero (inner pages) */
.page-hero {
  position: relative;
  color: #eef2f8;
  background:
    radial-gradient(120% 140% at 90% -20%, rgba(227,161,51,0.25), transparent 55%),
    linear-gradient(160deg, var(--navy-900), var(--navy-800));
  padding: clamp(3rem, 7vw, 5rem) 0 clamp(2.5rem, 6vw, 4rem);
  text-align: center;
}
.page-hero-eyebrow {
  font-size: 0.8rem; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase;
  color: var(--gold-300); display: block; margin-bottom: 0.8rem;
}
/* No ch cap — let titles use the hero width so they stay on one line
   (font size unchanged); they still wrap naturally on narrow screens. */
.page-hero-title { color: #fff; margin: 0 auto; max-width: none; }
.page-hero-sub { color: #d3dbe8; font-size: 1.15rem; max-width: 60ch; margin: 1rem auto 0; }

/* -----------------------------------------------
   7. Sections & cards
----------------------------------------------- */
/* Home: Meet Pastor Jim — landscape portrait beside a short teaser to /about */
.jim-feature-inner {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
.jim-feature-media img {
  width: 100%; height: auto; display: block;
  aspect-ratio: 3 / 2; object-fit: cover;
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
}
.jim-feature-body .section-title { margin-bottom: 0.75rem; }
.jim-feature-body p { color: var(--body); font-size: 1.1rem; margin-bottom: 1.75rem; }
@media (max-width: 860px) {
  .jim-feature-inner { grid-template-columns: 1fr; }
  .jim-feature-media { max-width: 560px; margin: 0 auto; }
  /* Center the CTA under the stacked text on mobile */
  .jim-feature-body .btn { display: block; width: fit-content; margin-inline: auto; }
}

.feature-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 1.5rem;
}
.feature-card {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 2rem 1.75rem;
  box-shadow: var(--shadow-sm);
  transition: transform var(--ease), box-shadow var(--ease);
}
.feature-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-md); }
.feature-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 52px; height: 52px; border-radius: 14px;
  background: linear-gradient(150deg, var(--gold-400), var(--sunrise-500));
  color: #fff; margin-bottom: 1.1rem;
}
.feature-icon svg { width: 26px; height: 26px; }
.feature-card h3 { margin-bottom: 0.5rem; }
.feature-card p { color: var(--muted); margin: 0; }

/* Mission / three-fold aim numbered list */
.aims { display: grid; gap: 1.25rem; margin-top: 1.5rem; }
.aim { display: flex; gap: 1rem; align-items: flex-start; }
.aim-num {
  flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: 50%;
  background: var(--navy-800); color: var(--gold-400);
  font-family: 'Bitter', serif; font-weight: 800;
}
.aim p { margin: 0; }

/* -----------------------------------------------
   8. Split (photo + text) & bio
----------------------------------------------- */
.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}
.split--reverse .split-media { order: 2; }
.split-media img {
  width: 100%; border-radius: var(--r-lg);
  box-shadow: var(--shadow-lg);
}
.split-body h2 { margin-bottom: 0.75rem; }

/* About · Pastor Jim — bio woven through the years.
   Portrait rows alternate side to side; a full-width preaching photo divides
   the story. Every photo uses object-fit:cover against a fixed aspect-ratio so
   nothing stretches, regardless of the source image's true proportions. */
/* Left-aligned article column so it shares its left edge with the section
   heading, and photo + text stay paired instead of spreading edge-to-edge. */
.jim-story { display: grid; gap: clamp(2.5rem, 5vw, 3.5rem); max-width: 960px; margin-top: clamp(1.75rem, 4vw, 2.5rem); }

.jim-row {
  display: grid;
  grid-template-columns: 340px 1fr;
  gap: clamp(2rem, 5vw, 3.25rem);
  align-items: center;
}
.jim-row--reverse { grid-template-columns: 1fr 340px; }
/* Match the site's standard body text (17px / 1.7) instead of a custom size, so
   the bio reads consistently with every other paragraph. */
.jim-row-body :is(p) { margin: 0; }

/* Aspect-ratio lives on the FIGURE (a plain block with no width/height
   attributes) so it can't be defeated by the img's presentational size
   hints; the img simply fills that box and is cropped, never stretched. */
.jim-portrait { margin: 0; width: 100%; aspect-ratio: 1 / 1; }
.jim-portrait img {
  width: 100%; height: 100%;
  object-fit: cover; object-position: center 22%; display: block;
  border-radius: var(--r-lg);
  border: 5px solid #fff; outline: 1px solid var(--line);
  box-shadow: var(--shadow-lg);
}
/* Admin mode injects a wrapper div between the figure and the img (the Replace
   overlay needs a positioned parent). Left at its default auto height the
   wrapper defeats the figure's 1:1 box and the portrait renders at its natural
   aspect ratio, so the row jumps the moment admin mode turns on. overflow stays
   visible so the img's own radius/shadow aren't clipped by the wrapper. */
.jim-portrait .admin-photo-wrap { width: 100%; height: 100%; overflow: visible; }


@media (max-width: 900px) {
  .jim-row, .jim-row--reverse { grid-template-columns: 1fr; gap: 1.5rem; }
  /* Photo above text on every row when stacked, whatever the source order */
  .jim-portrait { order: -1; width: 100%; max-width: 300px; margin-inline: auto; }
}

/* Beliefs summary */
.beliefs-list { display: grid; gap: 0.9rem; margin: 1.25rem 0; }
.beliefs-list li {
  position: relative; padding-left: 1.9rem; color: var(--body);
}
.beliefs-list li::before {
  content: ''; position: absolute; left: 0; top: 0.55em;
  width: 9px; height: 9px; border-radius: 50%;
  background: var(--sunrise-500);
}

/* Prose block for legacy rich content (Beliefs full, etc.) */
.prose h2 { margin: 2rem 0 0.75rem; }
.prose h3 { margin: 1.5rem 0 0.5rem; }
.prose p { margin-bottom: 1rem; }
.prose a { color: var(--sunrise-700); text-decoration: underline; }
.prose ul, .prose ol { margin: 0 0 1rem 1.4rem; }
.prose ul { list-style: disc; }
.prose ol { list-style: decimal; }
.prose li { margin-bottom: 0.4rem; }

/* -----------------------------------------------
   9. Episodes & audio player
----------------------------------------------- */
/* Home: latest episode feature */
.latest {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: 1.75rem;
  align-items: center;
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 1.75rem;
  box-shadow: var(--shadow-md);
}
.latest-art { border-radius: var(--r-md); overflow: hidden; box-shadow: var(--shadow-sm); }
.latest-art img { width: 100%; display: block; aspect-ratio: 1/1; object-fit: cover; }
.latest-badge {
  display: inline-block; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--sunrise-700); margin-bottom: 0.5rem;
}
.latest-title { font-size: 1.4rem; margin-bottom: 0.35rem; }
.latest-meta { font-size: 0.9rem; color: var(--muted); margin-bottom: 0.75rem; }
.latest-desc { color: var(--body); margin-bottom: 1.1rem; }

/* Listen: episode list */
.episodes-status { color: var(--muted); padding: 1.5rem 0; }
.episodes-status.error { color: var(--sunrise-700); }
.episode-list { display: grid; gap: 1rem; margin-top: 1.5rem; }
.episode {
  background: #fff;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  padding: 1.35rem 1.5rem;
  box-shadow: var(--shadow-sm);
  transition: box-shadow var(--ease);
}
.episode:hover { box-shadow: var(--shadow-md); }
.episode-title { font-size: 1.2rem; margin-bottom: 0.3rem; }
.episode-meta {
  display: flex; flex-wrap: wrap; gap: 0.4rem 1rem;
  font-size: 0.85rem; color: var(--muted); margin-bottom: 0.7rem;
}
.episode-meta .dot { color: var(--line); }
.episode-desc { color: var(--body); margin-bottom: 1rem; }
.episode-play {
  display: inline-flex; align-items: center; gap: 0.55rem;
  font-family: 'Inter', sans-serif; font-weight: 700; font-size: 0.95rem;
  color: #fff; background: var(--navy-800);
  border: none; border-radius: var(--r-full);
  padding: 0.6rem 1.25rem; cursor: pointer;
  transition: background var(--ease);
}
.episode-play:hover { background: var(--sunrise-600); }
.episode-play svg { width: 16px; height: 16px; }
.episode-audio { margin-top: 1rem; width: 100%; }
.episode-audio audio { width: 100%; display: block; }

/* Clamped episode description with a See more / See less toggle. Only one
   description is expanded at a time (managed in episodes.js). The clamp caps the
   text; the toggle is revealed only when the text actually overflows. */
.ep-desc-wrap { margin-bottom: 1.1rem; }
.ep-desc-text {
  color: var(--body);
  margin: 0;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
  line-clamp: 4;
  overflow: hidden;
}
.ep-desc-text.expanded {
  display: block;
  -webkit-line-clamp: unset;
  line-clamp: unset;
  overflow: visible;
}
.ep-desc-toggle {
  margin-top: 0.5rem; padding: 0;
  background: none; border: none;
  font-family: inherit; font-size: 0.9rem; font-weight: 600;
  color: var(--sunrise-700); cursor: pointer;
}
.ep-desc-toggle[hidden] { display: none; }
.ep-desc-toggle:hover { text-decoration: underline; }

/* Custom episode player (seek bar, ±15s skip, speed, download) — used by the
   home feature card, the Listen cards, and the archive rows. Accent = sunrise. */
.ep-player {
  display: flex; flex-direction: column; gap: 0.55rem;
  margin-top: 1rem; padding: 0.95rem 1.05rem;
  background: #fff; border: 1px solid var(--line);
  border-radius: var(--r-md); box-shadow: var(--shadow-sm);
}
.ep-bar { position: relative; height: 16px; display: flex; align-items: center; cursor: pointer; touch-action: none; }
.ep-bar-track { width: 100%; height: 5px; border-radius: 999px; background: var(--cream-200); overflow: hidden; }
.ep-bar-fill { height: 100%; width: 0; border-radius: 999px; background: var(--sunrise-500); }
.ep-bar-thumb {
  position: absolute; top: 50%; left: 0; width: 13px; height: 13px; border-radius: 50%;
  background: var(--sunrise-500); border: 2px solid #fff; box-shadow: var(--shadow-sm);
  transform: translate(-50%, -50%); pointer-events: none;
}
.ep-times { display: flex; justify-content: space-between; font-size: 0.72rem; font-weight: 600; color: var(--muted); font-variant-numeric: tabular-nums; }
.ep-controls { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
.ep-center { display: flex; align-items: center; gap: clamp(0.75rem, 3vw, 1.35rem); }
.ep-btn { display: inline-flex; align-items: center; justify-content: center; border: none; background: transparent; color: var(--navy-700); cursor: pointer; padding: 0; transition: color var(--ease), background var(--ease); }
.ep-skip { width: 34px; height: 34px; }
.ep-skip svg { width: 24px; height: 24px; }
.ep-skip:hover { color: var(--sunrise-600); }
.ep-play { width: 46px; height: 46px; border-radius: 50%; background: var(--sunrise-500); color: #fff; box-shadow: var(--shadow-sm); }
.ep-play svg { width: 20px; height: 20px; }
.ep-play:hover { background: var(--sunrise-600); }
.ep-speed { min-width: 40px; height: 32px; border-radius: 999px; background: var(--cream); color: var(--sunrise-700); border: 1px solid var(--line); font-weight: 700; font-size: 0.8rem; font-variant-numeric: tabular-nums; }
.ep-speed:hover { border-color: var(--sunrise-400); }
.ep-left { display: flex; align-items: center; gap: 0.4rem; }
.ep-restart { width: 34px; height: 34px; border-radius: 50%; color: var(--muted); }
.ep-restart svg { width: 19px; height: 19px; }
.ep-restart:hover { background: var(--cream); color: var(--navy-800); }
.ep-right { display: flex; align-items: center; gap: 0.25rem; }
.ep-download, .ep-close { width: 34px; height: 34px; border-radius: 50%; color: var(--muted); }
.ep-download svg, .ep-close svg { width: 18px; height: 18px; }
.ep-download:hover, .ep-close:hover { background: var(--cream); color: var(--navy-800); }

/* Full-screen mobile audio player overlay. Built + shown by episodes.js only on
   phones; desktop keeps the inline player, so these rules never apply there. */
.ep-overlay { position: fixed; inset: 0; z-index: 1100; }  /* above bottom sheets */
.ep-overlay[hidden] { display: none; }
.ep-overlay-backdrop { position: absolute; inset: 0; background: rgba(11,20,38,0.75); }
.ep-overlay-sheet {
  position: absolute; inset: 0;
  background: linear-gradient(165deg, var(--navy-900), var(--navy-800));
  color: #fff;
  display: flex; flex-direction: column; align-items: center; gap: 1.2rem;
  padding: 4.5rem 1.5rem 2.5rem;
  overflow-y: auto;
  /* Keep rubber-band overscroll inside the sheet: without this, dragging past the
     top/bottom on mobile bounces the sheet and exposes the white page body behind
     this fixed overlay. */
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}
.ep-overlay-close {
  position: absolute; top: 1rem; right: 1rem;
  width: 44px; height: 44px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255,255,255,0.10); color: #fff; border: none; cursor: pointer;
}
.ep-overlay-close:hover { background: rgba(255,255,255,0.18); }
.ep-overlay-close svg { width: 22px; height: 22px; }
.ep-overlay-art {
  width: min(300px, 68vw); aspect-ratio: 1 / 1; object-fit: cover;
  border-radius: var(--r-lg); box-shadow: var(--shadow-lg); margin-top: auto;
}
.ep-overlay-eyebrow {
  font-size: 0.75rem; font-weight: 700; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--gold-300);
}
.ep-overlay-title {
  color: #fff; text-align: center; font-size: 1.35rem; line-height: 1.25;
  margin: 0; width: 100%;
  overflow: hidden; white-space: nowrap;
}
/* Long titles run a seamless one-direction marquee: the text scrolls left until
   it clears and a second copy follows in from the right — continuous, no bounce.
   Short titles stay put (single copy, no animation). */
.ep-title-inner { display: inline-flex; gap: 56px; }   /* gap must match MARQUEE_GAP */
.ep-title-seg { white-space: nowrap; flex: none; }
.ep-overlay-title.is-scrolling { text-align: left; }
.ep-overlay-title.is-scrolling .ep-title-inner,
.ep-dock-title.is-scrolling .ep-title-inner,
.ep-mini-title.is-scrolling .ep-title-inner {
  animation-name: ep-title-marquee;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
  animation-duration: 20s;   /* ~5s rest (0–25%) + ~15s slow scroll (25–100%) */
  will-change: transform;
}
/* Rest at the home position for the first quarter of the cycle (~5s of 20s),
   then scroll one copy+gap to the left; the trailing copy lands where the first
   started, so it loops seamlessly and rests again. */
@keyframes ep-title-marquee {
  0%, 25% { transform: translateX(0); }
  100%    { transform: translateX(var(--ep-shift, 0)); }
}
@media (prefers-reduced-motion: reduce) {
  .ep-overlay-title.is-scrolling .ep-title-inner,
  .ep-dock-title.is-scrolling .ep-title-inner,
  .ep-mini-title.is-scrolling .ep-title-inner { animation: none; }
}
.ep-overlay-mount { width: 100%; max-width: 440px; margin-bottom: auto; }

/* Recolor the player controls for the dark overlay and drop the inline card
   chrome (white bg, border, shadow, top margin). */
.ep-overlay .ep-player { background: transparent; border: none; box-shadow: none; margin-top: 0; padding: 0; }
.ep-overlay .ep-bar-track { background: rgba(255,255,255,0.18); }
.ep-overlay .ep-times { color: rgba(255,255,255,0.7); }
.ep-overlay .ep-btn { color: #e7ecf4; }
.ep-overlay .ep-skip:hover { color: var(--gold-400); }
.ep-overlay .ep-speed { background: rgba(255,255,255,0.10); color: #fff; border-color: rgba(255,255,255,0.22); }
.ep-overlay .ep-restart:hover, .ep-overlay .ep-download:hover { background: rgba(255,255,255,0.12); color: #fff; }
.ep-overlay .ep-close { display: none; }  /* the overlay has its own close button */
/* Hiding the in-player close leaves the right group lighter than the left, which
   pushed Play off-center. Give both side groups equal width so the center group
   (with the Play button) sits dead-center. */
.ep-overlay .ep-left, .ep-overlay .ep-right { flex: 1 1 0; }
.ep-overlay .ep-left { justify-content: flex-start; }
.ep-overlay .ep-right { justify-content: flex-end; }
body.ep-overlay-open { overflow: hidden; }

/* Opening the full-screen player: the sheet slides up from the bottom edge while
   the backdrop fades in. The overlay toggles display:none→flex on open, which
   re-triggers these entrance animations each time it's shown. */
.ep-overlay-sheet { animation: ep-sheet-up 0.3s cubic-bezier(0.22, 0.61, 0.36, 1); }
.ep-overlay-backdrop { animation: ep-backdrop-in 0.3s ease-out; }
@keyframes ep-sheet-up {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}
@keyframes ep-backdrop-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}
/* Closing: reverse the entrance — sheet slides back down, backdrop fades out.
   `forwards` holds the end state so the sheet stays off-screen until the JS
   hides the overlay (no snap-back flash). The .ep-overlay-closing class is set
   by animateOverlayClose() and removed once the animation finishes. */
.ep-overlay-closing .ep-overlay-sheet {
  animation: ep-sheet-down 0.3s cubic-bezier(0.55, 0, 0.67, 0.2) forwards;
}
.ep-overlay-closing .ep-overlay-backdrop {
  animation: ep-backdrop-out 0.3s ease-in forwards;
}
@keyframes ep-sheet-down {
  from { transform: translateY(0); }
  to   { transform: translateY(100%); }
}
@keyframes ep-backdrop-out {
  from { opacity: 1; }
  to   { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .ep-overlay-sheet, .ep-overlay-backdrop,
  .ep-overlay-closing .ep-overlay-sheet,
  .ep-overlay-closing .ep-overlay-backdrop { animation: none; }
}

/* Persistent desktop "dock" — a Now Playing bar fixed to the bottom of every
   page (Spotify-style). Shown by episodes.js on desktop only; on phones the
   overlay is used instead. */
.ep-dock {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 1000;
  background: linear-gradient(180deg, var(--navy-800), var(--navy-900));
  border-top: 3px solid var(--gold-500);   /* gold "first light" line, like the CTA bands */
  box-shadow: 0 -8px 28px rgba(0,0,0,0.38);
  color: #fff;
}
.ep-dock[hidden] { display: none; }
/* Full width (not the centered container) so the Now Playing info sits at the
   far left edge and the transport still centers on the viewport. */
.ep-dock-inner {
  display: flex; align-items: center; gap: 1.1rem;
  padding: 0.7rem 24px;
}
/* Left region (art + title) and the right region are equal-width flexible thirds,
   so the fixed-width transport in the middle is centered on the page. */
.ep-dock-left { flex: 1 1 0; min-width: 0; display: flex; align-items: center; gap: 0.9rem; }
.ep-dock-right-region { flex: 1 1 0; min-width: 0; }
.ep-dock-art { width: 52px; height: 52px; border-radius: 8px; object-fit: cover; flex-shrink: 0; }
.ep-dock-meta { min-width: 0; }
.ep-dock-eyebrow {
  display: block; font-size: 0.62rem; font-weight: 700;
  letter-spacing: 0.14em; text-transform: uppercase; color: var(--gold-300);
  margin-bottom: 0.15rem;
}
.ep-dock-title {
  font-family: 'Bitter', serif; font-weight: 600; font-size: 0.98rem; color: #fff;
  overflow: hidden; white-space: nowrap; width: 100%;
}
/* (marquee animation for the dock title is defined with the overlay title above) */
.ep-dock-mount { flex: 0 0 auto; width: min(600px, 48vw); min-width: 0; }
/* Equal side groups inside the control row so the transport (play) is centered. */
.ep-dock .ep-left, .ep-dock .ep-right { flex: 1 1 0; }
.ep-dock .ep-left { justify-content: flex-start; }
.ep-dock .ep-right { justify-content: flex-end; }
/* Close (X) pinned to the top-right of the bar, out of the control row. Inset to
   match the dock's 24px content padding so it clears the page scroll bar. */
.ep-dock .ep-close {
  position: absolute; top: 8px; right: 24px;
  width: 30px; height: 30px;
}
/* The reused player wrap goes horizontal + dark inside the dock. */
.ep-dock .ep-player { background: transparent; border: none; box-shadow: none; margin: 0; padding: 0; gap: 0.3rem; }
.ep-dock .ep-bar-track { background: rgba(255,255,255,0.20); }
.ep-dock .ep-times { color: rgba(255,255,255,0.6); font-size: 0.68rem; }
.ep-dock .ep-btn { color: #e7ecf4; }
.ep-dock .ep-skip:hover { color: var(--gold-400); }
.ep-dock .ep-speed { background: rgba(255,255,255,0.10); color: #fff; border-color: rgba(255,255,255,0.22); }
.ep-dock .ep-play { background: var(--sunrise-500); color: #fff; }
.ep-dock .ep-play:hover { background: var(--sunrise-600); }
.ep-dock .ep-download:hover, .ep-dock .ep-close:hover { background: rgba(255,255,255,0.14); color: #fff; }
/* Keep the page's own footer clear of the fixed bar. */
body.ep-dock-open { padding-bottom: 92px; }

/* The dock is a desktop affordance; never show it on phones (overlay is used). */
@media (max-width: 768px) {
  .ep-dock { display: none !important; }
  body.ep-dock-open { padding-bottom: 0; }
}

/* Mobile mini bar — the collapsed, always-playing player. Artwork + title on the
   far left (tap to open the full-screen player), play/pause on the far right. */
.ep-mini {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 1000;
  display: flex; align-items: center; gap: 0.5rem;
  padding: 0.4rem 0.6rem 0.4rem 0.5rem;
  background: linear-gradient(180deg, var(--navy-800), var(--navy-900));
  box-shadow: 0 -6px 22px rgba(0,0,0,0.4);
  color: #fff;
}
.ep-mini[hidden] { display: none; }
/* The top gold line doubles as a playback progress indicator. The track is a dim
   gold rail across the full width; the fill grows left→right with playback. Purely
   a display — not seekable, no thumb (paint() sets its width). */
.ep-mini-progress {
  position: absolute; top: 0; left: 0; right: 0; height: 3px;
  background: rgba(243,202,125,0.28);   /* dim gold-500 rail */
  pointer-events: none;
}
.ep-mini-progress-fill { height: 100%; width: 0; background: var(--gold-500); }
.ep-mini-tap {
  flex: 1 1 auto; min-width: 0;
  display: flex; align-items: center; gap: 0.7rem;
  background: none; border: none; padding: 0.3rem; margin: 0;
  text-align: left; cursor: pointer; color: inherit; font: inherit;
}
.ep-mini-art { width: 46px; height: 46px; border-radius: 7px; object-fit: cover; flex-shrink: 0; }
.ep-mini-title {
  min-width: 0; overflow: hidden; white-space: nowrap;
  font-family: 'Bitter', serif; font-weight: 600; font-size: 0.95rem; color: #fff;
}
.ep-mini-mount { flex-shrink: 0; }
/* In mini mode the shared player wrap shows only the play/pause button. */
.ep-wrap-mini { }
.ep-wrap-mini .ep-bar, .ep-wrap-mini .ep-times,
.ep-wrap-mini .ep-left, .ep-wrap-mini .ep-right, .ep-wrap-mini .ep-skip { display: none; }
.ep-wrap-mini.ep-player { gap: 0; padding: 0; margin: 0; background: none; border: none; box-shadow: none; }
.ep-wrap-mini .ep-controls { gap: 0; }
.ep-wrap-mini .ep-center { gap: 0; }
.ep-wrap-mini .ep-play { width: 44px; height: 44px; background: var(--sunrise-500); color: #fff; }
body.ep-mini-open { padding-bottom: 66px; }
/* Mini bar is a phone affordance; never show it on desktop. */
@media (min-width: 769px) {
  .ep-mini { display: none !important; }
  body.ep-mini-open { padding-bottom: 0; }
}

/* -----------------------------------------------
   Bottom sheets (mobile pull-ups) — Contact quick actions, Browse episodes.
   Triggers are hidden on desktop; the sheet content stays inline there.
----------------------------------------------- */
.sheet-trigger { display: none; }
.sheet { position: fixed; inset: 0; z-index: 1050; }
.sheet[hidden] { display: none; }
.sheet-backdrop { position: absolute; inset: 0; background: rgba(11,20,38,0.5); opacity: 0; transition: opacity 0.3s ease; }
.sheet--open .sheet-backdrop { opacity: 1; }
.sheet-panel {
  position: absolute; left: 0; right: 0; bottom: 0;
  max-height: 88dvh;
  background: #fff; border-radius: 20px 20px 0 0;
  box-shadow: 0 -12px 40px rgba(0,0,0,0.28);
  /* Flex column: handle + title stay pinned at the top (and the absolutely-placed
     close rides the non-scrolling panel), only .sheet-body scrolls. */
  display: flex; flex-direction: column; overflow: hidden;
  padding: 0.65rem 1.25rem 0;
  transform: translateY(100%); transition: transform 0.32s cubic-bezier(0.22,1,0.36,1);
}
.sheet--open .sheet-panel { transform: translateY(0); }
.sheet-handle { flex: none; display: block; width: 42px; height: 4px; border-radius: 999px; background: var(--line); margin: 0.35rem auto 1rem; }
.sheet-title { flex: none; font-family: 'Bitter', serif; font-weight: 700; font-size: 1.2rem; color: var(--ink); margin: 0 0 0.9rem; padding-right: 2.5rem; }
/* overflow-x: hidden is load-bearing, not decoration. Per the CSS overflow spec, when
   one axis is not `visible` the other computes from `visible` to `auto` — so
   `overflow-y: auto` alone silently made this box horizontally scrollable, and the
   sheet's contents could be shoved left and right by a stray pixel of width.
   overscroll-behavior stops a scroll that reaches the end of the list from chaining
   through to the page underneath. */
.sheet-body {
  flex: 1 1 auto; min-height: 0;
  overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain;
  padding-bottom: 1.75rem;
}
.sheet-close {
  position: absolute; top: 0.7rem; right: 0.85rem;
  width: 38px; height: 38px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--cream); color: var(--navy-800); border: none; cursor: pointer;
}
.sheet-close svg { width: 20px; height: 20px; }
/* Neutralize card chrome for content moved inside a sheet (card-on-card looks off) */
.sheet .contact-card,
.sheet .contact-form-wrap { background: transparent; border: none; box-shadow: none; padding: 0; margin: 0; }
/* Even, tighter vertical rhythm between fields in the contact sheet. Fields
   inside a .form-row were getting the grid gap PLUS their own margin, making
   within-row gaps larger than between-row gaps — zero the in-row margin so every
   gap equals one value. */
.sheet .form-group { margin-bottom: 0.85rem; }
.sheet .form-row { gap: 0.85rem; margin-bottom: 0.85rem; }
.sheet .form-row .form-group { margin-bottom: 0; }
.sheet .contact-form-intro { margin-bottom: 1rem; }
/* Relocated content tagged .reveal must be visible in the sheet even though the
   scroll observer never fires for it while the sheet is closed/off-screen. */
.sheet .reveal, .sheet .reveal-scale { opacity: 1 !important; transform: none !important; }
/* Page lock while a sheet is open. overflow:hidden alone holds in Chromium but NOT on
   iOS Safari, which happily touch-scrolls the page behind the sheet; position: fixed is
   what actually pins it. script.js sets the inline `top: -<scrollY>px` that keeps the
   view from jumping, and restores the scroll offset on release — so this rule must not
   be applied by hand anywhere, only via RSSheets.lock()/unlock(). */
body.sheet-locked {
  position: fixed; left: 0; right: 0; width: 100%;
  overflow: hidden;
}
/* The Browse (search results) sheet stays a fixed height so it never resizes as
   the result count changes — the list scrolls inside it. */
#episodes-sheet .sheet-panel { height: 85dvh; }

/* The sermon archive pull-up. Same fixed height, for the same reason: 24 rows of
   results must not make the panel jump every time a filter narrows them. */
#sermons-sheet .sheet-panel { height: 85dvh; }
/* The panel's non-scrolling slot, between the title and the scrolling body. Holds the
   archive's search + Filter/Sort + count so they stay put while results scroll — with
   44 pages in here, having to scroll back up to reach Search would recreate the very
   problem this sheet exists to solve.
   This replaced a `position: sticky` version inside .sheet-body, which pinned them
   correctly but left both artefacts a sticky header always has: the scrollbar ran the
   panel's full height, implying the header scrolled too, and rows showed through above
   the search box as they passed behind it. Out of the scroll container, neither can
   happen. */
.sheet-fixed { flex: none; }
.sheet-fixed:not(:empty) {
  padding-bottom: 0.85rem; margin-bottom: 0.15rem;
  border-bottom: 1px solid var(--line);
}
#sermons-sheet .sheet-fixed .archive-controls { margin-bottom: 0; }
/* One hairline, not two. The fixed region's border-bottom and #sermon-list's own
   border-top were landing ~3px apart — a straight full-width rule directly above the
   card's rounded top edge, which read as a stray line floating above the list. The
   divider now IS the list's top edge: it stays put as the boundary the rows scroll
   under, and the card squares off its top to meet it. Scoped to this sheet, so the
   desktop list keeps its full rounded card. */
#sermons-sheet .sheet-fixed { margin-bottom: 0; }
#sermons-sheet #sermon-list {
  border-top: none;
  border-top-left-radius: 0; border-top-right-radius: 0;
}

/* Tap-to-call / email / etc. rows in the Contact sheet */
.sheet-action {
  display: flex; align-items: center; gap: 0.85rem;
  padding: 0.95rem 0.6rem; border-bottom: 1px solid var(--line);
  color: var(--ink); font-size: 1rem;
}
.sheet-action:last-child { border-bottom: none; }
.sheet-action svg { width: 22px; height: 22px; flex-shrink: 0; color: var(--sunrise-600); }
a.sheet-action:hover { text-decoration: none; background: var(--cream); border-radius: var(--r-sm); }

@media (max-width: 768px) {
  .sheet-trigger { display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem; width: 100%; }
}
.load-more-wrap { text-align: center; margin-top: 2rem; }

/* Archive: compact, searchable/filterable list of older episodes */
.archive-controls {
  display: flex; align-items: flex-end; gap: 1rem; flex-wrap: wrap;
  margin-bottom: 1.25rem;
}
.archive-controls .archive-search { flex: 1 1 260px; margin: 0; }
.archive-filters { display: flex; gap: 0.75rem; }
.archive-field { display: flex; flex-direction: column; gap: 0.35rem; }
.archive-field-label {
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted);
}
.archive-select {
  font-family: inherit; font-size: 0.95rem; color: var(--ink);
  padding: 0.7rem 2.2rem 0.7rem 0.9rem;
  border: 1.5px solid var(--line); border-radius: var(--r-sm);
  background-color: #fff;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%236c7686' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 0.75rem center;
  -webkit-appearance: none; appearance: none; cursor: pointer; outline: none;
  max-width: 220px;
  transition: border-color var(--ease), box-shadow var(--ease);
}
.archive-select:focus { border-color: var(--sunrise-500); box-shadow: 0 0 0 3px rgba(240,128,48,0.16); }
/* Filter button + Sort, side by side. On desktop the button is display:none
   (.sheet-trigger), so this contributes only the Sort field to the controls row. */
.archive-actions { display: flex; align-items: flex-end; gap: 0.75rem; }
.archive-filter-btn { padding: 0.62rem 1.15rem; font-size: 0.95rem; }
/* Count of active filters. Sits in the button, so a filter set inside the closed
   sheet is still visible on the page. */
.archive-filter-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; padding: 0 0.35rem; margin-left: 0.1rem;
  border-radius: 999px; background: var(--sunrise-600); color: #fff;
  font-size: 0.72rem; font-weight: 700; line-height: 1;
}
.archive-filter-count[hidden] { display: none; }
.archive-filter-btn--on { border-color: var(--sunrise-600); color: var(--sunrise-700); }
.archive-sort-btn { padding: 0.62rem 1.15rem; font-size: 0.95rem; }
/* Both mobile buttons show a value, so keep the text from being pushed around by a
   long label — the label is short by design ("Newest", "A–Z"), never the full option. */
.archive-filter-btn > span, .archive-sort-btn > span { white-space: nowrap; }

/* Tap list inside a sheet (the Sort menu). Rows are full-width targets, not a
   cramped native select. */
.sheet-options { display: flex; flex-direction: column; }
.sheet-option {
  display: flex; align-items: center; justify-content: space-between; gap: 0.85rem;
  width: 100%; text-align: left;
  padding: 0.95rem 0.25rem; border: none; border-bottom: 1px solid var(--line);
  background: transparent; color: var(--ink); font: inherit; font-size: 1rem;
  cursor: pointer;
}
.sheet-option:last-child { border-bottom: none; }
.sheet-option::after {
  content: ''; width: 20px; height: 20px; flex: none; opacity: 0;
  background: no-repeat center/20px 20px
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23cf6415' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
}
.sheet-option[aria-checked="true"] { color: var(--sunrise-700); font-weight: 600; }
.sheet-option[aria-checked="true"]::after { opacity: 1; }
/* "Best match" only ranks against a search term — shown but inert until there is one,
   so the menu never changes length underfoot. */
.sheet-option[disabled] { color: var(--muted); opacity: 0.5; pointer-events: none; }

/* ── Archive controls on mobile ──────────────────────────────────────────────
   Everything below 768px, NOT 600px: the filter sheet takes over at 768px, so a
   600px cutoff left 601-768px with desktop sizing inside a phone-width sheet —
   the four fields measured 719px inside a 640px viewport and ran off the screen.
   Series/Book/Year are relocated into the sheet and stack full-width there; the
   search box, the Filter/Sort row, the results and the pager stay on the page. */
@media (max-width: 768px) {
  .archive-controls { flex-direction: column; align-items: stretch; gap: 0.85rem; }
  .archive-controls .archive-search { flex: none; width: 100%; }
  .archive-actions { width: 100%; }
  /* .sheet-trigger is width:100% for full-width triggers elsewhere; here it shares
     the row with Sort, so each takes half. */
  .archive-actions .sheet-trigger { flex: 1 1 50%; width: auto; }
  /* The native Sort control is desktop-only; on mobile #sermon-sort-btn opens the Sort
     sheet instead. The <select> stays in the DOM (hidden) because it remains the state
     sermons.js reads — the sheet rows only write to it. */
  .archive-field--sort { display: none; }
  .archive-select { max-width: none; width: 100%; }
  .sheet .archive-filters { flex-direction: column; width: 100%; gap: 1.1rem; }
  .sheet .archive-field { width: 100%; }

  /* Archive rows carry the title, the passage and the duration only. The date and
     series pushed the meta onto three lines on a phone. Scoped to #sermon-list so the
     home page's single featured sermon keeps its full meta line.
     The separators have to be rebuilt, not inherited: `> * + *::before` keys on DOM
     order, so with the date merely display:none the scripture would still count as
     "preceded by a sibling" and pick up a leading '·'. The `~` rule below puts the dot
     on the duration only when a scripture actually precedes it, so a row with just a
     duration never opens with a stray dot. */
  #sermon-list .archive-date,
  #sermon-list .sermon-series { display: none; }
  #sermon-list .sermon-meta > * + *::before { content: none; margin-right: 0; }
  #sermon-list .sermon-meta > .sermon-scripture ~ .sermon-duration::before {
    content: '·'; margin-right: 0.55rem; opacity: 0.7;
  }
}

/* Pinned action row at the bottom of a sheet panel, outside the scrolling body. */
.sheet-footer {
  flex: none; display: flex; align-items: center; justify-content: space-between;
  gap: 0.85rem; padding: 0.85rem 0 1.1rem; border-top: 1px solid var(--line);
}
.sheet-footer .btn { flex: 1 1 auto; justify-content: center; }
.archive-search { position: relative; margin: 0 0 1rem; }
.archive-search-icon {
  position: absolute; left: 16px; top: 50%; transform: translateY(-50%);
  width: 18px; height: 18px; color: var(--muted); pointer-events: none;
}
.archive-search-input {
  width: 100%; box-sizing: border-box;
  font-family: inherit; font-size: 1rem; color: var(--ink);
  padding: 0.8rem 1.1rem 0.8rem 2.9rem;
  border: 1.5px solid var(--line); border-radius: var(--r-full);
  background: #fff; outline: none;
  transition: border-color var(--ease), box-shadow var(--ease);
}
.archive-search-input:focus {
  border-color: var(--sunrise-500);
  box-shadow: 0 0 0 3px rgba(240,128,48,0.16);
}
.archive-list { background: #fff; border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden; }
.archive-list:empty { display: none; }
/* Status/empty-state copy sits directly inside the bordered list card ("No sermons
   match your search…"), where the shared .episodes-status has no horizontal padding
   of its own and the text would butt against the border. Indent it to the same
   1rem the rows use. */
.archive-list > .episodes-status { padding-left: 1rem; padding-right: 1rem; }
.archive-item + .archive-item { border-top: 1px solid var(--line); }
.archive-row { display: flex; align-items: center; gap: 0.9rem; padding: 0.7rem 1rem; }
.archive-play {
  flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border: none; border-radius: 50%;
  background: var(--cream); color: var(--sunrise-700); cursor: pointer;
  transition: background var(--ease), color var(--ease);
}
.archive-play:hover { background: var(--sunrise-500); color: #fff; }
.archive-play svg { width: 16px; height: 16px; }
.archive-main { display: flex; flex-direction: column; min-width: 0; }
.archive-title { font-family: 'Bitter', serif; font-weight: 600; color: var(--ink); font-size: 1.02rem; line-height: 1.3; }
.archive-date { font-size: 0.82rem; color: var(--muted); }
.archive-audio:not(:empty) { padding: 0.25rem 0 0.9rem; }
.archive-audio audio { width: 100%; display: block; }

/* Sermon library (/sermons) — reuses the archive list above; these are the
   additions for a catalogue row, which carries more metadata than a feed episode.
   Deliberately generous type sizes: the audience skews older. */
a.archive-title { text-decoration: none; }
a.archive-title:hover { color: var(--sunrise-700); text-decoration: underline; }
/* Shown in place of Play when a sermon has no online recording yet (audio_url is
   null until the audio reaches S3). A dot, not a dead button — nothing to click. */
.archive-play--disabled {
  background: var(--cream); opacity: 0.4; cursor: default; pointer-events: none;
}
.archive-play--disabled::after {
  content: ''; width: 9px; height: 9px; border-radius: 50%; background: var(--muted);
}
/* date · scripture · series · duration, separated by dots that are not in the DOM
   (so they never end up in copied text or read out by a screen reader). */
.sermon-meta {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.15rem 0.55rem;
  margin-top: 0.15rem; font-size: 0.82rem; color: var(--muted); line-height: 1.45;
}
.sermon-meta > * + *::before { content: '·'; margin-right: 0.55rem; opacity: 0.7; }
.sermon-scripture { font-weight: 600; color: var(--sunrise-700); }
.sermon-series { font-style: italic; }
.sermon-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; margin-top: 0.85rem;
}
.sermon-count { margin: 0; font-size: 0.86rem; color: var(--muted); }
.sermon-clear {
  border: 1px solid var(--line); background: transparent; color: var(--ink);
  font: inherit; font-size: 0.84rem; padding: 0.3rem 0.75rem; border-radius: 999px;
  cursor: pointer; transition: background var(--ease), border-color var(--ease);
}
.sermon-clear:hover { background: var(--cream); border-color: var(--sunrise-500); }

/* Archive page selector. Targets are 44px so they stay comfortably tappable — the
   audience skews older, and 44 pages means real use of these controls. */
.sermon-pager {
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: 0.4rem; margin-top: 1.6rem;
}
/* min-width: 0 with shrink allowed is what keeps Prev/Next on the numbers' row: when
   the window is too wide for the viewport, the numbers wrap INSIDE this box instead of
   shoving Next onto a line of its own. */
.sermon-page-nums {
  display: flex; align-items: center; justify-content: center;
  gap: 0.3rem; flex-wrap: wrap; flex: 0 1 auto; min-width: 0;
}
.sermon-page {
  min-width: 44px; height: 44px; padding: 0 0.7rem;
  display: inline-flex; align-items: center; justify-content: center;
  border: 1px solid var(--line); border-radius: 10px; background: #fff;
  font: inherit; font-size: 0.95rem; font-variant-numeric: tabular-nums;
  color: var(--ink); cursor: pointer;
  transition: background var(--ease), border-color var(--ease), color var(--ease);
}
.sermon-page:hover:not(:disabled):not(.is-current) {
  background: var(--cream); border-color: var(--sunrise-500);
}
.sermon-page.is-current {
  background: var(--sunrise-600); border-color: var(--sunrise-600);
  color: #fff; font-weight: 600; cursor: default;
}
.sermon-page:disabled { opacity: 0.4; cursor: default; }
.sermon-page--step { font-weight: 500; }
.sermon-page-gap { padding: 0 0.2rem; color: var(--muted); user-select: none; }

/* Prev/Next are secondary to the numbers: smaller, quieter, and on the same line as
   them. They previously took `flex: 1 1 100%` below 560px, which gave each its own
   full-width row and made a three-row pager out of one. */
.sermon-page--step {
  min-width: 0; height: 36px; padding: 0 0.6rem; gap: 0.3rem;
  font-size: 0.86rem; font-weight: 500; color: var(--muted);
}
.sermon-page--step:hover:not(:disabled) { color: var(--ink); }
.sermon-page-arrow { font-size: 1.15em; line-height: 1; }

@media (max-width: 560px) {
  /* nowrap on the pager, wrap on the numbers inside it. A wrapping flex container
     breaks the LINE before it shrinks an item, which is what pushed Next onto a row of
     its own; with the row locked, the numbers box shrinks and wraps internally instead
     and both chevrons stay beside them. */
  .sermon-pager { gap: 0.3rem; flex-wrap: nowrap; }
  .sermon-page { min-width: 38px; height: 38px; padding: 0 0.45rem; font-size: 0.9rem; }
  .sermon-page--step { height: 34px; padding: 0 0.45rem; flex: none; }
}
@media (max-width: 420px) {
  /* Chevron only. At this width the words are what push the numbers onto a second
     line, and the aria-label still says "Previous page" / "Next page". */
  .sermon-page-step-label { display: none; }
  .sermon-page--step { min-width: 34px; padding: 0 0.3rem; }
  /* 34px keeps the whole pager — both chevrons and 1 2 3 4 5 … 44 — on one line at
     360px and up. Still a comfortable target; the row is what suffers otherwise. */
  .sermon-page { min-width: 34px; height: 34px; padding: 0 0.3rem; font-size: 0.86rem; }
  .sermon-page-gap { padding: 0 0.1rem; }
  .sermon-pager { gap: 0.25rem; }
}

/* ── Home: search the archive ─────────────────────────────────────────────────
   A plain GET form to /listen, so it works without JavaScript. */
.home-search {
  display: flex; align-items: stretch; gap: 0.6rem;
  max-width: 620px; margin: 0 auto 1.9rem;
}
.home-search-field { position: relative; display: block; flex: 1 1 auto; }
.home-search-icon {
  position: absolute; left: 16px; top: 50%; transform: translateY(-50%);
  width: 18px; height: 18px; color: var(--muted); pointer-events: none;
}
.home-search-input {
  width: 100%; box-sizing: border-box;
  font-family: inherit; font-size: 1rem; color: var(--ink);
  padding: 0.85rem 1.1rem 0.85rem 2.9rem;
  border: 1.5px solid var(--line); border-radius: var(--r-full);
  background: #fff; outline: none;
  transition: border-color var(--ease), box-shadow var(--ease);
}
.home-search-input:focus {
  border-color: var(--sunrise-500); box-shadow: 0 0 0 3px rgba(240, 128, 48, 0.16);
}
.home-search .btn { flex: none; }

/* Book-of-the-Bible tiles. Explicit column counts, not auto-fit: sermons.js renders
   eight tiles (HOME_BOOK_TILES), and auto-fit chose five across at this width, leaving
   a ragged half-row of three. Four columns makes it two full rows; if that constant
   changes, revisit these. */
.book-grid {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 0.75rem; max-width: 820px; margin: 0 auto;
}
@media (max-width: 720px) { .book-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.book-grid:empty { display: none; }
.book-tile {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 0.15rem; padding: 1rem 0.75rem; text-align: center;
  background: #fff; border: 1px solid var(--line); border-radius: var(--r-md);
  transition: transform var(--ease), border-color var(--ease), box-shadow var(--ease);
}
.book-tile:hover {
  text-decoration: none; border-color: var(--sunrise-500);
  transform: translateY(-2px); box-shadow: 0 4px 14px rgba(16, 24, 40, 0.07);
}
.book-tile-name {
  font-family: 'Bitter', serif; font-weight: 700; font-size: 1.02rem; color: var(--ink);
}
.book-tile-count { font-size: 0.8rem; color: var(--muted); }

@media (max-width: 560px) {
  /* Stack the field and the button: side by side, the button squeezes the input to
     about half a phone's width. */
  .home-search { flex-direction: column; gap: 0.55rem; }
  .home-search .btn { width: 100%; justify-content: center; }
  /* Two across on a phone: eight tiles, four full rows. */
  .book-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.6rem; }
  .book-tile { padding: 0.85rem 0.6rem; }
}

/* Home page's featured sermon. It reuses the archive row markup, which on its own is
   a borderless list item — under a centred section header that reads as unanchored,
   so give the single row a card of its own. */
#latest-sermon { max-width: 640px; margin: 0 auto; }
#latest-sermon .archive-item {
  border: 1px solid var(--line); border-radius: 14px; background: #fff;
  box-shadow: 0 1px 2px rgba(16, 24, 40, 0.04);
}
#latest-sermon .archive-row { padding: 1.05rem 1.2rem; }
#latest-sermon .archive-title { font-size: 1.12rem; }

/* Sermon detail page (/sermons/:slug) — server-rendered by sermonPage() */
.page-hero--compact { padding-top: 2.4rem; padding-bottom: 2.4rem; }
.sermon-back {
  display: inline-block; margin-bottom: 0.9rem; color: rgba(255,255,255,0.82);
  font-size: 0.88rem; text-decoration: none;
}
.sermon-back:hover { color: #fff; text-decoration: underline; }
/* Centred to match the hero's centred eyebrow/title — as a flex row it would
   otherwise sit hard left under a centred heading. */
.sermon-detail-meta {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: center;
  gap: 0.2rem 0.6rem;
  margin-top: 0.7rem; font-size: 0.9rem; color: rgba(255,255,255,0.78);
}
.sermon-detail-meta > * + *::before { content: '·'; margin-right: 0.6rem; opacity: 0.65; }
.sermon-detail-meta .sermon-series { color: rgba(255,255,255,0.9); }
.sermon-catalog { font-variant-numeric: tabular-nums; opacity: 0.75; }
.sermon-detail-scripture { margin: 0 0 1.3rem; font-size: 1.12rem; font-weight: 600; }
.sermon-detail-scripture a { color: var(--sunrise-700); text-decoration: none; }
.sermon-detail-scripture a:hover { text-decoration: underline; }
.sermon-detail-player {
  display: flex; align-items: center; gap: 1.1rem; flex-wrap: wrap;
  padding: 1.15rem 0 1.5rem; border-bottom: 1px solid var(--line); margin-bottom: 1.5rem;
}
.sermon-download { font-size: 0.9rem; color: var(--muted); text-decoration: none; }
.sermon-download:hover { color: var(--sunrise-700); text-decoration: underline; }
/* Generous reading size — the audience skews older. */
.sermon-detail-blurb p { font-size: 1.08rem; line-height: 1.75; margin: 0 0 1.1rem; }
/* Provenance, not content — sits quieter than the blurb it follows. */
.sermon-detail-broadcast {
  margin: 0; font-size: 0.92rem; color: var(--muted);
}
.sermon-topics {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0.45rem;
  margin: 1.6rem 0 0; padding-top: 1.3rem; border-top: 1px solid var(--line);
}
.sermon-topics-label {
  font-size: 0.74rem; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--muted); margin-right: 0.35rem;
}
.sermon-topic {
  font-size: 0.84rem; padding: 0.28rem 0.7rem; border-radius: 999px;
  background: var(--cream); color: var(--ink); text-decoration: none;
  transition: background var(--ease), color var(--ease);
}
.sermon-topic:hover { background: var(--sunrise-500); color: #fff; }
.sermon-nav {
  display: flex; justify-content: space-between; gap: 1.2rem;
  margin-top: 2.2rem; padding-top: 1.4rem; border-top: 1px solid var(--line);
}
.sermon-nav a {
  display: flex; flex-direction: column; gap: 0.15rem; max-width: 46%;
  font-family: 'Bitter', serif; font-weight: 600; color: var(--ink);
  text-decoration: none; font-size: 0.98rem; line-height: 1.35;
}
.sermon-nav a:hover { color: var(--sunrise-700); }
.sermon-nav a span {
  font-family: 'Inter', sans-serif; font-weight: 500; font-size: 0.74rem;
  letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted);
}
.sermon-nav-next { text-align: right; align-items: flex-end; }

/* Scripture reference menu (public/scripture.js) — the reference on a sermon page is
   a link to Bible Gateway that JS upgrades into a three-way menu. The chip keeps the
   link colour it already had; these rules only add the affordance that it opens
   something, plus the floating panel it opens on desktop. */
.sermon-detail-scripture a[data-scripture] { cursor: pointer; }
.sermon-detail-scripture a[data-scripture]:hover { text-decoration: underline; }
.sermon-detail-scripture a[data-scripture][aria-expanded="true"] { text-decoration: underline; }

.scripture-pop {
  position: absolute; z-index: 1040; width: 244px;
  background: #fff; border: 1px solid var(--line); border-radius: var(--r-md);
  box-shadow: var(--shadow-md); overflow: hidden; padding: 0.35rem;
  transform-origin: top center;
}
.scripture-pop[hidden] { display: none; }
.scripture-pop-ref {
  margin: 0.25rem 0.3rem 0.4rem; padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--line);
  font-size: 0.76rem; font-weight: 600; letter-spacing: 0.02em; color: var(--muted);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.scripture-pop-action {
  display: flex; align-items: center; gap: 0.6rem;
  padding: 0.55rem 0.6rem; border-radius: var(--r-sm);
  font-size: 0.9rem; font-weight: 500; color: var(--ink); text-decoration: none;
  transition: background var(--ease), color var(--ease);
}
.scripture-pop-action:hover { background: var(--cream); color: var(--sunrise-700); text-decoration: none; }
.scripture-pop-action svg { width: 16px; height: 16px; flex-shrink: 0; color: var(--sunrise-600); }

/* Open: a short scale-and-lift. Closing has two speeds — a quick fade when it is
   dismissed deliberately, a slower one when a scroll dismisses it, because the panel
   scrolls along with the page and an instant disappearance reads as a glitch. */
.scripture-pop.is-open { animation: scripture-pop-in 0.16s cubic-bezier(0.22,1,0.36,1); }
.scripture-pop.is-closing { animation: scripture-pop-out 0.18s ease-in forwards; }
.scripture-pop.is-closing-slow { animation: scripture-pop-out 0.48s ease-in forwards; }
@keyframes scripture-pop-in {
  from { opacity: 0; transform: translateY(-5px) scale(0.97); }
  to   { opacity: 1; transform: none; }
}
@keyframes scripture-pop-out {
  from { opacity: 1; transform: none; }
  to   { opacity: 0; transform: translateY(-3px) scale(0.98); }
}
@media (prefers-reduced-motion: reduce) {
  .scripture-pop.is-open, .scripture-pop.is-closing, .scripture-pop.is-closing-slow {
    animation: none;
  }
}
/* The mobile sheet reuses .sheet / .sheet-action wholesale; it only needs its
   reference title to wrap like a label rather than a heading. */
.scripture-sheet .sheet-title {
  font-family: 'Inter', sans-serif; font-size: 0.95rem; font-weight: 600;
  color: var(--muted);
}

/* -----------------------------------------------
   10. CTA banner & donate
----------------------------------------------- */
/* Pre-footer CTA: lighter navy than the footer, with a thin gold divider on top,
   so it reads as its own band and doesn't muddy into the (navy-900) footer. */
.cta {
  background: linear-gradient(150deg, var(--navy-800), var(--navy-700));
  border-top: 3px solid var(--gold-500);
  color: #fff;
}
.cta-inner { text-align: center; max-width: 720px; margin: 0 auto; }
.cta-title { color: #fff; }
.cta-text { color: #d3dbe8; font-size: 1.15rem; margin: 0.75rem 0 1.75rem; }
.cta .btn-outline-white { color:#fff; }

/* Donate */
.give-lead {
  max-width: 62ch; margin: 0 auto 2.5rem; text-align: center;
  font-size: 1.15rem; color: var(--body);
}
.give-methods {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 1.5rem;
  max-width: 920px;
  margin: 0 auto;
  align-items: stretch;
}
.give-method {
  display: flex; flex-direction: column;
  background: #fff; border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow-sm);
  padding: clamp(1.75rem, 3vw, 2.5rem);
}
.give-method--primary {
  border-color: var(--sunrise-400);
  box-shadow: var(--shadow-md);
}
/* Quiet round badges instead of gradient chips: the primary method reads as a
   solid sunrise mark, the secondary as a calm cream one — hierarchy without
   the toy-like look. */
.give-method-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 46px; height: 46px; border-radius: var(--r-full);
  background: var(--cream); border: 1px solid var(--line);
  color: var(--sunrise-700); margin-bottom: 1.25rem;
}
.give-method--primary .give-method-icon {
  background: var(--sunrise-600); border-color: var(--sunrise-600); color: #fff;
}
.give-method-icon svg { width: 22px; height: 22px; }
.give-method h2 { font-size: 1.5rem; margin-bottom: 0.5rem; }
.give-method-note { color: var(--body); margin-bottom: 1.4rem; }

/* Short reassurance list on the online card — gives it substance so it sits
   level with the mail card instead of trailing empty space above the button. */
.give-points {
  list-style: none; margin: 0 0 1.75rem; padding: 0;
  display: grid; gap: 0.7rem;
}
.give-points li {
  position: relative; padding-left: 1.9rem;
  color: var(--ink); font-size: 1.02rem; line-height: 1.4;
}
.give-points li::before {
  content: ''; position: absolute; left: 0; top: 0.05em;
  width: 1.25rem; height: 1.25rem; border-radius: var(--r-full);
  background: var(--cream);
  /* small sunrise check */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23a94f0c' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: center; background-size: 0.85rem;
  box-shadow: inset 0 0 0 1px var(--line);
}
/* Push the primary CTA to the card bottom so both cards' actions line up */
.give-method .btn-block { margin-top: auto; }
.give-address {
  font-family: 'Bitter', serif; font-size: 1.15rem; line-height: 1.55; color: var(--ink);
  background: var(--cream); border-radius: var(--r-md);
  padding: 1.15rem 1.4rem; margin: 0 0 1.1rem;
  border-left: 3px solid var(--sunrise-500);
}
.give-phone { color: var(--body); margin: 0; }
.give-thanks {
  text-align: center; max-width: 55ch; margin: 2.5rem auto 0;
  font-family: 'Bitter', serif; font-style: italic; font-size: 1.2rem; color: var(--ink);
}

/* -----------------------------------------------
   11. Subscribe & radio stations (Listen page)
----------------------------------------------- */
.subscribe-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 1rem;
  margin-top: 1.5rem;
}
.subscribe-card {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; gap: 0.9rem;
  aspect-ratio: 1 / 1;                 /* square tiles */
  background: #fff; border: 1px solid var(--line);
  border-radius: var(--r-md); padding: 1.3rem;
  box-shadow: var(--shadow-sm); color: var(--ink); font-weight: 700;
  transition: transform var(--ease), box-shadow var(--ease), border-color var(--ease);
}
.subscribe-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); text-decoration: none; border-color: var(--gold-400); }
.subscribe-card svg,
.subscribe-card img { width: 76px; height: 76px; flex-shrink: 0; color: var(--sunrise-500); }
.subscribe-card img { border-radius: 16px; }   /* app-icon tile (e.g. Spotify) */
.subscribe-card small { display: block; font-weight: 500; color: var(--muted); font-size: 0.82rem; margin-top: 0.15rem; }
/* Show the Spotify placeholder even before its URL is set, but make it
   non-clickable ("do nothing for now"). Once a URL is added in admin, admin.js
   removes .social-btn--empty and the card becomes a normal link. */
.subscribe-card.social-btn--empty { display: flex; pointer-events: none; }
.admin-mode .subscribe-card.social-btn--empty { display: flex; opacity: 0.6; }

.stations { display: grid; gap: 0.75rem; margin-top: 1.25rem; }
.station {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.35rem 1rem;
  padding: 1rem 1.25rem; background: #fff;
  border: 1px solid var(--line); border-radius: var(--r-md);
}
.station-name { font-family: 'Bitter', serif; font-weight: 700; color: var(--ink); font-size: 1.05rem; }
.station-city { color: var(--body); }
.station-time { margin-left: auto; color: var(--sunrise-700); font-weight: 600; font-size: 0.92rem; }

/* Messages on CD — for listeners who order physical discs by phone or mail. */
.cd-panel {
  display: flex; align-items: flex-start; gap: clamp(1.1rem, 2.5vw, 1.75rem);
  margin-top: 1.25rem;
  padding: clamp(1.5rem, 3vw, 2.25rem);
  background: #fff; border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow-sm);
}
.cd-panel-icon {
  flex-shrink: 0;
  display: inline-flex; align-items: center; justify-content: center;
  width: 56px; height: 56px; border-radius: var(--r-full);
  background: var(--cream); border: 1px solid var(--line);
  color: var(--sunrise-700);
}
.cd-panel-icon svg { width: 30px; height: 30px; }
.cd-panel-body { min-width: 0; }
.cd-panel-body p { margin: 0 0 0.85rem; color: var(--body); font-size: 1.05rem; }
.cd-panel-body p:last-child { margin-bottom: 0; }
/* Both paragraphs share the same body color/size so the section reads uniformly */
.cd-order { color: var(--body); }
.cd-order a { font-weight: 600; color: var(--sunrise-700); white-space: nowrap; }
/* Matches .give-address — the same shared site-address field renders in both places,
   so the mailing block should read identically on the give and listen pages. */
.cd-address {
  font-family: 'Bitter', serif; font-size: 1.05rem; line-height: 1.55; color: var(--ink);
  background: var(--cream); border-radius: var(--r-md);
  padding: 1rem 1.25rem; margin: 0 0 0.85rem;
  border-left: 3px solid var(--sunrise-500);
  font-style: normal;
}

@media (max-width: 560px) {
  /* Icon centered at the top of the box, larger; text below spans full width. */
  .cd-panel { flex-direction: column; align-items: center; gap: 1rem; padding: 1.5rem 1.35rem; }
  .cd-panel-icon { width: 76px; height: 76px; }
  .cd-panel-icon svg { width: 42px; height: 42px; }
  .cd-panel-body { align-self: stretch; }
}

/* -----------------------------------------------
   12. Contact form
----------------------------------------------- */
.contact-layout { display: grid; grid-template-columns: 1.3fr 0.7fr; gap: clamp(2rem, 4vw, 3rem); align-items: start; }
.contact-form-wrap {
  background: #fff; border: 1px solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--shadow-md);
  padding: clamp(1.5rem, 3vw, 2.25rem);
}
.contact-form-intro { color: var(--muted); margin-bottom: 1.5rem; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.form-group { margin-bottom: 1.1rem; }
.form-label { display: block; font-weight: 600; font-size: 0.9rem; color: var(--ink); margin-bottom: 0.4rem; }
.form-label .optional { color: var(--muted); font-weight: 400; }
.form-input, .form-textarea {
  width: 100%; box-sizing: border-box;
  font-family: inherit; font-size: 1rem; color: var(--ink);
  padding: 0.75rem 0.95rem;
  border: 1.5px solid var(--line); border-radius: var(--r-sm);
  background: #fdfcfa; outline: none;
  transition: border-color var(--ease), box-shadow var(--ease);
}
.form-input:focus, .form-textarea:focus {
  border-color: var(--sunrise-500);
  box-shadow: 0 0 0 3px rgba(240,128,48,0.18);
}
.form-textarea { min-height: 150px; max-height: 400px; resize: vertical; }
.form-footer { display: flex; align-items: center; gap: 1rem; flex-wrap: wrap; margin-top: 0.5rem; }
.form-note { font-size: 0.85rem; color: var(--muted); margin: 0; }
.form-error {
  margin-top: 1rem; padding: 0.75rem 1rem;
  background: #fdecea; color: #a8321e;
  border: 1px solid #f3c4bb; border-radius: var(--r-sm);
  font-size: 0.92rem;
}
.form-success { display: none; }
.form-success.is-visible {
  display: block; text-align: center; padding: 2rem 1rem;
}
.form-success__title { font-family: 'Bitter', serif; font-size: 1.5rem; color: var(--ink); margin-bottom: 0.5rem; }
.cf-turnstile { margin: 0.25rem 0 1rem; }

.contact-card {
  background: #fff; border: 1px solid var(--line);
  border-radius: var(--r-md); box-shadow: var(--shadow-sm);
  padding: 1.5rem 1.6rem; margin-bottom: 1.25rem;
}
.contact-card__heading { font-family: 'Bitter', serif; font-weight: 700; font-size: 1.15rem; color: var(--ink); margin-bottom: 0.6rem; }
.contact-card address p { margin-bottom: 0.4rem; }
.contact-card a { color: var(--sunrise-700); }
/* Larger social buttons on the Contact page than in the footer, so they read as
   a real "connect" invitation rather than a small footer afterthought. */
[data-egroup="contact-social-section"] .footer-social { gap: 0.85rem; margin-top: 1rem; justify-content: flex-start; }
[data-egroup="contact-social-section"] .social-btn { width: 56px; height: 56px; }
[data-egroup="contact-social-section"] .social-btn svg { width: 26px; height: 26px; }

/* -----------------------------------------------
   13. Footer
----------------------------------------------- */
.site-footer { background: var(--navy-900); color: #c3ccda; padding: clamp(3rem, 6vw, 4.5rem) 0 2rem; }
.footer-grid {
  display: grid;
  /* Brand takes the slack on the left; the three info columns shrink to their
     content and cluster together on the right with a tighter gap. */
  grid-template-columns: 1fr auto auto auto;
  column-gap: 2.75rem; row-gap: 2.5rem;
  padding-bottom: 2.5rem;
  border-bottom: 1px solid rgba(255,255,255,0.10);
}
/* ── Footer in admin mode ─────────────────────────────────────
   Editing the footer used to be a mess, and the fix is NOT to resize anything.

   The problem: the three info columns are sized `auto` (by their content). The
   admin editor injects an edit box (.admin-url-row, for the tel/email fields) into
   the flow right under the field being edited. That box is wider than the column,
   so the grid re-solved and the whole footer jumped mid-edit.

   The first attempt pinned the columns to fixed widths in admin mode. That did hold
   the layout still while editing, but it made the brand column much narrower
   (590px -> 330px), so the verse wrapped onto extra lines and the footer grew ~110px
   the instant admin mode was switched on — i.e. it traded a mid-edit jump for an
   on-entry jump. Admin chrome must not move page content at all.

   The fix: take the edit box OUT OF FLOW. It is absolutely positioned over the
   footer, anchored to its edit group (already position:relative in admin mode), so
   the grid never re-solves, nothing reflows, and no column changes width. Entering
   admin mode and opening an edit box are both layout-neutral.

   The pencil trigger stays at its default absolute top-right — a measured check
   confirmed it does not overlap the "Contact" <h4> or the verse, so it needs no
   offset (an earlier offset needed a margin, which shifted content). */
.admin-mode .site-footer .admin-url-row {
  position: absolute;
  z-index: 40;
  left: 0;
  top: 100%;
  width: 260px;
  max-width: 260px;
  margin-top: 4px;
  box-shadow: 0 6px 20px rgba(0,0,0,0.28);
}
/* Anchor for the box above: the address block is the positioned context inside the
   contact column, so the box hangs directly beneath the field being edited. */
.admin-mode .site-footer address,
.admin-mode .site-footer [data-egroup] { position: relative; }
.admin-mode .site-footer .admin-url-input { min-width: 0; width: 100%; box-sizing: border-box; }

.footer-brand img { margin-bottom: 1.1rem; }
.footer-verse { font-family: 'Bitter', serif; font-style: italic; font-size: 0.98rem; color: #aeb9c9; line-height: 1.6; }
.footer-verse-ref { display: block; font-style: normal; font-size: 0.82rem; color: var(--gold-400); margin-top: 0.5rem; letter-spacing: 0.03em; }
.footer-social { display: flex; gap: 0.6rem; margin-top: 1.25rem; }
.social-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: 50%;
  background: rgba(255,255,255,0.08); color: #fff;
  transition: background var(--ease), transform var(--ease);
}
.social-btn:hover { background: var(--sunrise-600); transform: translateY(-2px); text-decoration: none; }
.social-btn svg { width: 18px; height: 18px; }
.footer-col h4 { color: #fff; font-size: 1rem; margin-bottom: 1rem; }
.footer-col ul { display: grid; gap: 0.55rem; }
.footer-col a { color: #c3ccda; font-size: 0.95rem; }
.footer-col a:hover { color: var(--gold-400); text-decoration: none; }
.footer-col address a { color: #c3ccda; }
.footer-col address a:hover { color: var(--gold-400); }
.footer-bottom {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap; padding-top: 1.5rem;
}
.footer-legal p { font-size: 0.85rem; color: #8b96a8; margin: 0; }
.footer-legal a { color: #aeb9c9; }

/* ── Grace Polaris link-backs ─────────────────────────────────
   Right Start is a ministry of Grace Polaris Church; these reinforce that tie
   and link out to the church. */
/* Footer lockup (on dark navy) — sits beside the Right Start logo, split by a
   subtle divider. */
.footer-brand-top {
  display: flex; align-items: center; gap: 1.6rem; flex-wrap: wrap;
  margin-bottom: 1.1rem;
}
.footer-brand-top .footer-logo-link { display: inline-flex; }
.footer-brand-top img { margin-bottom: 0; }
.footer-gpc {
  display: inline-flex; flex-direction: column; align-items: flex-start; gap: 0.4rem;
  padding-left: 1.6rem; border-left: 1px solid rgba(255,255,255,0.14);
  transition: transform var(--ease);
}
/* Like the home mention: no underline on hover — the whole lockup lifts and the
   logo brightens instead. */
.footer-gpc:hover { text-decoration: none; transform: translateY(-3px); }
.footer-gpc-label {
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.16em;
  text-transform: uppercase; color: #8b96a8;
}
.footer-gpc img { height: 34px; width: auto; opacity: 0.9; transition: opacity var(--ease); }
.footer-gpc:hover img { opacity: 1; }

/* About-page callout card (navy card on the cream section) */
.gpc-card {
  display: grid;
  /* Logo spans the left; eyebrow sits above the body on the right. */
  grid-template-columns: auto 1fr;
  grid-template-areas:
    "logo eyebrow"
    "logo body";
  column-gap: clamp(1.5rem, 4vw, 3.5rem); row-gap: 0.5rem;
  align-items: center;
  background: linear-gradient(150deg, var(--navy-800), var(--navy-700));
  border-top: 3px solid var(--gold-500);
  border-radius: var(--r-lg); box-shadow: var(--shadow-lg);
  padding: clamp(1.8rem, 4vw, 3rem);
  width: 100%;
}
.gpc-card-logo { grid-area: logo; align-self: center; }
.gpc-card-logo img { height: clamp(64px, 9vw, 92px); width: auto; display: block; opacity: 0.95; transition: opacity var(--ease); }
.gpc-card-logo:hover img { opacity: 1; }
.gpc-card-eyebrow { grid-area: eyebrow; align-self: end; color: var(--gold-400); margin: 0; }
.gpc-card-body { grid-area: body; align-self: start; }
.gpc-card-title { font-family: 'Bitter', serif; color: #fff; font-size: clamp(1.3rem, 3vw, 1.7rem); margin: 0 0 0.7rem; }
.gpc-card-body p { color: #c3ccda; margin-bottom: 1.3rem; }
.gpc-card-body .btn { display: flex; width: fit-content; margin-left: auto; }
@media (max-width: 640px) {
  /* Stack, centered: eyebrow above the logo, then the body. */
  .gpc-card {
    grid-template-columns: 1fr;
    grid-template-areas: "eyebrow" "logo" "body";
    justify-items: center; text-align: center; row-gap: 0.9rem;
  }
  .gpc-card-body p { margin-left: auto; margin-right: auto; }
  .gpc-card-body .btn { margin-inline: auto; }
}

/* Home-page inline lockup (on the cream mission section). It's a link but reads as
   a button: no underline on hover — instead the whole lockup (label + logo) lifts
   together and the logo brightens. */
.gpc-inline {
  display: flex; align-items: center; justify-content: center; gap: 0.75rem;
  margin: 2.2rem auto 0; width: fit-content;
  transition: transform var(--ease);
}
.gpc-inline:hover { text-decoration: none; transform: translateY(-3px); }
.gpc-inline-label {
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--muted);
}
.gpc-inline img { height: 30px; width: auto; display: block; opacity: 0.85; transition: opacity var(--ease); }
.gpc-inline:hover img { opacity: 1; }

/* -----------------------------------------------
   14. Reveal animations (paired with script.js)
----------------------------------------------- */
.reveal {
  --reveal-delay: 0ms;
  opacity: 0; transform: translateY(22px);
  transition: opacity 0.6s ease-out var(--reveal-delay), transform 0.6s ease-out var(--reveal-delay);
}
.reveal.in-view { opacity: 1; transform: none; }
.reveal-scale {
  --reveal-delay: 0ms;
  opacity: 0; transform: scale(0.92);
  transition: opacity 0.6s ease-out var(--reveal-delay),
              transform 0.6s cubic-bezier(0.34,1.56,0.64,1) var(--reveal-delay);
}
.reveal-scale.in-view { opacity: 1; transform: none; }
.stagger > * { --reveal-delay: 0ms; }

@media (prefers-reduced-motion: reduce) {
  .reveal, .reveal-scale { opacity: 1 !important; transform: none !important; transition: none; }
}

/* Address popup (script.js data-addr) — minimal, in case used */
.addr-backdrop { position: fixed; inset: 0; background: rgba(0,0,0,0.35); z-index: 998; }
.addr-popup {
  position: fixed; z-index: 999; background: #fff; border: 1px solid var(--line);
  border-radius: var(--r-md); box-shadow: var(--shadow-lg); padding: 0.5rem; min-width: 220px;
}
.addr-popup-btn {
  display: flex; align-items: center; gap: 0.6rem; width: 100%;
  padding: 0.7rem 0.9rem; background: none; border: none; cursor: pointer;
  font-family: inherit; font-size: 0.95rem; color: var(--ink); border-radius: var(--r-sm);
}
.addr-popup-btn:hover { background: var(--cream); }

/* -----------------------------------------------
   15. Mobile / Responsive
----------------------------------------------- */
@media (max-width: 900px) {
  .hero-inner { grid-template-columns: 1fr; text-align: center; }
  .hero-desc { margin-left: auto; margin-right: auto; }
  .hero-eyebrow, .hero-actions, .hero-meta { justify-content: center; }
  /* Breathing room below the stats row before the hero's bottom edge */
  .hero-meta { margin-bottom: 1.5rem; }
  /* Image sits on top when stacked — give it some space beneath the header */
  .hero-art { order: -1; margin-top: 1.5rem; }
  .hero-art-frame { width: min(260px, 62vw); rotate: 0deg; }
  .split, .contact-layout { grid-template-columns: 1fr; }
  .split--reverse .split-media { order: 0; }
  .footer-grid { grid-template-columns: 1fr 1fr; gap: 2rem; }
  .latest { grid-template-columns: 1fr; text-align: center; }
  .latest-art { max-width: 200px; margin: 0 auto; }
}

@media (max-width: 768px) {
  .nav-toggle { display: flex; }
  .main-nav {
    position: fixed;
    top: var(--header-h);
    left: 0; right: 0;
    background: #fff;
    border-bottom: 1px solid var(--line);
    box-shadow: var(--shadow-md);
    /* Open by unrolling downward from just under the header (clip-path), not by
       sliding the whole panel down from above. The old translateY(-120%) slide
       parked the closed panel's bottom edge ~7px into the viewport, covering the
       header's gradient line, and swept the panel across the logo on open. */
    clip-path: inset(0 0 100% 0);
    opacity: 0;
    visibility: hidden;
    transition: clip-path 0.3s ease, opacity 0.25s ease, visibility 0s linear 0.3s;
    max-height: calc(100dvh - var(--header-h));
    overflow-y: auto;
  }
  .admin-mode .main-nav { top: calc(var(--header-h) + 34px); }
  .main-nav.open {
    clip-path: inset(0 0 0 0);
    opacity: 1;
    visibility: visible;
    transition: clip-path 0.3s ease, opacity 0.25s ease;
  }
  .main-nav ul { flex-direction: column; align-items: stretch; gap: 0; padding: 0.5rem 1.25rem 1.25rem; }
  /* display:block so each link (and its divider border-bottom) spans the full
     row width; as inline-block the divider only ran under the text (~20%). */
  .main-nav a:not(.btn-nav) { display: block; padding: 0.95rem 0.5rem; border-radius: 0; border-bottom: 1px solid var(--line); font-size: 1.08rem; }
  .main-nav a:not(.btn-nav)::after { display: none; }
  /* The desktop underline indicator is hidden on mobile, so mark the current
     page with a colored label + left accent bar + tint instead. */
  .main-nav a.active:not(.btn-nav) {
    color: var(--sunrise-700); font-weight: 700;
    border-left: 3px solid var(--sunrise-500);
    padding-left: 0.85rem;
    background: var(--cream);
  }
  .nav-cta-item { margin: 1rem 0 0; padding-left: 0; border-left: 0; }
  .main-nav a.btn-nav { display: block; margin: 0; text-align: center; padding: 0.95rem 1.4rem; font-size: 1.08rem; }
  .nav-touching { color: var(--sunrise-700); }
  .form-row { grid-template-columns: 1fr; }
  /* Station name on the left; location + date/time stacked, right-aligned */
  .station { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 0.1rem 0.75rem; }
  .station-name { grid-column: 1; grid-row: 1 / 3; align-self: center; }
  .station-city { grid-column: 2; text-align: right; }
  .station-time { grid-column: 2; text-align: right; margin-left: 0; width: auto; }
}

/* Stack multi-button rows on phones so two large buttons never overflow the
   viewport, and read better stacked. */
@media (max-width: 600px) {
  /* Smaller, content-width hero buttons on phones (was full-width btn-lg) */
  .hero-actions { flex-direction: column; align-items: center; }
  .hero-actions .btn { width: auto; font-size: 0.98rem; padding: 0.72rem 1.6rem; }
  .hero-desc { font-size: 1.02rem; }

  /* Scale down the dark CTA bands ("Keep the broadcast on the air", "Listen to
     Right Start today", etc.) on phones — smaller heading, body, padding, and a
     content-width button instead of a full-width one. */
  .cta { padding: clamp(2.5rem, 8vw, 3.25rem) 0; }
  .cta-title { font-size: 1.5rem; }
  .cta-text { font-size: 1rem; margin: 0.6rem 0 1.4rem; }
  .cta-inner .btn { width: auto; font-size: 0.98rem; padding: 0.72rem 1.6rem; }

  /* Footer on phones: brand spans full width and centers on top; Explore, Listen
     and Contact share one row below as three equal columns (equal thirds always
     fit and stay on one row). Content is LEFT-aligned within each column so every
     heading and link shares a clean left edge — centered ragged text of differing
     widths was what read as "off-center". Long strings (address, email) wrap. */
  .footer-grid { grid-template-columns: repeat(3, 1fr); gap: 2rem 0.7rem; text-align: left; }
  .footer-brand { grid-column: 1 / -1; display: flex; flex-direction: column; align-items: center; text-align: center; }
  .footer-social { justify-content: center; margin-top: 1.1rem; }
  /* Keep the Grace Polaris lockup to the RIGHT of the Right Start logo on phones;
     shrink both a touch so the row fits at narrow widths. */
  .footer-brand-top { flex-direction: row; justify-content: center; align-items: center; gap: 0.9rem; flex-wrap: nowrap; }
  .footer-brand-top .footer-logo-link img { height: 46px; width: auto; }
  .footer-brand-top .footer-gpc {
    align-items: flex-start; text-align: left;
    padding-left: 0.9rem; padding-top: 0;
    border-left: 1px solid rgba(255,255,255,0.14); border-top: none;
  }
  .footer-brand-top .footer-gpc-label { font-size: 0.64rem; letter-spacing: 0.12em; }
  .footer-brand-top .footer-gpc img { height: 26px; }
  .footer-col { min-width: 0; }
  .footer-col ul { justify-items: start; }
  .footer-col h4 { font-size: 0.9rem; margin-bottom: 0.7rem; }
  .footer-col a, .footer-col address { font-size: 0.82rem; overflow-wrap: anywhere; }
  .footer-col address p { margin-bottom: 0.35rem; }
  /* Stack + center the copyright and the Admin button */
  .footer-bottom { flex-direction: column; align-items: center; text-align: center; gap: 1rem; }
}

@media (max-width: 480px) {
  body { font-size: 16px; }
  .container { padding: 0 20px; }
  .give-address { font-size: 1.1rem; }
  .hero-meta { gap: 1.25rem; }
}
