/* =====================================================================
   MAXIMUS / One-on-One
   Static build — Phase 1 + 2. No animation library, no scroll motion.
   Tokens are locked by brand.md; the composition follows the approved
   boards in reference/approved-designs/.
   ===================================================================== */

/* ---------- 1. Tokens ------------------------------------------------ */
:root {
  --yellow:      #FAE74B;
  --yellow-deep: #E3CB1F;
  --yellow-tint: #FDF6C4;
  --ink:         #131110;
  --paper:       #FFFFFF;
  --graphite:    #2A2622;
  --bronze:      #6B4A1E;
  --wood:        #C9A97E;

  --display:        'Archivo', system-ui, sans-serif;
  --display-weight: 900;
  --display-width:  125%;
  --display-track:  -0.030em;
  --body:           'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;

  /* fluid type — calibrated so 1440px matches the boards */
  /* NOTE: the approved boards were rendered with a stand-in font roughly
     30% narrower than Archivo at wdth 125%. Brand rules win over the
     boards' glyph widths, so the scale below is calibrated to the real
     face and matches the boards' PROPORTIONS, not their pixel widths. */
  --fs-xl:    clamp(2.75rem,  5.85vw, 5.25rem);    /* 84px  clips title */
  --fs-word:  clamp(2rem,     5.30vw, 4.75rem);    /* 76px  hero h1, ONE-ON-ONE over PODCAST */
  --fs-lg:    clamp(2rem,     4.30vw, 3.875rem);   /* 62px  contact headline */
  --fs-md:    clamp(1.625rem, 2.90vw, 2.5rem);     /* 40px  about headline */
  --fs-voice: clamp(1.75rem,  3.45vw, 3.125rem);   /* 50px  voices headline */
  --fs-guest: clamp(1.375rem, 2.55vw, 2.25rem);    /* 32px  episode guest */
  --fs-sec:   clamp(1.25rem,  2.20vw, 2rem);       /* 32px  section head name */
  --fs-stat:  clamp(1.75rem,  3.10vw, 2.75rem);    /* 44px  stat figure */
  --fs-tag:   clamp(1.25rem,  2.35vw, 2.125rem);   /* 34px  hero supporting line */
  --fs-lede:  1.0625rem;
  --fs-label: 0.75rem;

  --shell:  1296px;
  --gutter: clamp(20px, 5vw, 72px);
  --pad-y:  clamp(56px, 8vw, 104px);
  --plane:  clamp(10px, 1.5vw, 21px);   /* offset-plane displacement */

  --focus: 3px;
}

/* ---------- 2. Reset -------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

html:focus-within { scroll-behavior: smooth; }
/* pinning makes the page much taller; a smooth jump across it reads as a hang */
html.js-pinned, html.js-pinned:focus-within { scroll-behavior: auto; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--body);
  font-weight: 400;
  font-size: var(--fs-lede);
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;         /* page never scrolls sideways; rails opt in */
}

h1, h2, h3, p, ul, ol, figure, blockquote { margin: 0; }
ul, ol { padding: 0; list-style: none; }
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; }
button { font: inherit; color: inherit; }

/* ---------- 3. Utilities --------------------------------------------- */
.shell {
  width: 100%;
  max-width: calc(var(--shell) + var(--gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.sr-only {
  position: absolute; left: 0; top: 0; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

.skip-link {
  position: absolute; left: var(--gutter); top: -100px; z-index: 100;
  background: var(--yellow); color: var(--ink);
  padding: .75rem 1.25rem; font-weight: 600; text-decoration: none;
}
.skip-link:focus { top: 12px; }

:where(a, button, input, textarea, [tabindex]):focus-visible {
  outline: var(--focus) solid var(--yellow);
  outline-offset: 3px;
}

/* ---------- 4. Type primitives --------------------------------------- */
.h2, .hero__wordmark, .ep__guest, .stat__n,
.section-label__t, .site-header__mark, .site-footer__mark {
  font-family: var(--display);
  font-weight: var(--display-weight);
  font-stretch: var(--display-width);
  letter-spacing: var(--display-track);
  text-transform: uppercase;
  line-height: .96;
}

.h2--xl { font-size: var(--fs-xl); }
.h2--lg { font-size: var(--fs-lg); }
#voices-title { font-size: var(--fs-voice); text-wrap: balance; }
.h2--md { font-size: var(--fs-md); }

.lede { max-width: 40ch; }

.section-label, .section-note, .hero__by,
.episodes__count, .clips__source, .contact__kinds, .voices__note {
  font-family: var(--body);
  font-weight: 600;
  font-size: var(--fs-label);
  letter-spacing: .10em;
  text-transform: uppercase;
  line-height: 1.4;
}

.dash {
  display: block; width: 56px; height: 8px;
  background: var(--yellow); margin-bottom: clamp(20px, 2.6vw, 34px);
}

/* ---------- 5. Sections & heads -------------------------------------- */
/* Every section is ink. Yellow and paper are text, rule and accent colours
   only — the alternating yellow/paper bands were dropped 2026-09-03 at the
   client's request, so no section carries its own background. */
.section { position: relative; padding-block: var(--pad-y); }

.section--hero {
  padding-top: clamp(96px, 11vw, 132px);
  min-height: 100svh;
  display: flex; align-items: center;
  overflow: hidden;                      /* the photograph fills the section */
}
.section--hero > .shell { width: 100%; }

/* The head used to be a 12px label over a hairline, which the client found
   too plain. The index is now display type at full size and the section
   name sits beside it in the same face, over a 2px rule. */
.section-head { margin-bottom: clamp(36px, 5vw, 64px); }
.section-head {
  display: flex; flex-wrap: wrap; gap: 8px 24px;
  align-items: baseline; justify-content: space-between;
}
.section-head::after {
  content: ""; display: block; height: 2px; flex: 1 0 100%;
  background: var(--yellow); margin-top: clamp(10px, 1.2vw, 16px);
  /* The rule is a pseudo-element, so GSAP cannot address it. It reads a
     custom property off the head instead, which motion.js can animate.
     The default is 1: with no JS, or under reduced motion, the rule is
     simply drawn, exactly as it was before. */
  transform: scaleX(var(--rule, 1)); transform-origin: left center;
}

.section-label {
  display: flex; align-items: baseline; gap: clamp(10px, 1.2vw, 18px);
  color: var(--paper);
}
.section-label__n {
  font-family: var(--body); font-weight: 600;
  font-size: var(--fs-label); letter-spacing: .10em;
  color: var(--yellow); line-height: 1.4;
  /* hold the number on the rule while the name grows beside it */
  align-self: center;
}
.section-label__t { font-size: var(--fs-sec); line-height: 1; }
.section-note { color: rgba(255, 255, 255, .55); }

/* The `band-ink` transition strip lived only at the foot of the Host and
   Services sections. Both were removed 2026-09-03 and the strip went with
   them, so no section carries a lead-in band any more. */

/* ---------- 6. Buttons ----------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; gap: .8em;
  padding: .95em 1.5em;
  font-family: var(--body); font-weight: 600;
  font-size: var(--fs-label); letter-spacing: .10em; text-transform: uppercase;
  text-decoration: none; border: 0; cursor: pointer;
  transition: background-color .18s ease, color .18s ease;
}
.btn--yellow { background: var(--yellow); color: var(--ink); }
.btn--yellow:hover { background: var(--yellow-deep); }
.btn--lg     { padding: 1.15em 1.7em; }
.btn--block  { width: 100%; justify-content: space-between; }
.btn__arrow  { font-size: 1.15em; line-height: 1; }

/* ---------- 7. Offset planes ----------------------------------------- */
/* Flat colour planes sitting behind an image. Decorative: pseudo-elements
   so they carry no semantics and need no aria-hidden. */
.plane { position: relative; }
.plane > img { position: relative; z-index: 1; }

/* The offset is expressed through --plane-x/--plane-y and scaled by --plane-k.
   Phase 3 animates --plane-k (0 -> 1) and --plane-o so the plane slides out from
   behind the photograph. With JS off both default to 1 and the static composition
   renders exactly as approved. */
.plane::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  transform: translate(calc(var(--plane-x, 0px) * var(--plane-k, 1)),
                       calc(var(--plane-y, 0px) * var(--plane-k, 1)));
  opacity: var(--plane-o, 1);
}

.plane--yellow-tr { --plane-x: var(--plane); --plane-y: calc(var(--plane) * -1); }
.plane--yellow-bl { --plane-x: calc(var(--plane) * -1); --plane-y: var(--plane); }
.plane--yellow-tr::before,
.plane--yellow-bl::before { background: var(--yellow); }

/* ---------- 8. Header / nav ------------------------------------------ */
.site-header {
  position: absolute; inset-inline: 0; top: 0; z-index: 40;
  padding-block: clamp(18px, 2.4vw, 30px);
}
.site-header__inner {
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
  padding-bottom: clamp(14px, 1.8vw, 26px);
  border-bottom: 1px solid rgba(255, 255, 255, .22);
}
.site-header__mark { font-size: 1rem; text-decoration: none; }
.site-header__end { display: flex; align-items: center; gap: clamp(14px, 2.2vw, 30px); }

/* X and YouTube, icon only. They sit outside the collapsing menu so they
   stay reachable at every width without opening it. */
.site-social { display: flex; align-items: center; gap: 4px; }
.socialbtn {
  width: 40px; height: 40px; display: grid; place-items: center;
  color: var(--paper); text-decoration: none;
  transition: color .18s ease;
}
.socialbtn:hover { color: var(--yellow); }

.site-nav__toggle {
  display: none; align-items: center; gap: .6em;
  background: transparent; border: 1.5px solid var(--paper);
  padding: .6em .9em; cursor: pointer;
  font-size: var(--fs-label); font-weight: 600;
  letter-spacing: .10em; text-transform: uppercase;
}
.site-nav__toggle-bars { display: grid; gap: 4px; }
.site-nav__toggle-bars i { display: block; width: 18px; height: 2px; background: currentColor; }

.site-nav__list { display: flex; align-items: center; gap: clamp(20px, 2.6vw, 38px); }
.site-nav__list a {
  text-decoration: none; font-weight: 600;
  font-size: var(--fs-label); letter-spacing: .10em; text-transform: uppercase;
}
.site-nav__list a:not(.btn):hover { text-decoration: underline; text-underline-offset: 5px; }

/* ---------- 9. 01 Hero -----------------------------------------------
   The photograph is the section's ground rather than a column beside it.
   The scrim over it is FLAT, not a gradient and not a blur: the brand
   forbids both, and a single opacity is measurable — every hero text
   colour was checked against the lightest pixels the photo puts behind
   it at each breakpoint. */
.hero__media { position: absolute; inset: 0; z-index: 0; }
.hero__media img {
  width: 100%; height: 100%; object-fit: cover;
  object-position: 50% 45%;
}
/* The source photograph is 3:2 and the hero is close to it, so `cover`
   leaves almost no horizontal crop and object-position alone cannot move
   him off the copy. Widening the image past the section gives that room:
   at 130% he sits right of the text with the framing gesture still whole.
   Width, deliberately, NOT transform — motion.js scales this same image on
   the way out, and its tween would overwrite a transform set here. */
@media (min-width: 901px) {
  .hero__media img { width: 130%; max-width: none; object-position: 50% 42%; }
}
.hero__media::after {
  content: ""; position: absolute; inset: 0;
  background: rgba(19, 17, 16, .66);
}

.hero__inner { position: relative; z-index: 1; }
.hero__copy {
  display: grid; grid-template-columns: minmax(0, 1fr);
  justify-items: start; gap: clamp(12px, 1.6vw, 20px);
  max-width: 42rem;
}
.hero__wordmark { font-size: var(--fs-word); line-height: .88; }
.hero__tagline {
  font-family: var(--display); font-weight: var(--display-weight);
  font-stretch: var(--display-width); letter-spacing: var(--display-track);
  text-transform: uppercase; font-size: var(--fs-tag); line-height: 1.16;
  color: var(--yellow);
}
.hero__by { color: rgba(255, 255, 255, .82); }
.hero__copy .btn { margin-top: clamp(10px, 1.4vw, 18px); }

/* -------- 10. 02 About ------------------------------------------------ */
/* The column had no rhythm of its own: every child sat flush against the
   next because the reset zeroes margins and nothing replaced them. It only
   held one paragraph before, so it never showed. */
.about__copy {
  display: grid; justify-items: start;
  gap: clamp(14px, 1.8vw, 22px);
}
.about__copy .dash { margin-bottom: 0; }
.about__copy > p { max-width: 46ch; }        /* one measure for both paragraphs */
.about__more { color: rgba(255, 255, 255, .82); }

/* Highlighted figures. Yellow leads, because these are the one place on the
   page carrying a claim. Every value is sourced in content.md.

   One tile per row, number left and label right on a shared baseline. The
   earlier side-by-side flex worked only because there were exactly two
   tiles: it sizes each tile to its own content, so a third made the row
   split unevenly and left the odd tile as a mostly-empty slab. Tiles cannot
   simply share a row equally either — the binding constraint is the widest
   NUMBER, `1 YEAR+`, which needs about 270px at 1440 and does not fit two
   or three across the About column at every width. A full-width row is
   immune to all of that: it holds any count of figures, at any container
   width, with no dead space and nothing to re-tune when one is added. */
.stats {
  display: grid; grid-template-columns: minmax(0, 1fr);
  /* Equal rows: the longest label wraps to two lines on narrow columns, and
     one taller tile in a stack of three reads as a mistake rather than as
     the copy simply being longer. */
  grid-auto-rows: 1fr;
  gap: clamp(10px, 1.2vw, 16px);
  margin-top: clamp(6px, 1vw, 12px);
}
.stat {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: clamp(12px, 1.6vw, 22px);
  background: var(--yellow); color: var(--ink);
  padding: clamp(12px, 1.3vw, 17px) clamp(16px, 1.8vw, 22px);
}
.stat__n {
  font-size: var(--fs-stat); line-height: .95;
  /* The figure is the claim; it never breaks across lines. `1 YEAR+` splits
     after the `1` on a narrow column otherwise, which reads as two numbers. */
  white-space: nowrap;
}
.stat__l {
  font-family: var(--body); font-weight: 600;
  font-size: var(--fs-label); letter-spacing: .08em; text-transform: uppercase;
  text-align: right;
}

.about__grid {
  display: grid; align-items: center;
  grid-template-columns: minmax(0, 1.30fr) minmax(0, 1fr);
  gap: clamp(40px, 5.4vw, 76px);
}
.about__figure img { width: 100%; aspect-ratio: 3 / 2; object-fit: cover; }

/* -------- 11. 03 Episodes -------------------------------------------- */
.episodes__rail-wrap { margin-block: clamp(28px, 3.6vw, 44px); }

.episodes__rail {
  display: flex; gap: clamp(20px, 3.4vw, 66px);
  overflow-x: auto; overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-left: var(--gutter);
  padding-inline: var(--gutter);
  padding-bottom: 12px;
  scrollbar-width: none;
}
.episodes__rail::-webkit-scrollbar { display: none; }
.episodes__rail > li {
  flex: 0 0 auto;
  width: clamp(260px, 54vw, 780px);
  scroll-snap-align: start;
}
/* keep the last card able to reach the left edge */
.episodes__rail::after {
  content: ""; flex: 0 0 auto;
  width: max(0px, calc(100vw - var(--gutter) * 2 - clamp(260px, 54vw, 780px)));
}

/* ---- while the pin drives the rail, the rail is not a scroller ---------
   Two rules that only apply when motion.js has taken the rail over
   (`js-pinned` is set by the Episodes scene and removed when it reverts),
   so native swipe on touch and under reduced motion is untouched.

   1. MANDATORY SNAP MUST BE OFF. The pin writes `scrollLeft` every frame,
      and a mandatory snap container refuses intermediate positions: setting
      137 gave back 0, and setting 903 gave back 827. The rail did not
      scrub, it teleported card to card, which is what read as lag. Snap is
      correct for a finger and wrong for a scrubbed animation.

   2. THE TRAILING SPACER MUST GO. It exists so the last card can reach the
      left edge under `scroll-snap-align: start`, which only matters when a
      finger is doing the scrolling. Under the pin it added 567px of travel
      after the final card had already passed — the stretch where the Nom
      card sits alone against empty black. Dropping it makes `scrollWidth`
      correct on its own, so the pin's own length follows automatically. */
html.js-pinned .episodes__rail { scroll-snap-type: none; }
html.js-pinned .episodes__rail::after { content: none; }

.ep { position: relative; display: grid; gap: 18px; text-decoration: none; color: inherit; }
.ep__figure {
  --plane: clamp(10px, 1.4vw, 20px);
  --plane-x: calc(var(--plane) * -1); --plane-y: var(--plane);
}
.ep__figure::before { background: var(--yellow); }
.ep__figure img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }

/* An X-only episode has no cached poster and X's CDN must never be
   hotlinked, so its card is DRAWN rather than fetched.

   It is built in the language of his own YouTube thumbnails — flat
   yellow, heavy black type — because that is what the four cached
   posters beside it look like. An ink card among yellow ones read as a
   frame that had failed to load; this one reads as artwork. */
.ep__figure--card { --plane-x: 0px; --plane-y: 0px; }
.ep__card {
  position: relative; z-index: 1;
  aspect-ratio: 16 / 9;
  display: grid; align-content: center; gap: .35em;
  padding: clamp(20px, 3vw, 44px);
  background: var(--yellow); color: var(--ink);
}
.ep__card-show {
  font-family: var(--body); font-weight: 600;
  font-size: var(--fs-label); letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink); opacity: .66;
}
.ep__card-guest {
  font-family: var(--display); font-weight: var(--display-weight);
  font-stretch: var(--display-width); letter-spacing: var(--display-track);
  text-transform: uppercase; line-height: .92;
  font-size: clamp(2.25rem, 6vw, 4.5rem); color: var(--ink);
}

.ep__play {
  position: absolute; z-index: 2; inset: 0; margin: auto;
  width: 74px; height: 52px; display: grid; place-items: center;
  background: rgba(19, 17, 16, .74); color: var(--paper);
  font-size: 1.2rem; line-height: 1;
  transition: background-color .18s ease;
}
.ep:hover .ep__play, .ep:focus-visible .ep__play { background: var(--ink); }
/* The drawn card is yellow, so its play marker is solid ink — the same
   figure/ground relationship the photographic posters have. It also moves
   out of the centre, where it landed directly beside the guest's name and
   read as a collision rather than a badge. */
.ep__figure--card .ep__play {
  background: var(--ink); color: var(--yellow);
  inset: auto clamp(18px, 2.4vw, 32px) clamp(18px, 2.4vw, 32px) auto;
  margin: 0;
}
.ep:hover .ep__figure--card .ep__play,
.ep:focus-visible .ep__figure--card .ep__play { background: var(--graphite); }

.ep__index { color: var(--yellow); }
.ep__guest { font-size: var(--fs-guest); }
.ep__meta { display: flex; align-items: baseline; justify-content: space-between; gap: 20px; }
.ep__line { color: rgba(255, 255, 255, .62); }
.ep__runtime {
  color: rgba(255, 255, 255, .62); white-space: nowrap;
  font-weight: 600; font-size: var(--fs-label);
  letter-spacing: .10em; text-transform: uppercase;
}
.ep[aria-current="true"] .ep__line, .ep[aria-current="true"] .ep__runtime { color: rgba(255,255,255,.78); }

.episodes__progress { display: flex; align-items: center; gap: 20px; }
.episodes__bar { flex: 1; height: 2px; background: rgba(255, 255, 255, .22); }
.episodes__bar > span { display: block; height: 100%; width: 20%; background: var(--yellow); }
.episodes__count { color: rgba(255, 255, 255, .55); }
.episodes__count--start { color: var(--yellow); }

/* -------- 12. 04 In Conversation With -------------------------------- */
.voices__head {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px 24px;
  margin-bottom: clamp(30px, 4vw, 48px);
}
.voices__note { color: var(--wood); }   /* bronze is too dark to read on ink */

/* Sixteen tiles since the roster was cut on 2026-09-04, so the desktop
   field is 4 x 4 and the stagger runs on 4n rather than 5n. A 5-column
   grid would leave one orphan on the last row. */
.voices__grid {
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(16px, 2.2vw, 30px) clamp(12px, 1.6vw, 22px);
}
/* The staggered editorial field from the board.
   Uses margin, NOT transform: motion.js animates x/y/rotation/scale on these
   same tiles, and the end state of that tween writes an inline transform that
   would silently wipe a CSS translateY and flatten the field into a plain
   uniform grid. Margin and transform never collide. */
.voices__grid > li:nth-child(4n + 2),
.voices__grid > li:nth-child(4n + 4) { margin-block-start: clamp(8px, 1.2vw, 17px); }

.org {
  position: relative; display: grid; gap: 10px;
  justify-items: center; align-content: center;
  /* Fill the grid cell. The offset plane behind a featured tile is inset:0
     on the CELL, so a tile shorter than its cell leaves the plane hanging
     below it — 17px at 1440, which is the stagger margin the taller
     siblings carry. Invisible while the plane was ink on a white page,
     obvious once it became paper on ink. */
  min-height: 104px; height: 100%; padding: 14px 12px;
  background: var(--ink); border: 1.5px solid rgba(255, 255, 255, .28);
  text-decoration: none; color: var(--paper);
  transition: background-color .18s ease, color .18s ease;
}
.org__logo {
  width: 54px; height: 54px; object-fit: contain;
  filter: grayscale(1); transition: filter .18s ease;
}
.org__name {
  font-weight: 600; font-size: .6875rem;
  letter-spacing: .07em; text-transform: uppercase; text-align: center;
}
.org__arrow { position: absolute; right: 10px; bottom: 8px; opacity: 0; font-size: .9rem; }

.org:hover, .org:focus-visible { background: var(--yellow); color: var(--ink); border-color: var(--yellow); }
.org:hover .org__logo, .org:focus-visible .org__logo { filter: none; }
.org:hover .org__arrow, .org:focus-visible .org__arrow { opacity: 1; }

/* featured tiles carry the active treatment shown on the board */
.org--yellow { background: var(--yellow); color: var(--ink); border-color: var(--yellow); }
.org--yellow .org__logo { filter: none; }
.org--yellow .org__arrow { opacity: 1; }
.org--paper { background: var(--paper); color: var(--ink); border-color: var(--paper); }
.org--paper .org__logo { filter: none; }
.org--paper .org__arrow { opacity: 1; }
.org--paper:hover, .org--paper:focus-visible { background: var(--yellow); color: var(--ink); border-color: var(--yellow); }

/* offset plane lives on the cell, not the tile, so it needs no z-index hack */
.voice-cell { position: relative; }
.voice-cell--yellow::before,
.voice-cell--paper::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  transform: translate(8px, 8px);
}
.voice-cell--yellow::before { background: var(--paper); }
.voice-cell--paper::before  { background: var(--yellow); }
.org { z-index: 1; }

/* -------- 13. 05 Clips ----------------------------------------------- */
.clips__grid {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, .82fr);
  gap: clamp(36px, 5vw, 72px);
}
.clips__copy { display: grid; align-content: center; gap: clamp(20px, 2.6vw, 32px); }
.clips__source { color: var(--yellow); }
.clips__pending { color: var(--wood); font-size: .8125rem; letter-spacing: .04em; }

.clips__reel { display: grid; gap: clamp(20px, 2.6vw, 32px); }
.clip { position: relative; }
.clip img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }
.clip__label {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 12px 16px; background: var(--graphite); color: var(--paper);
  font-weight: 600; font-size: var(--fs-label);
  letter-spacing: .10em; text-transform: uppercase;
}
.clip__label span:last-child { color: var(--wood); }

/* -------- 14. 06 Contact --------------------------------------------- */
.contact__grid {
  display: grid; align-items: center;
  grid-template-columns: minmax(0, 1.12fr) minmax(0, .78fr);
  gap: clamp(40px, 5.6vw, 84px);
}
.contact__copy { display: grid; justify-items: start; gap: clamp(20px, 2.6vw, 34px); }
.contact__ways { display: grid; gap: 10px; width: 100%; max-width: 26rem; }
.way {
  display: flex; align-items: baseline; justify-content: space-between; gap: 16px;
  padding: .85em 0; text-decoration: none;
  border-bottom: 1px solid rgba(255, 255, 255, .22);
  transition: border-color .18s ease, color .18s ease;
}
.way:hover { color: var(--yellow); border-bottom-color: var(--yellow); }
.way__k {
  font-family: var(--body); font-weight: 600;
  font-size: var(--fs-label); letter-spacing: .10em; text-transform: uppercase;
  color: var(--yellow);
}
.way__v { font-weight: 600; }
.contact__underline { display: block; width: 180px; height: 3px; background: var(--yellow); }

.contact__cardwrap { position: relative; }
.contact__plane { position: absolute; inset: 0; z-index: 0; }
.contact__plane--bronze { background: var(--bronze); transform: translate(calc(var(--plane) * 2), calc(var(--plane) * 2)); }
.contact__plane--yellow { background: var(--yellow); transform: translate(var(--plane), var(--plane)); }

.contact__card {
  position: relative; z-index: 1;
  background: var(--ink); color: var(--paper);
  border: 1.5px solid rgba(255, 255, 255, .28);
  padding: clamp(18px, 2vw, 22px);
}
.contact__figure { position: relative; }
.contact__figure img { width: 100%; aspect-ratio: 1.85 / 1; object-fit: cover; object-position: 50% 30%; }
.contact__tag {
  position: absolute; top: 20px; left: 18px;
  background: var(--yellow); color: var(--ink);
  padding: .55em 1.1em;
  font-weight: 600; font-size: var(--fs-label);
  letter-spacing: .10em; text-transform: uppercase;
}

.contact__form { display: grid; gap: clamp(18px, 2vw, 26px); padding-top: clamp(22px, 2.6vw, 32px); }
.field { display: grid; gap: 10px; }
.field label {
  font-weight: 600; font-size: var(--fs-label);
  letter-spacing: .10em; text-transform: uppercase;
}
.field input, .field textarea {
  width: 100%; background: transparent; color: var(--paper);
  border: 0; border-bottom: 1.5px solid rgba(255, 255, 255, .32);
  padding: 8px 0; font: inherit; font-size: 1rem; border-radius: 0;
}
.field textarea { resize: vertical; min-height: 62px; }
.field input:focus-visible, .field textarea:focus-visible {
  outline: none; border-bottom-color: var(--yellow);
  box-shadow: 0 2px 0 0 var(--yellow);
}
.field input:user-invalid, .field textarea:user-invalid { border-bottom-color: #FF8A73; }

.form-status { font-size: .8125rem; color: var(--wood); min-height: 1.4em; letter-spacing: .02em; }
.form-status[data-tone="error"] { color: #FFB4A2; }

/* -------- 15. Footer -------------------------------------------------- */
.site-footer {
  background: var(--ink); color: var(--paper);
  border-top: 1px solid rgba(255, 255, 255, .14);
  padding-block: clamp(28px, 3.4vw, 42px);
}
.site-footer__inner { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px 32px; }
.site-footer__mark { font-size: 1rem; text-decoration: none; color: var(--paper); }
.site-footer__links { display: flex; flex-wrap: wrap; gap: 16px 34px; }
.site-footer__links a {
  text-decoration: none; color: rgba(255, 255, 255, .72);
  font-weight: 600; font-size: var(--fs-label);
  letter-spacing: .10em; text-transform: uppercase;
}
.site-footer__links a:hover { color: var(--yellow); }

/* =====================================================================
   16. Responsive
   ===================================================================== */

/* ---- laptop / tablet landscape ---- */
@media (max-width: 1100px) {
  .voices__grid > li:nth-child(4n + 2),
  .voices__grid > li:nth-child(4n + 4) { margin-block-start: 12px; }
}

/* ---- tablet portrait ---- */
@media (max-width: 900px) {
  .site-nav__toggle { display: inline-flex; }
  .site-nav__list {
    display: none; position: absolute; right: var(--gutter); top: calc(100% + 10px);
    flex-direction: column; align-items: stretch; gap: 0;
    min-width: 230px; padding: 8px;
    background: var(--graphite); border: 1px solid rgba(255, 255, 255, .22);
  }
  .site-nav__list[data-open="true"] { display: flex; }
  .site-nav__list a { display: block; padding: .85em 1em; color: var(--yellow); }
  .site-nav__list a:hover { background: rgba(250, 231, 75, .12); text-decoration: none; }

  .about__grid,
  .clips__grid,
  .contact__grid { grid-template-columns: minmax(0, 1fr); }

  .about__grid > .about__figure { order: -1; }        /* image first on mobile */
  .contact__grid { gap: clamp(34px, 7vw, 52px); }

  .voices__grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .voices__grid > li:nth-child(4n + 2),
  .voices__grid > li:nth-child(4n + 4) { margin-block-start: 0; }
  .voices__grid > li:nth-child(2n) { margin-block-start: 10px; }

  /* clips become a simple vertical feed */
  .clips__reel { max-width: 560px; }
}

/* ---- mobile ---- */
@media (max-width: 640px) {
  :root { --plane: 10px; }

  /* Archivo at wdth 125% is very wide, so on narrow screens each heading is
     bound by its longest UNBREAKABLE word, not by the whole line. */
  /* ONE-ON-ONE is the longest unbreakable word on the page. At 10.4vw it
     filled 0.96 of the column at 390 and 0.97 at 360 — inside the box, but
     with no room for a device that renders Archivo a shade wider. */
  .hero__wordmark { font-size: clamp(1.7rem, 9.9vw, 3.25rem); }
  .hero__tagline  { font-size: clamp(1.15rem, 5.2vw, 1.5rem); }
  #contact-title  { font-size: clamp(1.375rem, 7.9vw, 2.5rem); } /* CONVERSATION. */
  .h2--xl         { font-size: clamp(1.75rem, 11vw, 3rem); }     /* & TEASERS */
  #voices-title   { font-size: clamp(1.625rem, 8.5vw, 2.5rem); }
  .h2--md         { font-size: clamp(1.5rem, 7.6vw, 2.25rem); }
  .hero__copy .btn--lg { width: 100%; justify-content: space-between; }

  .section-head { gap: 6px 16px; }

  /* two-column staggered grid, per the brief */
  .voices__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 12px; }
  .voices__grid > li:nth-child(2n) { margin-block-start: 14px; }
  .org { min-height: 96px; }
  .org__logo { width: 46px; height: 46px; }

  .episodes__rail > li { width: min(82vw, 420px); }
  .episodes__rail { scroll-snap-type: x mandatory; }

  .contact__underline { width: 120px; }
  .contact__figure img { aspect-ratio: 1.55 / 1; }
  /* leave room so the offset planes stay visible instead of being clipped */
  .contact__cardwrap { margin-right: calc(var(--plane) * 2); }

  /* The hero keeps its full height on a phone now that a photograph fills
     it. The old rule collapsed it because an empty yellow field that tall
     was dead space; a photograph is not. */
  .section--hero { padding-bottom: clamp(48px, 12vw, 72px); }
  .hero__media img { object-position: 58% 38%; }

  .site-footer__inner { flex-direction: column; align-items: flex-start; }
}

@media (max-width: 380px) {
  .voices__grid { gap: 12px 10px; }
  .org__name { font-size: .625rem; }
}

/* =====================================================================
   17. Reduced motion
   Motion is not implemented yet; this is the foundation the animation
   pass will extend. It must stay in place.
   ===================================================================== */
@media (prefers-reduced-motion: reduce) {
  html:focus-within { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
  .episodes__rail { scroll-snap-type: none; }
}


/* =====================================================================
   18. Motion hooks
   Everything here is inert until motion.js adds `.has-motion` to <html>.
   Delete motion.js and the approved static composition is untouched.
   ===================================================================== */

/* The `.tx-plane` transition planes and the stacking rules that layered
   the page content above them went with the spine in motion.js: the page
   is one colour now, so a plane in the incoming section's colour has
   nothing to reveal. `isolation` stays, because it keeps each section's
   own positioned children (the contact card and its offset planes) in
   their own stacking context. */
.section { isolation: isolate; }

/* ---- hero -----------------------------------------------------------
   The wordmark reveals through a vertical mask, not opacity, so it needs
   an overflow wrapper. motion.js creates it; without JS the h1 is plain. */
.wordmark-mask { display: block; overflow: hidden; }
.has-motion .hero__media img { will-change: transform, clip-path; }

/* ---- episodes -------------------------------------------------------
   The centred card is the sharp one. Neighbours recede, they never
   disappear. Driven by motion.js, not by a transition. */
.episodes__rail .ep { will-change: transform; }
.has-motion .episodes__rail .ep__figure img { will-change: filter; }

/* ---- voices ---------------------------------------------------------
   Layout transforms live on the LI. Interaction transforms live on the
   inner anchor, so hover can never overwrite the field's composition. */
.org { will-change: transform; }
.has-motion .org { transition: transform .32s cubic-bezier(.16,1,.3,1); }
.has-motion .org:hover, .has-motion .org:focus-visible { transform: translateY(-6px); }
.has-motion .org__arrow { transition: opacity .24s ease; }

/* ---- clips ----------------------------------------------------------
   When the title is pinned it must start at the TOP of its column. The
   static build centres it, which inside a ~1500px reel puts it halfway
   down the section — so pinning would hold it near the bottom of the
   viewport. Only applies while the pin is active. */
.clips__grid.is-pinned .clips__copy {
  align-content: start;
  padding-top: clamp(8px, 1.5vw, 24px);
}

/* One clear active state. Everything else recedes. */
.clips__reel.is-motion .clip { transition: transform .4s cubic-bezier(.16,1,.3,1); }
.clips__reel.is-motion .clip img { filter: brightness(.55) saturate(.8); transition: filter .4s ease; }
.clips__reel.is-motion .clip.is-active img { filter: none; }
.clips__reel.is-motion .clip.is-active { transform: scale(1.02); }

/* ---- contact --------------------------------------------------------
   Depth serves the entrance, then the card becomes flat and usable. */
.contact__grid { perspective: 1500px; }
.contact__cardwrap { transform-style: preserve-3d; will-change: transform; }

/* ---- an inert submit button must look inert ------------------------- */
.btn[disabled] { cursor: not-allowed; opacity: .55; }
.btn[disabled]:hover { background: var(--yellow); }

/* ---- footer curtain --------------------------------------------------
   The curtain is a plane drawn over the footer, not a clip on the footer:
   a clip would hide the footer's links outright if its trigger never
   fired, and the plane is pointer-events:none so links stay usable. */
.site-footer { position: relative; isolation: isolate; }
.site-footer > .shell { position: relative; z-index: 4; }

/* SplitText line wrappers */
.split-line { display: block; }

/* ---- boot hold ------------------------------------------------------
   Set by motion.js ONLY when a load has to restore a scroll position or
   a hash, and removed as soon as the position is applied — with a hard
   timeout behind it, so a thrown error can never leave the page blank.

   Three pins add roughly 4200px at 1440. A browser restoring a saved
   position does it against the un-pinned document, lands somewhere else,
   and the visitor watches the hero for a moment before the page
   scrambles. Holding the first paint for that one frame is what removes
   the flash. A fresh load at the top never sets this class. */
.mx-restoring body { visibility: hidden; }

@media (prefers-reduced-motion: reduce) {
  .clips__reel.is-motion .clip img,
  .clips__reel.is-motion .clip.is-active img { filter: none; }
  .clips__reel.is-motion .clip { transform: none; }
  .has-motion .org { transition: none; }
}

/* ---------- 19. Print ------------------------------------------------- */
@media print {
  /* the screen build is ink end to end; print it as ink on paper */
  body { background: #fff; color: #000; }
  .section-label, .section-head::after { color: #000; background: none; }
  .site-header, .episodes__rail-wrap, .contact__form { display: none; }
  .section { padding-block: 24px; }
}
