/* ============================================================
   bootcamp-event-single.css — page-specific styles for
   single-bootcamp_event.php. Loaded on /bootcamps/{slug}/.

   State-conditional layout, single stylesheet — both recap and
   upcoming branches share this file. State-specific rules are
   scoped under [data-cohort-state="recap"] or
   [data-cohort-state="upcoming"].

   Anchors:
     - flibbr-design-mockup-final-bootcamp-recap-bengaluru-april-2026.html
       (locked 30 April 2026) — recap state
     - flibbr-design-mockup-final-bootcamp-upcoming-bengaluru-august-2026.html
       (locked 30 April 2026) — upcoming state

   Phase-1 audit at v0.5.49 confirmed:
     .recap-header-*    — byte-identical between canonicals (lifted here)
     .recap-modules-*   — byte-identical between canonicals (lifted here)
     .recap-faculty-*   — byte-identical between canonicals (lifted here)
     .recap-tail-paths  — lifted to base.css (op-learning #16, 7th)
     .case-hero-*       — lifted to base.css (op-learning #16, 8th)

   v0.5.49 brace-balance integrity gate: all sections sed-extracted
   with verified-correct ranges (lines including the section's
   final closing brace) per op-learning #9 reinforcement.

   @package Flibbr
   @since   0.5.49
============================================================ */


/* ----------------------------------------------------------
   1. RECAP HEADER (shared between recap + upcoming)
   Recap canonical lines 2169-2210 (verbatim).
---------------------------------------------------------- */

  .recap-header {
    padding-block: var(--s-9) var(--s-6);
    border-bottom: 1px solid var(--rule-soft);
  }
  .recap-header-kicker {
    font-family: var(--sans); font-weight: 600;
    font-size: 11px; line-height: 1; letter-spacing: 0.18em;
    text-transform: uppercase; color: var(--accent);
    margin-bottom: var(--s-5);
  }
  .recap-header-headline {
    margin: 0 0 var(--s-5);
    max-width: 22ch;
    font-family: var(--serif); font-weight: 400;
    font-size: clamp(36px, 5.5vw, 68px); line-height: 1.06;
    letter-spacing: -0.018em; color: var(--ink);
  }
  .recap-header-headline em { font-style: italic; }

  /* sub-deck — single sentence in serif, sits between H1 and meta */
  .recap-header-deck {
    margin: 0 0 var(--s-6);
    max-width: 56ch;
    font-family: var(--serif); font-weight: 400;
    font-size: clamp(20px, 1.8vw, 24px); line-height: 1.45;
    color: var(--ink-soft); font-style: italic;
  }

  /* facts strip — sans, uppercase, dot-separated */
  .recap-header-meta {
    display: flex; flex-wrap: wrap;
    gap: var(--s-3) var(--s-4);
    font-family: var(--sans); font-weight: 400;
    font-size: 12px; line-height: 1.5;
    letter-spacing: 0.06em; text-transform: uppercase;
    color: var(--ink-quiet);
  }
  .recap-header-meta strong { font-weight: 600; color: var(--ink); }
  .recap-header-meta > * + *::before {
    content: "·"; margin-right: var(--s-3);
    color: var(--rule);
  }


/* ----------------------------------------------------------
   2. RECAP GALLERY family (recap state only)
   Recap canonical lines 2383-2536 (verbatim).
---------------------------------------------------------- */

  .page-prose .recap-gallery {
    margin-block: var(--s-7);
    max-width: none;
  }

  /* HERO frame — 16:10, click → lightbox.
     v5 fix: added `display: block; width: 100%; border: 0;
     padding: 0; font: inherit;` to override <button> user-agent
     defaults. Without these, the button rendered as inline-block
     with intrinsic content width — collapsing to near-zero
     because the centered display is position: absolute (taken
     out of flow). aspect-ratio couldn't compute height from
     no width. The thumbnails worked anyway because the strip's
     grid-auto-columns gave them explicit width; the hero had
     no such hand-holding. */
  .page-prose .recap-gallery-hero {
    display: block;
    width: 100%;
    border: 0;
    padding: 0;
    font: inherit;
    /* Ship v0.5.163 — gallery hero ratio changed from 16:10 to 3:2,
       aligning with lightbox (v0.5.161) and homepage 3-up grid (v0.5.161).
       cohort_gallery now has a single 3:2 source-of-truth across all
       four major consuming surfaces; the recap-gallery-thumb strip stays
       4:3 (small, cover-crop tolerant). */
    aspect-ratio: 3 / 2;
    background: var(--paper-warm);
    position: relative; overflow: hidden;
    border-radius: 4px;
    background-image: linear-gradient(135deg, rgba(20,20,19,.05) 0%, rgba(20,20,19,.01) 50%, rgba(20,20,19,.09) 100%);
    cursor: zoom-in;
    transition: filter var(--motion-duration-ui) var(--motion-ease-ui);
  }
  .page-prose .recap-gallery-hero:hover {
    filter: brightness(0.97);
  }
  .page-prose .recap-gallery-hero::before {
    /* image counter — content is set inline via data attribute
       in the mockup, since the hero is the active thumb */
    content: attr(data-label);
    position: absolute;
    bottom: var(--s-3); left: var(--s-3);
    font-family: var(--sans); font-size: 11px;
    letter-spacing: 0.18em; text-transform: uppercase;
    color: var(--ink-quiet);
    z-index: 2;
  }
  .page-prose .recap-gallery-hero::after {
    /* zoom-in glyph at top-right indicates lightbox.
       v0.5.136: SVG mask-image replaces ↗ U+2197 per op-learning #72 /
       playbook §5.3 (Safari emoji substitution). Sizing matches the prior
       font-size: 18px glyph footprint (~18px square). */
    content: "";
    position: absolute;
    top: var(--s-3); right: var(--s-4);
    display: inline-block;
    width: 18px; height: 18px;
    background-color: var(--ink-quiet);
    -webkit-mask: var(--arrow-svg-diagonal) no-repeat center / contain;
            mask: var(--arrow-svg-diagonal) no-repeat center / contain;
    z-index: 2;
    transition: background-color var(--motion-duration-ui) var(--motion-ease-ui), transform var(--motion-duration-ui) var(--motion-ease-ui);
  }
  .page-prose .recap-gallery-hero:hover::after {
    background-color: var(--ink);
    transform: translate(2px, -2px);
  }

  /* placeholder display — large centered image identifier inside
     the hero. In the mockup, this is what makes the swap visible.
     In production, a real image overlays this and the
     .recap-gallery-hero-display element is hidden via the
     :has-real-image hook (background-image set on hero), or
     simply outside the lit pixels of the photo.

     Two-line typography: a large numeral, a small "of N" suffix.
     Numerals tabular for swap stability. */
  .page-prose .recap-gallery-hero-display {
    position: absolute; inset: 0;
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    gap: var(--s-2);
    pointer-events: none;        /* clicks fall through to the hero button */
  }
  .page-prose .recap-gallery-hero-display .display-num {
    font-family: var(--serif); font-weight: 400;
    font-size: clamp(72px, 10vw, 140px);
    line-height: 1;
    letter-spacing: -0.02em;
    color: rgba(20,20,19,0.32);
    font-variant-numeric: tabular-nums;
  }
  .page-prose .recap-gallery-hero-display .display-suffix {
    font-family: var(--sans); font-weight: 600;
    font-size: 11px; letter-spacing: 0.20em;
    text-transform: uppercase;
    color: rgba(20,20,19,0.45);
  }

  /* STRIP — horizontal scrolling row of thumbnails */
  .page-prose .recap-gallery-strip {
    margin-top: var(--s-4);
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 120px;
    gap: var(--s-3);
    overflow-x: auto;
    scroll-snap-type: x proximity;
    padding-bottom: var(--s-3);
    /* subtle scrollbar styling — visible enough to communicate
       scrollability, quiet enough not to dominate */
    scrollbar-color: var(--rule) transparent;
    scrollbar-width: thin;
  }
  .page-prose .recap-gallery-strip::-webkit-scrollbar { height: 6px; }
  .page-prose .recap-gallery-strip::-webkit-scrollbar-track { background: transparent; }
  .page-prose .recap-gallery-strip::-webkit-scrollbar-thumb {
    background: var(--rule);
    border-radius: 3px;
  }
  @media (max-width: 720px) {
    .page-prose .recap-gallery-strip { grid-auto-columns: 100px; }
  }

  .page-prose .recap-gallery-thumb {
    aspect-ratio: 4 / 3;
    background: var(--paper-warm);
    position: relative; overflow: hidden;
    border-radius: 3px;
    background-image: linear-gradient(135deg, rgba(20,20,19,.06) 0%, rgba(20,20,19,.02) 50%, rgba(20,20,19,.10) 100%);
    cursor: pointer;
    border: 0;
    padding: 0;
    scroll-snap-align: start;
    outline: 2px solid transparent;
    outline-offset: 2px;
    transition: outline-color var(--motion-duration-ui) var(--motion-ease-ui),
                filter var(--motion-duration-ui) var(--motion-ease-ui);
  }
  .page-prose .recap-gallery-thumb:hover { filter: brightness(0.95); }
  .page-prose .recap-gallery-thumb.is-active {
    outline-color: var(--accent);
  }
  .page-prose .recap-gallery-thumb:focus-visible {
    outline-color: var(--accent);
  }
  .page-prose .recap-gallery-thumb::before {
    content: attr(data-index);
    position: absolute;
    bottom: var(--s-2); left: var(--s-2);
    font-family: var(--sans); font-weight: 600;
    font-size: 9px; letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--ink-quiet);
  }

  /* gallery caption — small, single line, sits beneath strip */
  .page-prose .recap-gallery-caption {
    margin-top: var(--s-3);
    font-family: var(--sans); font-size: 12px;
    color: var(--ink-quiet);
    line-height: 1.5;
  }
  .page-prose .recap-gallery-caption em { font-style: italic; }


/* ----------------------------------------------------------
   3. RECAP MODULES family (shared between recap + upcoming)
   Recap canonical lines 2680-2754 (verbatim).
---------------------------------------------------------- */

  .page-prose .recap-modules {
    margin-block: var(--s-7);
    max-width: none;
  }
  .page-prose .recap-modules-grid {
    display: grid; grid-template-columns: repeat(3, 1fr);
    gap: var(--s-7) var(--s-6);
  }
  @media (max-width: 880px) {
    .page-prose .recap-modules-grid {
      grid-template-columns: 1fr; gap: var(--s-6);
    }
  }
  .page-prose .recap-modules-day {
    display: flex; flex-direction: column;
    gap: var(--s-4);
  }
  .page-prose .recap-modules-day-label {
    font-family: var(--sans); font-weight: 600;
    font-size: 11px; line-height: 1.2;
    letter-spacing: 0.16em; text-transform: uppercase;
    color: var(--ink-quiet);
    padding-top: var(--s-3);
    border-top: 1px solid var(--ink);
  }
  /* day theme — italic serif sub-line under the day label.
     Identifies the editorial spine of the day (e.g.,
     'Brand · Customer'). */
  .page-prose .recap-modules-day-theme {
    font-family: var(--serif); font-weight: 400;
    font-style: italic;
    font-size: 14px; line-height: 1.4;
    color: var(--ink-soft);
    margin-top: calc(var(--s-2) * -1);   /* pull closer to day label */
  }
  .page-prose .recap-modules-list {
    list-style: none; padding: 0; margin: 0;
    display: flex; flex-direction: column;
  }
  .page-prose .recap-modules-list li {
    padding: var(--s-4) 0;
    border-bottom: 1px solid var(--rule-soft);
    display: flex; flex-direction: column;
    gap: var(--s-2);
  }
  .page-prose .recap-modules-list li:first-child { padding-top: var(--s-3); }
  .page-prose .recap-modules-list li:last-child { border-bottom: 0; }
  .page-prose .recap-modules-title {
    font-family: var(--serif); font-weight: 400;
    font-size: 17px; line-height: 1.35;
    color: var(--ink);
  }
  .page-prose .recap-modules-title em { font-style: italic; }
  .page-prose .recap-modules-architect {
    font-family: var(--sans); font-weight: 400;
    font-size: 11px; line-height: 1.4;
    letter-spacing: 0.06em;
    color: var(--ink-quiet);
  }
  /* practice-row variant — Angira's body/breath/embodiment
     thread that runs alongside the taught sessions. Quieter,
     all-sans, smaller — visually subordinate to the taught
     modules without disappearing entirely. */
  .page-prose .recap-modules-list li.is-practice {
    padding: var(--s-3) 0;
  }
  .page-prose .recap-modules-list li.is-practice .recap-modules-title {
    font-family: var(--sans); font-weight: 500;
    font-size: 13px; line-height: 1.4;
    color: var(--ink-soft); font-style: normal;
  }
  .page-prose .recap-modules-list li.is-practice .recap-modules-architect {
    font-size: 10px;
    color: var(--ink-quiet);
  }


/* ----------------------------------------------------------
   4. RECAP FACULTY family (shared between recap + upcoming)
   Recap canonical lines 2291-2356 (verbatim).
---------------------------------------------------------- */

  .page-prose .recap-faculty {
    margin-block: var(--s-7);
    max-width: none;
  }
  .page-prose .recap-faculty-grid {
    display: grid; grid-template-columns: repeat(3, 1fr);
    gap: var(--s-6) var(--s-5);
  }
  @media (max-width: 880px) {
    .page-prose .recap-faculty-grid {
      grid-template-columns: repeat(2, 1fr);
      gap: var(--s-5) var(--s-4);
    }
  }
  @media (max-width: 560px) {
    .page-prose .recap-faculty-grid {
      grid-template-columns: 1fr;
    }
  }
  .page-prose .recap-faculty-card {
    display: flex; flex-direction: column;
    gap: var(--s-3);
  }
  /* Ship v0.5.161 — faculty portrait ratio changed from 1:1 to 4:5
     per recap-page editorial direction. ACF instruction strings updated
     in lockstep (faculty_guest_portrait, etc.). */
  .page-prose .recap-faculty-portrait {
    aspect-ratio: 4 / 5;
    background: var(--paper-warm);
    position: relative; overflow: hidden;
    border-radius: 4px;
    background-image: linear-gradient(135deg, rgba(20,20,19,.05) 0%, rgba(20,20,19,.01) 50%, rgba(20,20,19,.09) 100%);
  }
  .page-prose .recap-faculty-portrait::before {
    content: "portrait";
    position: absolute;
    bottom: var(--s-3); left: var(--s-3);
    font-family: var(--sans); font-size: 10px;
    letter-spacing: 0.18em; text-transform: uppercase;
    color: var(--ink-quiet);
  }
  /* Ship v0.5.162 — suppress the "portrait" placeholder label when
     PHP renders an inline background-image URL on the portrait div.
     Same selector pattern as the v0.5.160 .recap-image-small.alt
     cascade fix. The base "portrait" label remains visible on the
     empty-fallback branch (cohort-faculty-grid.php line ~113) so
     editors see a missing-content signal when no portrait is set.
     The sibling-surface sweep landed across v0.5.162 (this rule),
     v0.5.163 (.dispatch-featured-image + .teaser-extract), and
     v0.5.165 (.teaser-image deleted as dead code; the dispatch
     teaser grid was removed from the homepage in the v0.5.99 / v169
     redesign and the render helper was an orphan). .case-figure-frame
     was closed as working-as-intended (PHP only emits the placeholder
     when image truly missing — correct empty-state signal). */
  .page-prose .recap-faculty-portrait[style*="background-image"]::before {
    content: none;
  }
  .page-prose .recap-faculty-name {
    margin: 0;
    font-family: var(--serif); font-weight: 400;
    font-size: clamp(18px, 1.5vw, 20px); line-height: 1.25;
    color: var(--ink);
    letter-spacing: -0.005em;
  }
  .page-prose .recap-faculty-role {
    margin: 0;
    font-family: var(--sans); font-weight: 400;
    font-size: 11px; line-height: 1.4;
    letter-spacing: 0.14em; text-transform: uppercase;
    color: var(--ink-quiet);
  }

  /* special-guest variant — Day 2 founder chat. Same card shape
     as a faculty card; differentiated via accent kicker line.
     Used for the Bengaluru cohort's Day 2 founder conversation
     with Dasarathi GV (CEO, Leanworx). Future cohorts may or
     may not have a guest; the variant exists in the chassis
     for reuse. */
  .page-prose .recap-faculty-card.is-special-guest .recap-faculty-kicker {
    font-family: var(--sans); font-weight: 600;
    font-size: 10px; line-height: 1;
    letter-spacing: 0.18em; text-transform: uppercase;
    color: var(--accent);
    margin: 0 0 calc(var(--s-2) * -1);
  }


/* ----------------------------------------------------------
   5. RECAP TESTIMONIALS family (shared between recap + upcoming)
   Recap canonical lines 2762-2850 (verbatim).
---------------------------------------------------------- */

  .page-prose .recap-testimonials {
    margin-block: var(--s-7);
    max-width: none;
  }
  .page-prose .recap-testimonials-grid {
    display: grid; grid-template-columns: repeat(2, 1fr);
    gap: var(--s-6) var(--s-7);
  }
  @media (max-width: 720px) {
    .page-prose .recap-testimonials-grid {
      grid-template-columns: 1fr;
      gap: var(--s-6);
    }
  }
  .page-prose .recap-testimonial {
    display: flex; flex-direction: column;
    gap: var(--s-4);
  }

  /* TEXT testimonial — large pull-quote in serif italic,
     attribution beneath in sans-caps. */
  .page-prose .recap-testimonial.is-text .recap-testimonial-quote {
    margin: 0;
    font-family: var(--serif); font-weight: 400;
    font-style: italic;
    font-size: clamp(20px, 1.8vw, 24px); line-height: 1.4;
    color: var(--ink);
    letter-spacing: -0.005em;
  }
  .page-prose .recap-testimonial.is-text .recap-testimonial-quote::before {
    content: "\201C";  /* opening curly double-quote */
    color: var(--ink-quiet);
    margin-right: 2px;
  }
  .page-prose .recap-testimonial.is-text .recap-testimonial-quote::after {
    content: "\201D";  /* closing curly double-quote */
    color: var(--ink-quiet);
    margin-left: 2px;
  }

  /* VIDEO testimonial — 16:9 frame with placeholder + caption */
  .page-prose .recap-testimonial.is-video .recap-testimonial-frame {
    aspect-ratio: 16 / 9;
    background: var(--paper-warm);
    position: relative; overflow: hidden;
    border-radius: 4px;
    background: linear-gradient(135deg, rgba(20,20,19,.04) 0%, rgba(20,20,19,.01) 50%, rgba(20,20,19,.08) 100%);
  }
  .page-prose .recap-testimonial.is-video .recap-testimonial-frame .play-glyph {
    position: absolute; top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    width: 56px; height: 56px; border-radius: 50%;
    background: rgba(20,20,19,.85);
    display: flex; align-items: center; justify-content: center;
  }
  .page-prose .recap-testimonial.is-video .recap-testimonial-frame .play-glyph::after {
    content: "";
    width: 0; height: 0;
    border-left: 16px solid var(--paper);
    border-top: 9px solid transparent;
    border-bottom: 9px solid transparent;
    margin-left: 3px;
  }
  .page-prose .recap-testimonial.is-video .recap-testimonial-frame .placeholder-label {
    position: absolute;
    bottom: var(--s-3); left: var(--s-3);
    font-family: var(--sans); font-size: 10px;
    letter-spacing: 0.18em; text-transform: uppercase;
    color: var(--ink-quiet);
  }

  /* attribution — used by both states */
  .page-prose .recap-testimonial-attribution {
    display: flex; flex-direction: column;
    gap: var(--s-1);
    padding-top: var(--s-3);
    border-top: 1px solid var(--rule-soft);
  }
  .page-prose .recap-testimonial-name {
    font-family: var(--sans); font-weight: 600;
    font-size: 13px; line-height: 1.3;
    color: var(--ink);
  }
  .page-prose .recap-testimonial-role {
    font-family: var(--sans); font-weight: 400;
    font-size: 11px; line-height: 1.4;
    letter-spacing: 0.06em;
    color: var(--ink-quiet);
  }


/* ----------------------------------------------------------
   6. RECAP GALLERY LIGHTBOX (recap state only)
   Recap canonical lines 2542-2672 (verbatim).
---------------------------------------------------------- */

  .recap-lightbox {
    position: fixed; inset: 0;
    z-index: 110;    /* above search-overlay (100) and header (40) */
    background: rgba(20, 20, 19, 0.94);
    display: flex; flex-direction: column;
    opacity: 0;
    transition: opacity var(--motion-duration-content) var(--motion-ease-content);
  }
  .recap-lightbox.is-open { opacity: 1; }
  .recap-lightbox[hidden] { display: none; }

  .recap-lightbox-bar {
    flex-shrink: 0;
    padding: var(--s-5) var(--s-7);
    display: flex; align-items: center; justify-content: space-between;
    gap: var(--s-5);
    color: var(--paper);
  }
  .recap-lightbox-counter {
    font-family: var(--sans); font-weight: 600;
    font-size: 12px; letter-spacing: 0.14em;
    text-transform: uppercase; color: var(--paper);
  }
  .recap-lightbox-close {
    background: transparent; border: 0;
    width: 40px; height: 40px;
    display: flex; align-items: center; justify-content: center;
    color: var(--paper); cursor: pointer;
    border-radius: 50%;
    transition: background var(--motion-duration-ui) var(--motion-ease-ui);
  }
  .recap-lightbox-close:hover { background: rgba(255,255,255,.08); }

  .recap-lightbox-stage {
    flex: 1;
    position: relative;
    display: flex; align-items: center; justify-content: center;
    padding: var(--s-3) var(--s-9);
  }
  @media (max-width: 720px) {
    .recap-lightbox-stage { padding: var(--s-3) var(--s-5); }
  }

  /* Ship v0.5.161 — lightbox frame ratio changed from 16:10 to 3:2.
     Source images (cohort_gallery) currently uploaded at mixed ratios
     pending open item #29 (recap-gallery-hero) decision; instruction
     string left unchanged in this ship pending coupled decision. */
  .recap-lightbox-frame {
    width: 100%; max-width: 1100px;
    aspect-ratio: 3 / 2;
    background: var(--paper-warm);
    position: relative; overflow: hidden;
    border-radius: 4px;
    background-image: linear-gradient(135deg, rgba(255,255,255,.06) 0%, rgba(255,255,255,.02) 50%, rgba(255,255,255,.10) 100%);
  }
  .recap-lightbox-frame::before {
    content: attr(data-label);
    position: absolute;
    bottom: var(--s-4); left: var(--s-4);
    font-family: var(--sans); font-weight: 600;
    font-size: 11px; letter-spacing: 0.18em;
    text-transform: uppercase;
    color: rgba(250,250,247,.7);
    z-index: 2;
  }

  /* lightbox placeholder display — same pattern as the hero,
     but tuned for the larger frame and the dark backdrop.
     In production: real image overlays; this is hidden. */
  .recap-lightbox-frame-display {
    position: absolute; inset: 0;
    display: flex; flex-direction: column;
    align-items: center; justify-content: center;
    gap: var(--s-3);
    pointer-events: none;
  }
  .recap-lightbox-frame-display .display-num {
    font-family: var(--serif); font-weight: 400;
    font-size: clamp(120px, 14vw, 220px);
    line-height: 1;
    letter-spacing: -0.025em;
    color: rgba(250,250,247,0.35);
    font-variant-numeric: tabular-nums;
  }
  .recap-lightbox-frame-display .display-suffix {
    font-family: var(--sans); font-weight: 600;
    font-size: 13px; letter-spacing: 0.20em;
    text-transform: uppercase;
    color: rgba(250,250,247,0.50);
  }

  .recap-lightbox-nav {
    position: absolute; top: 50%;
    transform: translateY(-50%);
    background: rgba(20,20,19,0.4);
    border: 1px solid rgba(255,255,255,.18);
    color: var(--paper);
    width: 44px; height: 44px;
    border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    cursor: pointer;
    font-family: var(--sans); font-size: 20px; font-weight: 400;
    line-height: 1;
    transition: background var(--motion-duration-ui) var(--motion-ease-ui),
                border-color var(--motion-duration-ui) var(--motion-ease-ui);
  }
  .recap-lightbox-nav:hover {
    background: rgba(20,20,19,0.65);
    border-color: rgba(255,255,255,.32);
  }
  .recap-lightbox-nav.is-prev { left: var(--s-5); }
  .recap-lightbox-nav.is-next { right: var(--s-5); }
  @media (max-width: 720px) {
    .recap-lightbox-nav { width: 36px; height: 36px; font-size: 16px; }
    .recap-lightbox-nav.is-prev { left: var(--s-3); }
    .recap-lightbox-nav.is-next { right: var(--s-3); }
  }

  .recap-lightbox-caption {
    flex-shrink: 0;
    padding: var(--s-4) var(--s-7) var(--s-7);
    text-align: center;
    color: rgba(250,250,247,.7);
    font-family: var(--sans); font-size: 12px;
    line-height: 1.5;
  }

  /* respect reduced motion — disable transitions in the lightbox */
  @media (prefers-reduced-motion: reduce) {
    .recap-lightbox,
    .recap-gallery-hero,
    .recap-gallery-thumb,
    .recap-lightbox-nav,
    .recap-lightbox-close { transition: none; }
  }


/* ----------------------------------------------------------
   7. UPCOMING-only families
   Upcoming canonical lines 2697-3025 (verbatim).
---------------------------------------------------------- */

  .page-prose .upcoming-cohort-facts {
    margin-block: var(--s-7);
    max-width: none;
    padding: var(--s-6) var(--s-6) var(--s-5);
    background: var(--paper-warm);
    border: 1px solid var(--rule-soft);
  }
  .page-prose .upcoming-cohort-facts-grid {
    display: grid; grid-template-columns: repeat(2, 1fr);
    gap: var(--s-5) var(--s-7);
  }
  @media (max-width: 720px) {
    .page-prose .upcoming-cohort-facts-grid {
      grid-template-columns: 1fr;
      gap: var(--s-4);
    }
  }
  .page-prose .upcoming-cohort-fact {
    display: flex; flex-direction: column;
    gap: var(--s-2);
  }
  .page-prose .upcoming-cohort-fact-label {
    font-family: var(--sans); font-weight: 600;
    font-size: 11px; line-height: 1.2;
    letter-spacing: 0.16em; text-transform: uppercase;
    color: var(--ink-quiet);
  }
  .page-prose .upcoming-cohort-fact-value {
    font-family: var(--serif); font-weight: 400;
    font-size: 17px; line-height: 1.4;
    color: var(--ink);
    margin: 0;
  }
  .page-prose .upcoming-cohort-fact-value em { font-style: italic; }
  .page-prose .upcoming-cohort-fact-note {
    font-family: var(--sans); font-weight: 400;
    font-size: 14px; line-height: 1.5;
    color: var(--ink-quiet);
    margin-top: var(--s-1);
  }

  /* ----------------------------------------------------------
     10. FOUNDER CHAT TEASER — small paragraph between the
     modules grid and the faculty grid. Visually quiet — sits
     left-aligned within the prose column at the natural prose
     measure, set in serif italic with a small kicker above.
     Treats the founder chat as a recurring fixture of the
     curriculum without claiming a specific guest for the
     upcoming cohort.
  ---------------------------------------------------------- */
  .page-prose .upcoming-founder-teaser {
    margin-block: var(--s-7);
    padding: var(--s-5) var(--s-6);
    border-left: 2px solid var(--rule);
    max-width: 60ch;
  }
  .page-prose .upcoming-founder-teaser-kicker {
    font-family: var(--sans); font-weight: 600;
    font-size: 11px; line-height: 1.2;
    letter-spacing: 0.16em; text-transform: uppercase;
    color: var(--ink-quiet);
    margin-bottom: var(--s-2);
  }
  .page-prose .upcoming-founder-teaser-body {
    font-family: var(--serif); font-weight: 400;
    font-style: italic;
    font-size: 17px; line-height: 1.55;
    color: var(--ink-soft);
    margin: 0;
  }

  /* ----------------------------------------------------------
     11. RESERVE SECTION — wraps both states A and B.

     STATE A (.upcoming-notify): the live commercial surface
     for a TBA cohort. Single email field + 'Notify me' button,
     a small note explaining what notification means.

     STATE B (.upcoming-state-b-preview): a labelled preview
     block visualising what the surface becomes when dates and
     pricing are announced. Carries the booking-fee explainer
     + application form pattern + 'Reserve your seat' CTA.
     Wrapped in a 'PREVIEW · WHEN DATES ARE ANNOUNCED' label
     so the reader understands this is not yet active.

     In production: the template renders only A or only B based
     on the ACF 'cohort_dates_announced' boolean on the
     Bootcamp Event CPT. The mockup shows both for evaluation.
  ---------------------------------------------------------- */
  .page-prose .upcoming-reserve {
    margin-block: var(--s-7);
    max-width: none;
  }

  /* State A — notify-me capture. Lives inside the prose column,
     paper-warm panel like the cohort facts panel above for visual
     consistency. */
  .page-prose .upcoming-notify {
    padding: var(--s-7) var(--s-6) var(--s-6);
    background: var(--paper-warm);
    border: 1px solid var(--rule-soft);
  }
  .page-prose .upcoming-notify-kicker {
    font-family: var(--sans); font-weight: 600;
    font-size: 11px; line-height: 1.2;
    letter-spacing: 0.16em; text-transform: uppercase;
    color: var(--accent);
    margin-bottom: var(--s-3);
  }
  .page-prose .upcoming-notify-headline {
    font-family: var(--serif); font-weight: 400;
    font-size: clamp(22px, 2.2vw, 28px); line-height: 1.2;
    letter-spacing: -0.012em;
    color: var(--ink);
    max-width: 22ch;
    margin: 0 0 var(--s-3);
  }
  .page-prose .upcoming-notify-headline em { font-style: italic; }
  .page-prose .upcoming-notify-supporting {
    font-family: var(--serif); font-weight: 400;
    font-size: 16px; line-height: 1.55;
    color: var(--ink-soft);
    max-width: 56ch;
    margin: 0 0 var(--s-5);
  }
  /* notify form — single email field + button row.
     CSS-grid: input flex-grows, button auto-width. */
  .page-prose .upcoming-notify-form {
    display: grid;
    grid-template-columns: 1fr auto;
    gap: var(--s-3);
    max-width: 480px;
  }
  @media (max-width: 480px) {
    .page-prose .upcoming-notify-form {
      grid-template-columns: 1fr;
    }
  }
  .page-prose .upcoming-notify-input {
    font-family: var(--sans); font-size: 15px;
    color: var(--ink);
    background: #fff;
    border: 1px solid var(--rule);
    padding: var(--s-3) var(--s-4);
    line-height: 1.4;
    /* button-defaults reset for input — same principle as
       operational learning #10 from v24, applied to <input>
       so it inherits page font-family rather than browser default. */
  }
  .page-prose .upcoming-notify-input::placeholder {
    color: var(--ink-quiet);
  }
  .page-prose .upcoming-notify-input:focus {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
    border-color: var(--accent);
  }
  .page-prose .upcoming-notify-submit {
    /* button-defaults reset before any visual styling —
       operational learning #10 (v24). */
    display: block;
    border: 0;
    font: inherit;
    font-family: var(--sans); font-weight: 600;
    font-size: 13px; line-height: 1;
    letter-spacing: 0.06em; text-transform: uppercase;
    color: var(--paper);
    background: var(--ink);
    padding: var(--s-3) var(--s-5);
    cursor: pointer;
    transition: background var(--motion-duration-ui) var(--motion-ease-ui);
  }
  .page-prose .upcoming-notify-submit:hover {
    background: var(--accent);
  }
  .page-prose .upcoming-notify-fineprint {
    font-family: var(--sans); font-size: 12px; line-height: 1.5;
    color: var(--ink-quiet);
    margin: var(--s-4) 0 0;
    max-width: 56ch;
  }

  /* ----------------------------------------------------------
     12. STATE B PREVIEW — labelled block previewing the
     post-announcement surface. Outer label reads 'PREVIEW ·
     WHEN DATES ARE ANNOUNCED' with a dashed top border so the
     reader can see this is illustrative, not live.

     Inside, three blocks stack:
     - 12a. Booking-fee explainer (3 short bullets)
     - 12b. Application form pattern
     - 12c. Reserve-your-seat CTA + Razorpay note
  ---------------------------------------------------------- */
  .page-prose .upcoming-state-b-preview {
    margin-top: var(--s-7);
    padding: var(--s-6) 0 0;
    border-top: 2px dashed var(--rule);
    /* visually quieter than State A; this is illustrative
       content, not a call to action right now. */
  }
  .page-prose .upcoming-state-b-label {
    font-family: var(--sans); font-weight: 600;
    font-size: 11px; line-height: 1.2;
    letter-spacing: 0.16em; text-transform: uppercase;
    color: var(--ink-quiet);
    margin-bottom: var(--s-2);
  }
  .page-prose .upcoming-state-b-supporting {
    font-family: var(--serif); font-style: italic; font-weight: 400;
    font-size: 14px; line-height: 1.5;
    color: var(--ink-quiet);
    max-width: 60ch;
    margin: 0 0 var(--s-6);
  }

  /* 12a. Booking-fee explainer. Three short bullets, set as
     a flex column with subtle dividers. Each bullet has a
     bold lead-in (the mechanic) followed by the short prose. */
  .page-prose .upcoming-booking-fee {
    padding: var(--s-5) var(--s-6);
    background: var(--paper-warm);
    border: 1px solid var(--rule-soft);
    margin-bottom: var(--s-6);
  }
  .page-prose .upcoming-booking-fee-headline {
    font-family: var(--serif); font-weight: 400;
    font-size: 18px; line-height: 1.3;
    color: var(--ink);
    margin: 0 0 var(--s-4);
  }
  .page-prose .upcoming-booking-fee-headline em { font-style: italic; }
  .page-prose .upcoming-booking-fee-list {
    list-style: none; padding: 0; margin: 0;
    display: flex; flex-direction: column;
  }
  .page-prose .upcoming-booking-fee-list li {
    padding: var(--s-3) 0;
    border-bottom: 1px solid var(--rule-soft);
    font-family: var(--serif); font-size: 16px; line-height: 1.5;
    color: var(--ink-soft);
  }
  .page-prose .upcoming-booking-fee-list li:first-child { padding-top: 0; }
  .page-prose .upcoming-booking-fee-list li:last-child { border-bottom: 0; padding-bottom: 0; }
  .page-prose .upcoming-booking-fee-mechanic {
    font-weight: 600;
    color: var(--ink);
    font-style: normal;
  }

  /* 12b. Application form. Two-column grid for the field rows
     on desktop, single column on tablet+. Inputs styled like
     .upcoming-notify-input. */
  .page-prose .upcoming-form {
    margin-bottom: var(--s-6);
  }
  .page-prose .upcoming-form-row {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--s-3) var(--s-5);
    margin-bottom: var(--s-4);
  }
  .page-prose .upcoming-form-row.is-single { grid-template-columns: 1fr; }
  @media (max-width: 720px) {
    .page-prose .upcoming-form-row {
      grid-template-columns: 1fr;
    }
  }
  .page-prose .upcoming-form-field {
    display: flex; flex-direction: column;
    gap: var(--s-2);
  }
  .page-prose .upcoming-form-label {
    font-family: var(--sans); font-weight: 600;
    font-size: 11px; line-height: 1.2;
    letter-spacing: 0.12em; text-transform: uppercase;
    color: var(--ink-quiet);
  }
  .page-prose .upcoming-form-input,
  .page-prose .upcoming-form-textarea {
    font-family: var(--sans); font-size: 15px;
    color: var(--ink);
    background: #fff;
    border: 1px solid var(--rule);
    padding: var(--s-3) var(--s-4);
    line-height: 1.4;
  }
  .page-prose .upcoming-form-textarea {
    min-height: 80px;
    resize: vertical;
    font-family: var(--sans);
  }
  .page-prose .upcoming-form-input:focus,
  .page-prose .upcoming-form-textarea:focus {
    outline: 2px solid var(--accent);
    outline-offset: 1px;
    border-color: var(--accent);
  }

  /* 12c. Reserve CTA — single primary action row. Mirrors the
     notify-submit visual but at full prominence — taller,
     wider, paired with a Razorpay redirect note beneath. */
  .page-prose .upcoming-reserve-cta-row {
    display: flex; flex-wrap: wrap;
    align-items: center;
    gap: var(--s-4) var(--s-5);
    padding-top: var(--s-3);
  }
  .page-prose .upcoming-reserve-cta {
    display: block;
    border: 0;
    font: inherit;
    font-family: var(--sans); font-weight: 600;
    font-size: 14px; line-height: 1;
    letter-spacing: 0.08em; text-transform: uppercase;
    color: var(--paper);
    background: var(--ink);
    padding: var(--s-4) var(--s-6);
    cursor: pointer;
    transition: background var(--motion-duration-ui) var(--motion-ease-ui);
  }
  .page-prose .upcoming-reserve-cta:hover {
    background: var(--accent);
  }
  .page-prose .upcoming-reserve-cta-note {
    font-family: var(--sans); font-size: 12px; line-height: 1.5;
    color: var(--ink-quiet);
    max-width: 36ch;
    margin: 0;
  }


/* ----------------------------------------------------------
   8. CASE-RELATED tail-rail overrides scoped to bootcamp single

   The base.css `.case-related-headline` lift uses the case-study
   canonical's values. Both bootcamp single canonicals diverge on
   line-height, max-width, letter-spacing, header alignment, and
   border-top tone. Per op-learning #16 v108 ratification posture,
   the lift in base.css is preserved (other consumers depend on
   it); divergences are scoped here under [data-cohort-state].

   Recap canonical lines 2857-2887 source the diverging values.
   Logged as open #261 for future review.
---------------------------------------------------------- */

[data-cohort-state] .case-related {
  border-top: 1px solid var(--rule-soft);
}
[data-cohort-state] .case-related-header {
  align-items: stretch;
  margin-bottom: var(--s-6);
}
[data-cohort-state] .case-related-headline {
  line-height: 1.18;
  letter-spacing: 0;
  max-width: 32ch;
}

/* G.3b — Recap-2: gallery hero img responsive constraint */
.page-prose .recap-gallery-hero-img {
	width: 100%;
	height: auto;
	display: block;
}
