/* The program sections: cover, sequence, participants, the two bios, duty stations, collage.
   Typography follows the site's own system (--font-display for names and headings, --font-ui for
   running text), not the printed program's serif. The cards sit on near-opaque paper so the scene
   behind them never competes with the words. Nothing here changes chapter heights, the camera
   path, or the scene. */

/* The stage's default 72px band above and below is generous for a short placeholder and wasteful
   for a long bio, so program chapters get a tighter one. This is padding only: chapter heights and
   the camera path are untouched. */
.program-section .chapter__stage { padding-block: 40px; }

.program-card {
  --program-paper: rgba(252, 250, 246, 0.965);
  position: relative;
  display: flex;
  width: min(560px, 100%);
  max-height: calc(var(--stage-h) - 80px);
  background: var(--program-paper);
  border: 1px solid rgba(46, 62, 92, 0.16);
  border-radius: 8px;
  box-shadow: 0 20px 56px rgba(24, 34, 54, 0.22), 0 2px 8px rgba(24, 34, 54, 0.1);
  overflow: hidden;                       /* the inner element scrolls, so the fade can stay put */
  opacity: 0.35;
  transform: translate3d(0, 14px, 0);
  transition: opacity 0.6s ease, transform 0.6s ease;
}
.chapter.is-current .program-card { opacity: 1; transform: none; }
.program-card--wide { width: min(1060px, 100%); }
.program-section--bio .program-card { width: min(640px, 100%); }

.program-card__scroll {
  flex: 1;
  min-width: 0;
  overflow-y: auto;
  overscroll-behavior-y: auto;            /* let the page take over once the card bottoms out */
  padding: clamp(22px, 3.2vw, 34px) clamp(20px, 3.4vw, 38px) clamp(24px, 3.4vw, 36px);
  scrollbar-width: thin;
  scrollbar-color: rgba(46, 62, 92, 0.3) transparent;
}
.program-card__scroll::-webkit-scrollbar { width: 9px; }
.program-card__scroll::-webkit-scrollbar-thumb {
  background: rgba(46, 62, 92, 0.26);
  border: 3px solid transparent;
  background-clip: content-box;
  border-radius: 9px;
}
/* Only shown when js/program.js measures real overflow, so it never lies about there being more. */
.program-card[data-scroll="1"]::after {
  content: "";
  position: absolute;
  left: 1px; right: 1px; bottom: 1px;
  height: 46px;
  border-radius: 0 0 7px 7px;
  background: linear-gradient(rgba(252, 250, 246, 0), var(--program-paper) 78%);
  pointer-events: none;
}

/* ---------------------------------------------------------------- shared type */
.program-stars {
  margin: 0 0 clamp(12px, 1.6vw, 18px);
  color: rgba(43, 58, 85, 0.5);
  font-size: 11px;
  letter-spacing: 0.5em;
  text-align: center;
  text-indent: 0.5em;
}
.program-stars:last-child { margin: clamp(16px, 2vw, 22px) 0 0; }

.program-heading {
  margin: 0 0 clamp(14px, 1.8vw, 20px);
  font: 600 clamp(24px, 2.5vw, 32px)/1.16 var(--font-display);
  letter-spacing: 0.005em;
  color: var(--ink);
  text-align: center;
}

/* ---------------------------------------------------------------- cover */
.program-section--cover .program-card__scroll { text-align: center; }
.program-cover__eyebrow {
  margin: 0 0 6px;
  font: 600 clamp(12px, 1.2vw, 13px)/1.4 var(--font-ui);
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.program-cover__lead {
  margin: 0 0 clamp(10px, 1.4vw, 14px);
  font: italic 400 clamp(16px, 1.6vw, 19px)/1.4 var(--font-display);
  color: var(--ink-soft);
}
.program-cover__name {
  margin: 0 0 clamp(10px, 1.4vw, 14px);
  font: 600 clamp(30px, 4.4vw, 46px)/1.1 var(--font-display);
  letter-spacing: 0.004em;
  color: var(--ink);
  text-wrap: balance;
}
.program-cover__branch {
  margin: 0 0 clamp(18px, 2.4vw, 26px);
  padding-bottom: clamp(16px, 2.2vw, 24px);
  border-bottom: 1px solid rgba(46, 62, 92, 0.18);
  font: 600 clamp(13px, 1.3vw, 15px)/1.4 var(--font-ui);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.program-cover__place { margin: 0 0 6px; font-size: clamp(15px, 1.5vw, 17px); color: var(--ink); }
.program-cover__date { margin: 0; font-size: clamp(15px, 1.5vw, 17px); color: var(--ink-soft); }

/* ---------------------------------------------------------------- sequence of events */
.program-sequence {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: seq;
  display: grid;
  gap: clamp(9px, 1.1vw, 13px);
}
.program-sequence li {
  counter-increment: seq;
  display: grid;
  grid-template-columns: 2.1em 1fr;
  align-items: baseline;
  gap: 4px;
  font-size: clamp(16px, 1.45vw, 18px);
  line-height: 1.5;
  color: var(--ink);
}
.program-sequence li::before {
  content: counter(seq, decimal-leading-zero);
  font: 600 12px/1.6 ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  letter-spacing: 0.06em;
  color: rgba(43, 58, 85, 0.5);
}

/* ---------------------------------------------------------------- participants */
.program-participants { margin: 0; display: grid; gap: clamp(12px, 1.5vw, 17px); }
.program-participants__row {
  display: grid;
  gap: 2px;
  padding-bottom: clamp(10px, 1.3vw, 14px);
  border-bottom: 1px solid rgba(46, 62, 92, 0.12);
}
.program-participants__row:last-child { border-bottom: 0; padding-bottom: 0; }
.program-participants dt {
  font: 600 clamp(11.5px, 1.1vw, 12.5px)/1.4 var(--font-ui);
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.program-participants dd {
  margin: 0;
  font: 400 clamp(17px, 1.7vw, 20px)/1.35 var(--font-display);
  color: var(--ink);
}

/* ---------------------------------------------------------------- bios */
.program-bio__portrait {
  margin: 0 auto clamp(14px, 1.8vw, 18px);
  width: clamp(150px, 20vw, 196px);
}
.program-bio__portrait img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 4px;
  border: 1px solid rgba(46, 62, 92, 0.18);
  box-shadow: 0 8px 22px rgba(24, 34, 54, 0.18);
}
.program-bio__rank {
  margin: 0 0 3px;
  font: 600 clamp(11.5px, 1.1vw, 12.5px)/1.4 var(--font-ui);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-soft);
  text-align: center;
}
.program-bio__name { margin-bottom: 4px; }
.program-bio__branch {
  margin: 0 0 clamp(18px, 2.2vw, 24px);
  padding-bottom: clamp(16px, 2vw, 22px);
  border-bottom: 1px solid rgba(46, 62, 92, 0.18);
  font: 600 clamp(11.5px, 1.1vw, 12.5px)/1.4 var(--font-ui);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-soft);
  text-align: center;
}
@media (min-width: 900px) {
  .program-section--bio .program-card { width: min(720px, 100%); }
  .program-bio__head {
    display: grid;
    grid-template-columns: clamp(140px, 15vw, 172px) 1fr;
    align-items: center;
    gap: clamp(18px, 2.2vw, 26px);
    margin-bottom: clamp(18px, 2.2vw, 24px);
    padding-bottom: clamp(16px, 2vw, 22px);
    border-bottom: 1px solid rgba(46, 62, 92, 0.18);
  }
  .program-bio__head .program-bio__portrait { margin: 0; width: 100%; }
  .program-bio__head .program-bio__rank,
  .program-bio__head .program-bio__name,
  .program-bio__head .program-bio__branch { text-align: left; }
  .program-bio__head .program-bio__branch { margin: 0; padding: 0; border-bottom: 0; }
}

.program-bio__text { max-width: 64ch; margin: 0 auto; }
.program-bio__text p {
  margin: 0 0 clamp(13px, 1.5vw, 17px);
  font-size: clamp(16.5px, 1.4vw, 17.5px);
  line-height: 1.72;
  color: var(--ink);
  hanging-punctuation: first;
}
.program-bio__text p:last-child { margin-bottom: 0; }

/* ---------------------------------------------------------------- duty stations */
.program-stations {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: station;
  display: grid;
  gap: clamp(13px, 1.6vw, 18px);
}
@media (min-width: 900px) {
  .program-section:has(.program-stations) .program-card { width: min(760px, 100%); }
  .program-stations {
    display: block;
    columns: 2;
    column-gap: clamp(26px, 3vw, 40px);
    column-rule: 1px solid rgba(46, 62, 92, 0.12);
  }
  .program-stations li {
    break-inside: avoid;
    margin-bottom: clamp(13px, 1.6vw, 18px);
  }
}
.program-stations li {
  counter-increment: station;
  padding-left: 2.4em;
  padding-bottom: clamp(11px, 1.4vw, 15px);
  border-bottom: 1px solid rgba(46, 62, 92, 0.12);
  position: relative;
}
.program-stations li:last-child { border-bottom: 0; padding-bottom: 0; }
.program-stations li::before {
  content: counter(station, decimal-leading-zero);
  position: absolute;
  left: 0;
  top: 0.32em;
  font: 600 12px/1 ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  letter-spacing: 0.06em;
  color: rgba(43, 58, 85, 0.48);
}
.program-station__unit {
  margin: 0 0 2px;
  font: 600 clamp(16px, 1.5vw, 18px)/1.34 var(--font-display);
  color: var(--ink);
}
.program-station__base { margin: 0 0 4px; font-size: clamp(14.5px, 1.35vw, 16px); color: var(--ink); }
.program-station__dates {
  margin: 0;
  font: 400 clamp(12.5px, 1.2vw, 13.5px)/1.4 var(--font-ui);
  letter-spacing: 0.055em;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}

/* ---------------------------------------------------------------- collage
   Three across, with the family group spanning a whole row, which is how the printed page sets it.
   Two across on a phone, where the wide photo still takes the full width. */
.program-collage {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(7px, 0.9vw, 11px);
}
.program-collage li { margin: 0; }
.program-collage img {
  display: block;
  width: 100%;
  height: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  object-position: center 28%;            /* faces sit high in most of these frames */
  border-radius: 3px;
  background: rgba(46, 62, 92, 0.08);
}
.program-collage li:nth-child(4) { grid-column: 1 / -1; }
.program-collage li:nth-child(4) img { aspect-ratio: 1027 / 522; object-position: center 34%; }

/* Wide screens: the stage is landscape, so a three-across column of tiles wastes it and pushes
   most of the photographs out of view. Five across with square tiles puts all ten on one screen,
   the family group riding two cells at the end of the first row. */
@media (min-width: 1100px) {
  .program-card--wide { width: min(1180px, 100%); }
  .program-collage { grid-template-columns: repeat(5, 1fr); }
  .program-collage img { aspect-ratio: 1 / 1; }
  .program-collage li:nth-child(4) { grid-column: span 2; }
  .program-collage li:nth-child(4) img { aspect-ratio: auto; height: 100%; }
  /* Ten photographs and a double-width banner make eleven cells, so the last one would sit alone
     against the left edge. Centre it instead and it reads as the closing image. */
  .program-collage li:nth-child(10) { grid-column: 3; }
}

/* Phones: two across. The third photograph goes full width as well as the fourth, which keeps the
   pairs even so the grid never leaves a hole, and gives the banner a companion. */
@media (max-width: 719px) {
  .program-collage { grid-template-columns: repeat(2, 1fr); }
  .program-collage li:nth-child(3) { grid-column: 1 / -1; }
  /* Near its own 431:575, so going full width costs it almost no crop. */
  .program-collage li:nth-child(3) img { aspect-ratio: 4 / 5; object-position: center 42%; }
}

/* ---------------------------------------------------------------- narrow screens */
@media (max-width: 719px) {
  .program-section .chapter__stage { padding-block: 24px; }
  .program-card { max-height: calc(var(--stage-h) - 48px); }
  .program-card__scroll { padding: 20px 18px 22px; }
  .program-bio__text { max-width: none; }
}

@media (prefers-reduced-motion: reduce) {
  .program-card { transition: none; transform: none; opacity: 1; }
  .program-card__scroll { scroll-behavior: auto; }
}

/* ---------------------------------------------------------------- closing card
   Short by design: it sits high over the flightline as the camera lifts away. */
.program-card--song { width: min(520px, 100%); }
.program-section--song .program-card__scroll { text-align: center; }
.program-song__lyric { margin: 0; }
.program-song__lyric p {
  margin: 0 0 clamp(7px, 0.9vw, 10px);
  font: 400 clamp(16.5px, 1.6vw, 19px)/1.62 var(--font-display);
  color: var(--ink);
  text-wrap: balance;
}
.program-song__lyric p:last-child { margin-bottom: 0; }
.program-song__lyric:not(:empty) + .program-song__close {
  margin-top: clamp(18px, 2.2vw, 24px);
  padding-top: clamp(14px, 1.8vw, 18px);
  border-top: 1px solid rgba(46, 62, 92, 0.18);
}
.program-song__close {
  margin: 0;
  font: italic 400 clamp(15px, 1.5vw, 17px)/1.5 var(--font-display);
  color: var(--ink-soft);
}

/* ---------------------------------------------------------------- touch screens: nothing scrolls inside
   On a phone or tablet no card scrolls inside itself. Nested scrolling was the whole problem there:
   a card that scrolls internally, inside a sticky stage that slides and fades in, is often not
   recognised as scrollable by iOS until it has been tapped, and every attempt to hand a gesture from
   the card to the page from JavaScript fought the platform's own momentum. With no nested scroller
   there is nothing to capture a gesture, so every swipe moves the page.

   Keyed on the input, not the width: `(hover: none) and (pointer: coarse)` is a touch-first device.
   A desktop with a mouse keeps scrolling cards at every window size.

   A card that fits the screen keeps the sticky stage and holds still while the camera moves, as
   before. A card taller than the screen (js/program.js marks its section `is-long`) cannot be held,
   because its lower half would never come into view, so its stage stops being sticky and the card
   scrolls past with the page, centred in its section. The section keeps its --chapter-h as a
   minimum and only grows if the card is taller than that. The camera
   is still driven by page scroll against each section's position, so the path is unchanged. */
@media (hover: none) and (pointer: coarse) {
  /* Last in the file and scoped to the section, so it outranks every width rule above
     (the phone rule caps .program-card at --stage-h - 48px). */
  .program-section .program-card { max-height: none; overflow: visible; }
  .program-section .program-card__scroll { overflow: visible; }
  .program-section .program-card[data-scroll="1"]::after { content: none; }

  .program-section.is-long {
    display: flex;
    flex-direction: column;
    height: auto;
    min-height: var(--chapter-h, 180vh);
  }
  .program-section.is-long .chapter__stage {
    position: relative;
    top: auto;
    flex: 1 0 auto;
    height: auto;
  }
  /* Nothing to fade in: the card arrives by scrolling, and the top of a long bio is read while the
     previous chapter is still the "current" one. */
  .program-section.is-long .program-card { opacity: 1; transform: none; transition: none; }
}
