/* ==========================================================================
   HOMEPAGE SECTIONS
   Each section is an independent block. Reordering them in index.html does not
   break anything: no section depends on the one above or below it.

   Layout family per section (deliberately no two the same):
     1 lede        magazine front page: one lead story, three beside it
     2 podcast     three video cards
     3 topics      bento grid, 7 cells for 7 topics
     4 updates     three column newspaper brief, no images, no card chrome
     5 blog        one featured post beside a stacked list
     6 resources   full width index rows
     7 hiring      full bleed accent band
     8 join        stacked actions plus inline form
   ========================================================================== */

/* ==========================================================================
   0. THE SLAB MODEL
   Homepage sections are stacked cards, not a continuous scroll.

   Every band is inset from the viewport by --slab-inset and carries --r-slab
   on all four corners. Consecutive slabs sit flush, so where two meet their
   rounded corners open a small lens of page floor. That notch is what makes
   the page read as layered, and it does the separating work the hairline
   rules used to do, which is why .section--ruled is gone from this page.

   Backgrounds alternate on a two-step ladder only: surface (white) and
   surface-2 (paper). Anything past those two belongs to the accent band that
   closes the page.
   ========================================================================== */
/* THE SEPARATOR IS A RULE, NOT A CHANGE OF PAPER.

   This page used to separate its sections by swapping the ground: white, then
   a warm grey, then a newsprint grey, then the ink band, several of them
   inset from the viewport with a 40px radius. Four changes of paper on one
   page means none of them signifies anything; it is four attempts at emphasis
   competing with each other.

   Now there is one hairline between sections and exactly one change of paper
   on the whole page, the ink band under the podcast. That band is the only
   surface change left, so it is the only one that has to carry meaning, and
   it does: it is the beat in the scroll.

   The inset and the radius go with them. A band that floats inside the
   viewport with rounded corners is a card, and a page made of cards is an
   app. This is a page. */
.slab {
  padding-block: var(--section-y);
}
/* Every band except the ink one now sits on the page ground and is divided
   from the one above it by a single rule. */
.slab--white + .slab--white,
.slab--paper, .slab--news, .slab--white {
  border-top: 1px solid var(--c-rule);
}
.slab--ink, .slab--ink + .slab { border-top: 0; }
.slab--white { background: transparent; }
/* The opening slab takes the page ground, not a surface. Header on oat and
   the lede on near-white put a hard edge two hundred pixels into the page, which
   sectioned the site before it had said anything. Now the nav, the headline
   and the Latest rail are one continuous field and the first change of paper
   is the ink band, which is a change worth making. */
.slab--ground { background: var(--c-ground); }
.slab--paper { background: transparent; }
.slab--news { background: transparent; }

/* The dark register. One band on the page where the type inverts, which gives
   the scroll a beat and makes the episode artwork carry. */
.slab--ink { background: var(--c-ground-ink); color: var(--c-on-ink); padding-top: 0; }
.slab--ink > .wrap { padding-top: var(--section-y); }
.slab--ink h2, .slab--ink h3 { color: var(--c-on-ink); }
.slab--ink .lead, .slab--ink p { color: var(--c-on-ink-2); }
.slab--ink .link-arrow { color: var(--c-accent-on-ink); }
.slab--ink .episode__title { color: var(--c-on-ink); }
.slab--ink .episode:hover .episode__title { color: var(--c-accent-on-ink); }
.slab--ink .episode__guest { color: var(--c-on-ink-2); }
.slab--ink .episode__scale { color: var(--c-on-ink-2); }
.slab--ink .media { border-color: rgb(255 255 255 / 0.14); }

/* ==========================================================================
   1. THE LEDE

   A front page, not a hero. The opening does not make a claim about the site,
   it shows the site doing its job: one story set large with a picture, three
   more beside it set small, every one of them real and dated.

   Why the asymmetry matters. A row of four equal cards is a list, and a list
   reads as inventory. One dominant story with a rail beside it reads as an
   edition, because somebody clearly decided which story leads. That decision
   is the thing a magazine sells, so it has to be visible in the layout before
   a word is read.

   The ratio is deliberate. At 1.7fr the lead is wide enough to carry display
   type across three lines at most; the rail at 1fr is narrow enough that its
   headlines set to two or three lines and never compete. Pull them closer to
   equal and the page turns back into a list.

   Only the lead carries a summary. The rail gets a rule, a category, a
   headline and a source, which is how a newspaper rail has always worked and
   is what keeps the hierarchy legible at a glance.
   ========================================================================== */
.lede {
  /* Tight at the top on purpose. With the masthead gone this padding is
     all that sits between the site header and the lead story, and every
     pixel of it pushes the headline down the page. */
  padding-block: var(--s-6) var(--s-8);
}


/* ---- The grid ----------------------------------------------------------- */
.lede__grid {
  display: grid;
  /* Three columns now: the lead, the secondary stack, and a permanent slot
     for the show. The rail is a fixed width rather than a fraction, because
     it holds a 300px class of content and should not stretch with the page. */
  grid-template-columns: 1.45fr 1.15fr 280px;
  /* A tighter gutter than the rest of the page, because three columns inside
     1160px cannot afford 48px twice: at the wider gutter the middle column
     fell to 285px and the secondary headlines were breaking four ways. */
  gap: var(--s-6);
  align-items: start;
}

/* ---- Lead story --------------------------------------------------------- */
.lede__lead-link {
  display: block;
  color: inherit;
  text-decoration: none;
}
.lede__figure {
  aspect-ratio: 2 / 1;
  margin-bottom: var(--s-5);
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--c-surface-2);
}
.lede__figure img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Slow, and small. A picture that leaps on hover reads as a web page; a
     picture that drifts reads as print that happens to be interactive. */
  transition: transform 700ms var(--ease);
}
.lede__lead-link:hover .lede__figure img { transform: scale(1.025); }


.lede__hed {
  margin: 0;
  font-size: clamp(1.65rem, 1.05rem + 1.75vw, 2.3rem);
  line-height: 1.13;
  letter-spacing: -0.021em;
  text-wrap: balance;
}
.lede__lead-link:hover .lede__hed {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}
/* Serif: this is the deck of the lead story, which is editorial writing, not
   chrome. It fell through to the sans in the previous build. */
.lede__dek {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  margin: var(--s-3) 0 0;
  max-width: 56ch;
  color: var(--c-ink-2);
  line-height: 1.6;
}

/* ---- The rail ------------------------------------------------------------
   A hairline separates the column from the lead rather than a gap alone,
   because at this width whitespace on its own reads as an accident of the
   grid instead of as a deliberate edge. */
.lede__stack {
  display: grid;
  gap: var(--s-5);
  padding-left: var(--s-6);
  border-left: 1px solid var(--c-rule-strong);
}
.lede__mini + .lede__mini { padding-top: var(--s-5); border-top: 1px solid var(--c-rule-strong); }
/* Picture left, words right. The thumbnail is square because the three source
   photographs have nothing in common compositionally, and a square crop is the
   one shape that treats them all equally. 88px is large enough to read as a
   photograph and small enough that it cannot compete with the lead. */
.lede__mini a {
  display: grid;
  grid-template-columns: 88px 1fr;
  gap: var(--s-4);
  align-items: start;
  color: inherit;
  text-decoration: none;
}
.lede__thumb {
  display: block;
  aspect-ratio: 1;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--c-surface-2);
}
.lede__thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 700ms var(--ease);
}
.lede__mini a:hover .lede__thumb img { transform: scale(1.04); }

.lede__mini-hed {
  margin: 0;
  font-size: 1.04rem;
  line-height: 1.32;
  letter-spacing: -0.012em;
}
.lede__mini a:hover .lede__mini-hed {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

/* ---- Shared editorial furniture ----------------------------------------- */
.lede__cat {
  margin: 0 0 var(--s-2);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--topic, var(--c-accent));
}
.lede__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-2);
  margin: var(--s-4) 0 0;
  font-size: var(--fs-xs);
  color: var(--c-ink-3);
}
/* In the rail the date and the source stack. Side by side they fit for some
   sources and wrap for others, so the column came out ragged: one item on one
   line, the next on two, for no reason a reader could see. Stacked, every item
   behaves the same way at every width. The slash goes with the single line it
   was separating. */
.lede__mini .lede__meta {
  display: block;
  margin-top: var(--s-3);
  line-height: 1.5;
}
.lede__mini .lede__meta time { display: block; }
.lede__mini .lede__sep { display: none; }
.lede__sep { color: var(--c-rule-strong); }

/* The rail closes on its own "more of this". It takes the same hairline the
   stories use, so it reads as the last item in the column rather than as a
   button bolted to the bottom. */
.lede__all {
  padding-top: var(--s-5);
  border-top: 1px solid var(--c-rule-strong);
}

/* ---- Narrow -------------------------------------------------------------
   One column, and the rail's left border becomes a top border, so the
   separation survives the stack instead of disappearing with it. */
@media (max-width: 900px) {
  .lede__grid { grid-template-columns: 1fr; gap: var(--s-6); }
  .lede__stack {
    padding-left: 0;
    padding-top: var(--s-6);
    border-left: 0;
    border-top: 1px solid var(--c-rule-strong);
  }
}
@media (max-width: 560px) {
  .lede__figure { aspect-ratio: 3 / 2; }
}
/* ==========================================================================
   2. PODCAST
   Episode cards. The thumbnail is the YouTube still, so the frame is 16:9 and
   the card is mostly image. Clicking opens the episode page, not YouTube.
   ========================================================================== */
.episodes__grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--s-5);
}

.episode { text-decoration: none; color: inherit; display: block; }
.episode .media { transition: border-color var(--dur) var(--ease); }
.episode:hover .media { border-color: var(--c-accent); }
.episode:hover .episode__title { color: var(--c-accent); }

.episode__body { padding-top: var(--s-4); }

.episode__title {
  font-family: var(--font-display);
  font-size: 1.14rem;
  font-weight: 600;
  line-height: 1.3;
  transition: color var(--dur) var(--ease);
}

/* A byline is editorial. */
.episode__guest { font-family: var(--font-display); font-optical-sizing: auto; margin-top: var(--s-2); font-size: var(--fs-sm); color: var(--c-ink-2); }
.episode__scale { margin-top: var(--s-1); font-size: var(--fs-xs); color: var(--c-ink-3); }

/* Play affordance sitting on the thumbnail. */
.media__play {
  position: absolute;
  left: var(--s-4); bottom: var(--s-4);
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px;
  border-radius: var(--radius);
  background: var(--c-accent);
  color: var(--c-on-accent);
}
.media__play .icon { width: 1rem; height: 1rem; }

/* ==========================================================================
   3. START WITH YOUR PROBLEM
   A scroll linked stepper, not a grid.

   Eight topics used to sit in a bento grid, which showed all eight at once and
   gave none of them a moment. Here the rail pins under the header and each
   card pins below it, so the next card slides up over the one before. The
   reader moves through the eight one at a time, and the fill under the tabs
   runs continuously across the whole stack rather than jumping tab to tab, so
   the distance travelled is always legible.

   Everything below is progressive enhancement. With no JS the tabs still
   anchor-scroll and the cards read as a plain stack; with no sticky support
   the stack simply scrolls. Nothing is hidden behind script.
   ========================================================================== */
.stepper { margin-top: var(--s-7); }

/* ---- The rail ---------------------------------------------------------- */
.stepper__rail {
  position: sticky;
  top: var(--header-h);
  z-index: 3;
  background: var(--c-surface);
  padding-top: var(--s-4);
}

.stepper__tabs {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(8, 1fr);
}

.stepper__tab {
  width: 100%;
  border: 0;
  background: none;
  padding: var(--s-2) var(--s-1) var(--s-3);
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 500;
  line-height: 1.3;
  color: var(--c-ink-3);
  text-align: center;
  cursor: pointer;
  transition: color var(--dur) var(--ease);
}
.stepper__tab:hover { color: var(--c-ink); }
.stepper__tab.is-current { color: var(--c-ink); font-weight: 600; }

/* One continuous fill across all eight segments, with a knob riding the head
   of it. The knob is what makes the bar read as a position rather than as a
   quantity, and it is butter because that is the one colour on the site whose
   whole job is to say look here. overflow is visible so the knob can sit
   proud of the track. */
.stepper__track {
  position: relative;
  height: 6px;
  background: var(--c-rule);
  border-radius: 999px;
}
.stepper__fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: 0;
  background: var(--c-accent);
  border-radius: 999px;
  transition: width 120ms linear;
}
.stepper__fill::after {
  content: "";
  position: absolute;
  right: 0;
  top: 50%;
  width: 14px;
  height: 14px;
  transform: translate(50%, -50%);
  border-radius: 50%;
  background: var(--c-statement);
  box-shadow: 0 0 0 3px var(--c-surface);
}
/* At zero there is nothing to point at yet, so the knob stays away. */
.stepper:not(.is-live) .stepper__fill::after { display: none; }

/* ==========================================================================
   ONE CARD, ONE PLACE

   .stepper__stage is tall and otherwise empty. Its only job is to supply the
   scroll distance the eight panels are spread across.

   .stepper__frame pins inside it and holds every panel in the same spot, so
   the card never moves and nothing slides past beneath it. Panels are stacked
   absolutely and crossfaded.

   All of that is gated behind .is-live, which the script adds. Before it runs,
   and if it never runs, the panels sit in normal flow as a readable list and
   every link works.
   ========================================================================== */
.stepper__stage { padding-top: var(--s-6); }

.stepper__panel {
  display: grid;
  grid-template-columns: 0.92fr 1.08fr;
  align-items: stretch;
  min-height: 430px;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--c-surface);
  border: var(--border);
}
.stepper__panel + .stepper__panel { margin-top: var(--s-5); }

/* ---- Live mode ---------------------------------------------------------- */
.stepper.is-live .stepper__stage { position: relative; }

/* The height is measured from the tallest panel by stepper.js and written to
   --stepper-h. It used to be a flat 430px, and every panel whose copy ran
   longer than that had its button clipped off the bottom edge. */
.stepper.is-live .stepper__frame {
  position: sticky;
  top: calc(var(--header-h) + 78px);
  height: var(--stepper-h, 430px);
}

.stepper.is-live .stepper__panel {
  position: absolute;
  inset: 0;
  margin-top: 0;
  opacity: 0;
  visibility: hidden;
  transition: opacity 260ms var(--ease);
}
.stepper.is-live .stepper__panel.is-active {
  opacity: 1;
  visibility: visible;
}

/* ---- Left: the drawn scene --------------------------------------------- */
/* ---- Left: the photograph -----------------------------------------------
   This column used to hold a drawing. The hand-drawn scenes are gone from
   here: a photograph of a real barbershop says more about Labor & Scheduling
   than any amount of line work did, and the drawings were being asked to carry
   a job photography does better.

   The files are pre-cropped to this column's shape, so cover has almost
   nothing left to trim and the browser is not discarding pixels it downloaded.
   The tint stays underneath as the colour that shows while the image loads and
   as the topic's colour coding on a slow connection. */
.stepper__scene {
  background: var(--tint);
  overflow: hidden;
}
.stepper__scene img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}
/* ---- Right: what is actually inside ------------------------------------ */
.stepper__copy {
  padding: var(--s-6) var(--s-7);
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.stepper__count {
  font-family: var(--font-body);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  color: var(--c-accent);
  font-variant-numeric: tabular-nums;
}
.stepper__count span { color: var(--c-ink-3); font-weight: 500; }

.stepper__name {
  margin-top: var(--s-3);
  font-family: var(--font-display);
  font-size: var(--fs-h2);
  font-weight: 600;
  line-height: var(--lh-heading);
  letter-spacing: var(--tracking-display);
}
.stepper__desc {
  margin-top: var(--s-3);
  max-width: 46ch;
  color: var(--c-ink-2);
  line-height: var(--lh-body);
}

.stepper__inside-label {
  margin-top: var(--s-5);
  padding-bottom: var(--s-3);
  border-bottom: var(--border);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--c-ink-3);
}

.stepper__inside { list-style: none; margin: 0; padding: 0; }
.stepper__inside li + li { border-top: var(--border); }
.stepper__inside a {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  padding-block: var(--s-3);
  font-size: var(--fs-sm);
  line-height: 1.45;
  color: var(--c-ink);
  text-decoration: none;
}
.stepper__inside a:hover { color: var(--c-accent); }
.stepper__inside .icon {
  flex: none;
  margin-top: 0.18em;
  color: var(--c-accent);
  transition: transform var(--dur) var(--ease);
}
.stepper__inside a:hover .icon { transform: translateX(3px); }

.stepper__copy .btn { align-self: flex-start; margin-top: var(--s-5); }

@media (prefers-reduced-motion: reduce) {
  .stepper__fill { transition: none; }
  .stepper.is-live .stepper__panel { transition: none; }
  .stepper__inside .icon { transition: none; }
}
/* ==========================================================================
   TICKER
   A single running line, set in ink rather than colour.

   An earlier pass made this a terracotta band, which put one saturated stripe
   into an otherwise quiet page and read as an intruder. Ink is the right
   register: it behaves like the rule at the foot of a page, and it also gives
   the eye a dark beat between two light sections.
   ========================================================================== */
/* The categories run round all four edges of the podcast band. Four copies of
   one strip: the horizontals sit flush to the top and bottom, the verticals
   are the same strip rotated a quarter turn about its top left corner and
   pushed back into place by its own height.

   The verticals are inset top and bottom by the strip height so the four runs
   meet at the corners instead of overprinting each other there. */
.tickerframe {
  --tf-h: 34px;
  position: absolute;
  inset: 0;
  pointer-events: none;
  z-index: 1;
}
.tickerframe__edge { position: absolute; overflow: hidden; }
.tickerframe__edge--top    { top: 0; left: 0; right: 0; height: var(--tf-h); }
.tickerframe__edge--bottom { bottom: 0; left: 0; right: 0; height: var(--tf-h); }
.tickerframe__edge--left   { left: 0; top: var(--tf-h); bottom: var(--tf-h); width: var(--tf-h); }
.tickerframe__edge--right  { right: 0; top: var(--tf-h); bottom: var(--tf-h); width: var(--tf-h); }

.tickerframe__rot { position: absolute; top: 0; left: 0; height: var(--tf-h); }
.tickerframe__edge--left .tickerframe__rot,
.tickerframe__edge--right .tickerframe__rot {
  transform-origin: 0 0;
  transform: translateX(var(--tf-h)) rotate(90deg);
}

/* The band is espresso and the strip sits on it, so the strip carries no
   ground of its own. A hairline on the inner side is what separates the run
   from the content and turns four strips into one frame. */
.tickerframe__edge--top    { border-bottom: 1px solid rgb(255 255 255 / 0.14); }
.tickerframe__edge--bottom { border-top: 1px solid rgb(255 255 255 / 0.14); }
.tickerframe__edge--left   { border-right: 1px solid rgb(255 255 255 / 0.14); }
.tickerframe__edge--right  { border-left: 1px solid rgb(255 255 255 / 0.14); }

.ticker__track {
  display: flex;
  width: max-content;
  height: var(--tf-h);
  align-items: center;
  animation: ticker-run 90s linear infinite;
}
.ticker__set { display: flex; list-style: none; margin: 0; padding: 0; }
.ticker__set li {
  padding-inline: var(--s-5);
  font-size: var(--fs-xs);
  font-weight: 500;
  letter-spacing: 0.04em;
  white-space: nowrap;
  color: var(--c-on-ink-2);
}
/* Each category takes one of the six accents in its on-ink value, cycling, so
   the run has colour without any one colour claiming the section. */
.ticker__set .tk--a2 { color: var(--c-a2-on-ink); }
.ticker__set .tk--a3 { color: var(--c-a3-on-ink); }
.ticker__set .tk--a4 { color: var(--c-a4-on-ink); }
.ticker__set .tk--a5 { color: var(--c-a5-on-ink); }
.ticker__set .tk--a6 { color: var(--c-a6-on-ink); }
.ticker__set .tk--a7 { color: var(--c-a7-on-ink); }
.ticker__set li::after {
  content: "";
  display: inline-block;
  width: 3px; height: 3px;
  margin-left: calc(var(--s-5) + 3px);
  border-radius: 50%;
  background: currentColor;
  opacity: 0.55;
  vertical-align: middle;
}
@keyframes ticker-run { from { transform: translateX(0); } to { transform: translateX(-50%); } }
.tickerframe:hover .ticker__track { animation-play-state: paused; }
@media (prefers-reduced-motion: reduce) {
  .ticker__track { animation: none; }
}

/* The band has to clip to its own corners or the four runs spill past the
   radius, and its content has to clear the frame on every side. */
.slab--ink.is-framed {
  position: relative;
  overflow: hidden;
  padding-top: 0;
}
.slab--ink.is-framed > .wrap {
  padding-top: calc(34px + var(--section-y));
  padding-bottom: 34px;
}
@media (max-width: 900px) {
  /* Two runs, not four: at this width the verticals eat the measure. */
  .tickerframe__edge--left, .tickerframe__edge--right { display: none; }
  .slab--ink.is-framed > .wrap { padding-inline: var(--s-5); }
}
/* ==========================================================================
   4. INDUSTRY UPDATES
   Set as a front page, and set DENSE.

   The previous attempt failed because it was a newspaper drawn at poster
   scale: three enormous stories and an empty photo box. A front page reads as
   a front page because of density, small type, many rules and column breaks,
   not because of a big headline. So: a folio line, three columns divided by
   rules, a lead given size only relative to its neighbours, and body copy at
   13px. No photo slot until there are photographs.
   ========================================================================== */
.nameplate {
  border-top: 4px solid var(--c-ink);
  border-bottom: 1px solid var(--c-ink);
  padding-block: var(--s-4) var(--s-2);
}
.nameplate__kicker {
  font-family: var(--font-display);
  font-size: clamp(2rem, 1.3rem + 2.4vw, 3rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1;
  text-align: center;
  text-transform: uppercase;
}
/* The folio line: small caps, spread edge to edge, the way a masthead sets
   its date and edition. */
.nameplate__folio {
  margin-top: var(--s-3);
  padding-top: var(--s-2);
  border-top: 1px solid var(--c-rule-strong);
  display: flex;
  justify-content: space-between;
  gap: var(--s-4);
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-ink-3);
}
.nameplate__folio a { color: var(--c-accent); text-decoration: none; }
.nameplate__folio a:hover { text-decoration: underline; text-underline-offset: 3px; }

.press {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: var(--s-6);
  padding-top: var(--s-5);
}
/* EQUAL COLUMNS. The padding used to sit inside the columns, with the outer
   two dropping their outer side so the row stayed flush with the container.
   That left the middle column narrower than its neighbours: measured 347, 322
   and 346, so the middle picture came out 14px shorter and the row did not
   line up.

   Now the space is a grid gap, so all three tracks are exactly 1fr, and the
   divider is drawn in the middle of the gap by a pseudo element rather than
   as a border that has to be paid for out of one column.s width. */
.press__col { position: relative; }
.press__col + .press__col::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(var(--s-6) / -2);
  width: 1px;
  background: var(--c-rule-strong);
}

.press__story { display: block; text-decoration: none; color: inherit; }
.press__story + .press__story {
  margin-top: var(--s-5);
  padding-top: var(--s-5);
  border-top: 1px solid var(--c-rule);
}

.press__cat {
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-accent-2);
}
.press__headline {
  margin-top: var(--s-2);
  font-family: var(--font-display);
  font-size: 1.16rem;
  font-weight: 600;
  line-height: 1.22;
  letter-spacing: -0.015em;
  text-wrap: balance;
  transition: color var(--dur) var(--ease);
}
/* The lead is bigger than its neighbours, not bigger than the page. */
/* No lead treatment. All three columns are the same width, carry the same
   kind of item and now read at the same size. The first story was set larger
   back when this section had a lead and two followers; with pictures on all
   three and equal columns, a bigger headline in the left column just looked
   like an accident. */
.press__story:hover .press__headline { color: var(--c-accent); }

/* One rule for all three. The lead used to have its own larger italic and the
   other two a smaller roman, which made the three columns look like two
   different kinds of item rather than three of the same. */
.press__standfirst {
  margin-top: var(--s-3);
  font-size: 0.92rem;
  font-style: italic;
  line-height: 1.5;
  color: var(--c-ink-2);
}

.press__byline {
  margin-top: var(--s-3);
  padding-top: var(--s-2);
  border-top: 1px solid var(--c-rule);
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-1) var(--s-3);
  font-size: 0.68rem;
  color: var(--c-ink-3);
}
.press__byline span { font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; }
.press__byline time { font-variant-numeric: tabular-nums; }

/* Photography, when it arrives, ships greyscale and colours on hover. */
.press__media {
  aspect-ratio: 3 / 2;
  overflow: hidden;
  margin-bottom: var(--s-3);
  background: var(--c-surface-2);
}
.press__media img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  filter: grayscale(1) contrast(1.05);
  transition: filter 240ms var(--ease);
}
.press__story:hover .press__media img { filter: grayscale(0) contrast(1); }
/* ==========================================================================
   5. BLOG
   One featured post carrying an image, two more as text rows beside it.
   ========================================================================== */
.blog__grid {
  display: grid;
  grid-template-columns: 1.15fr 0.85fr;
  gap: var(--s-8);
  align-items: start;
}

.post-feature { text-decoration: none; color: inherit; display: block; }
.post-feature:hover .post-feature__title { color: var(--c-accent); }
.post-feature__body { padding-top: var(--s-5); }
.post-feature__topic { font-size: var(--fs-xs); color: var(--c-ink-3); }
.post-feature__title {
  margin-top: var(--s-2);
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 500;
  line-height: 1.24;
  letter-spacing: var(--tracking-display);
  transition: color var(--dur) var(--ease);
}

.post-list { display: grid; gap: var(--s-5); }
.post-list > * + * { border-top: var(--border); padding-top: var(--s-5); }

.post {
  display: grid;
  grid-template-columns: 92px 1fr;
  gap: var(--s-4);
  text-decoration: none;
  color: inherit;
  align-items: start;
}
.post:hover .post__title { color: var(--c-accent); }

.post__topic { font-size: var(--fs-xs); color: var(--c-ink-3); }
.post__title {
  margin-top: var(--s-2);
  font-family: var(--font-display);
  font-size: 1.02rem;
  font-weight: 600;
  line-height: 1.3;
  transition: color var(--dur) var(--ease);
}

/* ==========================================================================
   6. PRACTICAL RESOURCES
   Index rows. Large type does the work, no cards.
   ========================================================================== */
.resource-list { border-top: var(--border-strong); }

.resource {
  display: grid;
  grid-template-columns: 140px 1fr auto;
  gap: var(--s-5);
  align-items: center;
  padding-block: var(--s-6);
  border-bottom: var(--border);
  text-decoration: none;
  color: inherit;
}
.resource:hover .resource__title { color: var(--c-accent); }
.resource:hover .link-arrow .icon { transform: translateX(3px); }

.resource__kind {
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--c-ink-3);
}

.resource__title {
  display: block;
  font-family: var(--font-display);
  font-size: 1.3rem;
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: var(--tracking-display);
  transition: color var(--dur) var(--ease);
}
.resource__desc {
  display: block;
  margin-top: var(--s-2);
  font-size: var(--fs-sm);
  color: var(--c-ink-2);
  max-width: 58ch;
}

/* 7. HIRING CTA
   Lives in components.css: it appears on topic pages too, not just here. */

/* ==========================================================================
   8. JOIN / CONTRIBUTE / NEWSLETTER
   ========================================================================== */
/* The closing stripe. Accent ground, because this is the only place on the
   page asking the reader to do anything. One ask, one button: the three
   competing actions and the newsletter that used to sit here made the page
   end on a menu rather than on a request. */
.join-band {
  background: var(--c-accent);
  color: var(--c-on-accent);
  padding-block: var(--s-7);
}
.join-band h2 { color: var(--c-on-accent); }
.join-band .lead {
  margin-top: var(--s-4);
  color: color-mix(in srgb, var(--c-on-accent) 86%, transparent);
  max-width: 56ch;
}

/* Copy left, button right, centred against each other. The button holds its
   width so the ask never wraps. */
.join-band__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-8);
}
.join-band__inner .btn { flex: none; }

/* ==========================================================================
   RESPONSIVE
   ========================================================================== */
@media (max-width: 1040px) {
}

@media (max-width: 1040px) {
  /* Eight labels will not fit one row much below this. The rail becomes a
     scrollable strip and the tabs keep their tap size. */
  .stepper__tabs {
    grid-template-columns: repeat(8, minmax(96px, 1fr));
    overflow-x: auto;
    scrollbar-width: none;
  }
  .stepper__tabs::-webkit-scrollbar { display: none; }
  .stepper__panel { grid-template-columns: 1fr; min-height: 0; }
  .stepper__scene { padding: var(--s-5); }
  .stepper__scene svg { max-width: 280px; }
  .stepper__copy { padding: var(--s-6); }
}

@media (max-width: 900px) {
  /* A 40px corner eats too much of a narrow slab, and the inset stops earning
     its keep once the gutter is only a few pixels wider than it. */
  .slab { border-radius: 24px; margin-inline: 4px; }

  /* Pinning on a short viewport traps the reader, so live mode is switched
     off entirely and the eight panels become an ordinary readable list. */
  .stepper.is-live .stepper__frame { position: static; height: auto; }
  .stepper.is-live .stepper__panel {
    position: static; opacity: 1; visibility: visible;
  }
  .stepper.is-live .stepper__panel + .stepper__panel { margin-top: var(--s-5); }
  .stepper__rail { position: static; }

  .join-band__inner { flex-direction: column; align-items: flex-start; gap: var(--s-6); }

  .episodes__grid { grid-template-columns: 1fr 1fr; }
  .episodes__grid > *:nth-child(3) { grid-column: span 2; }
  /* A broadsheet needs width. Below this the two columns become one and the
     column rule turns into a horizontal one. */
  .press { grid-template-columns: 1fr; gap: var(--s-6); }
  .press__column {
    border-left: 0;
    border-top: 1px solid var(--c-rule-strong);
    padding-left: 0;
    padding-top: var(--s-6);
  }
  .blog__grid { grid-template-columns: 1fr; gap: var(--s-7); }
}

@media (max-width: 760px) {

  .episodes__grid { grid-template-columns: 1fr; }
  .episodes__grid > *:nth-child(3) { grid-column: span 1; }

  .resource { grid-template-columns: 1fr; gap: var(--s-3); padding-block: var(--s-5); }
  .resource .link-arrow { margin-top: var(--s-2); }

}

@media (max-width: 520px) {
  .post { grid-template-columns: 76px 1fr; }
}

/* ==========================================================================

/* The brand mark on a rail item, when the story is about a company we have a
   mark for. It sits on the baseline of the category label and takes the label's
   colour, so it reads as part of the kicker rather than as a logo dropped on
   the card. Marks we do not have are simply absent: a missing mark is quieter
   than an invented one. */
.lede__cat { display: flex; align-items: center; gap: var(--s-2); }

/* ---- Logo tiles ----------------------------------------------------------
   A logo is fitted, never filled. The photo tiles use object-fit: cover, which
   crops to the square; do that to a wordmark and you slice it in half.

   The tile keeps its white and takes a hairline, because a white logo tile on
   a white page has no edge of its own and would otherwise float. And no hover
   scale: growing a photograph is a nice touch, growing a company's logo looks
   like a mistake. */
/* These are brand TILES now, not marks floating on a white card: the new
   artwork is full bleed on each brand.s own ground, Taco Bell purple and the
   WOWorks mark on its own field. So the frame stops supplying a white card
   and a border and simply gets out of the way, and the image covers it.

   Brand marks remain the one asset class on this site never graded into the
   palette, which is why no filter is applied here. */
/* A mark on a white card. The previous WOWorks file is square and already on
   white, so it wants the card and the hairline rather than a bleed. */
.lede__thumb--logo {
  background: #FFFFFF;
  box-shadow: inset 0 0 0 1px var(--c-rule-strong);
}
.lede__thumb--logo img { object-fit: contain; }

/* A BRAND TILE. Artwork that already carries its own ground, so the frame
   supplies nothing and the image covers it edge to edge. */
.lede__thumb--tile { background: var(--c-surface-2); }
.lede__thumb--tile img { object-fit: cover; }
.lede__mini a:hover .lede__thumb--tile img { transform: none; }
.lede__mini a:hover .lede__thumb--logo img { transform: none; }

/* The inline mark next to a category label is gone with the markup that used
   it: the tile carries the brand now, and two marks on one card is one too
   many. The flex row stays, it costs nothing and keeps the label aligned. */

/* ==========================================================================
   HOUSE AD

   The 300x250 medium rectangle. Deliberately the standard size: a reader
   recognises the shape as an ad before reading a word of it, which is the
   honest outcome. Inventing a bespoke promo block that looks like editorial
   would convert better and be worse.

   Centred with real air around it, the way a magazine sets an ad between two
   pieces rather than welding it to the section below.
   ========================================================================== */
.housead {
  display: block;
  padding-block: var(--s-8);
  background: var(--c-surface-2);
}
.housead .wrap { display: grid; justify-items: center; }

/* The visible label is gone by request. The disclosure now rests entirely on
   rel="sponsored" on the link and on aria-label="Advertisement" on the block,
   which is what a screen reader and a search engine read. Worth knowing that
   this is weaker than a printed label for a sighted reader, and that the site
   is a Peoplebox property, so if this unit is ever sold rather than house run
   the label has to come back. Kept as a rule in case it does. */
.housead__label {
  display: none;
  margin: 0 0 var(--s-3);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--c-ink-3);          /* 5.3:1 on the grey */
}

/* 728 x 90, the leaderboard: a strip, and a standard slot, so a real ad
   server can take this space later without the layout moving. Fluid under
   728 and stacked under 700, where the subline starts wrapping and the row
   runs out of air, because a fixed strip is the one shape that
   cannot survive a phone. */
.housead__unit {
  display: flex;
  align-items: center;
  gap: var(--s-5);
  width: 100%;
  max-width: 728px;
  height: 90px;
  padding: 0 var(--s-5);
  background: var(--ad-pb-gradient);
  border: 1px solid var(--ad-pb-line);
  border-radius: var(--radius);
  text-decoration: none;
  transition: box-shadow var(--dur) var(--ease);
}
.housead__unit:hover { box-shadow: 0 2px 14px rgba(31, 18, 53, 0.14); }

.housead__logo { flex: none; width: 118px; height: auto; }

.housead__copy { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.housead__hed {
  font-family: var(--font-display);
  font-size: 1.05rem;
  line-height: 1.2;
  letter-spacing: -0.014em;
  color: var(--ad-pb-ink);
}
.housead__sub {
  font-size: 0.78rem;
  line-height: 1.35;
  color: var(--ad-pb-muted);
}

/* The advertiser's purple, not the site's orange. An ad borrowing the
   publication's call to action colour is the blur the label is there to
   prevent. */
.housead__cta {
  flex: none;
  margin-left: auto;
  padding: 0.55em 1.05em;
  border-radius: 999px;
  background: var(--ad-pb-purple);
  color: #FFFFFF;                 /* 8.2:1 on the purple */
  font-size: var(--fs-sm);
  font-weight: 600;
  white-space: nowrap;
}

@media (max-width: 700px) {
  .housead__unit {
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    gap: var(--s-3);
    height: auto;
    padding: var(--s-5);
  }
  .housead__cta { margin-left: 0; }
}



/* ==========================================================================
   AI IN THE LOOP

   An empty section that reads as deliberately empty rather than as broken.
   The cards are dashed, not solid, because a dashed edge is the established
   way of saying "nothing here yet" and it stops a reader mistaking a
   placeholder for a published story.
   ========================================================================== */
.loop__note {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--s-3);
  margin: 0 0 var(--s-6);
  font-size: var(--fs-sm);
  color: var(--c-ink-3);
}

.loopgrid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s-5);
  list-style: none;
  margin: 0;
  padding: 0;
}

.loopcard {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--s-3);
}

/* The one dashed border on the site, and it means exactly one thing. */
.loopcard--empty .loopcard__figure {
  border: 1px dashed var(--c-rule-strong);
}
.loopcard__figure {
  display: block;
  width: 100%;
  border-radius: var(--radius-photo);
  overflow: hidden;
  background: var(--c-surface-2);
}
.loopcard__figure img {
  width: 100%;
  height: auto;
  aspect-ratio: 1;
  object-fit: cover;
  /* The figures are already low contrast by construction. This keeps them
     from competing with the real photography above them. */
  opacity: 0.85;
}

.loopcard__tag {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--c-ink-3);
}
.loopcard__line {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-size: 1.02rem;
  line-height: 1.3;
  color: var(--c-ink-3);
}

@media (max-width: 900px) { .loopgrid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 480px) { .loopgrid { grid-template-columns: 1fr; } }

/* ==========================================================================
   AI TOOLS AND PLAYBOOKS

   Two short rows, each under a Prussian bar with an orange mark in it. That
   bar is the podcast rail's header device reused: same publication, same
   furniture. The colour sits on the bars rather than on the section, because
   this block runs between a grey band above and the Prussian closing band
   below, and a third full width tint would have flattened all three.
   ========================================================================== */
.kitgroup + .kitgroup { margin-top: var(--s-6); }

.kitgroup__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-5);
  padding: var(--s-3) var(--s-4);
  background: var(--c-ground-ink);
  border-radius: var(--radius);
}

.kitgroup__title {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  margin: 0;
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-size: 1.16rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  color: var(--c-on-ink);              /* 16:1 on Prussian */
}

/* The one warm mark in the bar. Orange is a block colour on this site and
   never type, and a drawn mark is exactly a block. */
.kitgroup__icon {
  flex: none;
  width: 32px;
  height: 32px;
  fill: var(--c-statement);
}

/* Orange as type here is the established exception on an ink ground: the same
   token the podcast band already uses for its links. 7.6:1 on Prussian. */
.kitgroup__all {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--c-accent-on-ink);
  text-decoration: none;
  white-space: nowrap;
}
.kitgroup__all:hover { text-decoration: underline; text-underline-offset: 3px; }

/* Three across, divided by rules rather than floated apart as cards. */
.kitrow {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: var(--s-6);
  list-style: none;
  margin: 0;
  padding: 0;
}
.kititem { position: relative; }
.kititem + .kititem::before {
  content: "";
  position: absolute;
  top: var(--s-4);
  bottom: var(--s-4);
  left: calc(var(--s-6) / -2);
  width: 1px;
  background: var(--c-rule);
}

.kititem__link {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  height: 100%;
  padding-block: var(--s-4);
  text-decoration: none;
}

/* A label, not a control. It stopped being a filter when the section stopped
   being a list, so it drops the chip border and becomes an eyebrow like every
   other category mark on the site. Prussian rather than grey, because the
   whole card is a link and blue is what you click here. */
.kititem__tag {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--c-accent);
}
.kititem__title {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-size: 1.08rem;
  line-height: 1.26;
  letter-spacing: -0.014em;
  color: var(--c-ink);
  text-wrap: balance;
}
.kititem__link:hover .kititem__title {
  text-decoration: underline;
  text-underline-offset: 3px;
}

@media (max-width: 760px) {
  .kitrow { grid-template-columns: 1fr; }
  .kititem + .kititem::before {
    top: 0; bottom: auto; left: 0; right: 0;
    width: auto; height: 1px;
  }
  .kitgroup__bar { flex-wrap: wrap; gap: var(--s-3); }
}

/* ==========================================================================
   THE PODCAST RAIL

   The show's permanent slot on the front page: the name, the waveform, the
   latest episode and one button. It carried three episodes before, which made
   it a second contents list sitting beside the real one in the middle column.
   One episode with its artwork is a promo. Three headings in a box is just
   more articles.

   IT STICKS. The rail is shorter than the lead story beside it, so it pins
   under the header and rides down while the front page scrolls, releasing
   exactly where the grid ends, which is the top of the ad. That release point
   is free: a sticky element cannot escape its containing block, and the
   containing block here is the lede grid, whose last pixel is the ad's first.
   Nothing measures a scroll position and nothing has to be kept in sync with
   where the ad happens to sit.
   ========================================================================== */
/* THE FRAME STARTS BELOW THE WAVES.

   The border lives on the body, not on the rail, so the left and right lines
   begin at the bottom of the waveform rather than running up beside it.

   Removing the rail's top border was not enough on its own. The bars vary in
   height and the ones at each end are short by design, so the side lines were
   still standing a clear 25px above the wave at both corners and the band read
   as something sitting inside the box rather than as its edge. With the frame
   starting underneath, the waveform is the whole top of the block and there is
   no line above it anywhere along its width. */
.podrail {
  /* One number, and everything else is derived from it. The wave's height,
     the amount the box is pulled up under it and the extra top padding that
     keeps the copy clear of the overlap all come off this, so changing it
     cannot put the axis out of alignment. */
  --wave-h: 30px;
  /* The wave and the box share this, so they start and end on the same two
     vertical lines. Set in one place because the whole point is that they
     cannot drift apart. */
  --rail-inset: 10px;

  position: sticky;
  /* Clear of the sticky header, plus a little air. */
  top: calc(var(--header-h) + var(--s-4));
}

/* THE TOP EDGE IS THE WAVEFORM. There is no band behind it and no rule above
   it: the rail's top border is removed and the bars are what closes the box.
   A drawn line would have said "here is the top of a card"; the bars say
   "this is audio" and do the same structural job. */
/* THE WAVE'S AXIS OF SYMMETRY IS THE BOX'S TOP EDGE.

   The box has no top border. Where that line used to be is now the line the
   bars mirror about, so the wave straddles the edge: the upper half sits
   above the box and the lower half runs down into it. The left and right
   borders start at that same line, which is what makes it read as the edge
   rather than as a graphic parked above one.

   Done by pulling the box up under the wave by exactly half the wave's
   height. The wave has to paint on top, hence the stacking context: it comes
   first in the markup, so without it the box's background would cover the
   lower half.

   The wave is the same width as the box, so it begins and ends on the box's
   side borders. */
.podrail__edge {
  position: relative;
  z-index: 1;
  padding: 0;
  /* Same width as the box, not wider. The wave ends where the box ends, so
     the first and last bars sit on the box's two side borders. */
  margin-inline: var(--rail-inset);
  margin-bottom: calc(var(--wave-h) / -2);
}

.podrail__body {
  margin-inline: var(--rail-inset);
  /* Extra on top, so the copy clears the half of the wave hanging into it. */
  padding: calc(var(--s-4) + var(--wave-h) / 2) var(--s-4) var(--s-4);
  background: var(--c-surface-warm);
  border: 1px solid var(--c-ink);
  border-top: 0;                  /* the wave's axis is the top edge */
  border-radius: var(--radius);
}
/* Shorter than the story beside it on purpose. A sticky element can only
   travel through the difference between its own height and its container's,
   and the container here is the grid row, so every pixel the rail loses is a
   pixel of travel it gains. */

/* The waveform is the one orange thing in the rail. Orange is the site's
   block colour and never its type, and a drawn waveform is exactly a block,
   so this is the rule working as intended rather than an exception to it. At
   full strength it is also the only warm mark above the fold, which is what
   makes the rail read as audio before it is read at all. */
.podrail__wave {
  display: block;
  width: 100%;
  height: var(--wave-h);
  fill: var(--c-statement);
}

/* The rail's heading, and the only place its name appears. Two parts, and
   they are weighted deliberately: "Tune in to" is the instruction and the
   name is the thing, so the instruction goes small and in the sans, where
   every other label on this site lives, and the name takes the serif at
   nearly twice the size. */
.podrail__tune { margin: 0 0 var(--s-4); }

.podrail__tune-pre {
  display: block;
  text-align: center;
  margin-bottom: var(--s-1);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  color: var(--c-ink-3);
}
.podrail__tune-name {
  display: block;
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-size: 1.32rem;
  line-height: 1.16;
  letter-spacing: -0.02em;
  color: var(--c-ink);
  text-wrap: balance;
}

.podrail__latest { display: block; text-decoration: none; }
.podrail__thumb {
  display: block;
  margin-bottom: var(--s-3);
  border-radius: var(--radius-photo);
  overflow: hidden;
  background: var(--c-surface-2);
}
.podrail__thumb img {
  width: 100%;
  height: auto;            /* without this the height attribute wins and
                              aspect-ratio is ignored: the 16:9 still rendered
                              246 by 270, and that one number was most of why
                              the rail was taller than the story beside it */
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

.podrail__ep-hed {
  display: block;
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-size: 1.02rem;
  line-height: 1.26;
  letter-spacing: -0.012em;
  color: var(--c-ink);
}
.podrail__latest:hover .podrail__ep-hed { text-decoration: underline; text-underline-offset: 3px; }
.podrail__ep-who {
  display: block;
  margin-top: var(--s-2);
  font-size: var(--fs-xs);
  color: var(--c-ink-3);
}

/* Black. The orange in this rail is the waveform, and the one orange button
   on the page is Publish a PR in the masthead: a second orange button beside
   it would make the page look like it is asking for two things at once. */
.podrail__play {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  margin-top: var(--s-4);
  padding: 0.85em 1em;
  background: var(--c-ink);
  color: var(--c-ground);         /* 20:1 */
  border-radius: var(--radius);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: var(--tracking-label);
  text-transform: uppercase;
  text-decoration: none;
  transition: background var(--dur) var(--ease);
}
/* Orange on hover. Black at rest keeps the page to one orange button, the
   masthead's; the orange arrives only on intent, which is when a second one
   cannot be confused for a competing offer. The ink flips with it, because
   white on this orange is 2:1: --c-on-statement is 7.9:1 and exists for
   exactly this. */
.podrail__play:hover {
  background: var(--c-statement);
  color: var(--c-on-statement);
}
.podrail__play:hover .podrail__ico svg { fill: var(--c-on-statement); }
/* The triangle keeps the orange: on a black button it is the one warm mark
   that says audio, and it echoes the waveform along the top edge. */
.podrail__ico svg { width: 13px; height: 13px; display: block; fill: var(--c-statement); }

/* Below this the rail loses its own column, sits under the stack and stops
   sticking: a full width block pinned to the top of a phone is a banner, not
   a rail, and it would eat the screen the article is trying to use. */
@media (max-width: 1100px) {
  .lede__grid { grid-template-columns: 1.6fr 1fr; }
  .podrail { position: static; grid-column: 1 / -1; max-width: 420px; }
}
@media (max-width: 760px) {
  .lede__grid { grid-template-columns: 1fr; }
  .podrail { max-width: none; }
}

/* ==========================================================================
   OPERATOR PULSE: the pictures

   Every story carries one. The lead's is wider because its column is, not
   because it is a different kind of thing.

   Two treatments, and which one a story gets depends on what its picture is,
   the same split the lede rail uses: a photograph covers its frame, a brand
   mark is contained on a white card so it is not cropped through.
   ========================================================================== */
.press__figure {
  display: block;
  margin-bottom: var(--s-4);
  border-radius: var(--radius-photo);
  overflow: hidden;
  background: var(--c-surface-2);
}
.press__figure img {
  width: 100%;
  height: auto;              /* or the height attribute wins over aspect-ratio */
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

/* A mark has no ground of its own and must not be cropped, so it sits on a
   white card with air around it. Brand marks are the one asset class on this
   site never graded into the palette, so nothing is applied to them here. */
.press__figure--mark {
  background: #FFFFFF;
  box-shadow: inset 0 0 0 1px var(--c-rule);
}
.press__figure--mark img {
  object-fit: contain;
  padding: 2%;              /* was 6%: the mark was sitting too small in it */
}

/* A TILE IN A 16:9 FRAME CANNOT BE COVERED. The Taco Bell file is 512x512,
   so cover crops roughly a third off the top and a third off the bottom and
   cuts through the bell. It is contained instead, and the frame is painted
   the file.s own ground colour so the letterboxing is invisible and the card
   reads as one solid purple field with the whole mark on it.

   #653C8F is sampled from the file, not chosen. If a different brand tile is
   ever used here it needs its own ground, or this rule needs a variable. */
.press__figure--tile { background: #653C8F; }
.press__figure--tile img { object-fit: contain; padding: 0; }

/* The lead story's picture gets the room its column has. */
/* Every picture the same shape, for the same reason. */

@media (max-width: 900px) {
  .press__figure { margin-bottom: var(--s-3); }
}

/* The folio's left side is a description now, not a label, so it drops the
   small caps and the tracking the folio uses and reads as a sentence. The
   link on the right keeps them, because it is still a label. */
.nameplate__desc {
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
  font-size: 0.8rem;
}

/* ==========================================================================
   THE SHOW'S MARK

   Sits to the left of the podcast title, aligned to the title rather than to
   the block, so it reads as a logo on a name rather than as an icon on a
   section. It takes the statement colour, which on this site is a block
   colour and never type: a drawn mark is exactly a block.
   ========================================================================== */
.pod-title {
  display: flex;
  align-items: flex-start;
  gap: var(--s-4);
}
.pod-mark {
  flex: none;
  width: 52px;
  height: 52px;
  fill: var(--c-statement);
  /* Optically aligned to the cap height of the heading beside it, not to its
     box: the capsule has round ends and sitting it on the box top leaves it
     looking high. */
  margin-top: 2px;
}

@media (max-width: 640px) {
  .pod-mark { width: 40px; height: 40px; }
  .pod-title { gap: var(--s-3); }
}

/* All six Pulse stories now carry an image of their own subject, so the
   category art fallback is gone. It is kept as a rule, and documented, because
   the next story added may arrive without imagery: give its figure the --art
   modifier and an empty alt, and use the topic photograph for its category.
   That marks it clearly as illustration rather than a photograph of the
   subject, which is the distinction that matters. */
.press__figure--art img { object-fit: cover; }

/* ==========================================================================
   UPCOMING EVENTS BAND

   Read like a departure board: the label holds still and the events run past
   it. The band takes the recessed surface so it reads as a fixture on the
   page rather than as another editorial section.
   ========================================================================== */
.events {
  background: var(--c-surface-2);
  border-block: 1px solid var(--c-rule);
  padding-block: var(--s-6);
  overflow: hidden;              /* the track is wider than the page */
}

.events__head { display: flex; justify-content: flex-end; margin-bottom: var(--s-4); }
.events__all { font-size: var(--fs-xs); }

.events__row { display: flex; align-items: center; gap: var(--s-6); }

/* The label keeps the container's left gutter so it lines up with every other
   section on the page, while the marquee beside it runs to the viewport edge.
   The max() is what holds that alignment at any width: below the container's
   max-width the gutter is just the page padding. */
.events__label {
  flex: none;
  display: flex;
  flex-direction: column;
  margin: 0;
  /* 100%, not 100vw. 100vw includes the scrollbar and the container does
     not, so the vw version put the label 7.5px right of where every other
     section starts: computed 84px against the container.s 76.5px. The
     percentage resolves against .events__row, which is content width. */
  padding-left: max(var(--s-5), calc((100% - var(--w-page)) / 2 + var(--s-5)));
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-size: clamp(1.4rem, 1rem + 1.1vw, 1.9rem);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--c-ink);
}

.events__marquee { flex: 1; min-width: 0; overflow: hidden; }

/* THE LOOP. The track holds the set twice and slides exactly -50%, so at the
   end of the cycle the second set sits precisely where the first began and the
   restart cannot be seen. Any other distance shows a jump. */
.events__track {
  display: flex;
  width: max-content;
  animation: events-scroll 44s linear infinite;
}
@keyframes events-scroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
/* A reader who wants to look at one should be able to stop it. */
.events:hover .events__track,
.events:focus-within .events__track { animation-play-state: paused; }

.events__set {
  display: flex;
  align-items: center;
  gap: var(--s-6);
  margin: 0;
  padding: 0 var(--s-6) 0 0;
  list-style: none;
}

.ev-card {
  display: flex;
  align-items: center;
  gap: var(--s-4);
  width: 344px;
  flex: none;
}
/* 84, not 60. These are the organisers' own promotional tiles, drawn to be
   read at 120px and up: at 60 they were an unreadable mush. At 84 the tile
   reads as a distinct branded square even though its small print still does
   not, and the card's own name and date carry the facts. */
.ev-card__tile {
  flex: none;
  width: 84px;
  height: 84px;
  border-radius: var(--radius-photo);
  overflow: hidden;
}
.ev-card__tile img { width: 100%; height: auto; aspect-ratio: 1; object-fit: cover; }

.ev-card__body { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.ev-card__name {
  font-family: var(--font-display);
  font-optical-sizing: auto;
  font-size: 1rem;
  line-height: 1.22;
  letter-spacing: -0.012em;
  color: var(--c-ink);
}
.ev-card__date { font-size: var(--fs-xs); color: var(--c-ink-3); }

/* Motion off means the band becomes a plain scrollable row. It does not become
   a still frame showing only the first two events: the rest would simply be
   unreachable. */
@media (prefers-reduced-motion: reduce) {
  .events__track { animation: none; }
  .events__marquee { overflow-x: auto; }
  .events__set:last-child { display: none; }
}

@media (max-width: 760px) {
  .events__row { flex-direction: column; align-items: flex-start; gap: var(--s-4); }
  .events__label { padding-left: var(--s-4); }
  .events__marquee { width: 100%; }
}
