/* =============================================================================
 * LAYER 3 of 3 — Pressure Tested palette: midnight, field green, ivory, and
 * aged gold. This is the skin that actually ships.
 *
 * Loads last, so it wins. New components should take their colours from the
 * tokens below rather than from --ink/--paper/--warm (styles.css) or
 * --void/--bone/--ember (flagship.css), both of which this file remaps onto the
 * palette tokens anyway.
 *
 * The *-rgb tokens exist so rules can build translucent colours with
 * rgba(var(--maize-rgb), .2) -- use those rather than hardcoding rgba values.
 *
 * Style new sections HERE. Put structure in styles.css and colour in this file.
 * ========================================================================== */
:root {
  --maize: #f3e7cf;
  --paarl: #e39b2d;
  --millbrook: #212f25;
  --charade: #1a202c;
  --woodsmoke: #10141c;
  --bronze: #a3691c;
  --maize-rgb: 243, 231, 207;
  --paarl-rgb: 227, 155, 45;
  --millbrook-rgb: 33, 47, 37;
  --charade-rgb: 26, 32, 44;
  --woodsmoke-rgb: 16, 20, 28;
  --bronze-rgb: 163, 105, 28;

  --void: var(--woodsmoke);
  --slate: var(--charade);
  --surface: var(--charade);
  --bone: var(--maize);
  --ember: var(--paarl);
  --clay: var(--bronze);
  --faint: rgba(var(--maize-rgb), 0.15);
  --ink: var(--woodsmoke);
  --ink-2: var(--charade);
  --paper: var(--maize);
  --warm: var(--paarl);
  --muted: var(--bronze);
  --line: rgba(var(--maize-rgb), 0.18);
}

body,
.merch-page {
  background: radial-gradient(
    ellipse at 14% 0%,
    var(--charade) 0%,
    var(--charade) 38%,
    var(--woodsmoke) 100%
  );
  color: var(--maize);
}
body:before {
  background:
    radial-gradient(
      circle at 85% 5%,
      rgba(var(--paarl-rgb), 0.2),
      transparent 25%
    ),
    radial-gradient(
      circle at 3% 44%,
      rgba(var(--maize-rgb), 0.07),
      transparent 24%
    ),
    linear-gradient(
      126deg,
      var(--woodsmoke) 8%,
      var(--charade) 49%,
      var(--woodsmoke) 100%
    );
}
body:after {
  background-image:
    linear-gradient(rgba(var(--maize-rgb), 0.03) 1px, transparent 1px),
    linear-gradient(90deg, rgba(var(--maize-rgb), 0.03) 1px, transparent 1px);
}
.ambient {
  background:
    radial-gradient(
      circle at calc(82% - var(--ambient-progress, 0px))
        calc(16% + var(--ambient-progress, 0px)),
      rgba(var(--paarl-rgb), 0.17),
      transparent 27%
    ),
    radial-gradient(
      circle at calc(11% + var(--ambient-progress, 0px)) 72%,
      rgba(var(--maize-rgb), 0.07),
      transparent 27%
    );
}
.orb-one {
  background: radial-gradient(
    circle,
    rgba(var(--paarl-rgb), 0.3),
    rgba(var(--paarl-rgb), 0) 67%
  );
}
.orb-two {
  background: radial-gradient(
    circle,
    rgba(var(--maize-rgb), 0.13),
    rgba(var(--maize-rgb), 0) 69%
  );
}
.orb-three {
  background: radial-gradient(
    circle,
    rgba(var(--millbrook-rgb), 0.28),
    rgba(var(--millbrook-rgb), 0) 68%
  );
}
.badger-watermark {
  position: fixed;
  inset: 0;
  /* BEHIND the page content, so the badger never washes over a photograph --
     not the hero portrait, not the episode thumbnails. It used to sit at 19,
     above everything, which kept it visible in every section but also laid claw
     marks across every image.

     Lifting the images above it instead is not possible: #main is itself a
     stacking context at z-index 1, so no z-index on any descendant can climb
     past a fixed sibling at 19. The cap is #main, not the image.

     -1 rather than 0 keeps it clear of .ambient, which is also 0, while staying
     above body:after (-2, the grid) and body:before (-3, the page colour).
     Sections all have transparent backgrounds, so the badger still reads through
     them. .join was the one exception -- it painted a solid gradient -- and that
     gradient is now semi-transparent to match. Opacity stays at 0.065. */
  z-index: -1;
  pointer-events: none;
  /* The shorthand carries position/size plus the PNG for browsers without
     image-set(); the override below serves WebP (54 KB vs 357 KB) to the rest.
     Encoded at 1420px -- the widest this is ever painted -- and at low quality,
     which is invisible behind the grayscale filter and 0.065 opacity below. */
  background: url("assets/pressure-tested-negative.png") center 58% /
    min(92vw, 1420px) auto no-repeat;
  background-image: image-set(
    url("assets/pressure-tested-negative.webp") type("image/webp"),
    url("assets/pressure-tested-negative.png") type("image/png")
  );
  opacity: 0.065;
  filter: grayscale(1) contrast(1.08);
  mix-blend-mode: screen;
  will-change: transform;
}
@media (max-width: 700px) {
  .badger-watermark {
    background-size: 150vw auto;
    background-position: center 48%;
    opacity: 0.045;
  }
}
@media (prefers-reduced-motion: reduce) {
  .badger-watermark {
    will-change: auto;
  }
}

.site-header {
  border-color: rgba(var(--maize-rgb), 0.14);
  background: linear-gradient(
    180deg,
    rgba(var(--woodsmoke-rgb), 0.95),
    rgba(var(--woodsmoke-rgb), 0.52)
  );
}
.site-header.scrolled {
  background: rgba(var(--woodsmoke-rgb), 0.94);
  border-color: rgba(var(--maize-rgb), 0.27);
}
.brand-mark {
  box-shadow:
    0 0 0 1px rgba(var(--maize-rgb), 0.3),
    0 10px 22px rgba(0, 0, 0, 0.28);
}
/* Height drives the size and width follows the artwork's own ratio. Fixing both
   axes previously left object-fit: contain letterboxing the image inside its own
   box, and that dead space read as the logo sitting off-centre in the header.

   48px works with the wide lockup because its "WITH JOSH THIFAULT" line is 26.5%
   of the artwork's height -- about 12.7px here. The earlier stacked version put
   that line at 11.9%, which is why it needed a 92px mark and a taller header to
   be legible. */
.brand-lockup {
  display: block;
  width: auto;
  height: 48px;
  object-fit: contain;
  filter: drop-shadow(0 6px 12px rgba(0, 0, 0, 0.24));
}
@media (max-width: 700px) {
  .brand-lockup {
    height: 38px;
  }
}
.nav .nav-cta,
.button-primary {
  background: var(--woodsmoke);
  color: var(--maize);
  border: 1px solid var(--paarl);
  box-shadow: 5px 5px 0 rgba(var(--paarl-rgb), 0.35);
}
.nav .nav-cta:hover,
.button-primary:hover {
  background: var(--charade);
  color: var(--maize);
}

.hero-art {
  border-color: rgba(var(--maize-rgb), 0.17);
  background:
    radial-gradient(
      circle at 49% 42%,
      rgba(var(--paarl-rgb), 0.35),
      transparent 40%
    ),
    linear-gradient(150deg, rgba(var(--maize-rgb), 0.09), transparent 52%);
}
.hero-art:before,
.target-ring {
  border-color: rgba(var(--maize-rgb), 0.24);
}
.hero h1 em,
.eyebrow,
.hero-proof > span,
.hero-proof b,
.mission-number,
.mission h2 em,
.home-merch-heading h2 em,
.prelaunch .section-top h2 em,
.transmission-promise span {
  color: var(--paarl);
}
.eyebrow span {
  background: var(--paarl);
}
.mission-copy p,
.transmission-copy > p:not(.episode-label) {
  color: var(--maize);
}
/* The mission statement reads as a subtitle under the headline, so it steps back
   from full-strength ivory rather than competing with it. */
.hero-summary {
  color: rgba(var(--maize-rgb), 0.76);
}
.mission-copy {
  border-color: var(--paarl);
  padding: 27px 0 0 28px;
}
.mission-footnote {
  border-color: rgba(var(--maize-rgb), 0.2);
}

.pillars {
  background: var(--maize);
  color: var(--woodsmoke);
}
.pillars:before {
  color: rgba(var(--woodsmoke-rgb), 0.06);
}
.pillars .section-top,
.pillar-grid {
  border-color: rgba(var(--woodsmoke-rgb), 0.22);
}
.pillar-grid article {
  border-color: rgba(var(--woodsmoke-rgb), 0.22);
}
.pillar-grid article:hover {
  background: var(--paarl);
  color: var(--maize);
}
.pillars .eyebrow,
.pillar-grid .number {
  color: var(--millbrook);
}
.pillars .eyebrow span {
  background: var(--millbrook);
}

.episodes .section-top,
.featured-episode,
.episode-list article,
.transmission-panel {
  border-color: rgba(var(--maize-rgb), 0.24);
}
.featured-episode,
.transmission-panel {
  background: linear-gradient(
    135deg,
    rgba(var(--maize-rgb), 0.06),
    rgba(var(--paarl-rgb), 0.07)
  );
}
.episode-art,
.transmission-mark {
  background: linear-gradient(
    145deg,
    var(--paarl) 0 46%,
    var(--charade) 46% 100%
  );
}
.episode-list article:hover {
  background: rgba(var(--maize-rgb), 0.07);
}
.transmission-mark {
  border-color: rgba(var(--maize-rgb), 0.22);
}
.transmission-mark:before {
  text-shadow: 7px 8px 0 rgba(var(--woodsmoke-rgb), 0.28);
}
.transmission-promise {
  border-color: rgba(var(--maize-rgb), 0.2);
  background: rgba(var(--woodsmoke-rgb), 0.25);
}

.home-merch {
  background: linear-gradient(120deg, var(--charade), var(--woodsmoke));
  border-color: rgba(var(--maize-rgb), 0.18);
}
/* ONE skin for every merch card, deliberately the same as .featured-episode-panel:
   the identical translucent gradient, hairline border, and hard offset shadow. The
   cards used to carry a colourway each -- charade, maize, millbrook -- left over
   from a four-product placeholder set. With three cards that read as a pale tile
   between two dark ones, and .cap-card had to flip to dark ink and a bronze flag
   just to stay legible. A store shelf should look like a set, not three swatches. */
.merch-product {
  background: linear-gradient(
    135deg,
    rgba(var(--maize-rgb), 0.055),
    rgba(var(--paarl-rgb), 0.09)
  );
  border-color: rgba(var(--maize-rgb), 0.24);
  color: var(--maize);
  box-shadow: 12px 14px 0 rgba(var(--woodsmoke-rgb), 0.28);
}
.merch-product:hover,
.merch-product:focus-visible {
  border-color: var(--paarl);
  box-shadow: 16px 18px 0 rgba(var(--woodsmoke-rgb), 0.34);
}
/* The plate sits a shade darker than the card so the product reads as sitting ON
   something, rather than floating in the panel. */
.merch-plate {
  background: linear-gradient(
    160deg,
    rgba(var(--woodsmoke-rgb), 0.55),
    rgba(var(--charade-rgb), 0.35)
  );
}
/* Category kicker in gold, matching every other eyebrow on the page. */
.merch-number {
  color: var(--paarl);
}

/* Semi-transparent rather than the solid charade/woodsmoke it used to be. The
   badger watermark now sits BEHIND the page content (see .badger-watermark) so it
   cannot wash over the hero photo and the episode thumbnails. Every other section
   has a transparent background, so the badger still shows through them -- this one
   painted a solid gradient and was the only section that lost it entirely. The
   alpha is high enough that the panel still reads as its own block of colour. */
.join {
  background: linear-gradient(
    135deg,
    rgba(var(--charade-rgb), 0.88),
    rgba(var(--woodsmoke-rgb), 0.88)
  );
}
.join .eyebrow {
  color: var(--maize);
}
/* Gold, like every other accented heading word on the page. This was grouped with
   the eyebrow above and set to cream, so "MOVEMENT." matched the rest of the
   heading exactly and read as no accent at all. The eyebrow keeps its cream
   override deliberately. */
.join h2 em {
  color: var(--paarl);
}
.signup button {
  background: var(--woodsmoke);
  color: var(--maize);
}

.merch-page {
  background: radial-gradient(
    ellipse at 12% 0%,
    var(--charade) 0%,
    var(--charade) 38%,
    var(--woodsmoke) 100%
  );
}
.merch-hero-copy > p:not(.eyebrow) {
  color: var(--maize);
}
.hero-product {
  background:
    radial-gradient(
      circle at 50% 43%,
      rgba(var(--paarl-rgb), 0.42),
      transparent 43%
    ),
    linear-gradient(135deg, rgba(var(--maize-rgb), 0.1), transparent 55%);
  border-color: rgba(var(--maize-rgb), 0.18);
}
.hero-product:before,
.hero-product:after {
  border-color: rgba(var(--maize-rgb), 0.18);
}
.tee {
  background: var(--charade);
}
.tee:before {
  border-color: rgba(var(--maize-rgb), 0.45);
}
.sample-note {
  background: var(--millbrook);
  color: var(--maize);
}
.sample-note .eyebrow,
.sample-note h2 em {
  color: var(--maize);
}
.sample-note .button-outline {
  border-color: var(--maize);
  color: var(--maize);
}
.sample-note .button-outline:hover {
  background: var(--woodsmoke);
  color: var(--maize);
}
.site-footer {
  color: rgba(var(--maize-rgb), 0.72);
}
.site-footer a {
  color: var(--maize);
}
.site-footer small {
  color: rgba(var(--maize-rgb), 0.62);
}

/* Collection illustrations inherit the same six-color system. */
.shirt-visual {
  background: linear-gradient(145deg, var(--charade), var(--woodsmoke));
}
.hoodie-visual {
  background: linear-gradient(145deg, var(--paarl), var(--bronze));
}
.cap-visual {
  background: linear-gradient(145deg, var(--maize), var(--bronze));
}
.notebook-visual {
  background: linear-gradient(145deg, var(--charade), var(--woodsmoke));
}
.tee,
/* The garments are lifted well clear of the plate behind them. They used to be
   var(--charade), which was fine against the old pale card but is within a few
   percent of the new dark plate -- the silhouettes simply disappeared.
   The drop-shadow is inverted to sit ABOVE the shape, which gives a rim light
   along the top edge; clip-path shapes cannot take a border, and the rim is what
   separates a dark garment from a dark background. */
.mini-tee,
.cap,
.mini-cap {
  background: linear-gradient(165deg, #333d4d, #232b38);
  filter: drop-shadow(0 -1px 0 rgba(var(--maize-rgb), 0.22))
    drop-shadow(10px 14px 14px rgba(var(--woodsmoke-rgb), 0.45));
}
.cap:after,
/* The brim, a shade darker than the crown so the two read as separate planes.
   It inherits the crown's rim light and shadow, because a filter on .mini-cap
   applies to its pseudo-elements too. */
.mini-cap:after {
  background: linear-gradient(165deg, #2b3442, #1d2430);
}
/* The collar. At 0.45 alpha over the old pale card it was a neat neckline; against
   the dark plate the same stroke reads as a bright smudge, so it drops to a hint
   of a neck tape. */
.mini-tee:before {
  border-color: rgba(var(--maize-rgb), 0.2);
  border-top: 0;
}
/* Cream over gold, the way the real print will run. */
.mini-tee b {
  color: rgba(var(--maize-rgb), 0.72);
}
.mini-tee strong {
  color: var(--paarl);
}
.hoodie,
.hoodie-print,
.cap span,
.mini-cap {
  color: var(--paarl);
}
.notebook,

/* Official lockups replace all placeholder PT marks across the product samples. */
.tee-print-logo {
  position: absolute;
  top: 42%;
  left: 22.5%;
  width: 55%;
  height: auto;
  display: block;
  filter: drop-shadow(0 4px 5px rgba(0, 0, 0, 0.22));
}
.hoodie-print-logo {
  position: absolute;
  top: 35%;
  left: 30%;
  width: 40%;
  height: auto;
  display: block;
  mix-blend-mode: multiply;
}
.cap-logo {
  position: absolute;
  top: 23%;
  left: 31%;
  width: 38%;
  height: auto;
  display: block;
  mix-blend-mode: multiply;
}
/* The monogram artwork is dark ink meant for light garments, and it was composited
   with mix-blend-mode: multiply -- which on a dark cap multiplies toward black and
   erases it completely. brightness(0) crushes the artwork to a flat silhouette and
   invert(1) flips it to white, so it renders as a cream print whatever colours the
   source file happens to contain. */
.mini-cap img {
  position: absolute;
  top: 23%;
  left: 31%;
  width: 38%;
  height: auto;
  mix-blend-mode: normal;
  filter: brightness(0) invert(1);
  opacity: 0.86;
}

/* Featured episode: intentionally uses the supplied 16:9 artwork without cropping. */
/* The section keeps the shared 1240px measure. Widening it to 1320 was tried and
   reverted: every other element on the page -- the hero, the scripture, the episode
   list, and the logo and nav in the header -- sits at left 100 / right 1340, so a
   wider panel broke that alignment by 40px a side and read as a mistake rather than
   as emphasis. The panel is made larger by the column ratio instead, below.

   padding-bottom drops from 126px. That plus the list's top padding put 156px of
   air between the featured episode and the row beneath it, which read as two
   unrelated sections rather than one idea. */
.featured-episode-section {
  position: relative;
  z-index: 1;
  padding-top: 34px;
  padding-bottom: 30px;
  scroll-margin-top: 112px;
}
.featured-episode-heading {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 24px;
  margin-bottom: 22px;
  padding-bottom: 18px;
  border-bottom: 1px solid rgba(var(--maize-rgb), 0.2);
}
.featured-episode-heading .eyebrow {
  margin: 0;
}
.featured-episode-index {
  margin: 0;
  color: rgba(var(--maize-rgb), 0.7);
  font: 800 11px/1 var(--body);
  letter-spacing: 0.14em;
}
.featured-episode-panel {
  display: grid;
  /* The still takes more of the row than it used to (1.58fr), which is what makes
     the featured episode larger: its height is derived from its width at 16:9, so
     the only way to grow the panel inside a fixed measure is to give the media a
     bigger share. The copy column loses some width in exchange and the headline
     auto-fits a little smaller -- a fair trade, since the video is the thing being
     featured. */
  grid-template-columns: minmax(0, 1.9fr) minmax(300px, 0.72fr);
  overflow: hidden;
  border: 1px solid rgba(var(--maize-rgb), 0.24);
  background: linear-gradient(
    135deg,
    rgba(var(--maize-rgb), 0.055),
    rgba(var(--paarl-rgb), 0.09)
  );
  box-shadow: 16px 18px 0 rgba(var(--woodsmoke-rgb), 0.28);
}
/* The homepage stacks two featured panels, so they need air between them --
   enough to clear the offset box-shadow above. */
.featured-episode-panel + .featured-episode-panel {
  margin-top: 46px;
}
/* Locked to 16:9 rather than stretching to the copy column's height.
 *
 * This is what caused the black letterbox bars. The panel is a two-column grid
 * whose row height comes from the copy column, so a longer description made a
 * taller figure -- 850x599 (1.42) for episode one against 850x505 (1.68) for
 * episode two. The 16:9 thumbnail was then painted `contain` inside that
 * too-tall box, and .video-embed's black background filled the rest: 121px of
 * bars on the first panel, 27px on the second. Hence "not even on episode two".
 *
 * Cropping to fill instead was tried and rejected: at 850x599 it eats 10% off
 * each side, which cut the "EP. 1" label off entirely and sliced the badger
 * mark in half.
 *
 * aspect-ratio is the FLOOR, not a lock. It is what the figure contributes when
 * the grid row is measured, so a panel whose copy is shorter than the picture is
 * exactly 16:9 with nothing cropped -- the common case.
 *
 * align-self is stretch (the default, stated here because an earlier revision set
 * `start` and that was wrong). With `start` the figure refused to fill a row the
 * text overran, which left a thin band of panel showing under the artwork: 4.6px
 * on episode two, none on episode one, because the copy column is 482.9px against
 * the figure's 478.4px. Now that the blurbs come from YouTube rather than being
 * hand-written, that height varies per episode, so any fixed alignment leaves a
 * sliver on some of them.
 *
 * Stretching means the box can end up marginally taller than 16:9, and
 * object-fit: cover absorbs the difference. The crop is proportional to the
 * overrun, so at 4.6px it is 0.5% off each side -- invisible, and bounded, because
 * the derived title and blurb are both length-capped and the panels stack below
 * 1280px where the columns stop competing at all.
 *
 * The transparent background stays: nothing should paint its own fill behind the
 * artwork, or a rounding error becomes a visible band again. */
.featured-episode-art {
  position: relative;
  margin: 0;
  min-width: 0;
  /* width is pinned to the column so aspect-ratio can only ever drive the HEIGHT.
     Without it, a stretched row height becomes definite and aspect-ratio runs
     backwards to compute the width instead -- which pushed the figure 8.1px past
     its column and under the copy panel. With both axes definite the ratio is
     ignored for the used size, while still supplying the intrinsic height that
     sizes the row in the first place. */
  width: 100%;
  aspect-ratio: 16 / 9;
  /* CENTRED, not stretched. Stretching tied the still's height to the row, so a copy
     column one line taller than the picture squeezed the frame out of 16:9 and
     object-fit cropped the episode's own artwork -- measured at 1.735 for a
     seven-line blurb and 1.656 for eight. Centred, the ratio is fixed and any extra
     row height becomes equal space above and below the still, which reads as inset
     rather than as the 4.5px bottom sliver that made this stretch in the first
     place. */
  align-self: center;
  background: transparent;
}
.featured-episode-art:after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    90deg,
    transparent 67%,
    rgba(var(--woodsmoke-rgb), 0.3)
  );
}
/* `cover`, not `contain`. With the figure locked to 16:9 above and YouTube
   thumbnails being 16:9, the two are identical here -- but cover is the safer
   default, because a thumbnail that ever arrives at another ratio crops instead
   of reintroducing the bars this change exists to remove. */
.featured-episode-art img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
/* The media/copy divider moved here from .featured-episode-art's border-right.
   The figure no longer stretches the full row, so a border on it would stop
   partway down and read as a stub; the copy column is what sets the row height,
   so its left edge always spans the full panel. */
.featured-episode-copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  border-left: 1px solid rgba(var(--maize-rgb), 0.2);
  /* Both axes are trimmed to buy headroom: the copy has to fit inside the height of
     the 16:9 artwork beside it, or the row grows past the picture, the figure
     stretches to fill it, and object-fit crops the still.
     The horizontal trim is the one that does the work. At 1440 the column is 340px
     and the old 4vw padding spent 115px of it, leaving the blurb a 224px measure --
     27 characters a line, so two sentences ran to seven lines. 3vw leaves 254px. */
  padding: clamp(26px, 3.1vw, 48px) clamp(24px, 3vw, 46px);
  background: linear-gradient(
    155deg,
    rgba(var(--charade-rgb), 0.84),
    rgba(var(--woodsmoke-rgb), 0.92)
  );
}
.featured-episode-copy .episode-label {
  margin: 0 0 18px;
  color: var(--paarl);
  font: 800 11px/1 var(--body);
  letter-spacing: 0.16em;
}
.featured-episode-copy h2 {
  margin: 0;
  color: var(--maize);
  font: 800 clamp(58px, 7vw, 104px)/0.76 var(--display);
  letter-spacing: -0.035em;
}
.featured-episode-copy h2 em {
  color: var(--paarl);
  font-style: normal;
}
/* 32ch rather than 28ch so the blurb can use the measure the padding trim just gave
   it, with tighter leading and margins because a two-sentence blurb runs four or five
   lines rather than two -- at 1.65 with 30px margins it pushed the copy column 50px
   past the height of the still. */
.featured-episode-copy > p:not(.episode-label) {
  max-width: 32ch;
  margin: 20px 0;
  color: rgba(var(--maize-rgb), 0.82);
  line-height: 1.55;
}
/* Only when something follows it. This margin exists to separate the CTA from
   .featured-episode-note, but the note is optional and usually absent -- so on
   these panels it was 28px of dead space under the last element, pushing the copy
   column past the height of the 16:9 artwork beside it. */
.featured-episode-copy .button:not(:last-child) {
  margin-bottom: 28px;
}
.featured-episode-note {
  padding-top: 17px;
  border-top: 1px solid rgba(var(--maize-rgb), 0.18);
  color: rgba(var(--maize-rgb), 0.6);
  font: 800 10px/1.4 var(--body);
  letter-spacing: 0.13em;
}
/* Stack below 1280.
 *
 * The side-by-side layout only holds while the copy fits inside the height of the
 * 16:9 artwork beside it. Measured, it does at 1280 and above -- 34px of slack on
 * episode one, 23px on episode two -- and fails by 1200, because narrowing the
 * panel shrinks the media height while rewrapping the text taller. That is what
 * produced the uneven gaps (8px on one panel, 23px on the other) this layout
 * exists to avoid.
 *
 * Stacked, a mismatch is impossible: the figure is full width at 16:9 with the
 * copy beneath it, so the copy's length cannot affect the picture. */
@media (max-width: 1279px) {
  .featured-episode-panel {
    grid-template-columns: 1fr;
  }
  .featured-episode-art {
    border-bottom: 1px solid rgba(var(--maize-rgb), 0.2);
  }
  .featured-episode-art:after {
    background: linear-gradient(
      0deg,
      rgba(var(--woodsmoke-rgb), 0.25),
      transparent 38%
    );
  }
  .featured-episode-copy {
    border-left: 0;
  }
}
@media (max-width: 900px) {
  .featured-episode-section {
    padding-bottom: 98px;
  }
  .featured-episode-copy {
    padding: 34px 28px;
  }
  .featured-episode-copy h2 {
    font-size: clamp(52px, 8vw, 78px);
  }
}
@media (max-width: 700px) {
  .featured-episode-section {
    padding-top: 10px;
    padding-bottom: 76px;
  }
  .featured-episode-heading {
    align-items: flex-start;
    flex-direction: column;
    margin-bottom: 16px;
  }
  /* Already single-column and already divided by the figure's border-bottom from
     the 1279px block above; only the phone-specific spacing belongs here. */
  .featured-episode-panel {
    box-shadow: 9px 11px 0 rgba(var(--woodsmoke-rgb), 0.3);
  }
  .featured-episode-copy {
    padding: 38px 28px;
  }
  .featured-episode-copy h2 {
    font-size: clamp(60px, 19vw, 92px);
  }
  .featured-episode-copy > p:not(.episode-label) {
    margin: 24px 0;
  }
  .featured-episode-note {
    width: 100%;
  }
}

/* Ordered video playlist: content is rendered from playlist-data.js. */
.video-playlist-section {
  position: relative;
  z-index: 1;
  padding-top: 26px;
  padding-bottom: 128px;
  scroll-margin-top: 112px;
}
.video-playlist-heading {
  display: flex;
  align-items: end;
  justify-content: space-between;
  gap: 48px;
  margin-bottom: 26px;
  padding-bottom: 16px;
  border-bottom: 1px solid rgba(var(--maize-rgb), 0.2);
}
.video-playlist-heading .eyebrow {
  margin: 0 0 15px;
}
/* Down from clamp(58px, 7vw, 100px), where it competed with the featured episode's
   own headline directly above it -- the thing meant to lead.
   40px rather than 48px because widening the still narrowed the copy column, which
   auto-fits the panel headline down to about 51px; at 48px the section label was
   within three points of the title above it and the hierarchy read flat. */
.video-playlist-heading h2 {
  margin: 0;
  color: var(--maize);
  /* Down from clamp(26px, 2.9vw, 40px). Titles are now the full YouTube titles, which
     land in the high thirties once the fitter has them, so a 40px label would sit level
     with -- or above -- the episode headline it belongs under. */
  font: 800 clamp(21px, 2.2vw, 30px)/0.9 var(--display);
  letter-spacing: -0.03em;
}
.video-playlist-heading h2 em {
  color: var(--paarl);
  font-style: normal;
}
.video-playlist-heading > p {
  max-width: 32ch;
  margin: 0 0 4px;
  color: rgba(var(--maize-rgb), 0.76);
  line-height: 1.6;
}
.video-playlist-list {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(20px, 2.4vw, 34px);
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: playlist;
}
/* The way to older episodes: one line under the row, set as a headline rather than
   a card, so it closes the section instead of pretending to be a fourth episode.
   Held to 28px against the section heading's 40px -- close enough to read as
   display type, far enough that it does not look like a second heading. */
/* The words sit in one span rather than as bare text beside the arrow: flex
   blockifies loose text nodes, which would have turned the space between "see more"
   and "episodes" into a gap value to maintain. Padding carries the tap target past
   44px on a 21px line without opening the gap above it. */
.video-playlist-more {
  display: inline-flex;
  align-items: center;
  margin-top: clamp(14px, 1.4vw, 20px);
  padding: 12px 0;
  color: var(--maize);
  font: 800 clamp(21px, 2.1vw, 28px)/1 var(--display);
  letter-spacing: -0.02em;
  text-transform: uppercase;
  text-decoration: none;
  transition: color 0.2s ease;
}
.video-playlist-more em {
  color: var(--paarl);
  font-style: normal;
}
.video-playlist-more .ui-icon {
  width: 21px;
  height: 21px;
  margin-left: 9px;
  transition: transform 0.2s ease;
}
/* Colour alone would be a weak affordance on a line that already looks like a
   heading, so the arrow travels and the words underline on hover. */
.video-playlist-more:hover,
.video-playlist-more:focus-visible {
  color: var(--paarl);
}
.video-playlist-more:hover span,
.video-playlist-more:focus-visible span {
  text-decoration: underline;
  text-decoration-thickness: 2px;
  text-underline-offset: 6px;
}
.video-playlist-more:hover .ui-icon,
.video-playlist-more:focus-visible .ui-icon {
  transform: translateX(6px);
}
.video-playlist-more:focus-visible {
  outline: 2px solid var(--paarl);
  outline-offset: 6px;
}
.video-playlist-item {
  min-width: 0;
  counter-increment: playlist;
}
.video-card {
  height: 100%;
  border-top: 1px solid rgba(var(--maize-rgb), 0.28);
  background: linear-gradient(
    145deg,
    rgba(var(--charade-rgb), 0.56),
    rgba(var(--woodsmoke-rgb), 0.74)
  );
}
.video-card-media {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  aspect-ratio: 16/9;
  overflow: hidden;
  background: linear-gradient(135deg, var(--charade), var(--woodsmoke));
  isolation: isolate;
}
.video-card-media:not(.is-placeholder) {
  cursor: pointer;
}
.video-card-media img {
  position: relative;
  z-index: 1;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition:
    transform 0.42s cubic-bezier(0.16, 1, 0.3, 1),
    filter 0.42s ease;
}
.video-card-media:after {
  content: "";
  position: absolute;
  z-index: 2;
  inset: 0;
  background: linear-gradient(
    135deg,
    rgba(var(--woodsmoke-rgb), 0.08),
    rgba(var(--woodsmoke-rgb), 0.44)
  );
  pointer-events: none;
  transition: background-color 0.35s ease;
}
.video-thumbnail-fallback {
  position: absolute;
  z-index: 0;
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  padding: 22px;
  border: 1px solid rgba(var(--paarl-rgb), 0.32);
  color: rgba(var(--maize-rgb), 0.6);
  font: 800 12px/1.2 var(--body);
  letter-spacing: 0.16em;
  text-align: center;
  background: repeating-linear-gradient(
    135deg,
    rgba(var(--maize-rgb), 0.04) 0 1px,
    transparent 1px 12px
  );
  opacity: 0;
}
.video-card-media.is-placeholder .video-thumbnail-fallback,
.video-card-media.has-thumbnail-error .video-thumbnail-fallback {
  opacity: 1;
}
.video-play-indicator {
  position: absolute;
  z-index: 3;
  display: grid;
  place-items: center;
  width: 54px;
  height: 54px;
  border: 1px solid var(--paarl);
  color: var(--maize);
  background: rgba(var(--woodsmoke-rgb), 0.82);
  box-shadow: 5px 5px 0 rgba(var(--paarl-rgb), 0.32);
  transition:
    transform 0.35s cubic-bezier(0.16, 1, 0.3, 1),
    background-color 0.35s ease;
}
.video-play-indicator svg {
  width: 24px;
  height: 24px;
  fill: currentColor;
  transform: translateX(1px);
}
.video-card-media:not(.is-placeholder):hover img {
  transform: scale(1.045);
  filter: brightness(1.05);
}
.video-card-media:not(.is-placeholder):hover .video-play-indicator {
  transform: translate(3px, -3px);
  background: var(--paarl);
  color: var(--woodsmoke);
}
.video-card-media:not(.is-placeholder):focus-visible {
  z-index: 4;
  outline: 2px solid var(--maize);
  outline-offset: -5px;
}
.video-card-media:not(.is-placeholder):focus-visible .video-play-indicator {
  background: var(--paarl);
  color: var(--woodsmoke);
}
.video-card-copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-height: 188px;
  padding: 23px 23px 25px;
}
.video-card-number,
.video-card-pending,
.video-card-link-label {
  font: 800 10px/1 var(--body);
  letter-spacing: 0.14em;
}
.video-card-number {
  color: var(--paarl);
}
/* Release dates ride the episode label rather than taking a line of their own, dimmed
   so the episode number still leads it. The separator lives in CSS so it exists only
   when a date does, and uppercasing here leaves the <time> text readable as
   "Aug 7, 2026" for anything reading the markup. */
.episode-date {
  color: rgba(var(--maize-rgb), 0.58);
  text-transform: uppercase;
}
.episode-date:before {
  content: " \00b7  ";
}
/* Down from clamp(29px, 3vw, 43px), because a card carries the whole YouTube title now
   and 43px ran a 56-character one to six lines in a third of the row. At 27px the
   longest of them holds three. */
.video-card-copy h3 {
  margin: 15px 0 11px;
  color: var(--maize);
  font: 800 clamp(21px, 1.9vw, 27px)/0.94 var(--display);
  letter-spacing: -0.02em;
}
.video-card-copy p {
  margin: 0;
  color: rgba(var(--maize-rgb), 0.72);
  font-size: 14px;
  line-height: 1.55;
}
.video-card-pending,
.video-card-link-label {
  margin-top: auto;
  padding-top: 22px;
}
.video-card-pending {
  color: rgba(var(--maize-rgb), 0.48);
}
.video-card-link-label {
  color: var(--paarl);
}
.video-playlist-status {
  margin: 24px 0 0;
  color: rgba(var(--maize-rgb), 0.5);
  font: 700 11px/1.4 var(--body);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}
@media (max-width: 900px) {
  .video-playlist-section {
    padding-bottom: 98px;
  }
  .video-playlist-heading {
    align-items: start;
    gap: 28px;
  }
  .video-playlist-list {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (max-width: 700px) {
  .video-playlist-section {
    padding-top: 8px;
    padding-bottom: 76px;
  }
  .video-playlist-heading {
    display: block;
    margin-bottom: 28px;
  }
  .video-playlist-heading > p {
    margin-top: 22px;
  }
  /* Phones get a compact list rather than three stacked blocks. Full-width cards ran
     447, 469 and 469px -- 1429px with the gaps, nearly two phone screens to pass three
     episodes, with the featured panel and its own still sitting directly above them.
     The still moves left at 124px, the title sits beside it, and the blurb comes off:
     in a list the title and the date are what the eye scans for. Desktop keeps the
     full cards. */
  .video-playlist-list {
    grid-template-columns: 1fr;
    gap: 12px;
  }
  /* The still takes a share of the row rather than a fixed width: at 320px a fixed
     124px left the title 116px to work in and dragged the longest one to three lines.
     The percentage resolves against the card's content box -- 309px at 375px wide, not
     the viewport -- so 38% lands at about 117px there. Floored at 112px so the frame
     stays readable on a small phone, capped at 176px so it does not balloon at the top
     of this range. */
  .video-card {
    display: grid;
    grid-template-columns: clamp(112px, 38%, 176px) minmax(0, 1fr);
    column-gap: 14px;
    align-items: start;
    padding: 13px;
  }
  /* Tapping the small still would otherwise play the episode 124px wide, so the player
     takes the whole row as soon as it goes live. */
  .video-card-media:has(.video-embed--live) {
    grid-column: 1 / -1;
  }
  .video-card-copy {
    min-height: 0;
    padding: 0;
  }
  .video-card-copy h3 {
    margin: 6px 0 0;
    /* 24px held a written title in two lines; a full YouTube title needs 18px to stay
       inside three beside a 117px still. */
    font-size: 18px;
  }
  .video-card-copy p {
    display: none;
  }
  .video-card-action {
    margin-top: 4px;
    padding: 7px 0;
  }
  /* The 68x48 play button covers most of a 124px still. */
  .video-embed-play {
    width: 42px;
    height: 30px;
    border-radius: 7px;
  }
  .video-embed-play::before {
    border-width: 6px 0 6px 10px;
  }
  .video-play-indicator {
    width: 50px;
    height: 50px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .video-card-media img,
  .video-play-indicator {
    transition: none !important;
  }
}
@media (max-width: 700px) {
  .tee-print-logo {
    top: 43%;
  }
}

/* Site-wide finishing pass: clearer wayfinding, repeatable editorial framing, and honest prelaunch states. */
:root {
  --page-progress: 0%;
}
.site-header:after {
  content: "";
  position: absolute;
  right: 0;
  bottom: -1px;
  left: 0;
  height: 2px;
  pointer-events: none;
  background: linear-gradient(90deg, var(--paarl), var(--maize));
  transform: scaleX(var(--page-progress));
  transform-origin: left;
  transition: transform 0.1s linear;
}
.nav a {
  position: relative;
  transition: color 0.22s ease;
}
.nav a:not(.nav-cta):after {
  content: "";
  position: absolute;
  right: 0;
  bottom: -9px;
  left: 0;
  height: 1px;
  background: var(--paarl);
  transform: scaleX(0);
  transform-origin: right;
  transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}
.nav a:not(.nav-cta):hover:after,
.nav a:not(.nav-cta).is-active:after {
  transform: scaleX(1);
  transform-origin: left;
}
.nav a.is-active {
  color: var(--maize);
}

/* The "01 / INTRODUCTION" corner labels are gone, along with the data-section
   attributes that fed them and the four per-section position overrides.

   The deleted block also carried `position: relative` for every section. That is
   safe to lose: only #contact, #about, and #mission had no other rule providing
   it, and nothing inside them anchors to the section -- the honeypot label in the
   contact form resolves against the form, not the section. The sections that do
   need a positioning context (.hero, .featured-episode-section, .join,
   .home-merch, .video-playlist-section, .audience) each declare their own. */

.featured-episode-panel,
.transmission-panel,
.video-card {
  position: relative;
}
.featured-episode-panel:before,
.transmission-panel:after,
.video-card:before {
  content: "";
  position: absolute;
  z-index: 4;
  width: 18px;
  height: 18px;
  pointer-events: none;
}
.featured-episode-panel:before {
  top: -1px;
  left: -1px;
  border-top: 2px solid var(--paarl);
  border-left: 2px solid var(--paarl);
}
.transmission-panel:after {
  right: -1px;
  bottom: -1px;
  border-right: 2px solid var(--paarl);
  border-bottom: 2px solid var(--paarl);
}
.video-card:before {
  top: -1px;
  right: -1px;
  border-top: 2px solid var(--paarl);
  border-right: 2px solid var(--paarl);
  opacity: 0.72;
}
.featured-episode-panel,
.transmission-panel {
  transition:
    transform 0.35s cubic-bezier(0.16, 1, 0.3, 1),
    box-shadow 0.35s ease;
}
.featured-episode-panel:hover,
.transmission-panel:hover {
  transform: translate3d(0, -4px, 0);
  box-shadow: 22px 26px 0 rgba(var(--woodsmoke-rgb), 0.28);
}
.video-card {
  overflow: hidden;
  transition:
    transform 0.32s cubic-bezier(0.16, 1, 0.3, 1),
    border-color 0.32s ease,
    box-shadow 0.32s ease;
}
.video-card:hover {
  transform: translateY(-7px);
  box-shadow: 11px 15px 0 rgba(var(--woodsmoke-rgb), 0.25);
}
.video-card:hover:before {
  opacity: 1;
}

.merch-product {
  transition:
    transform 0.28s cubic-bezier(0.16, 1, 0.3, 1),
    border-color 0.28s ease,
    filter 0.28s ease;
}
.merch-product:hover {
  transform: translateY(-5px);
  filter: brightness(1.045);
}
.signup small {
  display: block;
}
.signup:focus-within {
  box-shadow: 0 0 0 4px rgba(var(--paarl-rgb), 0.16);
}

@media (max-width: 700px) {
  .nav a:not(.nav-cta):after {
    bottom: -4px;
  }
  .featured-episode-panel:hover,
  .transmission-panel:hover,
  .video-card:hover {
    transform: none;
    box-shadow: none;
  }
  .featured-episode-panel:before,
  .transmission-panel:after,
  .video-card:before {
    width: 13px;
    height: 13px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .site-header:after,
  .nav a:not(.nav-cta):after,
  .featured-episode-panel,
  .transmission-panel,
  .video-card,
  .merch-product {
    transition: none !important;
  }
}

/* Audience-led path: recognition first, then a clear alternative, then the work itself. */
.audience {
  position: relative;
  z-index: 1;
  padding: 44px 0 148px;
}
.audience-intro {
  max-width: 870px;
}
.audience-intro .eyebrow {
  margin-bottom: 24px;
}
.audience h2 {
  margin: 0;
  color: var(--maize);
  font: 800 clamp(55px, 6.9vw, 104px)/0.79 var(--display);
  letter-spacing: -0.035em;
}
.audience h2 em {
  color: var(--paarl);
  font-style: normal;
}
.audience-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.82fr) minmax(400px, 1.18fr);
  gap: clamp(52px, 9vw, 145px);
  margin-top: 64px;
  padding-top: 30px;
  border-top: 1px solid rgba(var(--maize-rgb), 0.22);
}
.audience-copy {
  max-width: 450px;
  padding-left: 28px;
  border-left: 2px solid var(--paarl);
}
.audience-copy p {
  margin: 0 0 21px;
  color: rgba(var(--maize-rgb), 0.87);
  font-size: 17px;
  line-height: 1.68;
}
.audience-copy .text-link {
  margin-top: 9px;
}
.audience-markers {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
  border: 1px solid rgba(var(--maize-rgb), 0.2);
  background: rgba(var(--charade-rgb), 0.22);
}
.audience-markers li {
  min-height: 223px;
  padding: 25px 22px;
  border-right: 1px solid rgba(var(--maize-rgb), 0.2);
}
.audience-markers li:last-child {
  border-right: 0;
}
.audience-markers span {
  display: block;
  margin-bottom: 43px;
  color: var(--paarl);
  font: 800 10px/1 var(--body);
  letter-spacing: 0.15em;
}
.audience-markers strong {
  display: block;
  color: var(--maize);
  font: 800 23px/0.87 var(--display);
  letter-spacing: 0.015em;
}
.audience-markers p {
  margin: 15px 0 0;
  color: rgba(var(--maize-rgb), 0.65);
  font-size: 13px;
  line-height: 1.5;
}
@media (max-width: 900px) {
  .audience {
    padding-bottom: 112px;
  }
  .audience-grid {
    grid-template-columns: 1fr;
    gap: 42px;
  }
  .audience-copy {
    max-width: 620px;
  }
  .audience-markers {
    max-width: 720px;
  }
  .audience-markers li {
    min-height: 194px;
  }
}
@media (max-width: 700px) {
  .audience {
    padding-top: 18px;
    padding-bottom: 80px;
  }
  .audience h2 {
    font-size: clamp(52px, 15.5vw, 82px);
  }
  .audience-grid {
    gap: 32px;
    margin-top: 39px;
    padding-top: 22px;
  }
  .audience-copy {
    padding-left: 21px;
  }
  .audience-copy p {
    font-size: 16px;
  }
  .audience-markers {
    grid-template-columns: 1fr;
  }
  .audience-markers li {
    display: grid;
    grid-template-columns: 44px 1fr;
    column-gap: 12px;
    min-height: 0;
    padding: 22px 20px;
    border-right: 0;
    border-bottom: 1px solid rgba(var(--maize-rgb), 0.2);
  }
  .audience-markers li:last-child {
    border-bottom: 0;
  }
  .audience-markers span {
    margin: 2px 0 0;
    grid-row: 1 / span 2;
  }
  .audience-markers strong {
    font-size: 25px;
  }
  .audience-markers p {
    grid-column: 2;
    margin-top: 8px;
  }
}

/* Private concept framing: explicit in language and behavior, secondary in hierarchy. */
.concept-notice {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 12px;
  max-width: 650px;
  margin: -2px 0 28px;
  padding: 12px 14px;
  border: 1px solid rgba(var(--maize-rgb), 0.23);
  border-left: 2px solid var(--paarl);
  background: rgba(var(--woodsmoke-rgb), 0.38);
  color: rgba(var(--maize-rgb), 0.74);
  font-size: 12px;
  line-height: 1.5;
}
.concept-notice strong,
.concept-chip,
.concept-control-note strong {
  align-self: start;
  color: var(--paarl);
  font: 800 10px/1.25 var(--body);
  letter-spacing: 0.15em;
  white-space: nowrap;
}
.platform-link--planned {
  cursor: default;
  opacity: 0.74;
}
.platform-link--planned:hover,
.platform-link--planned:focus-visible {
  color: var(--paper);
  transform: none;
}
.platform-link--planned:focus-visible {
  outline: 0;
}
.footer-channels {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  align-items: center;
  font: 700 10px/1.3 var(--body);
  letter-spacing: 0.11em;
  text-transform: uppercase;
}
.footer-channels > span:first-child {
  color: var(--paarl);
}

/* Proposed media remains editorial, never a deceptive playable card. */
.video-card--concept:hover {
  transform: none;
  box-shadow: none;
}
.video-card-media.is-concept {
  min-height: 0;
  cursor: default;
  background:
    linear-gradient(
      135deg,
      rgba(var(--paarl-rgb), 0.16),
      rgba(var(--charade-rgb), 0.8)
    ),
    repeating-linear-gradient(
      135deg,
      rgba(var(--maize-rgb), 0.05) 0 1px,
      transparent 1px 14px
    );
  border-bottom: 1px solid rgba(var(--maize-rgb), 0.18);
}
.video-card-media.is-concept:after {
  display: none;
}
.video-concept-mark {
  display: grid;
  place-items: center;
  width: 112px;
  height: 112px;
  border: 1px solid rgba(var(--maize-rgb), 0.46);
  color: var(--maize);
  font: 800 11px/1.35 var(--body);
  letter-spacing: 0.13em;
  text-align: center;
  box-shadow: 7px 7px 0 rgba(var(--woodsmoke-rgb), 0.35);
}
.video-card-status {
  margin-top: auto;
  padding-top: 22px;
  color: var(--paarl);
  font: 800 10px/1.4 var(--body);
  letter-spacing: 0.13em;
}
.video-card--concept .video-card-copy {
  min-height: 222px;
}
.video-card--concept .video-card-number {
  color: rgba(var(--maize-rgb), 0.75);
}

/* Concept merchandise keeps its motion but removes all store affordances. */
.concept-chip {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 2;
  padding: 5px 7px;
  border: 1px solid rgba(var(--maize-rgb), 0.52);
  background: rgba(var(--woodsmoke-rgb), 0.7);
  color: var(--maize);
}
/* No display override here: styles.css lays this row out as flex with
   space-between so the name sits left and the price (or COMING SOON flag) right.
   Forcing block collapsed them into inline siblings that ran together, which
   would have read as "Standard Issue Tee$32" once real products land. */
.home-merch-heading > div:last-child > p {
  margin-bottom: 0;
}

/* Disabled signup controls are explicit and remain readable. */
.concept-control-note {
  display: flex;
  align-items: baseline;
  gap: 12px;
  max-width: 540px;
  margin: 24px 0 10px;
  color: rgba(var(--maize-rgb), 0.74);
  font-size: 12px;
  line-height: 1.5;
}
.signup input:disabled,
.signup button:disabled {
  cursor: not-allowed;
  opacity: 0.7;
}
.signup input:disabled {
  border-color: rgba(var(--maize-rgb), 0.45);
  background: rgba(var(--woodsmoke-rgb), 0.62);
  color: rgba(var(--maize-rgb), 0.68);
}
.signup input:disabled::placeholder {
  color: rgba(var(--maize-rgb), 0.58);
}
.signup button:disabled {
  border: 1px solid rgba(var(--maize-rgb), 0.3);
  background: rgba(var(--woodsmoke-rgb), 0.72);
  color: rgba(var(--maize-rgb), 0.7);
}
.signup:focus-within {
  box-shadow: none;
}

/* Compact approval review, visually subordinate to the brand story. */
.concept-testing {
  position: relative;
  z-index: 1;
  padding: 118px 0 90px;
  border-top: 1px solid rgba(var(--maize-rgb), 0.18);
}
.concept-testing-intro {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(260px, 0.5fr);
  gap: 54px;
  align-items: end;
  padding-bottom: 38px;
  border-bottom: 1px solid rgba(var(--maize-rgb), 0.2);
}
.concept-testing-intro .eyebrow {
  grid-column: 1/-1;
  margin: 0;
}
.concept-testing h2 {
  margin: 0;
  color: var(--maize);
  font: 800 clamp(52px, 6.4vw, 96px)/0.78 var(--display);
  letter-spacing: -0.035em;
}
.concept-testing h2 em {
  color: var(--paarl);
  font-style: normal;
}
.concept-testing-intro > p:last-child {
  max-width: 460px;
  margin: 0;
  color: rgba(var(--maize-rgb), 0.75);
  line-height: 1.65;
}
.approval-grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
  border-bottom: 1px solid rgba(var(--maize-rgb), 0.2);
}
.approval-grid li {
  min-height: 252px;
  padding: 27px 21px 29px;
  border-right: 1px solid rgba(var(--maize-rgb), 0.2);
}
.approval-grid li:last-child {
  border-right: 0;
}
.approval-grid span {
  display: block;
  margin-bottom: 50px;
  color: var(--paarl);
  font: 800 10px/1 var(--body);
  letter-spacing: 0.15em;
}
.approval-grid h3 {
  margin: 0;
  color: var(--maize);
  font: 800 26px/0.88 var(--display);
  letter-spacing: 0.02em;
}
.approval-grid p {
  margin: 15px 0 0;
  color: rgba(var(--maize-rgb), 0.67);
  font-size: 13px;
  line-height: 1.55;
}
.concept-provisional {
  margin: 23px 0 0;
  color: rgba(var(--maize-rgb), 0.6);
  font: 700 11px/1.5 var(--body);
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

@media (max-width: 900px) {
  .approval-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .approval-grid li:nth-child(2) {
    border-right: 0;
  }
  .approval-grid li:nth-child(n + 3) {
    border-top: 1px solid rgba(var(--maize-rgb), 0.2);
  }
  .approval-grid li:nth-child(4) {
    border-right: 0;
  }
  .concept-testing-intro {
    gap: 30px;
  }
}
@media (max-width: 700px) {
  .concept-notice {
    grid-template-columns: 1fr;
    gap: 7px;
    margin: 0 0 25px;
    padding: 11px 12px;
    font-size: 11px;
  }
  .concept-notice strong {
    white-space: normal;
  }
  .hero .concept-notice {
    max-width: 100%;
  }
  .listen-on {
    margin-top: 22px;
  }
  .listen-on > span:first-child {
    width: max-content;
  }
  .footer-channels {
    gap: 10px;
    font-size: 9px;
  }
  .video-card--concept .video-card-copy {
    min-height: 0;
  }
  .video-concept-mark {
    width: 96px;
    height: 96px;
    font-size: 10px;
  }
  .concept-control-note {
    align-items: flex-start;
    flex-direction: column;
    gap: 5px;
    margin-top: 21px;
  }
  .concept-testing {
    padding: 76px 0 62px;
  }
  .concept-testing-intro {
    display: block;
    padding-bottom: 29px;
  }
  .concept-testing-intro .eyebrow {
    margin-bottom: 21px;
  }
  .concept-testing-intro > p:last-child {
    margin-top: 24px;
  }
  .approval-grid {
    grid-template-columns: 1fr;
  }
  .approval-grid li,
  .approval-grid li:nth-child(2),
  .approval-grid li:nth-child(4) {
    min-height: 0;
    padding: 22px 19px;
    border-right: 0;
    border-top: 1px solid rgba(var(--maize-rgb), 0.2);
  }
  .approval-grid li:first-child {
    border-top: 0;
  }
  .approval-grid span {
    margin-bottom: 18px;
  }
  .approval-grid h3 {
    font-size: 28px;
  }
  .approval-grid p {
    margin-top: 10px;
  }
  .concept-provisional {
    margin-top: 18px;
    font-size: 10px;
  }
}
@media (prefers-reduced-motion: reduce) {
  .video-card--concept,
  .video-card--concept:hover {
    transform: none !important;
    box-shadow: none !important;
  }
}

/* Prelaunch states use the established editorial system without implying availability. */
.prelaunch-notice {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin: 0 0 25px;
  color: var(--paarl);
  font: 800 10px/1.4 var(--body);
  letter-spacing: 0.15em;
}
.prelaunch-notice:before {
  content: "";
  width: 30px;
  height: 1px;
  background: var(--paarl);
}
.prelaunch-notice span {
  color: rgba(var(--maize-rgb), 0.68);
}
.playlist-prelaunch {
  max-width: 920px;
  padding: clamp(34px, 5vw, 68px);
  border: 1px solid rgba(var(--maize-rgb), 0.22);
  background: linear-gradient(
    135deg,
    rgba(var(--maize-rgb), 0.06),
    rgba(var(--paarl-rgb), 0.08)
  );
  box-shadow: 15px 18px 0 rgba(var(--woodsmoke-rgb), 0.25);
}
.playlist-prelaunch .eyebrow {
  margin-bottom: 22px;
}
.playlist-prelaunch h3 {
  max-width: 740px;
  margin: 0;
  color: var(--maize);
  font: 800 clamp(45px, 6vw, 82px)/0.8 var(--display);
  letter-spacing: -0.035em;
}
.playlist-prelaunch h3 em {
  color: var(--paarl);
  font-style: normal;
}
.playlist-prelaunch > p:not(.eyebrow) {
  max-width: 620px;
  margin: 25px 0;
  color: rgba(var(--maize-rgb), 0.78);
  line-height: 1.65;
}
.playlist-prelaunch ul {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 24px;
  margin: 0 0 30px;
  padding: 0;
  list-style: none;
}
.playlist-prelaunch li {
  color: var(--maize);
  font: 800 10px/1.4 var(--body);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}
.playlist-prelaunch li:before {
  content: "/";
  margin-right: 8px;
  color: var(--paarl);
}
.availability-note,
.signup-status {
  display: inline-block;
  margin: 18px 0 0;
  padding: 7px 9px;
  border: 1px solid rgba(var(--maize-rgb), 0.38);
  color: var(--maize);
  font: 800 10px/1.3 var(--body);
  letter-spacing: 0.14em;
}
.availability-chip {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 2;
  padding: 5px 7px;
  border: 1px solid rgba(var(--maize-rgb), 0.52);
  background: rgba(var(--woodsmoke-rgb), 0.72);
  color: var(--maize);
  font: 800 9px/1.2 var(--body);
  letter-spacing: 0.12em;
}
.signup-status {
  color: var(--paarl);
  border-color: rgba(var(--paarl-rgb), 0.62);
}
@media (max-width: 700px) {
  .prelaunch-notice {
    gap: 7px;
    margin-bottom: 21px;
    font-size: 9px;
  }
  .prelaunch-notice:before {
    width: 22px;
  }
  .playlist-prelaunch {
    padding: 31px 22px;
    box-shadow: 8px 10px 0 rgba(var(--woodsmoke-rgb), 0.26);
  }
  .playlist-prelaunch h3 {
    font-size: clamp(43px, 13vw, 66px);
  }
  .playlist-prelaunch ul {
    display: grid;
    gap: 9px;
    margin-bottom: 26px;
  }
  .availability-note {
    margin-top: 15px;
  }
}

/* Launch rendering primitives. Each data-backed section is hidden until complete live data is present. */
.video-card--editorial .video-card-media {
  cursor: default;
}
.video-card--editorial .video-card-media img {
  filter: saturate(0.82) contrast(0.96);
}
.video-card--editorial {
  box-shadow: none;
}
.video-card--editorial:hover {
  transform: none;
}
[id] {
  scroll-margin-top: 110px;
}
.topic-pathways {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: 1px;
  background: rgba(var(--maize-rgb), 0.2);
  border: 1px solid rgba(var(--maize-rgb), 0.2);
}
.topic-pathway {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 255px;
  padding: 25px 20px;
  background: var(--woodsmoke);
  color: var(--maize);
  text-decoration: none;
  transition:
    background 0.22s ease,
    transform 0.22s ease;
}
.topic-pathway:hover,
.topic-pathway:focus-visible {
  background: var(--charade);
  transform: translateY(-4px);
  outline: 2px solid var(--paarl);
  outline-offset: -2px;
}
.topic-pathway > span {
  color: var(--paarl);
  font: 800 10px/1 var(--body);
  letter-spacing: 0.14em;
}
.topic-pathway h3 {
  margin: 48px 0 12px;
  font: 800 clamp(28px, 2.3vw, 38px)/0.88 var(--display);
  letter-spacing: -0.02em;
}
.topic-pathway p {
  margin: 0;
  color: rgba(var(--maize-rgb), 0.74);
  font-size: 13px;
  line-height: 1.55;
}
.topic-pathway b {
  margin-top: auto;
  padding-top: 22px;
  color: var(--paarl);
  font-size: 19px;
}
.about {
  display: grid;
  grid-template-columns: minmax(260px, 0.75fr) minmax(0, 1fr);
  gap: clamp(34px, 7vw, 108px);
  align-items: center;
  padding-top: 110px;
  padding-bottom: 110px;
  border-top: 1px solid rgba(var(--maize-rgb), 0.18);
}
.about-photo {
  overflow: hidden;
  aspect-ratio: 4/5;
  background: var(--charade);
}
.about-photo img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.about-copy h2,
.contact h2 {
  margin: 18px 0 26px;
  color: var(--maize);
  font: 800 clamp(56px, 7vw, 108px)/0.78 var(--display);
  letter-spacing: -0.035em;
}
.about-copy p,
.contact-intro p {
  max-width: 680px;
  color: rgba(var(--maize-rgb), 0.78);
  line-height: 1.65;
}
.about-experience {
  color: var(--paarl) !important;
  font-weight: 700;
}
/* The padding is the tap target. At 10px/1.2 the link box was 127x12, well under
   the 24x24 minimum, and it is the only text link on these cards -- the play
   facade beside it is 335x188 and fine. Vertical padding takes it to 40px without
   moving the text, since the margin above absorbs the added top padding. */
.video-card-action {
  display: inline-block;
  margin-top: 7px;
  padding: 14px 0;
  color: var(--paarl);
  font: 800 10px/1.2 var(--body);
  letter-spacing: 0.13em;
  text-decoration: none;
}
.video-card-action:hover,
.video-card-action:focus-visible {
  color: var(--maize);
  outline: 2px solid var(--paarl);
  outline-offset: 4px;
}
.merch-product {
  display: flex;
  flex-direction: column;
  text-decoration: none;
}
.merch-product > img {
  display: block;
  width: 100%;
  height: 220px;
  object-fit: cover;
  object-position: center;
  border: 1px solid rgba(var(--maize-rgb), 0.17);
  background: var(--charade);
}
.merch-product > strong {
  display: block;
  margin-top: 8px;
  color: var(--paarl);
  font: 800 13px/1 var(--body);
  letter-spacing: 0.08em;
}
.merch-product:focus-visible {
  outline: 2px solid var(--paarl);
  outline-offset: 5px;
}
.join small a,
.contact small a {
  color: var(--paarl);
}
.form-status {
  min-height: 1.5em;
  margin: 14px 0 0;
  color: var(--paarl);
  font-size: 13px;
  line-height: 1.5;
}
.contact {
  display: grid;
  grid-template-columns: minmax(0, 0.8fr) minmax(0, 1fr);
  gap: clamp(36px, 8vw, 126px);
  align-items: start;
  padding-top: 110px;
  padding-bottom: 110px;
  border-top: 1px solid rgba(var(--maize-rgb), 0.18);
}
.contact-form {
  display: grid;
  gap: 17px;
}
.contact-form label {
  display: grid;
  gap: 8px;
  color: var(--maize);
  font: 800 10px/1.2 var(--body);
  letter-spacing: 0.13em;
}
.contact-form input,
.contact-form select,
.contact-form textarea {
  width: 100%;
  box-sizing: border-box;
  border: 1px solid rgba(var(--maize-rgb), 0.42);
  border-radius: 0;
  padding: 14px;
  background: rgba(var(--woodsmoke-rgb), 0.72);
  color: var(--maize);
  font: 400 16px/1.4 var(--body);
}
.contact-form textarea {
  resize: vertical;
  min-height: 150px;
}
.contact-form input:focus-visible,
.contact-form select:focus-visible,
.contact-form textarea:focus-visible {
  outline: 2px solid var(--paarl);
  outline-offset: 2px;
}
/* Both forms carry a honeypot, so this is not scoped to one of them. */
.honeypot {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}
.footer-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 12px 22px;
}
.footer-nav a,
.footer-privacy {
  color: rgba(var(--maize-rgb), 0.75);
  font: 800 10px/1.2 var(--body);
  letter-spacing: 0.12em;
  text-decoration: none;
}
.footer-nav a:hover,
.footer-privacy:hover,
.footer-nav a:focus-visible,
.footer-privacy:focus-visible {
  color: var(--paarl);
  outline: 2px solid var(--paarl);
  outline-offset: 4px;
}
.footer-platforms {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}
.footer-platforms a,
.footer-platforms .is-unlinked {
  color: rgba(var(--maize-rgb), 0.75);
  font: 800 10px/1.2 var(--body);
  letter-spacing: 0.12em;
  text-decoration: none;
}
.footer-platforms img,
.listen-on img {
  width: 15px;
  height: 15px;
  vertical-align: middle;
  margin-right: 5px;
}
/* Platform row under the hero lockup. It is a child of .hero, not of .hero-art:
   that box has a fixed height with overflow hidden, and putting the row inside
   left it overlapping the logo by 9px. grid-column 2 drops it into the second
   row of the hero grid, directly beneath the art. */
/* The hero grid has a second row now. Without this its rows stretch to fill the
   hero's min-height, and align-items:center then strands ~100px of dead space
   above and below the platform row. Centring the row group instead keeps the
   rows content-sized, so the gap is just the margin below. */
.hero {
  align-content: center;
  /* .hero's `gap` shorthand sets the column split between copy and art, but it
     applies to rows too -- 77px of it at 1280px, which stacked on top of the
     platform row's own margin. Zero it and let that margin own the spacing;
     column-gap is untouched. */
  row-gap: 0;
}
/* Lives inside .hero-copy under the mission statement now, not in the hero grid
   under the photograph. So: no grid-column, and no transform of its own -- it
   inherits .hero-copy's parallax by being inside it.

   Centred on the MISSION STATEMENT, not on the copy column. .hero-summary is
   capped at 495px (flagship.css) while the column runs to 595px, so centring on
   the column would push the marks about 50px right of the paragraph they sit
   under. Matching that max-width and centring inside it is what lines the row up
   with the text above. Keep the two values in step. */
.hero-platforms {
  margin-top: 34px;
  width: min(495px, 100%);
  display: flex;
  align-items: center;
  justify-content: center;
  /* Wraps rather than overflowing if a seventh mark is ever added. */
  flex-wrap: wrap;
  gap: 4px;
}
/* Both selectors: a platform with a URL renders as <a>, one without as a
   <span>.is-unlinked, so the marks look identical either way and only the
   linked ones respond to hover. */
.hero-platforms a,
.hero-platforms .is-unlinked {
  display: block;
  line-height: 0;
  /* 42px icon + 22px padding = a 64px hit area. Six of those plus gaps is 404px,
     inside the 495px the row is allowed. */
  padding: 11px;
  border-radius: 2px;
  opacity: 0.82;
  transition: opacity 0.3s ease, transform 0.3s ease, background-color 0.3s ease;
}
/* A faint plate on hover rather than only a lift: at this size the marks read as
   buttons, so they want a visible target. Linked only -- an unlinked mark must
   not look interactive. */
.hero-platforms a:hover,
.hero-platforms a:focus-visible {
  opacity: 1;
  transform: translateY(-2px);
  background: rgba(var(--maize-rgb), 0.07);
}
.hero-platforms img {
  display: block;
  width: 42px;
  height: 42px;
}
@media (max-width: 900px) {
  .hero-platforms {
    margin-top: 28px;
  }
}
@media (max-width: 700px) {
  /* Six marks have to fit a ~335px column, so the desktop 64px hit area would
     overflow by 50px. 34px of icon plus 20px of padding is 54px each, 324px in
     total with the gaps zeroed -- still larger than the 46px it was before, and
     still past the 44px minimum. */
  .hero-platforms {
    margin-top: 24px;
    gap: 0;
  }
  .hero-platforms a,
  .hero-platforms .is-unlinked {
    padding: 10px;
  }
  .hero-platforms img {
    width: 34px;
    height: 34px;
  }
}
[hidden] {
  display: none !important;
}
@media (max-width: 900px) {
  .topic-pathways {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .topic-pathway:last-child {
    grid-column: 1/-1;
  }
  .about,
  .contact {
    grid-template-columns: 1fr;
    gap: 38px;
  }
}
@media (max-width: 700px) {
  [id] {
    scroll-margin-top: 86px;
  }
  .topic-pathways {
    grid-template-columns: 1fr;
  }
  .topic-pathway:last-child {
    grid-column: auto;
  }
  .topic-pathway {
    min-height: 0;
    padding: 23px 19px;
  }
  .topic-pathway h3 {
    margin: 33px 0 11px;
  }
  .about,
  .contact {
    padding-top: 76px;
    padding-bottom: 76px;
  }
  .about-copy h2,
  .contact h2 {
    font-size: clamp(52px, 15vw, 74px);
  }
  .merch-product > img {
    height: 190px;
  }
  .contact-form {
    gap: 14px;
  }
  .footer-nav {
    gap: 12px 16px;
  }
}
.featured-episode-copy h2 {
  font-size: clamp(48px, 5.2vw, 78px);
}
/* Keep the topic cards at a readable width on wide editorial layouts. */
.audience-grid {
  grid-template-columns: 1fr;
  gap: 42px;
}
.audience-copy {
  max-width: 700px;
}
.topic-pathway {
  min-height: 360px;
}
.topic-pathway h3 {
  font-size: clamp(22px, 1.35vw, 29px);
  line-height: 0.92;
  overflow-wrap: anywhere;
}
/* Teaser cards are <article>, not links -- there is nowhere to send anyone yet --
   so they must not answer to hover the way a real product card does. */
.merch-teaser:hover {
  transform: none;
  filter: none;
  border-color: rgba(var(--maize-rgb), 0.24);
  box-shadow: 12px 14px 0 rgba(var(--woodsmoke-rgb), 0.28);
}
/* The status word sits opposite the product name in the same row. Gold would put
   it in a dead heat with the price on a real product card, so it takes the quieter
   bronze and lets the price own the accent. */
.merch-flag {
  color: var(--bronze);
}
