/* Program section — merged into index.html's #program (was a standalone
   draft page). Reuses design tokens (--blue/--green/--font/etc.) defined
   in style.css, loaded first.

   Structure: #program > .program-scroller > .program-sticky. The
   scroller is given extra height by program.js (100vh + one "step" per
   extra session) purely to create scroll distance; .program-sticky
   (position:sticky, exactly 100vh) rides pinned at the top of the
   viewport for that whole distance, so it reads as a single full-screen
   carousel even though the page keeps scrolling through it — and once
   the scroller's height runs out, it un-sticks and normal page scroll
   continues into the next section. See program.js for how scroll
   position maps to the carousel's "progress". */

#program {
  position: relative;
  background: var(--bg-section);
  color: var(--ink-light);
}

/* Mobile-only vertical scroll-progress rail (see @media 560px below for
   the one place it's actually shown). Width is a comfortable tap target;
   the visible line is the thinner ::before centered inside it, with
   .carousel-progress-thumb (positioned/sized by program.js each scroll
   tick) riding on top of it. */
.carousel-progress {
  display: none;
}

.program-sticky {
  --pane-height: 236px; /* kept in sync with .session-card's height per
    breakpoint, so the day numeral's bottom (anchored off this) always
    lines up with the scroll pane's bottom edge */
  --pane-left: clamp(360px, 30vw, 460px); /* kept in sync with
    .session-card's left edge per breakpoint, so the day numeral can
    anchor its right edge a fixed gap away from the pane */
  --pane-width: min(680px, 54vw); /* drives .session-card's own width too,
    so .carousel-heading can size itself to exactly match the pane */
  --rail-gap: 48px;
  --heading-gap: 20px;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
}

/* Soft green glow behind the day numeral and the carousel panes, matching
   the COKPIT/assets/programs.jpeg reference. */
.program-sticky::before {
  content: "";
  position: absolute;
  top: 50%; left: clamp(40px, 6vw, 120px);
  z-index: 0;
  width: 680px; height: 680px;
  transform: translateY(-50%);
  border-radius: 50%;
  background: radial-gradient(circle, rgba(60,182,74,0.38), rgba(60,182,74,0.14) 45%, transparent 72%);
  filter: blur(10px);
  pointer-events: none;
}

/* ============ Day rail ============
   Only the active day's numeral is shown — "1" and "2" occupy the same
   spot and crossfade into each other rather than both being visible. */
.day-rail {
  /* Bottom-anchored at the same line as the scroll pane's bottom edge
     (pane is centered at 50% with height --pane-height), rather than
     centering the rail independently — keeps the numeral's bottom and
     the pane's bottom aligned, matching the programs.jpeg reference.
     Horizontally it's just an anchor LINE (zero-width) sitting a fixed
     gap left of the pane — markers right-align to it (see below) so "1"
     and "2" share one right edge next to the pane despite their very
     different natural widths, instead of both starting from the same
     left edge and ending at different distances from the pane. */
  position: absolute;
  bottom: calc(50% - (var(--pane-height, 236px) / 2));
  left: calc(var(--pane-left, 460px) - var(--rail-gap, 48px));
  z-index: 10;
}
.day-marker {
  position: absolute;
  bottom: 0; right: 0; left: auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.4rem;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s ease;
}
.day-marker.is-active { opacity: 1; pointer-events: auto; }
.day-marker img {
  /* Sized by height, not width — "1" and "2" have very different natural
     aspect ratios, so matching width alone made "2" look much smaller.
     These bounds reproduce "1"'s previous on-screen size exactly. */
  height: clamp(161px, 19.4vw, 290px);
  width: auto;
  max-width: none; /* global `img{max-width:100%}` was clamping "2"'s
    wider natural width against its shrink-to-fit flex-item container,
    squashing it horizontally instead of letting it scale down cleanly */
  transform-origin: right bottom; /* grow up-and-left on activate so
    both the numeral's bottom edge (pane-aligned) and its right edge
    (rail-anchor-aligned, closest to the pane) stay pinned in place */
  transform: scale(1);
  transition: transform 0.45s cubic-bezier(.2,.8,.2,1);
}
.day-marker.is-active img { transform: scale(1.35); }
.day-marker span {
  font: 600 1rem var(--font);
  color: var(--ink-light);
  transition: font-size 0.4s ease, margin-bottom 0.45s cubic-bezier(.2,.8,.2,1);
}
/* Active img scales 1.35x from its bottom edge, so its (unscaled-layout)
   top rises by height*0.35 — push the label up by the same amount so the
   bigger glyph never grows back up into it. */
.day-marker.is-active span {
  font-size: 1.15rem;
  margin-bottom: calc(clamp(161px, 19.4vw, 290px) * 0.35);
}

/* ============ Heading ============ */
.carousel-heading {
  /* Sized and positioned off the same --pane-left/--pane-width/--pane-height
     vars as .session-card and .day-rail, so it sits flush above the pane
     (left edge aligned with the pane's left edge) instead of floating
     independently in the corner of the viewport. */
  position: absolute;
  left: var(--pane-left, 460px);
  width: var(--pane-width, 680px);
  bottom: calc(50% + (var(--pane-height, 236px) / 2) + var(--heading-gap, 20px));
  z-index: 10;
  text-align: left;
}
.carousel-heading p { font-size: 1rem; color: var(--muted-light); }
.carousel-heading h2 {
  margin-top: 0.3rem;
  font: 600 clamp(1.6rem, 3vw, 2.2rem)/1.15 var(--font);
  letter-spacing: -0.01em;
}
.carousel-heading h2 span { color: var(--green); }

/* ============ Carousel ============
   Radial layout: every session's PHOTO rides a big circle whose center
   sits off-screen to the right of the active slot — up-right for cards
   before the active one, down-right for cards after it, exactly like
   watching a wheel turn, regardless of scroll direction. The photo carries
   its own wheel transform independent of the pane, so the pane can stay
   perfectly still (plain fade, see program.jpeg reference) while the photo
   still animates. At rest (delta=0) the photo lands exactly inside the
   pane's reserved frame slot on its right edge, so the pane's border reads
   as wrapping the photo — JS sets --dx/--dy/--rot/--scale/--opacity/--blur
   on .card-photo-wheel and --pane-opacity on .card-pane. */
.carousel {
  position: relative;
  z-index: 2;
  height: 100%;
  overflow: hidden;
}

.carousel-track {
  position: absolute;
  inset: 0;
}

.session-card {
  position: absolute;
  top: 50%;
  left: var(--pane-left, 460px);
  width: var(--pane-width, 680px);
  height: var(--pane-height, 236px);
  transform: translateY(-50%);
}

/* ---- the text pane: fixed in place, a plain fade, border reserves a
   frame slot on the right for the photo ---- */
.card-pane {
  position: absolute;
  inset: 0;
  padding: 1.75rem 2rem;
  padding-right: calc(300px + 2rem);
  border: 1px solid #e2e2e2;
  border-radius: 28px;
  background: none;
  text-align: center;
  display: flex;
  flex-direction: column;
  justify-content: center;
  opacity: var(--pane-opacity, 0);
  pointer-events: none;
  transition: opacity 0.3s ease;
}
.session-quote {
  position: absolute;
  top: 0.75rem; left: 1.25rem;
  width: 56px;
  height: auto;
  opacity: 0.45;
  pointer-events: none;
}

/* ---- the photo: its own independent wheel transform. At rest it sits
   inset in the pane's reserved right-hand slot. ---- */
.card-photo-wheel {
  position: absolute;
  top: 50%;
  right: 16px;
  z-index: 2;
  width: 300px;
  height: 204px;
  border-radius: 22px;
  background: none;
  border: 1px solid #e6e6e6;
  display: flex;
  align-items: center;
  justify-content: center;
  transform:
    translateY(-50%)
    translate(var(--dx, 0px), var(--dy, 0px))
    rotate(var(--rot, 0deg))
    scale(var(--scale, 1));
  opacity: var(--opacity, 1);
  filter: blur(var(--blur, 0px));
  will-change: transform, opacity, filter;
}
.card-photo-wheel img:first-child {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 22px; /* rounds the photo itself now that the parent no
    longer clips with overflow:hidden — that clip was also cutting off
    .photo-mic, which pokes out past the parent's left edge */
}
.photo-mic {
  position: absolute;
  z-index: 3;
  left: -14px; top: 50%;
  transform: translateY(-50%);
  width: 32px; height: auto;
  filter: drop-shadow(0 3px 8px rgba(0,0,0,0.3));
}
.placeholder-icon { width: 34%; height: 34%; color: var(--muted-light); }
.high-table { width: 46%; height: 46%; color: var(--muted-light); }
.session-time {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.4em;
  font: 500 0.75rem var(--font-alt);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted-light);
}
.session-time .dot { color: var(--green); font-size: 0.5rem; }
.session-title {
  position: relative;
  margin-top: 1.1rem;
  font: 600 clamp(1.1rem, 1.9vw, 1.5rem)/1.3 var(--font);
}
.session-person { position: relative; margin-top: 1.3rem; }
.person-name { font: 600 1rem var(--font); }
.person-role { margin-top: 0.2rem; font-size: 0.85rem; color: var(--muted-light); }

/* ============ View agenda ============
   Base pill styling — no longer placed in #program (see .agenda-toggle
   below for that), but still used by the Speakers section's own
   "Download Agenda" button (.view-agenda--speakers in style.css), which
   relies on this for shape/border/font/shadow. */
.view-agenda {
  position: absolute;
  bottom: clamp(1.25rem, 3vh, 2rem);
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  display: inline-flex;
  align-items: center;
  gap: 0.4em;
  padding: 0.6rem 1.3rem;
  border: 1px solid #e7e7e7;
  border-radius: 56px;
  background: #fff;
  color: #1c1b1f;
  font: 500 0.8rem var(--font-alt);
  box-shadow: 0 4px 14px rgba(0,0,0,0.08);
}

/* ============ Agenda day toggle (Program section) ============
   Split pill replacing the old single "View Agenda" link — same pill
   shape/position as .view-agenda above, but two independently clickable
   halves. Each opens the matching day's agenda image in #agenda-modal
   (see program.js) and fills with the Program section's green accent
   on hover. */
.agenda-toggle {
  position: absolute;
  bottom: clamp(1.25rem, 3vh, 2rem);
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  display: flex;
  border: 1px solid #e7e7e7;
  border-radius: 56px;
  background: #fff;
  box-shadow: 0 4px 14px rgba(0,0,0,0.08);
  overflow: hidden;
}
.agenda-toggle-half {
  appearance: none;
  border: none;
  background: transparent;
  color: #1c1b1f;
  font: 500 0.8rem var(--font-alt);
  padding: 0.6rem 1.6rem;
  cursor: pointer;
  transition: background 0.25s ease, color 0.25s ease;
}
.agenda-toggle-half:first-child { border-right: 1px solid #e7e7e7; }
.agenda-toggle-half:hover,
.agenda-toggle-half:focus-visible {
  background: var(--green);
  color: #fff;
}

/* ============ Agenda image modal ============
   Lives at the body level (see index.html, right after <footer>) so it
   overlays the whole page above every section's own stacking context. */
.agenda-modal {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 1000;
  align-items: center;
  justify-content: center;
  padding: 32px;
}
.agenda-modal.is-open { display: flex; }
.agenda-modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(10, 14, 22, 0.78);
}
.agenda-modal-panel {
  position: relative;
  max-width: min(640px, 92vw);
  max-height: 90vh;
  display: flex;
  background: #fff;
  border-radius: 20px;
  overflow: hidden;
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.35);
}
.agenda-modal-img { display: block; width: 100%; max-height: 90vh; object-fit: contain; }
.agenda-modal-close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: rgba(10, 14, 22, 0.55);
  color: #fff;
  font-size: 1.3rem;
  line-height: 1;
  cursor: pointer;
  transition: background 0.2s ease;
}
.agenda-modal-close:hover { background: var(--green); }

/* Mobile: the panel fills the screen instead of floating as a card, and
   the close button pins to the top-right corner of the viewport. */
@media (max-width: 560px) {
  .agenda-modal { padding: 0; }
  .agenda-modal-panel {
    width: 100vw;
    height: 100vh;
    max-width: 100vw;
    max-height: 100vh;
    border-radius: 0;
  }
  .agenda-modal-img { max-height: 100vh; }
  .agenda-modal-close { top: 16px; right: 16px; }
}

/* ============ Responsive ============ */
@media (max-width: 900px) {
  /* .session-card is centered at this width — express that centering as
     an explicit left edge (50% - width/2) so .day-rail and
     .carousel-heading, which both anchor off --pane-left, stay in sync
     with it instead of needing their own translateX(-50%) hack. */
  .program-sticky {
    --pane-height: 172px;
    --pane-width: min(520px, 86vw);
    --pane-left: calc(50% - var(--pane-width) / 2);
    --rail-gap: 32px;
    --heading-gap: 14px;
  }
  .card-pane { padding: 1.5rem; padding-right: calc(190px + 1.5rem); }
  .card-photo-wheel { width: 190px; height: 140px; right: 12px; }
  .photo-mic { width: 26px; }
}

@media (max-width: 560px) {
  .program-sticky {
    --pane-height: 380px; /* now the whole stacked card (photo band +
      text), not just a side-by-side strip — see .session-card below */
    --pane-width: min(340px, 90vw);
    --pane-left: calc(50% - var(--pane-width) / 2);
    --heading-gap: 10px;
  }

  /* Day rail: at this width the pane alone can be ~90vw, so there's no
     room left to sit the numeral beside it (the --pane-left/--rail-gap
     anchor used at every wider breakpoint would push "1"/"2" off the
     left edge of the screen). Pin it to a small fixed corner instead —
     guarantees it always stays fully visible — and drop the active-state
     grow/shift animation, which only makes sense with room to spare. */
  .day-rail {
    /* top offset clears the site's fixed header (.site-header, ~75px
       tall incl. padding) so the day numeral doesn't sit underneath it */
    bottom: auto;
    top: 88px;
    left: 14px;
  }
  .day-marker {
    bottom: auto; top: 0; left: 0; right: auto;
    align-items: flex-start;
  }
  .day-marker img { height: clamp(52px, 15vw, 76px); }
  .day-marker.is-active img { transform: none; }
  .day-marker.is-active span { margin-bottom: 0; font-size: 1rem; }

  /* Scroll-progress rail, right edge, thumb tracks --progress-rail-* vars
     program.js sets on every scroll tick. Tapping anywhere in the rail
     jumps to the nearest session (see program.js click handler). */
  .carousel-progress {
    display: block;
    position: absolute;
    top: 50%;
    right: 0;
    z-index: 3;
    width: 28px;
    height: min(240px, 60vh);
    transform: translateY(-50%);
    cursor: pointer;
  }
  .carousel-progress::before {
    content: "";
    position: absolute;
    right: 6px; top: 0; bottom: 0;
    width: 4px;
    background: rgba(255, 255, 255, 0.55);
    border-radius: 999px;
    box-shadow: 0 0 4px rgba(0, 0, 0, 0.25);
  }
  .carousel-progress-thumb {
    position: absolute;
    right: 6px;
    top: 0;
    width: 6px;
    background: #fff;
    border-radius: 999px;
    box-shadow: 0 0 6px rgba(0, 0, 0, 0.35);
  }

  /* Session card: stacked (photo/icon band on top, text below) instead
     of the wider breakpoints' side-by-side overlap, which needs more
     horizontal room than a phone has.

     All 17 cards sit absolutely positioned at this exact same spot (only
     their *children*'s opacity/transform normally signal which one is
     active) — on wider breakpoints that's fine because only .card-pane
     carries a background, faded via --pane-opacity. Here the whole card
     is a single bordered unit, so the card ITSELF now has to fade with
     --pane-opacity too, or every inactive card stacks on top and blanks
     out the active one entirely (this was the "only the last card shows,
     everything else is blank" bug). The wheel's dx/dy/rotate/scale
     "ride off to the side" transform is dropped too — it was built for
     the photo to separate from a stationary pane, which doesn't apply
     once they're one fading unit; cards now simply cross-fade in place
     as you scroll. */
  .session-card {
    display: flex;
    flex-direction: column;
    border-radius: 22px;
    overflow: hidden;
    border: 1px solid #e2e2e2;
    opacity: var(--pane-opacity, 0);
  }
  .card-photo-wheel {
    position: relative;
    top: auto; right: auto;
    flex-shrink: 0;
    width: 100%;
    height: 50%; /* photo band is exactly half the card; .card-pane
      (flex: 1 1 auto) fills the other half */
    border-radius: 0;
    background: none;
    border: none;
    box-shadow: none;
    transform: none;
    opacity: 1;
    filter: none;
  }
  .card-photo-wheel img:first-child { border-radius: 0; }
  .photo-mic {
    left: auto; right: 10px; top: auto; bottom: 10px;
    transform: none;
    width: 24px;
  }

  .card-pane {
    position: relative;
    inset: auto;
    flex: 1 1 auto;
    min-height: 0;
    padding: 1rem 1.25rem;
    border: none;
    border-radius: 0;
    background: none;
    justify-content: flex-start;
    overflow: auto;
  }
  .session-title { font-size: 0.95rem; }

  .carousel-heading h2 { font-size: 1.5rem; }
}
