/* =========================================================================
   Dallas Children's Chorus — Design System
   A quiet, editorial visual language borrowed from institutional finance:
   generous whitespace, restrained color, serif headlines over clean sans
   body copy, thin rules instead of boxes, and a single considered accent.
   ========================================================================= */

/* ---- Fonts ------------------------------------------------------------- */

:root {
  /* Neutral system -- navy is reserved for the DCC logo artwork itself
     (unchanged, still #0B2A4A) and no longer feeds any UI color below.
     Text, buttons and section backgrounds all run on true neutral greys,
     with a single teal accent standing in for the old navy "accent". */
  --graphite-900: #1c1e21;
  --graphite-800: #23262a; /* was the brand navy; now the one dark neutral reserved for buttons and other small dark UI elements */
  --graphite-700: #3a3d40;
  --graphite-600: #53565a;
  --graphite-100: #eceeef;

  --stone-600: #0f4a6b; /* accent hover -- deep blue-teal (was navy) */
  --stone-500: #1a70a3; /* accent -- blue-teal, a lighter cousin of the logo navy (was navy, then #1a7b99); the site's one accent colour, used for buttons, links, focus rings and small highlights */
  --stone-100: #e9e9ea; /* light neutral grey, used for text on the one remaining dark section (the homepage hero video) */
  --stone-ink: #5b5f63; /* WCAG-AA-safe true neutral grey for small text on light backgrounds (was blue-tinted) */

  --cream-000: #ffffff; /* page background -- crisp white */
  --cream-025: #fafafb; /* midpoint between white and --cream-050 -- gives the CTA band (and, per-instance via .on-mid, an occasional section) its own step on the staircase when white/cream-050 alone can't keep every neighboring pair distinct */
  --cream-050: #f5f5f6; /* alternating section band / light section backgrounds (page-hero, footer) -- true neutral, was a cool blue-tinted grey */
  --line-100: #e3e5e7; /* hairline dividers -- true neutral, was blue-tinted */

  --ink-900: #1c1e21;
  --ink-600: #4c5157;
  --ink-400: #6b6f74;

  --white: #ffffff;

  /* Type */
  --font-serif: "Instrument Serif", Georgia, "Times New Roman", serif; /* display serif: one weight (400) only -- never set bolder weights on it or browsers fake-bold it */
  --font-text-serif: "EB Garamond", Georgia, "Times New Roman", serif; /* reading serif: quotes, small serif headings */
  --font-sans: "Encode Sans Semi Condensed", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-wordmark: Optima, Candara, "Noto Sans", var(--font-sans);

  /* Layout */
  --container: 1280px;
  --container-narrow: 860px;
  --gutter: clamp(1.5rem, 4vw, 3.5rem);
  --section-pad: clamp(4rem, 7vw, 6.5rem);

  /* Line-height system -- one value per kind of text; change here, changes everywhere.
     display: h1 | heading: h2/h3 | quote: pull quotes, intro text, mission |
     read: all paragraphs, card text, bios, captions, notes | long: legal/FAQ long-form */
  --lh-display: 1.06;
  --lh-h2: 1.1;
  --lh-heading: 1.2;
  --lh-quote: 1.3;
  --lh-read: 1.5;
  --lh-long: 1.6;

  /* Motion */
  --ease: cubic-bezier(.4,0,.2,1);
}

/* ---- Reset --------------------------------------------------------------*/
*, *::before, *::after { box-sizing: border-box; }
html {
  scroll-behavior: smooth;
  /* Disable Mobile Safari's automatic text-size boosting. Without this,
     iOS inflates paragraph/body text based on how wide its container is
     relative to the viewport -- most noticeable rotating a phone to
     landscape (a much wider viewport than the page was designed around)
     and on any block that spans more width than its neighbors (like the
     full-width Mailing Address row in the resources box). Pinning this to
     100% makes text render at exactly the size the CSS specifies, in
     every orientation and column width, instead of Safari's guess. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; }
}
html, body { overflow-x: hidden; }
body {
  margin: 0;
  font-size: 1.07rem;
  font-family: var(--font-sans);
  color: var(--ink-900);
  background: var(--cream-000);
  -webkit-font-smoothing: antialiased;
  line-height: 1.6;
  width: 100%;
}
img, video { max-width: 100%; display: block; }
/* Images declare width/height so the browser reserves their space (no layout jump while loading); height:auto keeps CSS in control of the final shape. */
img[width][height] { height: auto; }
a { color: inherit; text-decoration: none; }
ul { list-style: none; margin: 0; padding: 0; }
h1, h2, h3, h4, p, figure { margin: 0; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }

.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.container--narrow { max-width: var(--container-narrow); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: 1rem; top: -60px; z-index: 300;
  background: var(--graphite-800); color: var(--white);
  padding: .75rem 1.25rem; border-radius: 2px; transition: top .2s var(--ease);
}
.skip-link:focus { top: 1rem; }

/* ---- Type scale ----------------------------------------------------------*/
.eyebrow {
  display: inline-flex; align-items: center; gap: .6em;
  font-family: var(--font-sans);
  font-size: 0.88rem;
  font-weight: 600;
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--stone-ink);
}
.eyebrow::before {
  content: "";
  width: 2.25em; height: 1px; background: currentColor;
}
.eyebrow--center { justify-content: center; }
.eyebrow--center::before { display: none; }
.eyebrow--light { color: var(--stone-100); }
.cta-band .eyebrow { color: var(--stone-500); }

h1, .h1 {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: clamp(2.75rem, 5vw, 4.6rem);
  line-height: var(--lh-display);
  letter-spacing: -.005em;
  color: var(--graphite-900);
}
h2, .h2 {
  font-family: var(--font-serif);
  font-weight: 400;
  font-size: clamp(2.15rem, 3.6vw, 3.1rem);
  line-height: var(--lh-h2);
  color: var(--graphite-900);
}
h3, .h3 {
  font-family: var(--font-text-serif);
  font-weight: 400;
  font-size: clamp(1.7rem, 2.2vw, 2.1rem);
  line-height: var(--lh-heading);
  color: var(--graphite-900);
}
.lede {
  /* Text under page and hero headings: EB Garamond, a classic old-style
     serif that echoes the upright stress and narrow proportions of the
     Instrument Serif headline while staying comfortable over several lines
     (the condensed Instrument Serif gets thin at paragraph length). Garamond
     has a small x-height, so it is set a little larger than other serifs. */
  font-family: "EB Garamond", Georgia, "Times New Roman", serif;
  font-size: clamp(1.3rem, 1.85vw, 1.6rem);
  line-height: var(--lh-quote);
  color: #41464c;
  font-weight: 400;
  text-wrap: pretty;
}
p.body, .body-text { font-size: 1.18rem; line-height: var(--lh-read); color: var(--ink-600); }
.small-caps-label {
  font-family: var(--font-sans); font-size: 0.88rem; font-weight: 600; letter-spacing: .14em; font-style: normal;
  text-transform: uppercase; color: var(--ink-400);
}

/* ---- Buttons -------------------------------------------------------------*/
.btn {
  display: inline-flex; align-items: center; gap: .6rem;
  font-family: var(--font-sans);
  font-size: 1rem; font-weight: 600; letter-spacing: .02em;
  padding: .7rem 1.45rem;
  border: 1px solid transparent;
  border-radius: 1px;
  transition: background-color .25s var(--ease), color .25s var(--ease), border-color .25s var(--ease), transform .2s var(--ease);
  white-space: nowrap;
}
.btn svg { width: 1em; height: 1em; transition: transform .25s var(--ease); }
.btn:hover svg { transform: translateX(3px); }

/* Off-site links (e.g. to the DSO's own website): a diagonal arrow rather
   than the chevron used for links within the DCC site, so it's clear at a
   glance the button leads away from dallaschildrenschorus.org. */
.btn--external:hover svg { transform: translate(2px, -2px); }

/* Generic side-by-side button group -- context-specific spots below (the
   CTA band, page-hero) add their own centering/margin on top of this. */
.btn-row { display: flex; gap: 1rem; flex-wrap: wrap; }

.btn--primary { background: var(--graphite-800); color: var(--white); }
.btn--primary:hover { background: var(--graphite-900); }

.btn--accent { background: var(--stone-500); color: var(--white); }
.btn--accent:hover { background: var(--stone-600); }

.btn--outline { border-color: currentColor; color: var(--graphite-800); }
.btn--outline:hover { background: var(--graphite-800); color: var(--white); }

/* Built for the one remaining dark section (the homepage hero video) --
   a light border/text that stays legible over the footage. */
.btn--outline-light { border-color: rgba(255,255,255,.55); color: var(--white); }
.btn--outline-light:hover { background: var(--white); color: var(--graphite-900); border-color: var(--white); }

/* The CTA band and every interior page-hero are light sections now, so an
   outline-light button there would be invisible (light-on-light) -- it
   renders like the ordinary dark outline button instead. The homepage
   hero keeps the light styling above, since its video background stays
   dark. */
.cta-band .btn--outline-light, .page-hero .btn--outline-light {
  border-color: var(--graphite-800); color: var(--graphite-800);
}
.cta-band .btn--outline-light:hover, .page-hero .btn--outline-light:hover {
  background: var(--graphite-800); color: var(--white); border-color: var(--graphite-800);
}

.btn--ghost { padding: 0; color: var(--graphite-800); border-bottom: 1px solid var(--stone-500); border-radius: 0; }
.btn--ghost:hover { color: var(--stone-600); }

/* ---- Header / Nav ---------------------------------------------------------*/
.site-header {
  position: fixed; inset: 0 0 auto 0; z-index: 200;
  transition: background-color .35s var(--ease), box-shadow .35s var(--ease), border-color .35s var(--ease);
  border-bottom: 1px solid transparent;
}
.site-header .container {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  max-width: 2000px; /* wider than the page content container, so a centered nav has room to breathe next to the wordmark and buttons */
  height: 83px; /* trimmed from 92px so the buttons and secondary links sit with equal space above and below (about 13px each) */
  transition: height .3s var(--ease);
}
/* True centering (independent of the wordmark/actions' widths on either
   side) only kicks in once there's enough room either side of it not to
   collide with them. That room opens up at ~1550px+. Below that, down to
   the drawer-menu breakpoint, it falls back to the default flex placement
   above (unopposed, so no overlap, just not perfectly centered) -- which
   is exactly where ordinary 13"-15" laptop widths (~1200-1550px) land. */
@media (min-width: 1550px) {
  .site-header .main-nav {
    position: absolute;
    left: 50%;
    top: 0;
    height: 100%;
    width: max-content;
    transform: translateX(-50%);
  }
}

.site-header--transparent { background: transparent; }
.site-header--solid,
.site-header.is-scrolled {
  background: #fff; /* fully opaque -- at 96% opacity, the backdrop-filter's saturate(180%) boosted whatever sat directly behind the fixed header (most visibly the dark navy page-hero band that starts at the top of every interior page), tinting the header grey-blue instead of true white. Opaque leaves nothing for the filter to reveal. */
  backdrop-filter: saturate(180%) blur(10px);
  border-bottom-color: var(--line-100);
}
/* No height reduction here anymore: the scrolled header used to drop
   the secondary links (News/Contact/Family Portal) so a single row of
   buttons could fit a shorter bar. Now that those links stay visible at
   every scroll position (see .secondary-links below), the header still
   needs room for both rows while scrolled, so it keeps the same height
   as the unscrolled state instead of shrinking out from under them. */

.wordmark {
  font-family: var(--font-wordmark);
  font-weight: 500;
  color: var(--graphite-800);
  line-height: 1.05;
  display: flex; flex-direction: column;
}
.site-header--transparent:not(.is-scrolled) .wordmark { color: var(--white); }
.site-header--transparent:not(.is-scrolled) .wordmark__tag { color: var(--stone-100); }
.wordmark__name {
  display: inline-flex;
  align-items: center;
}
.wordmark__name img {
  display: block;
}
/* Header logo: width matched to the rendered width of the tagline text
   below it (which is a fixed .62rem, non-fluid size), height follows
   automatically so the artwork is never stretched or squeezed. */
.site-header .wordmark__name img {
  height: 1.16rem;
  width: auto;
  max-width: 100%;
  /* object-fit:contain matters here: at narrow widths the header row doesn't
     have room for the logo's full natural width at this height, so max-width
     clamps the box narrower than the image's own ratio wants. Without
     object-fit the browser's default (fill) stretches the artwork to match
     that narrower box, visibly squashing it horizontally. contain keeps the
     artwork's own proportions and simply doesn't fill the box's full height
     in that edge case, instead of distorting it. */
  object-fit: contain;
}
/* Wherever the tagline is shown, the logo is scaled to exactly the tagline's
   width: the name box contributes no width of its own (width:0 + min-width:100%)
   so the wordmark is as wide as the tagline, and the artwork fills that width
   with its height following proportionally. Below 641px the tagline is hidden,
   so the fixed-height rule above applies instead. */
@media (min-width: 641px) {
  .site-header .wordmark__name { width: 0; min-width: 100%; }
  .site-header .wordmark__name img { width: 100%; height: auto; max-width: none; }
}
/* Footer logo: fills the footer-brand column up to a sensible cap;
   height is always derived from width, so it can never be distorted
   even as the column narrows at smaller breakpoints. */
.footer-brand .wordmark__name img {
  width: 100%;
  height: auto;
}
.wordmark__name--swap {
  display: grid;
}
.wordmark__name--swap img {
  grid-area: 1 / 1;
  transition: opacity .3s var(--ease);
}
.wordmark__logo--color { opacity: 1; }
.wordmark__logo--white { opacity: 0; }
.site-header--transparent:not(.is-scrolled) .wordmark__logo--color { opacity: 0; }
.site-header--transparent:not(.is-scrolled) .wordmark__logo--white { opacity: 1; }
.wordmark__tag {
  font-family: var(--font-sans);
  font-size: .62rem;
  font-weight: 500;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--stone-ink);
  margin-top: .4rem;
}

.main-nav { display: flex; align-items: stretch; height: 100%; }
.main-nav > ul { display: flex; align-items: stretch; gap: 0; height: 100%; }
.main-nav > ul > li { position: relative; display: flex; }
.main-nav__link {
  display: flex; align-items: center; gap: .3rem;
  padding: 0 .5rem;
  font-size: 0.78rem; font-weight: 500; letter-spacing: .02em; text-transform: uppercase;
  color: var(--graphite-800);
  position: relative;
}
.site-header--transparent:not(.is-scrolled) .main-nav__link,
.site-header--transparent:not(.is-scrolled) .header-actions .btn--outline { color: var(--white); }
.site-header--transparent:not(.is-scrolled) .header-actions .btn--outline { border-color: rgba(255,255,255,.55); }

.main-nav__link::after {
  content: ""; position: absolute; left: .5rem; right: .5rem; bottom: 11px; height: 1px;
  background: var(--stone-500); transform: scaleX(0); transform-origin: left; transition: transform .25s var(--ease);
}
.main-nav__link:hover::after, .main-nav__item.is-open .main-nav__link::after,
.main-nav__item--current .main-nav__link::after { transform: scaleX(1); }
.main-nav__link .chev { width: .55em; height: .55em; opacity: .7; transition: transform .25s var(--ease); }
.main-nav__item.is-open .chev { transform: rotate(180deg); }

.main-nav__panel {
  /* Shrinks to fit each menu's own longest item (capped at 260px, which is
     roughly what "Our Connection to the DSO" needs) instead of forcing
     every dropdown to the same fixed minimum -- so a short menu like
     "Give" doesn't end up as a mostly-empty box. */
  position: absolute; top: 100%; left: 50%; transform: translate(-50%, 6px);
  width: max-content; max-width: 260px; background: var(--white); border: 1px solid var(--line-100);
  box-shadow: 0 18px 40px -12px rgba(58,62,66,.18);
  padding: .4rem;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .2s var(--ease), transform .2s var(--ease);
}
.main-nav__item.is-open .main-nav__panel { opacity: 1; visibility: visible; pointer-events: auto; transform: translate(-50%, 0); }
.main-nav__panel a {
  display: block; padding: .5rem .75rem; font-size: 0.714rem; font-weight: 500; letter-spacing: .02em; text-transform: uppercase;
  color: var(--ink-900); border-radius: 2px; white-space: nowrap;
}
.main-nav__panel a:hover { background: var(--cream-050); color: var(--graphite-800); }

/* header-actions is one row on desktop: the quiet secondary links
   (News/Contact/Family Portal) sit to the left of the Give button, all
   centered on the header's middle line along with the primary nav labels. In drawer-menu mode (see the 1236px-and-below rules further down) it
   goes back to two stacked rows: Give + hamburger on top, links beneath. */
.header-actions {
  display: flex; flex-direction: row; align-items: center;
  align-self: flex-end;
  gap: 1.75rem;
  padding-bottom: 11.75px; /* centers the Give button on the nav labels' line */
}
.header-actions__buttons { display: flex; align-items: center; gap: .7rem; }
.header-actions__buttons .btn { padding-block: .5rem; font-size: 0.756rem; letter-spacing: .02em; text-transform: uppercase; } /* shorter than the site-wide .btn, just for the header */
.nav-toggle { display: none; }

.secondary-links { display: flex; align-items: center; gap: .85rem; position: relative; top: .8px; } /* .8px: lines their baseline up with the tagline's and the nav labels' */
.secondary-links a {
  font-size: 0.7rem; font-weight: 500; letter-spacing: .02em; text-transform: uppercase;
  color: var(--stone-ink);
}
.secondary-links a:hover { color: var(--graphite-800); }
.site-header--transparent:not(.is-scrolled) .secondary-links a { color: var(--stone-100); }

/* Desktop (inline nav) only: a slim 64px header. The wordmark, the
   primary nav labels, the secondary links and the Give button are all
   centered on the header's middle line (equal space above and below). The
   active-page underline sits ~10px under the labels. Drawer-menu widths keep
   the taller header, which needs the room for the stacked Give/hamburger +
   links. */
@media (min-width: 1237px) {
  .site-header .container { height: 58px; }
  /* The wordmark image carries a little extra space below its ink, so its
     visible letters would sit ~1.9px above the header's true middle;
     nudging it down centers the logo + tagline as seen. */
  .site-header .wordmark { position: relative; top: 1px; }
  .header-actions { align-self: center; padding-bottom: 0; }
  /* Capital letters sit a little above their line box's middle (the box
     reserves room for descenders), so the labels get a small nudge down to
     put the visible letters on the header's exact middle line. */
  .main-nav__link { padding-top: 1.8px; }
  .secondary-links { top: 1.2px; }
  .main-nav__link::after { bottom: 12px; }
}

@media (max-width: 1236px) {
  /* Below ~1237px the nav row no longer has enough room to keep every
     label (e.g. "Sing With Us") on one line without wrapping, so the
     drawer menu takes over instead of showing a cramped nav row. The
     cutoff has moved over time: 1249px originally, 1199px once "Home"
     left the nav, 1159px once the labels went all-caps but untracked
     (letter-spacing .02em) with tighter .5rem side padding, and now
     1134px with the primary labels at .72rem -- leaving ~21px of air
     either side of the nav at 1135px. Moving the secondary links onto
     the same row as the Give button (and dropping the Auditions button)
     widened the right-hand group, so the cutoff is now 1236px: ~21px of
     air either side of the nav at 1237px.
     From 1237px up through ~1549px it still shows inline, just left-
     flowing rather than centered (see the note above the matching
     centering rule) -- comfortably covering ordinary 13"-15" laptop
     widths. */
  .main-nav { display: none; }
  .header-actions {
    flex-direction: column-reverse; align-items: flex-end;
    gap: .5625rem; /* 9px: makes the space above the secondary links match the space below them */
    padding-bottom: .5rem;
  }
  .nav-toggle {
    display: inline-flex; align-items: center; justify-content: center;
    width: 42px; height: 42px; flex-direction: column; gap: 5px;
  }
  .nav-toggle span { width: 22px; height: 1.5px; background: currentColor; color: var(--graphite-800); transition: transform .25s var(--ease), opacity .25s var(--ease); }
  .site-header--transparent:not(.is-scrolled) .nav-toggle span { background: var(--white); }
}

@media (max-width: 640px) {
  .wordmark__tag { display: none; }
  .header-actions .btn--accent { display: none; }
  /* No buttons left at this width (both are hidden above) and the
     secondary links fold into the mobile drawer instead of floating
     under a bare hamburger icon -- see .mobile-nav__secondary. That
     leaves header-actions holding just the hamburger, so the bottom
     anchor that used to line its two rows up under the wordmark no
     longer applies -- re-center it with the wordmark instead. */
  .header-actions { flex-direction: column; gap: 0; padding-bottom: 0; align-self: center; }
  .secondary-links { display: none; }
  .site-header .container { height: 76px; }
  .site-header.is-scrolled .container { height: 64px; }
}

/* Mobile drawer -- full-width on phones (there's no spare width for a
   partial panel to make sense of, and a full-screen takeover is the
   standard mobile pattern), but capped to a comfortable reading width on
   larger screens using the drawer (a resized browser window, a tablet, or
   a laptop below the inline-nav breakpoint) so it reads as a side panel
   rather than taking over the whole screen. */
.mobile-nav {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 250; background: var(--cream-000);
  width: 100%; max-width: 440px;
  transform: translateX(100%); transition: transform .35s var(--ease), box-shadow .35s var(--ease);
  overflow-y: auto;
  box-shadow: none; /* only shown while open -- a shadow on the closed, off-screen panel leaks a faint grey strip onto the right edge of every page */
}
@media (min-width: 500px) {
  /* Past real-phone-portrait widths there's room to spare, and the
     content (longest label "Board of Trustees", ~126px of text) only
     needs a fraction of the 440px above -- so cap it tighter here to
     read as a proportionate side panel instead of an oversized slab,
     which is most noticeable in landscape on a phone. */
  .mobile-nav { max-width: 340px; }
}
.mobile-nav.is-open { transform: translateX(0); box-shadow: -24px 0 48px -20px rgba(20, 24, 28, .25); }
.mobile-nav__head { display: flex; justify-content: flex-end; padding: 1.4rem var(--gutter) 0; }
.mobile-nav__close { width: 42px; height: 42px; }
.mobile-nav__body { padding: 1rem var(--gutter) 3rem; }
.mobile-nav__body > ul > li { border-bottom: 1px solid var(--line-100); }
.mobile-nav__top {
  width: 100%; display: flex; align-items: center; justify-content: space-between;
  padding: 1.1rem 0; font-family: var(--font-sans); font-weight: 500; font-size: 1.18rem; color: var(--graphite-900); text-align: left;
}
.mobile-nav__sub { display: none; padding: 0 0 1rem 1rem; }
.mobile-nav__sub a { display: block; padding: .5rem 0; color: var(--ink-600); font-size: 1.07rem; }
.mobile-nav li.is-open .mobile-nav__sub { display: block; }
.mobile-nav li.is-open .chev { transform: rotate(180deg); }
.mobile-nav__actions { margin-top: 1.5rem; display: flex; flex-direction: column; gap: .8rem; }
.mobile-nav__actions .btn { justify-content: center; }

/* The drawer's own copy of the secondary links (News/Contact/Family
   Portal) -- shown here instead of the header once the secondary-links
   row hides itself at 640px and below. */
.mobile-nav__secondary {
  margin-top: 1.4rem; padding-top: 1.4rem; border-top: 1px solid var(--line-100);
  display: flex; flex-wrap: wrap; justify-content: center; gap: .5rem 1.1rem;
}
.mobile-nav__secondary a { font-size: 0.94rem; font-weight: 500; color: var(--stone-ink); }
.mobile-nav__secondary a:hover { color: var(--graphite-800); }

body.nav-open { overflow: hidden; }

/* ---- Hero ------------------------------------------------------------- */
.hero {
  position: relative;
  width: 100%;
  /* mobile only — overridden below at 900px+. This is deliberately a loose
     pre-JS starting point, not the real target height: on a tall phone
     (tall viewport, i.e. the 96vh term this used to use) it left a lot of
     dead, over-zoomed video below the buttons, since object-fit:cover on
     this wide ~2.35:1 footage inside a too-tall box crops hard on the
     sides to fill that extra height rather than showing more of the
     scene. main.js's hero-height sync (below the CSS, see that file)
     measures the real copy height on every device and raises min-height
     to match almost exactly — same mechanism the desktop breakpoint
     relies on — so this formula only needs to be a reasonable floor/cap
     for the instant before that runs; the JS result is what actually
     ships. Oct 2026. */
  height: clamp(480px, 55vh, 620px);
  overflow: hidden;
  background: var(--graphite-900);
}
/* On phones a tall, more-cropped hero reads better than a thin widescreen
   strip. On wider/landscape viewports, size the hero to the footage's own
   cinematic ~2.35:1 aspect ratio instead of an independent height — that's
   what stops object-fit:cover from cropping the choristers out of frame.
   No max-height here on purpose: on very wide/4K displays the box keeps
   following that ratio (taller box, more vertical scroll to clear it)
   rather than capping out and forcing an even wider, shorter crop of the
   footage. */
@media (min-width: 900px) {
  .hero {
    height: auto;
    aspect-ratio: 40 / 17; /* native crop of hero-*.mp4/webm, ~2.35:1 */
    /* 780px is a static worst-case floor for the instant before main.js
       runs (and for no-JS) — not the real, operative one. main.js measures
       the hero copy's actual rendered height on every load/resize and sets
       an inline min-height from that, which — being inline — overrides
       this value outright rather than just raising it. So in practice the
       box is always max(aspect-ratio height, that measured copy height),
       and the true crossover into pure ~2.35:1 (no floor influence at all)
       is wherever the aspect-ratio height overtakes the copy's real
       height, which as of the Oct 2026 copy-block trim above is ~1412px
       wide, not whatever plugging 780 into the ratio formula would
       suggest. Narrowing the copy block (shorter padding-top/margins, or
       shorter button labels) lowers that crossover further; this 780
       value only matters for that brief pre-JS instant and is deliberately
       a bit generous there. */
    min-height: 780px;
  }
}
.hero__media { position: absolute; inset: 0; width: 100%; height: 100%; }
.hero__video, .hero__poster {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: center center;
}
.hero__poster { z-index: 1; }
/* The global rule img[width][height] { height: auto } outranks .hero__poster, so on phones/tablets the
   fallback poster showed as a short strip (its natural aspect) instead of filling the hero. Higher
   specificity here restores height:100% (object-fit: cover is already set above). */
.hero__media img.hero__poster { height: 100%; }
.hero__video { z-index: 2; opacity: 0; transition: opacity .8s var(--ease); }
.hero__video.is-ready { opacity: 1; }
.hero__scrim {
  position: absolute; inset: 0; z-index: 3;
  background:
    linear-gradient(180deg, rgba(46,49,52,.55) 0%, rgba(46,49,52,.15) 32%, rgba(46,49,52,.25) 68%, rgba(46,49,52,.72) 100%);
}
.hero__content {
  /* Anchored near the top rather than the bottom: on very tall hero boxes
     (wide/4K viewports, where the box can run well past 1000px following
     the ~2.35:1 ratio above) bottom-anchored copy could sit far below the
     fold. Pinning it just under the fixed header keeps it visible as soon
     as the page loads, at any hero height.

     The padding-top formula, plus the eyebrow/sub/actions margins below,
     were all trimmed together (Oct 2026) specifically to lower how much
     vertical space the copy block needs: main.js's hero-height sync (see
     that file) raises .hero's min-height above the aspect-ratio value
     whenever this content needs more room than the ratio currently gives
     it, which is what was quietly overriding the old 780px CSS floor
     across most of the mid-width range. A shorter copy block means that
     override kicks in less often and by less, so more of that range shows
     the true ~2.35:1 crop instead of a content-driven taller box. Still
     plenty of clearance under the ~72-83px fixed header at the 7rem floor. */
  position: relative; z-index: 4; height: 100%;
  display: flex; flex-direction: column; justify-content: flex-start;
  padding-top: clamp(7rem, 9vw, 9rem);
}
.hero__eyebrow { color: var(--stone-100); margin-bottom: 1.1rem; }
.hero__title {
  color: var(--white);
  max-width: 22ch;
  font-size: clamp(3rem, 6.2vw, 5.2rem);
}
.hero__sub {
  color: rgba(255,255,255,.86);
  max-width: 60ch;
  margin-top: 1.1rem;
}
.hero__actions { display: flex; flex-wrap: wrap; gap: 1rem; margin-top: 1.9rem; }
.hero__scroll-cue {
  position: absolute; z-index: 4; left: var(--gutter); bottom: 1.75rem;
  display: flex; align-items: center; gap: .7rem;
  color: rgba(255,255,255,.75); font-size: 0.8rem; letter-spacing: .14em; text-transform: uppercase;
}
.hero__scroll-cue .line { width: 1px; height: 30px; background: rgba(255,255,255,.5); position: relative; overflow: hidden; }
.hero__scroll-cue .line::after {
  content: ""; position: absolute; top: -100%; left: 0; width: 100%; height: 100%; background: var(--white);
  animation: scrollcue 2.2s var(--ease) infinite;
}
@keyframes scrollcue { 0% { top: -100%; } 60% { top: 100%; } 100% { top: 100%; } }
@media (max-width: 720px) { .hero__scroll-cue { display: none; } }

.hero__mute {
  position: absolute; z-index: 5; right: var(--gutter); bottom: 1.75rem;
  width: 42px; height: 42px; border: 1px solid rgba(255,255,255,.5); border-radius: 50%;
  display: none; align-items: center; justify-content: center; color: var(--white);
}
.has-audio .hero__mute { display: inline-flex; }

/* ---- Section rhythm ----------------------------------------------------*/
.section { padding-block: var(--section-pad); }
.section--tight { padding-block: clamp(2.75rem, 4.7vw, 4rem); }
/* Whatever ends (or starts) a section shouldn't add its own margin on top of
   the section's padding -- otherwise sections finishing in a pull-quote, quote
   carousel or <dl> end up 16-56px roomier at the bottom than the rest. */
.section .container > :first-child,
.section .container--narrow > :first-child { margin-top: 0; }
.section .container > :last-child,
.section .container--narrow > :last-child { margin-bottom: 0; }
/* Sets the "commitments" stat block apart from the plain white sections
   around it. Uses the same --cream-050 floor as --section--cream, the
   page-hero, the CTA band and the footer, so no section between the hero
   and the footer ever reads darker than that shared light tone -- the
   homepage's video hero is the one deliberately darker exception. The
   top/bottom hairlines are a belt-and-suspenders fallback for wherever a
   page still lands two same-shaded bands back to back. */
.section--tint { background: var(--cream-050); color: var(--graphite-900); border-top: 1px solid var(--line-100); border-bottom: 1px solid var(--line-100); }
.section--tint h2, .section--tint h3 { color: var(--graphite-900); }
.section--cream { background: var(--cream-050); }
/* Per-instance escape hatch: --section--cream and --section--tint both
   default to --cream-050, but the same section class shows up in
   different neighborhoods on different pages. Adding .on-white to one
   specific instance drops it back to plain white, and .on-mid drops it to
   the --cream-025 midpoint instead -- either way it alternates properly
   against whichever neighbor it happens to sit next to on that page,
   without changing the class's default anywhere else. */
.section--cream.on-white, .section--tint.on-white { background: var(--cream-000); }
.section--cream.on-mid, .section--tint.on-mid { background: var(--cream-025); }
.section-head { max-width: 760px; margin-bottom: clamp(2.5rem, 5vw, 4rem); }
.section-head--center { margin-inline: auto; text-align: center; }
.section-head h2 { margin-top: 1rem; }
.section-head p + p { margin-top: 1rem; }
.rule { border: none; border-top: 1px solid var(--line-100); }

/* ---- Mission strip -------------------------------------------------------*/
.mission-strip { padding-block: clamp(2.75rem, 4.7vw, 4rem); border-bottom: 1px solid var(--line-100); }
.mission-strip blockquote {
  font-family: var(--font-serif); font-weight: 400;
  font-size: clamp(1.6rem, 2.9vw, 2.3rem); line-height: var(--lh-quote); color: var(--graphite-900);
  margin: 0 auto; text-align: center; max-width: 74rem; text-wrap: balance;
}
.mission-strip blockquote p { margin: 0; line-height: var(--lh-quote); }
.mission-strip cite { display: block; margin-bottom: 1.2rem; font-style: normal; }

/* ---- Video embed ----------------------------------------------------------*/
.video-embed { position: relative; aspect-ratio: 16/9; background: var(--cream-050); }
.video-embed iframe { width: 100%; height: 100%; border: 0; display: block; }
.video-embed .frame { position: absolute; inset: 18px -18px -18px 18px; border: 1px solid var(--stone-500); z-index: -1; }
/* ---- Stats ---------------------------------------------------------------*/
.stat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 2rem; }
.stat { position: relative; text-align: center; padding-inline: .5rem; }
.stat:not(:first-child)::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: -1rem;
  width: 1px;
  background: rgba(11,42,74,.18); /* graphite-800 at low opacity -- was white-on-navy, now dark-on-pale-tint */
}
.stat__num { max-width: 5.3em; margin-inline: auto; text-wrap: balance; font-family: var(--font-serif); font-size: clamp(2.1rem, 4vw, 3.1rem); color: var(--graphite-900); } /* only used inside .section--tint, so this follows that section's dark-on-light treatment rather than any other accent token */
.stat__label { margin-top: .5rem; font-size: 1.07rem; letter-spacing: .04em; color: var(--stone-ink); }
@media (max-width: 780px) {
  /* minmax(0, 1fr) lets both columns shrink to the same width instead of growing around
     a long word ("Education") and pushing the right column off-centre / off-screen. */
  .stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); row-gap: 2.4rem; }
  .stat:nth-child(3)::before { display: none; }
}
@media (max-width: 480px) {
  /* Scale the big words with the screen so the longest one fits its half-width column
     on every phone (about 320-430px wide). */
  .stat__num { font-size: clamp(1.4rem, 7.6vw, 2.1rem); }
}

/* ---- Pillars section (What Guides Us) overrides ---------------------------- */
.pillars .section-head { max-width: 1000px; }
.pillars .stat__num { font-size: clamp(1.5rem, 2.6vw, 2.5rem); line-height: 1.2; }
.pillars .stat__label { margin-top: .35rem; }
@media (max-width: 480px) { .pillars .stat__num { font-size: clamp(1.25rem, 6.4vw, 1.5rem); } } /* keeps "Belonging" inside its half-width column on the smallest phones */

/* ---- Programs page: ensemble breakdown ------------------------------------- */
.programs-list { display: flex; flex-direction: column; gap: clamp(2.5rem, 5vw, 4rem); }
.program-card { border-top: 1px solid var(--line-100); padding-top: clamp(2rem, 4vw, 3rem); }
.program-card:first-child { border-top: none; padding-top: 0; }
.program-card__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: .75rem 1.25rem; margin-bottom: 1rem; }
.program-card__head h2 { margin: 0; }
/* Widescreen photo banner at the top of a program card (Programs page) or
   at the top of a narrow text column (.page-banner, Auditions page).
   2.35:1 echoes the homepage hero and keeps the picture short so the facts
   below stay close to the top. It stays 2.35:1 at every screen width, phones
   included, so the photos always read as widescreen. The vertical crop
   point is set per photo with an inline object-position. */
.program-card__media { margin: 0 0 1.4rem; }
.page-banner { margin: 0 0 2rem; }
.program-card__media img, .page-banner img {
  display: block; width: 100%; aspect-ratio: 2.35 / 1; object-fit: cover;
}
.program-card__tag { font-size: 0.88rem; letter-spacing: .06em; text-transform: uppercase; color: var(--stone-ink); font-weight: 600; }
.program-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 1.2rem 2rem; margin-top: 1.5rem; padding: 1.5rem; background: var(--cream-050); border-radius: 4px; }
.program-facts__full { grid-column: 1 / -1; }
/* Past-performance archive sits on the cream section background, so its fact boxes go white (with a hairline border) to stay distinct from it. */
.perf-list .program-facts { background: var(--white); border: 1px solid var(--line-100); }

/* Contact page: single-column facts, spanning the full text width (like Programs page fact rows) */
.contact-details { grid-template-columns: 1fr; }
/* Location page only: sits directly on the white page background (no card)
   so it reads as part of the same white canvas as the map below it, rather
   than boxed off like the Contact page's version of this same component. */
.contact-details--plain { padding: 0; background: none; border-radius: 0; margin-top: 0; }
.contact-details.has-image { grid-template-columns: auto 1fr; align-items: center; gap: 1.2rem 1.5rem; }
.contact-details__facts { display: grid; gap: 1.2rem; border-left: 2px solid var(--stone-500); padding-left: 1.5rem; }
.contact-details__image img { display: block; border-radius: 4px; }
/* Specificity note: these use the .contact-details__image ancestor + child
   class (two classes) rather than relying on the rule above, so the
   show/hide toggle below reliably wins over ".contact-details__image img"
   (one class + one type) regardless of source order. */
.contact-details__image .contact-details__image--tall { height: 100%; width: auto; max-width: 100%; }
.contact-details__image .contact-details__image--wide { display: none; }
@media (max-width: 640px) {
  .contact-details.has-image { grid-template-columns: 1fr; }
  .contact-details__image { margin-bottom: .75rem; height: auto !important; }
  /* Below this width the layout stacks to one column, so the tall lockup
     (sized for sitting beside the contact facts) gives way to a wider,
     shorter logo that reads better stacked above them. */
  .contact-details__image .contact-details__image--tall { display: none; }
  .contact-details__image .contact-details__image--wide { display: block; width: 100%; height: auto; }
  .contact-details__facts { border-left: none; padding-left: 0; }
}

/* Rehearsal-location map (Location page): a hand-drawn schematic, not a
   real tile-based map -- simplified/not to scale on purpose, the point is
   to orient a visitor to the intersection and the entrance to use, not to
   replace a real map for turn-by-turn navigation. Delivered as a flat PNG
   so the labels render in the exact typeface and layout chosen for it,
   rather than depending on a visitor's installed fonts. */
.location-illustration {
  margin-top: 2rem;
}
.location-illustration img { display: block; width: 100%; height: auto; }
.location-illustration figcaption {
  margin-top: 1rem; font-size: 1rem; color: var(--ink-600); line-height: var(--lh-read);
}
.location-cta { margin-top: 1.25rem; }

.program-facts dt { font-size: 0.8rem; letter-spacing: .06em; text-transform: uppercase; color: var(--stone-ink); font-weight: 600; margin: 0; }
.program-facts dd { margin: .3rem 0 0; color: var(--ink-900); font-size: 1.07rem; }
.program-note { margin-top: 1rem; font-size: 0.94rem; color: var(--stone-500); font-style: normal; }
.status-badge {
  display: inline-block;
  font-size: 0.8rem; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase;
  padding: .3rem .75rem;
  margin-bottom: .9rem;
  border-radius: 2px;
  background: var(--stone-100);
  color: var(--stone-ink);
}
/* Positive/active variant (e.g. "Tickets On Sale Now") -- accent-coloured
   text only (no filled box), so it flags the status without competing
   with the solid Buy Tickets button below it. */
.status-badge--accent { background: transparent; color: var(--stone-500); padding: 0; }

/* ---- Board of Trustees ------------------------------------------------------ */
.trustee-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2.5rem; }

@media (max-width: 900px) { .trustee-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .trustee-grid { grid-template-columns: 1fr; } }
.trustee { border-top: 1px solid var(--line-100); padding-top: 1.5rem; }
.trustee h3 { font-size: 1.55rem; margin: 0; }
.trustee .role { font-size: 0.94rem; color: var(--stone-ink); margin-top: .2rem; font-weight: 600; letter-spacing: .02em; }
.trustee .affiliation { margin-top: .5rem; color: var(--ink-600); font-size: 1rem; line-height: var(--lh-read); }

/* ---- Program / card grid --------------------------------------------------*/
.card-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 2.25rem;
  max-width: 1000px; margin-inline: auto; /* smaller, centered cluster rather than stretching the full container width */
}
@media (max-width: 980px) { .card-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 640px) { .card-grid { grid-template-columns: 1fr; } }

.card {
  background: var(--white); border: 1px solid var(--line-100);
  display: flex; flex-direction: column; height: 100%;
  transition: transform .35s var(--ease), box-shadow .35s var(--ease);
}
.card:hover { transform: translateY(-4px); box-shadow: 0 24px 48px -20px rgba(58,62,66,.22); }
.card__media { aspect-ratio: 4/3; overflow: hidden; background: var(--graphite-100); }
.card__media a { display: block; width: 100%; height: 100%; }
.card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--ease); }
.card:hover .card__media img { transform: scale(1.06); }
.card__body { padding: 1.6rem 1.6rem 1.9rem; display: flex; flex-direction: column; gap: .8rem; flex: 1; }
.card__body p { color: var(--ink-600); font-size: 1.07rem; line-height: var(--lh-read); flex: 1; }
.card__link { font-size: 0.94rem; font-weight: 600; color: var(--graphite-800); display: inline-flex; align-items: center; gap: .5rem; }
.card:hover .card__link { color: var(--stone-ink); }

/* ---- Two column feature ---------------------------------------------------*/
.feature {
  display: grid; grid-template-columns: 1.1fr 1fr; gap: clamp(2rem, 6vw, 5rem); align-items: start;
}
.feature--reverse .feature__media { order: 2; }
@media (max-width: 900px) {
  .feature { grid-template-columns: 1fr; }
  .feature--reverse .feature__media { order: 0; }
}
.feature--textonly { grid-template-columns: 1fr; }
.feature__media { position: relative; }
.feature__media img { width: 100%; aspect-ratio: 5/4; object-fit: cover; }
.feature__media--headshot { max-width: 360px; justify-self: center; }
.feature__media--headshot img { aspect-ratio: 4/5; object-position: 39% center; }
.feature__media .frame {
  position: absolute; inset: 18px -18px -18px 18px; border: 1px solid var(--stone-500); z-index: -1;
}
.feature__body p { margin-top: 1.2rem; }
.feature__body .eyebrow + h2 { margin-top: 1.1rem; }
.feature__body h2 + p { margin-top: 1.6rem; }
.feature__body .btn { margin-top: 2rem; }

/* ---- News teaser ----------------------------------------------------------*/
.news-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2.25rem; }
@media (max-width: 900px) { .news-grid { grid-template-columns: 1fr; } }
.news-card { border-top: 2px solid var(--graphite-800); padding-top: 1.4rem; }
.news-card time { font-size: 0.88rem; letter-spacing: .08em; text-transform: uppercase; color: var(--stone-ink); }
.news-card h3 { margin-top: .6rem; }
.news-card p { margin-top: .7rem; color: var(--ink-600); font-size: 1.07rem; }
.news-card .video-embed { margin-top: 1.4rem; margin-bottom: calc(18px + 1.2rem); max-width: 640px; } /* recordings embedded in a news entry; the offset .frame pokes 18px right and down, so the bottom margin keeps it clear of what follows */
@media (max-width: 700px) { .news-card .video-embed { max-width: calc(100% - 18px); } } /* leaves room for the offset frame so it never extends past the page edge */

/* ---- News page (year sidebar + list) ---------------------------------------*/
.news-layout {
  display: grid;
  grid-template-columns: 200px 1fr;
  gap: clamp(2.5rem, 5vw, 4.5rem);
  align-items: start;
}
.news-sidebar { position: sticky; top: 112px; } /* clears the fixed .site-header (64-83px depending on width) plus breathing room */
.news-sidebar h2 {
  font-size: 0.8rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--stone-ink); margin: 0 0 1rem;
}
.year-list { display: flex; flex-direction: column; gap: .15rem; }
.year-list__btn {
  display: flex; align-items: center; justify-content: space-between; gap: .75rem;
  width: 100%; text-align: left;
  background: none; border: 0; border-left: 2px solid transparent;
  padding: .55rem .9rem;
  font-family: var(--font-sans); font-size: 1rem; font-weight: 600;
  color: var(--ink-600);
  cursor: pointer;
  transition: color .2s var(--ease), border-color .2s var(--ease), background-color .2s var(--ease);
}
.year-list__btn:hover { color: var(--graphite-900); background: var(--cream-050); }
.year-list__btn.is-active { color: var(--graphite-900); border-left-color: var(--stone-500); background: var(--cream-050); }
.year-list__count { font-size: 0.8rem; font-weight: 500; color: var(--stone-ink); }

.news-list { display: flex; flex-direction: column; gap: 2.4rem; }
.news-list .news-card { border-top: 1px solid var(--line-100); padding-top: 1.6rem; }
.news-list .news-card:first-child { border-top: none; padding-top: 0; }
.news-empty { color: var(--ink-400); font-style: italic; }

@media (max-width: 780px) {
  .news-layout { grid-template-columns: 1fr; }
  .news-sidebar { position: static; }
  .year-list { flex-direction: row; flex-wrap: wrap; column-gap: 1.25rem; row-gap: .5rem; }
  .year-list__btn { width: auto; border-left: 0; border-bottom: 2px solid transparent; padding: .3rem .1rem; background: none !important; }
  .year-list__btn.is-active { border-bottom-color: var(--stone-500); }
  .news-list .news-card:first-child { border-top: 1px solid var(--line-100); padding-top: 1.6rem; }
}

/* ---- Media page (recording grid) --------------------------------------------*/
.media-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(2.25rem, 4vw, 3.25rem);
}
@media (max-width: 780px) { .media-grid { grid-template-columns: 1fr; } }

.media-item { display: flex; flex-direction: column; }
.media-item .video-embed { margin-bottom: 1.6rem; }
.media-item__placeholder {
  aspect-ratio: 16/9;
  margin-bottom: 1.6rem;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .6rem;
  background: var(--cream-050); border: 1px dashed var(--line-100);
  color: var(--stone-ink);
}
.media-item__placeholder span { font-size: 0.94rem; font-weight: 600; letter-spacing: .02em; }
.media-item__meta {
  font-size: 0.88rem; font-weight: 600; letter-spacing: .04em; text-transform: uppercase;
  color: var(--stone-ink);
}
.media-item__body h3 { margin-top: .5rem; }
.media-item__body p { margin-top: .6rem; color: var(--ink-600); font-size: 1.07rem; }

/* ---- CTA band --------------------------------------------------------------*/
.cta-band {
  /* Its own permanent step on the staircase -- lighter than the
     --cream-050 used by --section--cream/--section--tint/the subscribe
     band/the footer, but not plain white either. The CTA band is almost
     always sandwiched between one of those --cream-050 sections and the
     --cream-050 footer, so giving it a color of its own (rather than
     matching one side or the other) keeps every page's last two seams
     distinct without needing a page-by-page override. */
  background: var(--cream-025); color: var(--graphite-900);
  border-top: 1px solid var(--line-100); /* belt-and-suspenders: still a
     visible seam even on the rare page where a neighbor also ends up at
     this same tone. */
  padding-block: clamp(3.5rem, 7vw, 5.5rem);
  text-align: center;
}
.cta-band h2 { color: var(--graphite-900); }
.cta-band p { color: var(--ink-600); margin-top: 1rem; max-width: 56ch; margin-inline: auto; }
.cta-band .btn-row { display: flex; justify-content: center; gap: 1rem; margin-top: 2.2rem; flex-wrap: wrap; }

/* ---- Subscribe / newsletter -------------------------------------------------*/
.subscribe-band { text-align: center; background: var(--cream-050); border-top: 1px solid var(--line-100); }
.subscribe-band p.body-text { max-width: 52ch; margin-inline: auto; margin-top: 1rem; }
.subscribe-form { display: flex; gap: .75rem; justify-content: center; flex-wrap: wrap; margin-top: 2rem; }
.subscribe-form input[type="email"] {
  flex: 1 1 240px; max-width: 360px; padding: .85rem 1.1rem;
  border: 1px solid var(--line-100); border-radius: 4px;
  font-family: var(--font-sans); font-size: 1.07rem; color: var(--ink-900); background: var(--white);
}
.subscribe-form input[type="email"]::placeholder { color: var(--stone-ink); }
.subscribe-form input[type="email"]:focus { outline: 2px solid var(--stone-500); outline-offset: 2px; }
.subscribe-form .btn { flex: 0 0 auto; }
.subscribe-form__fineprint { margin-top: 1rem; font-size: 0.94rem; color: var(--stone-ink); }
.subscribe-form__fineprint a { text-decoration: underline; text-underline-offset: 2px; }
.subscribe-form__fineprint--footer { margin-top: .6rem; font-size: 0.88rem; max-width: 40ch; }
.subscribe-form__message { margin-top: .6rem; font-size: 0.94rem; color: var(--stone-ink); }
.subscribe-form__message:empty { display: none; }
.subscribe-form__message.is-error { color: #a13a2a; }
.subscribe-form[hidden], .footer-subscribe[hidden], .subscribe-form__fineprint[hidden] { display: none; }

.footer-subscribe { display: flex; gap: .5rem; margin-top: 1.3rem; max-width: 320px; }
.footer-subscribe input[type="email"] {
  flex: 1 1 auto; min-width: 0; padding: .65rem .85rem;
  border: 1px solid var(--line-100); border-radius: 4px;
  background: var(--white); color: var(--graphite-900);
  font-family: var(--font-sans); font-size: 1rem;
}
.footer-subscribe input[type="email"]::placeholder { color: var(--stone-ink); }
.footer-subscribe input[type="email"]:focus { outline: 2px solid var(--stone-500); outline-offset: 1px; }
.footer-subscribe button {
  flex: 0 0 auto; width: 40px; height: 40px; border-radius: 4px;
  border: 1px solid var(--stone-500); background: transparent; color: var(--stone-500);
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease);
}
.footer-subscribe button:hover { background: var(--stone-500); color: var(--white); border-color: var(--stone-500); }
.footer-brand .subscribe-form__message { font-size: 0.88rem; max-width: 40ch; }

/* ---- Footer ----------------------------------------------------------------*/
.site-footer { background: var(--cream-050); color: var(--ink-600); border-top: 1px solid var(--line-100); padding-top: clamp(3.5rem, 7vw, 5rem); }
.footer-grid {
  display: grid; grid-template-columns: 1.4fr repeat(4, 1fr); gap: 2.5rem;
  padding-bottom: 3rem; border-bottom: 1px solid var(--line-100);
}
@media (max-width: 980px) { .footer-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px) { .footer-grid { grid-template-columns: 1fr; } }
.footer-brand .wordmark { color: var(--graphite-800); }
.footer-brand p { margin-top: 1.2rem; color: var(--stone-ink); font-size: 1rem; max-width: 40ch; }
.footer-col h4 {
  font-family: var(--font-sans); font-size: 0.88rem; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--stone-ink); margin-bottom: 1.1rem;
}
.footer-col li { margin-bottom: .45rem; }
.footer-col a { font-size: 1rem; color: var(--ink-600); }
.footer-col a:hover { color: var(--stone-500); }
.footer-social { display: flex; gap: .9rem; margin-top: 1.3rem; }
.footer-social a {
  width: 36px; height: 36px; border: 1px solid var(--line-100); border-radius: 50%; color: var(--graphite-800);
  display: inline-flex; align-items: center; justify-content: center;
}
.footer-social a:hover { background: var(--stone-500); color: var(--white); border-color: var(--stone-500); }
.footer-bottom {
  display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 1rem;
  padding-block: 1.6rem; font-size: 0.94rem; color: var(--stone-ink);
}
.footer-bottom ul { display: flex; gap: 1.5rem; flex-wrap: wrap; }
.footer-bottom a:hover { color: var(--stone-500); }

/* ---- Reveal-on-scroll -------------------------------------------------------
   Progressive enhancement only: content is fully visible by default so it
   never depends on JavaScript running. The early inline script in <head>
   adds "js-reveal" to <html> before first paint; only then do elements start
   hidden, to be faded in by main.js's IntersectionObserver. ------------------*/
.js-reveal [data-reveal] { opacity: 0; transform: translateY(22px); transition: opacity .7s var(--ease), transform .7s var(--ease); }
.js-reveal [data-reveal].is-visible { opacity: 1; transform: translateY(0); }

/* ---- Page hero (interior pages) --------------------------------------------*/
.page-hero {
  padding-top: clamp(7.5rem, 10vw, 9rem); /* ~80px of air under the 64px header at desktop width */
  padding-bottom: clamp(2.5rem, 4.5vw, 3.5rem);
  background: var(--cream-050);
  border-bottom: 1px solid var(--line-100);
  color: var(--graphite-900);
}
.page-hero .eyebrow { color: var(--stone-500); }
.page-hero h1 { margin-top: 1rem; max-width: 20ch; }
.page-hero p.lede { color: var(--ink-600); margin-top: 1.3rem; max-width: 56ch; }
.page-hero .btn-row { display: flex; gap: 1rem; flex-wrap: wrap; }
.breadcrumb { display: flex; gap: .5rem; align-items: center; font-size: 0.88rem; color: var(--stone-ink); margin-bottom: 1.2rem; }
.breadcrumb a:hover { color: var(--stone-500); }

/* ---- Artistic Director welcome (centered title, left-aligned letter) ------
   The eyebrow/heading stay centered like every other section title, but the
   message itself and its signature are left-aligned within a centered
   narrow column -- long-form paragraphs read as a ragged-centered block are
   genuinely harder to scan than a fixed left edge, and it reads more like
   an actual letter this way. The photo stays a compact, secondary byline
   element rather than the large framed feature photo used for scenic
   imagery elsewhere on the page. */
.section-head.welcome-head { max-width: 38rem; margin-inline: auto; margin-bottom: 1.2rem; }
.welcome-message { text-align: left; max-width: 38rem; margin-inline: auto; }
.welcome-byline {
  display: flex; align-items: center; justify-content: flex-end; gap: 1.15rem;
  max-width: 38rem; margin-inline: auto;
  margin-top: clamp(2rem, 4vw, 2.75rem);
}
.welcome-byline__photo {
  flex: 0 0 128px; width: 128px; height: 128px; border-radius: 50%;
  overflow: hidden; background: var(--graphite-100);
}
.welcome-byline__photo img { width: 100%; height: 100%; object-fit: cover; object-position: 39% center; }
.welcome-byline__text { text-align: left; line-height: 1.4; }
.welcome-byline__text strong { display: block; font-family: var(--font-sans); font-size: 1.07rem; font-weight: 600; color: var(--ink-900); }
.welcome-byline__text span { font-size: 0.94rem; color: var(--stone-ink); }

/* ---- Pull quote -------------------------------------------------------------*/
.pull-quote {
  border-left: 3px solid var(--stone-500);
  padding-left: clamp(1.5rem, 3vw, 2.5rem);
  margin-block: clamp(2.5rem, 5vw, 3.5rem);
}
.pull-quote p { font-family: var(--font-text-serif); font-size: clamp(1.5rem, 2.2vw, 1.8rem); color: var(--graphite-900); line-height: var(--lh-quote); text-wrap: pretty; }
.pull-quote cite { display: block; margin-top: 1rem; font-style: normal; font-size: 0.94rem; color: var(--ink-400); letter-spacing: .04em; }

/* ---- Quote carousel (chorister quotes) --------------------------------------
   One quote visible at a time via CSS scroll-snap -- draggable/swipeable
   natively on any device -- plus arrow/dot controls and a JS-driven
   auto-advance (main.js) that pauses on hover/touch/focus and is skipped
   entirely under prefers-reduced-motion. */
.quote-carousel { margin-block: clamp(2.5rem, 5vw, 3.5rem); }
.quote-carousel__track {
  display: flex; overflow-x: auto; scroll-snap-type: x mandatory;
  scrollbar-width: none; -ms-overflow-style: none;
}
.quote-carousel__track::-webkit-scrollbar { display: none; }
.pull-quote.quote-carousel__slide { flex: 0 0 100%; width: 100%; scroll-snap-align: start; margin-block: 0; }
.quote-carousel__controls {
  display: flex; align-items: center; justify-content: center; gap: 1.25rem;
  margin-top: 1.75rem;
}
.quote-carousel__arrow {
  width: 40px; height: 40px; border-radius: 50%; border: 1px solid var(--line-100);
  display: inline-flex; align-items: center; justify-content: center; color: var(--graphite-800);
  flex: none; transition: background .2s var(--ease), color .2s var(--ease), border-color .2s var(--ease);
}
.quote-carousel__arrow:hover { background: var(--stone-500); color: var(--white); border-color: var(--stone-500); }
.quote-carousel__dots { display: flex; align-items: center; gap: .55rem; }
.quote-carousel__dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--line-100); padding: 0; border: none;
  transition: background .2s var(--ease), transform .2s var(--ease);
}
.quote-carousel__dot.is-active { background: var(--stone-500); transform: scale(1.35); }

/* ---- Timeline ---------------------------------------------------------------*/
.timeline { position: relative; padding-left: clamp(1.5rem, 4vw, 3rem); }
.timeline::before { content: ""; position: absolute; left: 0; top: 6px; bottom: 6px; width: 1px; background: var(--line-100); }
.timeline__item { position: relative; padding-bottom: clamp(2.2rem, 4vw, 3rem); }
.timeline__item:last-child { padding-bottom: 0; }
.timeline__item::before {
  content: ""; position: absolute; left: calc(-1 * clamp(1.5rem, 4vw, 3rem)); top: 5px;
  width: 9px; height: 9px; border-radius: 50%; background: var(--stone-500);
  transform: translateX(calc(clamp(1.5rem, 4vw, 3rem) / 2 - 4.5px));
}
.timeline__year { font-size: 0.94rem; letter-spacing: .08em; text-transform: uppercase; color: var(--stone-ink); font-weight: 600; }
.timeline__item h3 { margin-top: .5rem; }
.timeline__item p { margin-top: .7rem; color: var(--ink-600); font-size: 1.18rem; line-height: var(--lh-read); }

/* ---- People grid (leadership) ------------------------------------------------*/
.people-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 3rem 3.5rem; }
@media (max-width: 760px) { .people-grid { grid-template-columns: 1fr; gap: 2.5rem; } }
.person { display: flex; flex-direction: row; align-items: flex-start; gap: 1.25rem; }
.person__photo { flex: 0 0 100px; width: 100px; aspect-ratio: 1/1; background: var(--graphite-100); overflow: hidden; border-radius: 50%; }
.person__photo img { width: 100%; height: 100%; object-fit: cover; }
.person__info { flex: 1; min-width: 0; border-left: 2px solid var(--stone-500); padding-left: 1.25rem; }
.person h3 { margin-top: 0; font-size: 1.55rem; }
.person .role { font-size: 0.94rem; color: var(--stone-ink); margin-top: .2rem; }
.person__bio { margin-top: .6rem; font-size: 1rem; color: var(--ink-900); line-height: var(--lh-read); }
.person__detail { margin-top: .85rem; font-size: 0.94rem; color: var(--ink-600); line-height: var(--lh-read); }
.person__detail-label { display: block; font-size: 0.8rem; letter-spacing: .06em; text-transform: uppercase; color: var(--stone-ink); font-weight: 600; margin-bottom: .2rem; }
.person__bio-toggle {
  margin-top: .9rem; display: inline-flex; align-items: center; gap: .35rem;
  font-size: 0.94rem; font-weight: 600; color: var(--ink-600);
  background: none; border: none; padding: 0; cursor: pointer; font-family: inherit;
}
.person__bio-toggle .chev { width: .85em; height: .85em; flex: none; transform: rotate(-90deg); }
.person__full-bio-inner p + p { margin-top: .9rem; }

/* ---- Leadership bio modal ------------------------------------------------------*/
.bio-modal { position: fixed; inset: 0; z-index: 300; display: none; align-items: center; justify-content: center; padding: 2rem 1.25rem; }
.bio-modal.is-open { display: flex; }
.bio-modal__backdrop { position: absolute; inset: 0; background: rgba(12, 33, 54, .55); }
.bio-modal__dialog {
  position: relative; z-index: 1; background: var(--cream-000); width: 100%; max-width: 720px;
  max-height: 85vh; overflow-y: auto; border-radius: 14px; padding: 2.5rem;
  box-shadow: 0 24px 64px rgba(9, 34, 61, .28);
}
.bio-modal__close {
  position: absolute; top: 1.1rem; right: 1.1rem; width: 2.25rem; height: 2.25rem; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; background: var(--graphite-100);
  color: var(--graphite-800); font-size: 1.4rem; line-height: 1;
}
.bio-modal__close:hover { background: var(--stone-100); }
.bio-modal__head { display: flex; align-items: center; gap: 1.25rem; margin-bottom: 1.5rem; padding-right: 2.25rem; }
.bio-modal__photo { flex: 0 0 72px; width: 72px; height: 72px; border-radius: 50%; overflow: hidden; background: var(--graphite-100); }
.bio-modal__photo img { width: 100%; height: 100%; object-fit: cover; }
.bio-modal__name { font-size: 1.3rem; margin: 0; }
.bio-modal__role { font-size: 1rem; color: var(--stone-ink); margin-top: .2rem; }
.bio-modal__body { font-size: 1rem; color: var(--ink-900); line-height: var(--lh-read); }
.bio-modal__body p + p { margin-top: .9rem; }
body.modal-open { overflow: hidden; }
@media (max-width: 600px) {
  .bio-modal { padding: 0; }
  .bio-modal__dialog { max-height: 100vh; height: 100%; border-radius: 0; padding: 2.25rem 1.5rem; }
}

/* ---- Give Online modal ---------------------------------------------------------
   Same accessible pattern as the leadership bio modal above (focus trap,
   Escape/backdrop-click closes, focus returns on close -- see the shared
   controller in assets/js/main.js), reused on the Give page and the Ways
   to Give page so the donation form opens as an overlay instead of sitting
   inline. Its visual "card" is .donate-box itself (already styled as a
   bordered box elsewhere on the site) rather than a second nested box. */
.donate-modal, .pledge-modal, .audition-modal { position: fixed; inset: 0; z-index: 300; display: none; align-items: center; justify-content: center; padding: 2rem 1.25rem; }
.donate-modal.is-open, .pledge-modal.is-open, .audition-modal.is-open { display: flex; }
.donate-modal__backdrop, .pledge-modal__backdrop, .audition-modal__backdrop { position: absolute; inset: 0; background: rgba(12, 33, 54, .55); }
.donate-modal__dialog, .pledge-modal__dialog, .audition-modal__dialog { position: relative; z-index: 1; width: 100%; max-width: 560px; max-height: 90vh; overflow-y: auto; }
.donate-modal .donate-box, .pledge-modal .donate-box, .audition-modal .donate-box { position: relative; margin-inline: 0; border-radius: 14px; box-shadow: 0 24px 64px rgba(9, 34, 61, .28); }
.donate-modal__close, .pledge-modal__close, .audition-modal__close {
  position: absolute; top: 1.1rem; right: 1.1rem; width: 2.25rem; height: 2.25rem; border-radius: 50%;
  display: flex; align-items: center; justify-content: center; background: var(--graphite-100);
  color: var(--graphite-800); font-size: 1.4rem; line-height: 1; z-index: 2;
}
.donate-modal__close:hover, .pledge-modal__close:hover, .audition-modal__close:hover { background: var(--stone-100); }
@media (max-width: 600px) {
  .donate-modal, .pledge-modal, .audition-modal { padding: 0; }
  .donate-modal__dialog, .pledge-modal__dialog, .audition-modal__dialog { max-height: 100vh; height: 100%; max-width: none; }
  .donate-modal .donate-box, .pledge-modal .donate-box, .audition-modal .donate-box { border-radius: 0; min-height: 100%; }
}

/* ---- FAQ / accordion ----------------------------------------------------------*/
.accordion__item { border-bottom: 1px solid var(--line-100); }
.accordion__trigger {
  width: 100%; display: flex; justify-content: space-between; align-items: center; gap: 1rem;
  padding: 1.4rem 0; text-align: left; font-family: var(--font-sans); font-weight: 500; font-size: 1.18rem; color: var(--graphite-900);
}
.accordion__trigger .chev { width: 1em; height: 1em; flex: none; transition: transform .3s var(--ease); }
.accordion__item.is-open .chev { transform: rotate(180deg); }
.accordion__panel {
  max-height: 0; overflow: hidden; transition: max-height .35s var(--ease);
}
.accordion__panel-inner { padding-bottom: 1.4rem; color: var(--ink-600); max-width: 62ch; }

/* ---- misc utility ---------------------------------------------------------*/
.text-center { text-align: center; }
.mt-lg { margin-top: clamp(2rem, 4vw, 3rem); }
.mt-sm { margin-top: 1.2rem; }

/* ---- Long-form legal/policy prose (Privacy Policy, Terms of Use, etc.) ----
   These pages are plain stacked h2/h3/p rather than the feature/section-head
   components the rest of the site uses, so they get their own vertical
   rhythm here instead of relying on those components' spacing rules. */
/* Legal-page (Privacy Policy, Terms of Use) section headings are quieter
   and smaller than the site's usual h2 -- those pages are reference
   material to be scanned section by section, not marketing copy, so the
   heading shouldn't compete with a page's actual headline treatment.
   Scoped to .prose only, so every other page's h2 is untouched. */
.prose h2 { margin-top: clamp(2rem, 4vw, 2.75rem); margin-bottom: .75rem; font-family: var(--font-text-serif); font-size: clamp(1.7rem, 2.5vw, 2.1rem); }
/* Sub-headers within a section (e.g. "Information You Provide" under
   "Information We Collect") switch to sans-serif at a smaller size, so
   they read as clearly subordinate to the serif section heading above
   them rather than a second, near-identical heading. */
.prose h3 {
  margin-top: 1.75rem; margin-bottom: .75rem;
  font-family: var(--font-sans); font-size: 1.18rem; font-weight: 600; color: var(--ink-900);
}
/* Body copy on these reference pages matches the News page's text size
   (.95rem), which reads cleaner than the site-wide body size. */
.prose p.body-text, .prose li { font-size: 1.07rem; line-height: var(--lh-long); }
.prose p.body-text { max-width: none; }
.container--narrow.prose { max-width: 47rem; }
.prose p.body-text + p.body-text { margin-top: 1rem; }
/* Divider spacing is tuned by the visible ink, not the boxes: the last
   paragraph line carries a few px of leading below its text and the h2 a
   few px above its capitals, so the box gaps differ (36px vs 34px) to make
   the space above and below each rule look equal (~41px). */
.prose hr.rule { margin-top: clamp(1.75rem, 3.5vw, 2.25rem); margin-bottom: 0; }
.prose hr.rule + h2 { margin-top: clamp(1.5rem, 3vw, 2.15rem); }

/* ---- Give Online (Stripe) ---------------------------------------------------
   Custom "pre-checkout" front door: the donor picks an amount and optional
   extras in this box, then submitting it hands off entirely to Stripe's
   own hosted Checkout page (via /api/create-checkout-session) for all
   actual card collection and processing -- this markup and its JS never
   see or touch card details. Reused as-is on the Give page (its own
   section) and on Ways to Give (nested inside the "Give Online" accordion
   panel). */
.donate-box {
  background: var(--white); border: 1px solid var(--line-100);
  max-width: 560px; margin-inline: auto;
  padding: clamp(1.75rem, 4vw, 2.75rem);
}
.donate-form, .family-login-form, .pledge-form, .audition-form { display: flex; flex-direction: column; gap: 1.5rem; }

.donate-amounts { display: grid; grid-template-columns: repeat(3, 1fr); gap: .75rem; }
.donate-amount {
  padding: .9rem .5rem; text-align: center;
  border: 1px solid var(--line-100); border-radius: 4px;
  font-family: var(--font-sans); font-size: 1.18rem; font-weight: 600; color: var(--graphite-800);
  background: var(--cream-000);
  transition: border-color .2s var(--ease), background-color .2s var(--ease), color .2s var(--ease);
}
.donate-amount:hover { border-color: var(--stone-500); }
.donate-amount.is-selected { background: var(--stone-500); border-color: var(--stone-500); color: var(--white); }
@media (max-width: 460px) { .donate-amounts { grid-template-columns: repeat(2, 1fr); } }

.donate-custom-amount { display: flex; flex-direction: column; gap: .4rem; }
/* An author display rule (even via a plain class selector) always beats the
   UA stylesheet's [hidden]{display:none} regardless of specificity or source
   order, so the rule above alone would leave this field visible even while
   the hidden attribute is present -- this explicit override (higher
   specificity: class + attribute) restores that default. */
.donate-custom-amount[hidden] { display: none; }
.donate-custom-amount label { font-size: 0.94rem; font-weight: 600; color: var(--ink-900); }
.donate-custom-input-wrap {
  display: flex; align-items: center; gap: .4rem;
  border: 1px solid var(--line-100); border-radius: 4px; padding: .7rem .9rem;
  background: var(--white);
}
.donate-custom-input-wrap:focus-within { outline: 2px solid var(--stone-500); outline-offset: 1px; }
.donate-custom-input-wrap span { color: var(--stone-ink); font-weight: 600; }
.donate-custom-amount input {
  flex: 1; min-width: 0; border: none; padding: 0; font-family: var(--font-sans);
  font-size: 1.18rem; color: var(--ink-900); background: none;
}
.donate-custom-amount input:focus { outline: none; }

.donate-field { display: flex; flex-direction: column; gap: .4rem; }
.donate-field label { font-size: 0.94rem; font-weight: 600; color: var(--ink-900); }
.donate-field input[type="text"],
.donate-field input[type="email"],
.donate-field input[type="password"],
.donate-field input[type="tel"],
.donate-field input[type="number"] {
  padding: .7rem .9rem; border: 1px solid var(--line-100); border-radius: 4px;
  font-family: var(--font-sans); font-size: 1.07rem; color: var(--ink-900); background: var(--white);
}
.donate-field input[type="text"]:focus,
.donate-field input[type="email"]:focus,
.donate-field input[type="password"]:focus,
.donate-field input[type="tel"]:focus,
.donate-field input[type="number"]:focus { outline: 2px solid var(--stone-500); outline-offset: 1px; }
.donate-field input[type="text"]::placeholder,
.donate-field input[type="email"]::placeholder,
.donate-field input[type="password"]::placeholder,
.donate-field input[type="tel"]::placeholder,
.donate-field input[type="number"]::placeholder { color: var(--stone-ink); }

.donate-checkbox {
  display: flex; align-items: flex-start; gap: .7rem; cursor: pointer;
  font-size: 1rem; color: var(--ink-600); line-height: var(--lh-read);
}
.donate-checkbox input[type="checkbox"],
.donate-checkbox input[type="radio"] {
  flex: none; width: 1.15rem; height: 1.15rem; margin-top: .15rem; accent-color: var(--graphite-800);
}

/* Groups the pledge form's payment-cadence radio options (reusing
   .donate-checkbox for each row's look) under one labeled, borderless
   fieldset -- semantically a group of related radios, styled the same
   as the rest of this form. */
.pledge-cadence-fieldset { border: none; padding: 0; margin: 0; display: flex; flex-direction: column; gap: .6rem; }
.pledge-cadence-fieldset legend { font-size: 0.94rem; font-weight: 600; color: var(--ink-900); padding: 0; margin: 0 0 .4rem; }

/* Audition Interest form (auditions.html): reuses the .donate-field look,
   adds a select, side-by-side field pairs, and small group headings. */
.donate-field select {
  padding: .7rem .9rem; border: 1px solid var(--line-100); border-radius: 4px;
  font-family: var(--font-sans); font-size: 1.07rem; color: var(--ink-900); background: var(--white);
}
.donate-field select:focus { outline: 2px solid var(--stone-500); outline-offset: 1px; }
.audition-form__row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 1.5rem; }
/* Inputs have an intrinsic minimum width, which pushed the right-hand field
   of each pair past the edge of the box; let them shrink to their column. */
.audition-form .donate-field { min-width: 0; }
.audition-form .donate-field input,
.audition-form .donate-field select { width: 100%; min-width: 0; box-sizing: border-box; }
.audition-modal__dialog { max-width: 680px; }
@media (max-width: 460px) { .audition-form__row { grid-template-columns: 1fr; } }
.audition-form__group { margin: .5rem 0 -.25rem; padding-top: 1.25rem; border-top: 1px solid var(--line-100); font-family: var(--font-sans); font-size: 1.18rem; font-weight: 600; color: var(--ink-900); }
.audition-form__group:first-child { margin-top: 0; padding-top: 0; border-top: none; }
.audition-form__hint { margin: -.75rem 0 0; font-size: 0.94rem; color: var(--stone-ink); }

.donate-form__error {
  padding: .85rem 1rem; border-radius: 4px;
  background: #fbeaea; border: 1px solid #e4b8b8; color: #8a2f2f;
  font-size: 1rem;
}

.donate-submit { justify-content: center; width: 100%; }
.donate-submit.is-loading { opacity: .7; pointer-events: none; }

.donate-form__note { font-size: 0.94rem; color: var(--stone-ink); text-align: center; margin: 0; }
.donate-form__note a { text-decoration: underline; text-underline-offset: 2px; }
.donate-form__note a:hover { color: var(--graphite-800); }

/* ---- Give Online: embedded Stripe Payment Element -----------------------
   Stripe's own "Payment Element" mounts inside .donate-payment-element
   (card fields, plus Apple Pay / Google Pay buttons where available) --
   its internal appearance is themed to match the site via the
   `appearance` object passed in main.js, not by CSS reaching into it.
   .donate-payment-placeholder is the plain-text stand-in shown before an
   amount has been chosen (or if Stripe.js itself failed to load). */
.donate-payment-field { display: flex; flex-direction: column; gap: .4rem; }
.donate-payment-placeholder {
  margin: 0; padding: .9rem 1rem; border: 1px dashed var(--line-100); border-radius: 4px;
  font-size: 1rem; color: var(--stone-ink); text-align: center;
}

/* ---- Thank-you page ---------------------------------------------------------
   "Where your gift goes" -- a large serif figure beside the explanation, stacking
   on narrow screens. .share-status is the quiet confirmation line under the
   share buttons. */
.gift-gap { display: grid; grid-template-columns: auto 1fr; gap: clamp(1.5rem, 5vw, 4rem); align-items: center; }
.gift-gap__figure {
  margin: 0; font-family: var(--font-serif); font-size: clamp(3.5rem, 9vw, 5.75rem);
  line-height: 1; color: var(--stone-500); white-space: nowrap;
}
.gift-gap__caption { margin: .7rem 0 0; max-width: 15rem; font-size: 1rem; line-height: var(--lh-read); color: var(--ink-600); }
.gift-gap__note { margin-top: 1.1rem; font-size: 1rem; color: var(--ink-400); }
@media (max-width: 720px) { .gift-gap { grid-template-columns: 1fr; } }
.share-status { min-height: 1.5em; margin-top: 1.1rem !important; font-size: 1rem; }

/* "Where your gift goes" bar: one track, grey for tuition fading into the accent
   across the 15-20% range, so the soft edge says "about", not an exact split. The
   label grid uses the same 17.5 / 82.5 proportions as the bar. */
.gap-bar { margin: clamp(2rem, 4vw, 2.75rem) 0 0; }
.gap-bar__track {
  height: .9rem; border-radius: 999px;
  background: linear-gradient(to right, #c7ccd1 0, #c7ccd1 15%, var(--stone-500) 20%, var(--stone-500) 100%);
}
.gap-bar__labels {
  display: grid; grid-template-columns: minmax(max-content, 17.5fr) 82.5fr; gap: .75rem; margin-top: .75rem;
  font-size: 0.94rem; line-height: 1.35; color: var(--ink-600); /* two short labels under a bar: tight on purpose */
}
.gap-bar__labels strong { display: block; white-space: nowrap; font-size: 1.18rem; color: var(--ink-900); }
.gap-bar__labels .gap-bar__strong--support { color: var(--stone-500); }

/* ---- Phone country picker (intl-tel-input; see assets/js/phone-input.js) ----
   The library wraps each tel input in .iti with a flag + dial-code button on
   the left. Make the wrapper fill the form field and match the site's inputs. */
.dcc-iti { width: 100%; --iti-border-color: var(--line-100); --iti-dropdown-bg: var(--white); --iti-hover-color: var(--graphite-100); --iti-arrow-color: var(--stone-ink); }
.dcc-iti input[type="tel"] { width: 100%; box-sizing: border-box; }
.iti__country-list, .iti__dropdown-content { font-family: var(--font-sans); font-size: 1rem; }
.iti--fullscreen-popup, .iti--container, .iti__dropdown-content { z-index: 400; }

/* Required-field marker on the Audition Interest form */
.req { color: #8a2f2f; font-weight: 700; }
.audition-form__required-note { margin-top: .75rem; font-size: 0.94rem; color: var(--stone-ink); }

/* ---- Type scale consistency pass ----
   Text sizes were consolidated into a small set of steps (0.8 / 0.88 /
   0.94 / 1.0 / 1.07 / 1.18rem) so that similar roles read at the same size
   on every page. The rules below cover the few places that need a specific
   step beyond that mapping. */
.cta-band p { font-size: 1.18rem; }           /* matches section intro text (.body-text) */
.donate-form__note { font-size: 1rem; }       /* fine print stays comfortably readable */

/* Compact teaser (Give page "Ways to Give"): spacing matches the CTA band below */
.teaser .section-head { margin-bottom: 0; }
.teaser .section-head p.mt-lg { margin-top: 1rem; }
.teaser .text-center.mt-lg { margin-top: 2.2rem; }
.teaser .donate-form__note { margin-top: 0; }
.teaser .text-center + .mt-lg { margin-top: 2.2rem; }
.cta-band .eyebrow + h2 { margin-top: 1rem; }

/* ---- Line-height system: applied to running text -------------------------
   Anything not listed here (header, nav, buttons, form controls, badges, labels)
   keeps its own tuned spacing. Specific component rules above win over this. */
main p, main li, main dd, main figcaption,
.site-footer p, [class*="-modal"] p {
  line-height: var(--lh-read);
}
.prose p, .prose li, .accordion__panel-inner, .accordion__panel-inner p {
  line-height: var(--lh-long);
}
/* Phones: narrow columns read best slightly tighter */
@media (max-width: 640px) {
  :root { --lh-read: 1.44; --lh-long: 1.55; }
}

/* ---- Keyboard focus: one visible ring everywhere -------------------------
   Shown only for keyboard users (:focus-visible), so mouse clicks stay clean. */
a:focus-visible, button:focus-visible, summary:focus-visible,
[tabindex]:focus-visible, select:focus-visible, textarea:focus-visible,
input:focus-visible {
  outline: 2px solid var(--stone-500);
  outline-offset: 3px;
}
.hero a:focus-visible, .hero button:focus-visible,
.site-header--transparent:not(.is-scrolled) a:focus-visible { outline-color: var(--white); }
.donate-custom-amount input:focus-visible { outline: none; } /* its wrapper shows the ring */

/* ---- Print: clean, ink-friendly pages (audition details, FAQ, bios) ------ */
@media print {
  @page { margin: 1.8cm; }
  .site-header, .skip-link, .site-footer, .footer-subscribe, .cta-band, .subscribe-band,
  .hero__video, .video-embed, .quote-carousel__controls, [class*="-modal"],
  .btn-row, .btn, .feature__media .frame, .breadcrumb { display: none !important; }
  html, body { background: #fff !important; color: #000 !important; font-size: 11.5pt; }
  *, *::before, *::after { box-shadow: none !important; text-shadow: none !important; }
  [data-reveal] { opacity: 1 !important; transform: none !important; }
  .section, .page-hero { padding-block: 1.2rem !important; background: #fff !important; }
  .container, .container--narrow { max-width: none !important; padding-inline: 0 !important; }
  h1, h2, h3 { color: #000 !important; break-after: avoid; }
  p, li, .program-facts, .timeline__item, .person, .accordion__item { break-inside: avoid; }
  img { max-width: 100% !important; break-inside: avoid; }
  .accordion__panel { max-height: none !important; overflow: visible !important; }
  .accordion__trigger svg, .accordion__trigger::after { display: none !important; }
  main a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 0.85em; word-break: break-all; }
  main a[href^="mailto:"]::after { content: " (" attr(href) ")"; font-size: 0.85em; }
}
.main-nav__link:focus-visible { outline-offset: -9px; border-radius: 2px; }
.subscribe-band .eyebrow + h2 { margin-top: 1rem; }

/* ---- "Stay Informed" side tab ----------------------------------------------
   Fixed to the right edge, vertically centred. The tab is always visible; the
   card slides out to its left when opened. Sits above page content but below
   the header (200), mobile menu (250) and modals (300). */
.side-tabs { position: fixed; right: 0; top: 50%; z-index: 150; transform: translateY(-50%); display: flex; flex-direction: column; align-items: flex-end; gap: 6px; }
.stay-informed { position: relative; transition: opacity .5s var(--ease); }
.side-give {
  display: flex; align-items: center; justify-content: center; width: 34px; box-sizing: border-box;
  background: var(--white); color: var(--stone-500); border: 2px solid var(--stone-500); border-left: 0; text-decoration: none;
  font: 600 .86rem/1 var(--font-sans); letter-spacing: .16em; text-transform: uppercase;
  padding: 26px 0; writing-mode: vertical-rl; transform: rotate(180deg);
  border-radius: 0 4px 4px 0; box-shadow: 0 2px 14px rgba(0,0,0,.18);
  transition: background .2s var(--ease), color .2s var(--ease), width .2s var(--ease);
}
.side-give span { display: block; padding: .16em 0 0; position: relative; left: -1.5px; }
.side-give:hover, .side-give:focus-visible { background: var(--stone-500); color: var(--white); width: 37px; }
.stay-informed.is-done { opacity: 0; pointer-events: none; }
.stay-informed__tab {
  display: flex; align-items: center; justify-content: center; width: 34px; box-sizing: border-box;
  background: var(--stone-500); color: var(--white); border: 0; cursor: pointer;
  font: 600 .86rem/1 var(--font-sans); letter-spacing: .16em; text-transform: uppercase;
  padding: 15.5px 0; writing-mode: vertical-rl; transform: rotate(180deg);
  border-radius: 0 4px 4px 0; box-shadow: 0 2px 14px rgba(0,0,0,.18);
  transition: background .2s var(--ease), width .2s var(--ease);
}
.stay-informed__tab span { display: block; padding: .16em 0 0; position: relative; left: -1.5px; } /* letter-spacing adds trailing space; balance it so the text sits centred */
.stay-informed__tab:hover { background: var(--graphite-800); width: 37px; }
.stay-informed.is-open .stay-informed__tab { background: var(--graphite-800); }
.stay-informed__panel {
  position: absolute; right: 100%; top: 50%; width: min(340px, calc(100vw - 64px));
  background: var(--cream-000); color: var(--graphite-800); padding: 1.6rem 1.5rem 1.4rem;
  border-top: 3px solid var(--stone-500); box-shadow: 0 10px 40px rgba(0,0,0,.22);
  transform: translate(24px, -50%); opacity: 0; visibility: hidden;
  transition: transform .3s var(--ease), opacity .25s var(--ease), visibility 0s linear .3s;
}
.stay-informed.is-open .stay-informed__panel { transform: translate(0, -50%); opacity: 1; visibility: visible; transition-delay: 0s; }
.stay-informed__close {
  position: absolute; top: .45rem; right: .6rem; background: none; border: 0; cursor: pointer;
  font-size: 1.6rem; line-height: 1; color: var(--graphite-800); padding: .2rem .4rem;
}
.stay-informed__title { font-size: 1.55rem; line-height: var(--lh-h2); margin: .9rem 0 1.1rem; }
.stay-informed .eyebrow { margin: 0; }
.stay-informed__form { display: flex; flex-direction: column; gap: .6rem; }
.stay-informed__form input[type="email"] {
  width: 100%; padding: .8rem .9rem; border: 1px solid #c9ced3; background: var(--white);
  font: inherit; font-size: 1rem; color: var(--graphite-800); border-radius: 0;
}
.stay-informed__form input[type="email"]::placeholder { color: var(--stone-ink); }
.stay-informed__form input[type="email"]:focus { outline: 2px solid var(--stone-500); outline-offset: 1px; }
.stay-informed__form .btn { width: 100%; justify-content: center; }
.stay-informed__form[hidden] { display: none; }
.stay-informed .subscribe-form__fineprint { margin-top: .8rem; font-size: .86rem; }
.stay-informed .subscribe-form__message { font-size: .94rem; }
@media (max-width: 640px) {
  .side-tabs { top: 62%; }
  .stay-informed__tab { width: 33px; padding: 15.5px 0; font-size: .8rem; }
  .side-give { width: 33px; padding: 24px 0; font-size: .8rem; }
}
@media (prefers-reduced-motion: reduce) {
  .stay-informed__panel, .stay-informed__tab, .stay-informed, .side-give { transition: none; }
}
@media print { .stay-informed, .side-tabs { display: none !important; } }

/* ---- Floating notice ("Subscribing...", "Thank you for subscribing!") --------
   A blue box that slides up from the bottom centre of the screen and fades
   away on its own (timing is set in main.js). Above the side tab (150) and
   mobile menu (250), at the same level as the modals' backdrop edge. */
.toast {
  position: fixed; left: 50%; bottom: 28px; z-index: 320;
  width: max-content; max-width: min(440px, calc(100vw - 32px));
  background: var(--stone-500); color: var(--white);
  padding: 1rem 1.5rem; border-radius: 4px;
  font-size: 1.02rem; font-weight: 500; line-height: var(--lh-read); text-align: center;
  box-shadow: 0 8px 30px rgba(0,0,0,.25);
  opacity: 0; visibility: hidden; transform: translate(-50%, 16px);
  transition: opacity .3s var(--ease), transform .3s var(--ease), visibility 0s linear .3s;
  pointer-events: none;
}
.toast.is-visible { opacity: 1; visibility: visible; transform: translate(-50%, 0); transition-delay: 0s; }
@media (prefers-reduced-motion: reduce) { .toast { transition: none; } }
@media print { .toast { display: none !important; } }

/* ---- Family Portal season calendar --------------------------------------
   Year-at-a-glance on wide screens (all months of the season in a grid);
   one month at a time on phones. Day cells with events are buttons; a
   single bubble (.cal__bubble) shows the details for the tapped day. */
.cal { position: relative; display: flex; flex-direction: column; margin-top: clamp(1.5rem, 3vw, 2.2rem); }
.cal__controls { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 1rem 2rem; }
.cal__choirs { display: flex; flex-wrap: wrap; gap: .6rem; }
.cal__chip {
  font: 600 .84rem/1 var(--font-sans); letter-spacing: .12em; text-transform: uppercase;
  padding: .8rem 1.05rem; border: 1px solid var(--line-100); border-radius: 999px;
  background: var(--white); color: var(--stone-ink); cursor: pointer;
  transition: background .2s ease, color .2s ease, border-color .2s ease;
}
.cal__chip:hover { border-color: var(--stone-500); color: var(--stone-500); }
.cal__chip.is-on { background: var(--stone-500); border-color: var(--stone-500); color: var(--white); }
.cal__chip:focus-visible, .cal-day:focus-visible, .cal__arrow:focus-visible, .cal__bubble-close:focus-visible { outline: 2px solid var(--stone-500); outline-offset: 2px; }
.cal__legend { display: flex; flex-wrap: wrap; gap: .4rem 1.3rem; list-style: none; margin: 0; padding: 0; font-size: .95rem; color: var(--ink-600); }
.cal__legend li { display: flex; align-items: center; gap: .5rem; }
.cal__swatch { width: 14px; height: 14px; border-radius: 3px; display: inline-block; }
.cal__swatch--rehearsal, .cal-day.cal-day--rehearsal { background: #cfe3f1; color: var(--graphite-900); }
.cal__swatch--concert, .cal-day.cal-day--concert { background: var(--stone-500); color: var(--white); }
.cal__swatch--other, .cal-day.cal-day--other { background: #f3e4b8; color: var(--graphite-900); }

.cal__status { margin-top: 1.6rem; font-size: 1.1rem; color: var(--ink-600); }
.cal__status[hidden], .cal__upnext[hidden], .cal__mobile-nav[hidden], .cal__bubble[hidden] { display: none; }

.cal__upnext { margin-top: 2rem; padding: 1.4rem 1.6rem; background: var(--cream-050); border-left: 3px solid var(--stone-500); }
.cal__upnext h3 { font-size: 1.15rem; margin: 0 0 .8rem; }
.cal__upnext ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .9rem 2rem; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }
.cal-up { display: grid; gap: .15rem; }
.cal-up__date { font-size: .84rem; letter-spacing: .1em; text-transform: uppercase; font-weight: 600; color: var(--stone-ink); }
.cal-up__title { font-size: 1.08rem; color: var(--graphite-900); }
.cal-up__row { display: grid; gap: .1rem; margin-top: .45rem; }
.cal-up__who { font-size: .95rem; color: var(--ink-400); }

.cal__mobile-nav { display: none; align-items: center; justify-content: space-between; margin-top: 2rem; }
.cal__nav-title { font-family: var(--font-serif); font-size: 1.7rem; }
.cal__arrow { width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--line-100); background: var(--white); color: var(--graphite-800); display: grid; place-items: center; cursor: pointer; }
.cal__arrow:disabled { opacity: .35; cursor: default; }

.cal__months { margin-top: 2rem; display: grid; gap: 2rem 1.8rem; grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cal-month__title { font: 600 1rem/1.2 var(--font-sans); letter-spacing: .04em; text-align: center; margin: 0 0 .6rem; color: var(--graphite-900); }
.cal-grid { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; }
.cal-grid__dow { text-align: center; font-size: .78rem; font-weight: 600; color: var(--ink-400); padding-bottom: .2rem; }
.cal-day {
  aspect-ratio: 1 / 1; display: grid; place-items: center; border-radius: 4px;
  font: 400 1rem/1 var(--font-sans); color: var(--ink-600); border: 0; padding: 0;
}
.cal-day--none { background: transparent; }
button.cal-day { cursor: pointer; font-weight: 600; transition: transform .15s ease, box-shadow .15s ease; }
button.cal-day:hover { transform: translateY(-1px); box-shadow: 0 2px 8px rgba(0,0,0,.18); }
.cal-day.is-today { box-shadow: inset 0 0 0 2px var(--graphite-800); }

.cal__bubble {
  position: absolute; z-index: 30; width: min(340px, 100%); max-height: 70vh; overflow-y: auto;
  background: var(--white); border: 1px solid var(--line-100); border-radius: 6px;
  box-shadow: 0 14px 40px rgba(0,0,0,.2); padding: 1.2rem 1.3rem 1.3rem;
}
.cal__bubble-title { font-family: var(--font-serif); font-weight: 400; font-size: 1.5rem; margin: 0 2rem .8rem 0; }
.cal__bubble-close { position: absolute; top: .55rem; right: .6rem; width: 34px; height: 34px; border: 0; background: transparent; font-size: 1.7rem; line-height: 1; color: var(--ink-600); cursor: pointer; }
.cal-ev { display: grid; gap: .2rem; padding: .9rem 0; border-top: 1px solid var(--line-100); }
.cal-ev:first-child { border-top: 0; padding-top: 0; }
.cal-ev__tag { justify-self: start; font-size: .74rem; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; padding: .28rem .55rem; border-radius: 3px; }
.cal-ev--rehearsal .cal-ev__tag { background: #cfe3f1; color: var(--graphite-900); }
.cal-ev--concert .cal-ev__tag { background: var(--stone-500); color: var(--white); }
.cal-ev--other .cal-ev__tag { background: #f3e4b8; color: var(--graphite-900); }
.cal-ev__title { font-size: 1.12rem; margin-top: .3rem; color: var(--graphite-900); }
.cal-ev__line { font-size: 1rem; color: var(--ink-600); }
.cal-ev__notes { font-size: .98rem; color: var(--ink-600); margin-top: .35rem; white-space: pre-line; }

@media (max-width: 1000px) { .cal__months { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 760px) {
  .cal__upnext { order: 5; }  /* phones: calendar first, upcoming list below it */
  .cal__mobile-nav { display: flex; padding-right: 14px; }  /* keeps the next arrow clear of the floating Stay Informed tab */
  .cal__months { grid-template-columns: 1fr; margin-top: 1rem; }
  .cal-month { display: none; }
  .cal-month.is-current { display: block; }
  .cal-month__title { display: none; }
  .cal-grid { gap: 4px; }
  .cal-day { font-size: 1.05rem; }
}
@media (max-width: 640px) {
  .cal__chip { font-size: .74rem; letter-spacing: .08em; padding: .75rem .85rem; }
  .cal__bubble { position: fixed; left: 0 !important; right: 0; top: auto !important; bottom: 0; width: auto; max-height: 65vh; border-radius: 14px 14px 0 0; padding-bottom: 1.8rem; }
}
@media (prefers-reduced-motion: reduce) { button.cal-day { transition: none; } button.cal-day:hover { transform: none; } }
@media print { .cal__bubble, .cal__chip:not(.is-on), .cal__arrow { display: none; } }
