/* The Fufi Show — site styles
   Brand spec (locked): marketing/the-fufi-show/brand/README.md
   Lobster display · Fredoka text · cream #F2EDE2 on oxblood #6F1D1B · gold #D9A227 keyline */

@font-face {
  font-family: "Lobster";
  src: url("fonts/lobster.woff") format("woff");
  font-weight: 400;
  font-display: swap;
}
@font-face {
  font-family: "Fredoka";
  src: url("fonts/fredoka.woff") format("woff");
  font-weight: 300 700;          /* variable wght axis */
  font-display: swap;
}

:root {
  --oxblood:      #6F1D1B;
  --oxblood-deep: #4E1412;
  /* The page steps down through LIGHT cream/sand tones and only then drops into the reds
     (founder, 2026-08-19: lighter shades of cream before going to red). All four light steps
     take ink text at 11:1 or better — measured, not eyeballed.
     ⚠️ An earlier ramp used mid-tones and put a band at #8D4E48; do not reintroduce mid browns.
     There is a contrast DEAD ZONE around #A5756C–#99615A where neither ink nor cream reaches
     4.5:1, so any future stop between cream and oxblood must be measured before shipping. */
  --sand-1:       #ECE3D2;   /* ink 13.6:1 */
  --sand-2:       #E5DAC2;   /* ink 12.5:1 */
  --sand-3:       #DFD0B2;   /* ink 11.4:1 */
  --cream:        #F2EDE2;
  --cream-warm:   #E8E0CE;
  --gold:         #D9A227;
  --ink:          #2A1512;
  --ink-soft:     #6B4A42;

  --display: "Lobster", Georgia, serif;
  --text: "Fredoka", "Trebuchet MS", system-ui, sans-serif;

  --measure: 68ch;
  --pad: clamp(20px, 5vw, 48px);
}

*, *::before, *::after { box-sizing: border-box; }

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

/* Web Interface Guidelines: never animate for someone who asked us not to. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}

body {
  margin: 0;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--text);
  font-weight: 400;
  font-size: clamp(17px, 1.05vw + 14px, 19px);
  line-height: 1.65;
  overflow-x: hidden;

  /* short pages (Academy index, press) must still push the footer to the bottom */
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}
body > main { flex: 1 0 auto; }
/* Text pages ended flush against the footer. Only the narrow content column gets the padding —
   the lander's last band is full-bleed oxblood running into the footer, and padding on `main`
   would open a cream gap in the middle of that colour ramp. */
main > .wrap.narrow { padding-bottom: clamp(44px, 6vw, 76px); }
body > footer { flex: none; margin-top: auto; }

img { max-width: 100%; height: auto; display: block; }

a { color: var(--oxblood); text-decoration-thickness: 2px; text-underline-offset: 3px; }
a:hover { color: var(--gold); }

:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }

.wrap { width: 100%; max-width: 1240px; margin-inline: auto; padding-inline: var(--pad); }
/* .narrow constrains the CONTENT, not the container — so every section keeps the same left edge */
.narrow > * { max-width: 720px; }


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

/* ── Top bar ─────────────────────────────────────────────── */
.topbar {
  background: var(--oxblood);
  border-bottom: 3px solid var(--gold);
}
/* ⚠️ FULL-BLEED, deliberately — brand pinned to the left edge, nav to the right.
   The bar's ground already spans the window, so capping its contents at the 1240px column
   stranded both of them ~700px in from either edge on a wide screen, with a lake of empty
   oxblood at each end (founder, 2026-08-19: "position of the buttons makes no sense").
   It now shares its left edge with the hero and with the overflowing shelf rows — the chrome
   bleeds, the reading column stays centred. Do not re-cap this at --maxw. */
.topbar .wrap { max-width: none; }
.topbar .wrap {
  display: flex; align-items: center; gap: 16px;
  min-height: 66px; flex-wrap: wrap;
}
.topbar a { color: var(--cream); text-decoration: none; }
.topbar a:hover { color: var(--gold); }
.brandlink { display: flex; align-items: center; gap: 12px; font-weight: 600; }
.brandlink img { width: 38px; height: 38px; border-radius: 50%; border: 2px solid var(--gold); }
.brandlink span { font-family: var(--display); font-size: 1.35rem; letter-spacing: .01em; }
.topnav { margin-left: auto; display: flex; gap: clamp(14px, 3vw, 28px); font-size: .95rem; }

/* ── Hero ────────────────────────────────────────────────── */
/* ⚠️ THE FOLD IS THE DESIGN — do not size this by "how big can the picture be".
   The opening view must compose as: topbar + hero + the FULL logline + a slice of the next
   section. A hero that fills the fold and guillotines the text below it is the failure mode
   this block exists to prevent (founder, 2026-08-19, twice).

   How it holds: hero.jpg is pre-cropped to ~3.3:1 in the FILE, so at a ~1990px window it lands
   ~605px and the logline clears with room to spare. Full-bleed, natural aspect, no letterboxing.
   Deliberately NO max-height + object-fit: cover — that cut heads and feet twice. If the hero
   must get shorter, re-crop the file (recipe in brand/_work/keyart/web-hero-plate.md). */
.hero {
  position: relative;
  background: var(--oxblood);
  border-bottom: 3px solid var(--gold);   /* mirrors the topbar keyline, framing the plate */
}
/* The locked lockup, centred over the plate. It is the outlined SVG master, so it carries no
   font dependency and stays crisp at any size. Decorative: the page's real <h1> is the
   visually-hidden one, so this is alt="" + aria-hidden. */
.hero img.hero-logo {
  position: absolute;
  top: clamp(14px, 2.5vw, 34px);
  left: 50%;
  transform: translateX(-50%);
  width: clamp(170px, 26vw, 380px);
  height: auto;
  z-index: 2;
  border-radius: 50%;
  box-shadow: 0 8px 30px rgba(0, 0, 0, .45);
}
.hero > picture img,
.hero > img:not(.hero-logo) { width: 100%; }
/* The ACCEPTED seal — Fufi's own quality stamp, slapped into the bottom-right corner of the
   plate. Same seal system as the REJECTED stamps used in the episodes (built from the shared
   overlay template), so the site and the show speak with one graphic. It sits on the dark
   cabinet/wall side of the frame, clear of both characters and of the centred logo.
   The tilt is baked into the PNG; the shadow is CSS so the artwork stays a flat 2-colour
   file (a baked soft shadow quantises into visible grey banding).
   Decorative — alt="" + aria-hidden, exactly like the logo. */
.hero img.hero-stamp {
  position: absolute;
  right: clamp(8px, 2.4vw, 46px);
  top: clamp(10px, 2.6vw, 40px);
  /* Scales with the hero, not with the page. The narrow plate is a 2.31:1 crop where the
     desktop one is 3.29:1, so the same vw makes a much taller-looking seal on a phone — an
     88px floor there put it at half the hero's height, on top of the poodle. 12.5vw holds it
     at ~30% of the hero height at every width. */
  width: clamp(58px, 12.5vw, 216px);
  height: auto;
  z-index: 2;
  /* ⚠️ NO skew, and no transform that can deform a circle. The seal must stay PERFECTLY ROUND
     (founder, 2026-08-19) — a skewed circle reads as a broken image, not as a pressed stamp.
     The "hand-stamped" impression is built into the artwork instead, where it belongs: the seal
     carries its own -9deg tilt, and its centre die is deliberately out of register with the ring
     (see stamp-accepted.html). Rotation is the only transform that leaves a circle a circle. */
  /* ⚠️ NO drop shadow, deliberately. Ink does not float — a shadow under the seal instantly
     turns it back into a sticker lying on top of the picture, which is the exact opposite of
     the effect. The slight transparency lets the wall behind it come through just enough to
     read as printed onto the plate rather than pasted over it. */
  opacity: .92;
}
.logline {
  background: var(--oxblood);
  color: var(--cream);
  padding: clamp(22px, 3.5vw, 36px) 0 clamp(24px, 4vw, 40px);
  text-align: center;
}
.logline p {
  max-width: 30ch;
  margin: 0 auto;
  font-family: var(--display);
  font-size: clamp(1.5rem, 3.6vw, 2.5rem);
  line-height: 1.25;
}
.logline .sub {
  font-family: var(--text);
  font-size: clamp(1rem, 1.4vw, 1.12rem);
  max-width: 62ch;
  margin: 16px auto 0;
  color: var(--cream-warm);
  line-height: 1.6;
}

/* ── Sections ────────────────────────────────────────────── */
section { padding: clamp(44px, 7vw, 84px) 0; }
section + section { border-top: 1px solid rgba(111,29,27,.16); }
.band-dark { background: var(--oxblood-deep); color: var(--cream); border-top: none; }
.band-dark a { color: var(--gold); }
/* Lighter oxblood, so the contact band doesn't merge into the footer below it */
.band-mid { background: var(--oxblood); color: var(--cream); border-top: none; }
.band-mid a { color: var(--gold); }
.band-mid .kicker { color: var(--gold); }

.kicker {
  font-size: .78rem; letter-spacing: .16em; text-transform: uppercase;
  font-weight: 600; color: var(--gold); margin-bottom: 10px;
}
.band-dark .kicker { color: var(--gold); }

h1, h2, h3 { font-family: var(--display); font-weight: 400; line-height: 1.15; margin: 0 0 .5em; }
h2 { font-size: clamp(1.7rem, 3.6vw, 2.6rem); }
/* inside the article body, h2s need air above them; section h2s get it from section padding */
main h2 { margin-top: 1.6em; }
main .recipe-head h1 { margin-top: 0; }
h3 { font-size: clamp(1.25rem, 2.2vw, 1.55rem); }
p { max-width: var(--measure); }

/* ── Episode card ────────────────────────────────────────── */
.episode {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: clamp(20px, 4vw, 44px);
  align-items: center;
}
@media (max-width: 720px) { .episode { grid-template-columns: 1fr; } }
.episode figure { margin: 0; }
.episode img { border-radius: 10px; border: 3px solid var(--oxblood); }
.ep-no {
  font-size: .78rem; letter-spacing: .16em; text-transform: uppercase;
  font-weight: 600; color: var(--ink-soft);
}
.episode h3 { margin-top: 6px; font-size: clamp(1.6rem, 3.2vw, 2.2rem); }

.pill {
  display: inline-block; padding: 7px 15px; border-radius: 999px;
  font-size: .82rem; font-weight: 600; letter-spacing: .04em;
  background: var(--cream-warm); color: var(--ink-soft);
  border: 1px solid rgba(111,29,27,.25);
}

.btn {
  display: inline-block; padding: 13px 26px; border-radius: 999px;
  font-weight: 600; text-decoration: none; font-size: .98rem;
  background: var(--oxblood); color: var(--cream);
  border: 2px solid var(--oxblood); transition: background .15s, color .15s;
}
.btn:hover { background: var(--gold); border-color: var(--gold); color: var(--ink); }
.btn.ghost { background: transparent; color: var(--oxblood); }
.btn.ghost:hover { background: var(--oxblood); color: var(--cream); }
.band-dark .btn.ghost, .band-mid .btn.ghost { color: var(--cream); border-color: var(--cream); }
.band-dark .btn.ghost:hover, .band-mid .btn.ghost:hover { background: var(--gold); border-color: var(--gold); color: var(--ink); }

/* ── Cast ────────────────────────────────────────────────── */
.cast { display: grid; gap: clamp(20px, 3vw, 32px); grid-template-columns: repeat(auto-fit, minmax(270px, 1fr)); }
.cast h3 { margin-bottom: .3em; }
.cast p { font-size: .96rem; margin: 0; }

/* ── Recipe index teaser ─────────────────────────────────── */
.recipe-link {
  display: flex; align-items: center; gap: clamp(16px, 3vw, 28px);
  background: var(--cream-warm); border: 2px solid var(--oxblood);
  border-radius: 12px; padding: clamp(16px, 3vw, 24px);
  text-decoration: none; color: var(--ink);
  transition: border-color .15s, transform .15s;
  max-width: 720px;
}
.recipe-link:hover { border-color: var(--gold); transform: translateY(-2px); color: var(--ink); }
.recipe-link img { width: clamp(90px, 18vw, 150px); border-radius: 8px; flex: none; }
.recipe-link span { min-width: 0; }   /* flex child must be shrinkable or text overflows */
.recipe-link strong { font-family: var(--display); font-size: clamp(1.2rem, 2.4vw, 1.5rem); font-weight: 400; display: block; }
.recipe-link em { font-style: normal; font-size: .9rem; color: var(--ink-soft); }

/* ── Recipe page ─────────────────────────────────────────── */
.crumb { font-size: .88rem; color: var(--ink-soft); padding-top: 26px; }
.crumb a { color: var(--ink-soft); }

.recipe-head { padding: 24px 0 0; }
.recipe-head h1 { font-size: clamp(2.2rem, 6vw, 3.6rem); margin-bottom: .15em; }
.dek { font-size: clamp(1.05rem, 1.6vw, 1.2rem); color: var(--ink-soft); max-width: 56ch; margin-top: 0; }
.recipe-hero { margin: clamp(22px, 4vw, 34px) 0; }
.recipe-hero img { border-radius: 12px; border: 3px solid var(--oxblood); width: 100%; }
.recipe-hero figcaption { font-size: .84rem; color: var(--ink-soft); margin-top: 8px; }

.meta {
  display: flex; flex-wrap: wrap; gap: 0;
  border-block: 2px solid var(--oxblood);
  margin: 0 0 clamp(28px, 5vw, 44px);
  padding: 0; list-style: none;
}
.meta li { flex: 1 1 130px; padding: 16px 18px 14px; border-right: 1px solid rgba(111,29,27,.2); }
.meta li:last-child { border-right: none; }
.meta b { display: block; font-size: .72rem; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-soft); font-weight: 600; margin-bottom: 3px; }
.meta span { font-family: var(--display); font-size: 1.15rem; }

blockquote.fufi {
  margin: 26px 0; padding: 18px 24px;
  border-left: 4px solid var(--gold);
  background: var(--cream-warm);
  border-radius: 0 8px 8px 0;
  font-size: 1.02rem;
}
blockquote.fufi p { margin: 0; max-width: none; }
blockquote.fufi cite { display: block; margin-top: 8px; font-style: normal; font-size: .82rem; color: var(--ink-soft); letter-spacing: .04em; }

.ingredients { list-style: none; padding: 0; margin: 0 0 10px; max-width: 620px; }
.ingredients li {
  padding: 12px 0 12px 34px; position: relative;
  border-bottom: 1px solid rgba(111,29,27,.16);
}
.ingredients li::before {
  content: ""; position: absolute; left: 0; top: 18px;
  width: 15px; height: 15px; border: 2px solid var(--oxblood); border-radius: 3px;
}
.ingredients b { font-weight: 600; }
/* AI disclosure + ingredient notes — must stay readable, not fine print */
.note { font-size: .95rem; color: var(--ink-soft); border-left: 3px solid var(--gold); padding-left: 14px; }

.steps { list-style: none; counter-reset: step; padding: 0; margin: 0; }
.steps > li {
  counter-increment: step;
  position: relative;
  padding: 0 0 clamp(26px, 4vw, 36px) clamp(52px, 8vw, 68px);
}
.steps > li::before {
  content: counter(step);
  position: absolute; left: 0; top: -4px;
  width: clamp(38px, 6vw, 46px); height: clamp(38px, 6vw, 46px);
  display: grid; place-items: center;
  background: var(--oxblood); color: var(--cream);
  font-family: var(--display); font-size: 1.3rem;
  border-radius: 50%;
}
.steps h3 { margin-bottom: .25em; font-size: clamp(1.15rem, 2vw, 1.4rem); }
.steps p { margin-top: 0; }

/* Step photographs — frames lifted from the episodes, so they are already on-model.
   Shown at their NATIVE ratio: the sources are 16:9 and are never cropped at render time
   (see website/README.md — "crop in the FILE, never at render time"). */
.steps figure { margin: 16px 0 0; max-width: 560px; }
.steps figure img { display: block; width: 100%; height: auto; border-radius: 10px; border: 2px solid var(--oxblood); }
.steps figcaption { font-size: .82rem; color: var(--ink-soft); margin-top: 7px; line-height: 1.45; }

/* ── "SUPERSTOVE SAYS" ────────────────────────────────────────────────────────
   The kitchen's own intelligence owns every precise number on this site: temperatures,
   ratios, thresholds. Fufi does the believing; the stove does the measuring.

   Comic-book grammar, built from shaped divs — no new image assets and no new fonts:
   heavy ink border, a HARD FLAT offset shadow (never a soft blur — a comic panel is
   printed, it does not float), and a two-triangle speech tail so the border reads
   continuous through the point. Palette is the locked one; the gold dashed strip is the
   KITT-style scanner LED off his oven door, which is his only expressive feature.
   Figures use the SYSTEM monospace stack — an engineering register for 0 KB. */
.stove-says {
  display: grid;
  grid-template-columns: 104px 1fr;
  gap: 20px;
  align-items: start;
  margin: 32px 0;
}
.stove-says .who img {
  display: block; width: 104px; height: 104px;
  border-radius: 10px;
  border: 3px solid var(--oxblood);
  box-shadow: 4px 4px 0 var(--gold);
}
.stove-says .who b {
  display: block; margin-top: 10px; text-align: center;
  font-size: .68rem; font-weight: 700; line-height: 1.3;
  letter-spacing: .13em; text-transform: uppercase; color: var(--oxblood);
}
.stove-says .bubble {
  position: relative;
  background: var(--cream-warm);
  border: 3px solid var(--oxblood);
  border-radius: 14px;
  box-shadow: 5px 5px 0 var(--oxblood);
  padding: 15px 20px 14px;
}
/* Two stacked triangles: the outer one is the border colour, the inner one punches the
   fill back through, so the tail keeps a continuous 3px outline. */
.stove-says .bubble::before,
.stove-says .bubble::after {
  content: ""; position: absolute; top: 24px;
  width: 0; height: 0; border-top: 12px solid transparent; border-bottom: 12px solid transparent;
}
.stove-says .bubble::before { left: -18px; border-right: 16px solid var(--oxblood); }
.stove-says .bubble::after  { left: -13px; border-right: 16px solid var(--cream-warm); }
/* the scanner LED */
.stove-says .led {
  height: 5px; border-radius: 3px; margin-bottom: 11px;
  background: repeating-linear-gradient(90deg, var(--gold) 0 10px, transparent 10px 16px);
}
.stove-says .bubble p { margin: 0 0 .55em; max-width: none; font-size: .96rem; line-height: 1.55; }
.stove-says .bubble p:last-child { margin-bottom: 0; }
.stove-says .val {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-weight: 600; font-size: .92em; font-variant-numeric: tabular-nums;
  color: var(--oxblood);
}

/* Narrow: portrait and name become a row above the bubble, and the tail points UP. */
@media (max-width: 620px) {
  .stove-says { grid-template-columns: 1fr; gap: 14px; }
  .stove-says .who { display: flex; align-items: center; gap: 14px; }
  .stove-says .who img { width: 68px; height: 68px; }
  .stove-says .who b { margin-top: 0; text-align: left; }
  .stove-says .bubble::before { left: 26px; top: -18px;
    border: 0; border-left: 12px solid transparent; border-right: 12px solid transparent;
    border-bottom: 16px solid var(--oxblood); }
  .stove-says .bubble::after { left: 31px; top: -13px;
    border: 0; border-left: 12px solid transparent; border-right: 12px solid transparent;
    border-bottom: 16px solid var(--cream-warm); }
}

/* Same treatment for a technique figure sitting in running prose rather than in a step list. */
figure.technique { margin: 22px 0; max-width: 560px; }
figure.technique img { display: block; width: 100%; height: auto; border-radius: 10px; border: 2px solid var(--oxblood); }
figure.technique figcaption { font-size: .82rem; color: var(--ink-soft); margin-top: 7px; line-height: 1.45; }

.rescue { background: var(--oxblood); color: var(--cream); border-radius: 12px; padding: clamp(24px, 4vw, 36px); }

/* ⚠️ A padded box blocks margin-collapse, so the box's padding and its first child's margin-top
   STACK instead of overlapping. `main h2 { margin-top: 1.6em }` on a 2.6rem heading is ~66px —
   landing on top of the box's own ~36px, which shipped as a ~100px void above "When it goes wrong".
   Zero the first and last child on every padded box; do not fix this per-box. */
.rescue > :first-child,
.press > :first-child,
.stove-says .bubble > :first-child { margin-top: 0; }
.rescue > :last-child,
.press > :last-child,
.stove-says .bubble > :last-child { margin-bottom: 0; }
.rescue h2, .rescue h3 { color: var(--cream); }
.rescue a { color: var(--gold); }
.rescue dt { font-weight: 600; margin-top: 18px; color: var(--gold); }
.rescue dd { margin: 4px 0 0; max-width: var(--measure); }

/* ── Footer ──────────────────────────────────────────────── */
footer {
  background: var(--oxblood-deep); color: var(--cream-warm);
  padding: clamp(36px, 5vw, 56px) 0 clamp(30px, 4vw, 44px); font-size: .92rem;
}
footer a { color: var(--gold); }

/* Footer spans the full band like the topbar (same max-width override). */
footer .wrap { max-width: none; }

/* Conventional footer (founder, 2026-08-21): brand block on the left, link columns on the
   right, one full legal bar underneath -- the layout every site shares. No floating islands. */
footer .fgrid { display: grid; grid-template-columns: 1fr auto auto 1fr; gap: 40px 64px; align-items: start; }
footer .fright { justify-self: end; text-align: right; font-size: .82rem; opacity: .75; }
footer .fright p { margin: 0 0 7px; max-width: none; }
footer .fbrand { display: flex; flex-direction: column; align-items: flex-start; gap: 18px; }
footer .fname { font-family: var(--display); font-size: 1.35rem; color: var(--cream); margin: 0; }
footer .cols { display: grid; grid-template-columns: repeat(2, minmax(130px, 210px)); gap: 28px 64px; }
footer .cols p { margin: 0 0 5px; max-width: none; }
footer h4 {
  font-family: var(--text); font-weight: 600; font-size: .72rem;
  letter-spacing: .14em; text-transform: uppercase; color: var(--gold);
  margin: 0 0 13px;
}
footer ul { list-style: none; padding: 0; margin: 0; }
footer li { margin-bottom: 8px; }
footer .legal {
  margin-top: clamp(28px, 4vw, 40px);
  border-top: 1px solid rgba(242, 237, 226, .15);
  font-size: .82rem; opacity: .7;
}
footer .legal .wrap { padding-block: 17px clamp(30px, 4vw, 44px); }
footer .legal p { margin: 0; max-width: none; }
@media (max-width: 440px) { footer .cols { grid-template-columns: 1fr; } }
footer p { margin: 0 0 6px; max-width: 46ch; }

/* ── Print: people print recipes ─────────────────────────── */
@media print {
  .topbar, footer, .recipe-hero, .btn, .rescue { display: none !important; }
  body { background: #fff; color: #000; font-size: 12pt; }
  .steps > li::before { background: #000; color: #fff; }
  a::after { content: ""; }
}

/* ── Index card grids (recipes, Academy) ─────────────────── */
.card-grid {
  display: grid; gap: clamp(16px, 2.5vw, 24px);
  grid-template-columns: repeat(auto-fill, minmax(255px, 1fr));
  margin-top: clamp(22px, 4vw, 32px);
}
.narrow > .card-grid { max-width: none; }
.link-card {
  display: block; text-decoration: none; color: var(--ink);
  background: var(--cream-warm); border: 2px solid var(--oxblood);
  border-radius: 12px; padding: 20px 22px;
  transition: border-color .15s, transform .15s;
}
.link-card:hover { border-color: var(--gold); transform: translateY(-2px); color: var(--ink); }
.link-card strong {
  display: block; font-family: var(--display); font-weight: 400;
  font-size: clamp(1.2rem, 2.2vw, 1.45rem); margin-bottom: 6px;
}
.link-card span { display: block; font-size: .94rem; color: var(--ink-soft); line-height: 1.5; }
.link-card.soon { opacity: .62; border-style: dashed; pointer-events: none; }

/* ── "Learn this properly" — recipe → Academy cross-link ── */
.academy-ref {
  display: block; margin: 20px 0 0; padding: 14px 18px;
  background: transparent; border: 2px dashed var(--oxblood);
  border-radius: 8px; text-decoration: none; color: var(--ink);
  font-size: .95rem; transition: border-color .15s, background .15s;
}
.academy-ref:hover { border-color: var(--gold); background: var(--cream-warm); color: var(--ink); }
.academy-ref b { font-family: var(--display); font-weight: 400; }

/* ── Press page — the one out-of-voice surface ───────────── */
.press dt { font-weight: 600; margin-top: 20px; color: var(--ink-soft); font-size: .88rem; letter-spacing: .04em; }

/* A spec list should scan like a table, not as a column of stacked paragraphs. Two-column
   grid on wide screens, stacked on narrow where a 9rem label column would crush the values. */
.press dl.facts { display: grid; grid-template-columns: minmax(9rem, 13rem) 1fr; margin: 0 0 10px; }
.press dl.facts dt,
.press dl.facts dd { margin: 0; padding: 11px 0; border-top: 1px solid rgba(111,29,27,.16); }
.press dl.facts dt { padding-right: 18px; }
@media (max-width: 560px) {
  .press dl.facts { grid-template-columns: 1fr; }
  .press dl.facts dd { border-top: 0; padding-top: 0; }
}
/* credits are content, not caption — keep them at full contrast */
.press dd { margin: 3px 0 0; max-width: var(--measure); color: var(--ink); }

/* ── Shelves — horizontal, snap-scrolling rows of cards ──────
   Native scroll, deliberately NOT a rotating carousel: keyboard, touch and trackpad all work
   for free, nothing is hidden behind a timer, and no JS. Cards hold a fixed track width so a
   shelf with one item reads as a shelf with one item, not a carousel with a hole in it.
   The container scrolls, never the page body (Web Interface Guidelines). */
.shelf {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: min(380px, 80vw);   /* fixed track — the shelf scrolls, cards never shrink */
  gap: clamp(14px, 1.6vw, 22px);
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x proximity;
  scroll-behavior: smooth;   /* the arrows just assign a position; CSS does the animating */
  margin-top: clamp(20px, 3vw, 30px);
  /* Full-bleed: the shelf is a direct child of its <section>, not of .wrap, so it spans the
     viewport. This inset re-aligns the FIRST card with the section heading above it — it is the
     same sum .wrap resolves to (its centred max-width plus its own padding). Cards then run off
     the right edge, which is the point. scroll-padding keeps snap landing on that same line. */
  padding-block: 4px 6px;
  /* The standard shelf pattern (Netflix / Spotify / Disney+): the heading stays in the centred
     content column, the FIRST CARD aligns to that column's left edge, and the row bleeds off the
     RIGHT edge of the screen. So: start inset = whatever .wrap resolves to, end inset ~0.
     Do NOT move the headings out of the column to chase alignment — that is not a pattern real
     sites use, and it was tried and reverted on 2026-08-19.
     scroll-padding MUST equal padding-inline-start, or scroll-snap and the arrow maths disagree
     and the previous-arrow silently stops working. */
  /* DEFAULT = the row fits on screen: small symmetric inset and centred, so a short row sits in
     the middle of the viewport rather than hugging the left with a dead gap beside it. */
  padding-inline: var(--pad);
  scroll-padding-inline-start: var(--pad);
  justify-content: safe center;
  /* scrollbar hidden — the arrows and the peeking next card are the affordance instead */
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.shelf::-webkit-scrollbar { display: none; }
.shelf > * { scroll-snap-align: start; }

/* OVERFLOWING = more cards than fit. The row then uses the whole width: it starts near the LEFT
   EDGE of the screen (not indented to the heading column — that left a dead ~550px margin while
   the far end was already cut off) and bleeds off the right edge.
   The headings stay in the centred column regardless; only the row goes full width.
   `.is-overflowing` is set by shelf.js, because the decision needs the row measured in the
   *centred* state and CSS cannot ask that question about itself.
   scroll-padding must track padding-inline-start here, or the arrows aim off a snap point.
   ⚠️ The END inset is NOT zero. "Bleeds off the right edge" describes the row at REST — cards
   running past the edge is the affordance that says there is more. It does not mean the row
   should hit a hard stop with the last card jammed against the screen: scrolled to the end, a
   zero end-inset leaves the final card flush to the glass with no air at all, which reads as
   clipped rather than finished (founder, 2026-08-19). Matching the start inset closes the row
   symmetrically — same air on the left before you scroll, on the right once you have. */
.shelf.is-overflowing {
  padding-inline: var(--pad);
  scroll-padding-inline-start: var(--pad);
  justify-content: start;
}
.narrow > .shelf { max-width: none; }

.shelf-card {
  display: flex;
  flex-direction: column;
  background: var(--cream-warm);
  border: 2px solid var(--oxblood);
  border-radius: 12px;
  overflow: hidden;
  text-decoration: none;
  color: var(--ink);
  transition: border-color .15s, transform .15s;
}
.shelf-card:hover { border-color: var(--gold); transform: translateY(-3px); color: var(--ink); }
.shelf-card img { width: 100%; aspect-ratio: 16 / 9; object-fit: cover; }
.shelf-card .body { padding: 16px 18px 18px; display: flex; flex-direction: column; gap: 6px; }
.shelf-card .eyebrow {
  font-size: .7rem; letter-spacing: .16em; text-transform: uppercase;
  font-weight: 600; color: var(--ink-soft);
}
.shelf-card strong {
  font-family: var(--display); font-weight: 400;
  font-size: clamp(1.15rem, 1.8vw, 1.4rem); line-height: 1.15;
}
.shelf-card span.dek { font-size: .92rem; color: var(--ink-soft); line-height: 1.5; }
.shelf-card .pill { align-self: flex-start; margin-top: 4px; }

/* A shelf holding exactly ONE card reads as a carousel with a hole in it — and right now
   Episodes and Recipes have one each. Until a second arrives, lay the lone card out
   horizontally so the section keeps its presence. This reverts to a normal shelf on its own
   the moment a second card is added — no flag to remember, no code to revisit. */
.shelf:has(> :only-child) { grid-auto-columns: min(720px, 88vw); }
@media (min-width: 720px) {
  .shelf > .shelf-card:only-child { flex-direction: row; align-items: stretch; }
  .shelf > .shelf-card:only-child img { width: 48%; flex: none; aspect-ratio: auto; }
  .shelf > .shelf-card:only-child .body { flex: 1; justify-content: center; padding: 22px 26px; }
  .shelf > .shelf-card:only-child strong { font-size: clamp(1.4rem, 2.4vw, 1.85rem); }
  .shelf > .shelf-card:only-child span.dek { font-size: .98rem; }
}

/* ── Wide shelf — used by Episodes ───────────────────────────
   Founder preferred the large horizontal card. Episodes always use it, at any card count;
   Recipes and Academy keep the compact vertical card. */
.shelf.wide { grid-auto-columns: min(860px, 90vw); }
@media (min-width: 860px) {
  .shelf.wide > .shelf-card { flex-direction: row; align-items: stretch; }
  /* 52% of a 740px card against the card's own height gives a slot of ~2.15:1 — which is
     the image slot land at 2.15:1 — exactly the ratio the episode card images are cut to, so
     the thumbnail shows WHOLE, 0% cropped (measured, not assumed). The text column is
     deliberately kept shorter than the image's natural height, or it drives the card taller and
     the crop comes straight back. If you change the card width, this percentage, or add a line
     of card copy, re-measure — and re-cut the images if the slot ratio moves. */
  .shelf.wide > .shelf-card img { width: 56%; flex: none; aspect-ratio: auto; }
  .shelf.wide > .shelf-card .body { flex: 1; justify-content: center; padding: 20px 24px; }
  .shelf.wide > .shelf-card strong { font-size: clamp(1.35rem, 2.1vw, 1.7rem); }
}
/* the locked YouTube title, quiet under the dish name */
.shelf-card .ep-title {
  font-size: .86rem; font-style: italic; color: var(--ink-soft); line-height: 1.35;
}

/* ── Area grounds — each room its own ground, all inside the locked palette ──
   Rhythm down the page: light → warm → dark → oxblood → deep.
   No new hues: the brand is cream / oxblood / gold, and stays that way. */
.area-episodes { background: var(--cream); }
.area-recipes  { background: var(--sand-1); }
.area-recipes .shelf-card { background: var(--cream); }
.area-academy { background: var(--sand-2); color: var(--ink); border-top: none; }
.area-academy .kicker { color: var(--oxblood); }
.area-academy .shelf-card { background: var(--cream); border-color: var(--oxblood); }
.area-academy .note { color: var(--ink-soft); }

/* Cast sits between the dark Academy and the oxblood contact band — keep it light so the
   page does not run three dark bands together. */
.area-cast { background: var(--sand-3); color: var(--ink); border-top: none; }
.area-cast .kicker { color: var(--oxblood); }
/* The portrait sits OUTSIDE the text box: <article> is just a container, and the card styling
   (ground, gold rule, padding) lives on the inner .body instead. */
.area-cast .cast article {
  background: none;
  border: 0;
  padding: 0;
  color: var(--ink);
}
.area-cast .cast article img {
  width: 92px;
  height: 92px;
  aspect-ratio: 1;
  object-fit: cover;
  border-radius: 50%;
  border: 3px solid var(--gold);
  margin: 0 0 14px 4px;
}
.area-cast .cast article .body {
  background: var(--cream-warm);
  border-left: 3px solid var(--gold);
  border-radius: 4px;
  padding: 20px 22px;
}
.area-cast .cast h3 { color: var(--ink); margin-bottom: .3em; }
.area-cast .cast p { color: var(--ink-soft); }

/* availability folded into the eyebrow so the text column stops out-growing the thumbnail */
.shelf-card .eyebrow em { font-style: normal; text-transform: none; letter-spacing: .02em; opacity: .75; }


/* ── Carousel arrows ─────────────────────────────────────────
   The scrollbar is hidden, so mouse-only users need another way across. Touch and trackpad
   swipe natively; keyboard scrolls the focused shelf. These are progressive enhancement —
   with JS off the shelf still scrolls by every other means. */
.shelf-wrap { position: relative; }
.shelf-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--cream); color: var(--oxblood);
  border: 2px solid var(--oxblood);
  cursor: pointer; z-index: 2; padding: 0;
  transition: background .15s, color .15s, opacity .2s;
}
.shelf-nav:hover { background: var(--oxblood); color: var(--cream); }
.shelf-nav[hidden] { display: none; }
.shelf-nav.prev { left: 14px; }
.shelf-nav.next { right: 14px; }
.shelf-nav svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2.5;
                 stroke-linecap: round; stroke-linejoin: round; }
.area-academy .shelf-nav { background: var(--oxblood-deep); color: var(--cream); border-color: var(--gold); }
.area-academy .shelf-nav:hover { background: var(--gold); color: var(--ink); }
@media (max-width: 860px) { .shelf-nav { display: none; } }   /* touch devices swipe */

/* ── Placeholder card — an episode that exists but is not made yet ──
   Structurally IDENTICAL to a real episode card: same markup, a real <img> cut to the same
   2.15:1 ratio. That is deliberate — an earlier version used a CSS panel with its own
   aspect-ratio and it drove the whole shelf row taller, re-cropping the real thumbnails.
   Only two things differ: it is a <div>, not a link (there is nowhere to go), and the border
   is dashed. No date is promised anywhere on it — cadence is unresolved, and the house rule
   is never to promise above the floor. */
.shelf-card.is-placeholder { cursor: default; border-style: dashed; }
.shelf-card.is-placeholder:hover { transform: none; border-color: var(--oxblood); }
.shelf-card.is-placeholder strong { color: var(--ink-soft); }

/* ── Studio credit (footer) ──────────────────────────────── */
footer .studio-credit {
  display: inline-flex; align-items: center; gap: 12px;
  text-decoration: none; opacity: .72; color: inherit;
}
footer .studio-credit:hover { opacity: 1; }
footer .studio-credit img { height: 28px; display: block; }
footer .studio-credit span { font-size: .8rem; letter-spacing: .22em; }

@media (max-width: 700px) { footer .fgrid { grid-template-columns: 1fr; } }
