/* Advanced AI training — Board and Trust
   "Newsroom dataroom" design system, second edition.
   One source of truth: tokens, materiality, chrome, motion and every
   slide component live here. index.html carries markup only;
   motion.js drives the choreography. */

/* ============================================================
   1 · Fonts — the real Guardian cuts, including true italics.
   (The first edition synthesised its italics; these are the
   drawn ones from the Guardian CDN.)
   ============================================================ */
@font-face {
  font-family: 'GH Guardian Headline';
  src: url('https://assets.guim.co.uk/static/frontend/fonts/guardian-headline/noalts-not-hinted/GHGuardianHeadline-Medium.woff2') format('woff2');
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'GH Guardian Headline';
  src: url('https://assets.guim.co.uk/static/frontend/fonts/guardian-headline/noalts-not-hinted/GHGuardianHeadline-MediumItalic.woff2') format('woff2');
  font-weight: 500; font-style: italic; font-display: swap;
}
@font-face {
  font-family: 'GH Guardian Headline';
  src: url('https://assets.guim.co.uk/static/frontend/fonts/guardian-headline/noalts-not-hinted/GHGuardianHeadline-Bold.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'GH Guardian Headline';
  src: url('https://assets.guim.co.uk/static/frontend/fonts/guardian-headline/noalts-not-hinted/GHGuardianHeadline-Black.woff2') format('woff2');
  font-weight: 900; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'GuardianTextEgyptian';
  src: url('https://assets.guim.co.uk/static/frontend/fonts/guardian-textegyptian/noalts-not-hinted/GuardianTextEgyptian-Regular.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'GuardianTextEgyptian';
  src: url('https://assets.guim.co.uk/static/frontend/fonts/guardian-textegyptian/noalts-not-hinted/GuardianTextEgyptian-RegularItalic.woff2') format('woff2');
  font-weight: 400; font-style: italic; font-display: swap;
}
@font-face {
  font-family: 'GuardianTextEgyptian';
  src: url('https://assets.guim.co.uk/static/frontend/fonts/guardian-textegyptian/noalts-not-hinted/GuardianTextEgyptian-Bold.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'GuardianTextSans';
  src: url('https://assets.guim.co.uk/static/frontend/fonts/guardian-textsans/noalts-not-hinted/GuardianTextSans-Regular.woff2') format('woff2');
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: 'GuardianTextSans';
  src: url('https://assets.guim.co.uk/static/frontend/fonts/guardian-textsans/noalts-not-hinted/GuardianTextSans-Bold.woff2') format('woff2');
  font-weight: 700; font-style: normal; font-display: swap;
}

/* ============================================================
   2 · Tokens
   ============================================================ */
:root {
  --paper: #F4EFE6;
  --paper-deep: #E8DFD0;
  --paper-bright: #FBF8F1;
  --paper-rule: #D0C4AE;
  --ink: #121212;
  --ink-soft: #3d3a35;
  --ink-mute: #7a766e;
  --guardian-blue: #052962;
  --guardian-blue-soft: #4a6fa5;
  --guardian-yellow: #FFE500;
  --news-red: #C70000;
  --eco-green: #22874d;
  --display: 'GH Guardian Headline', Georgia, 'Times New Roman', serif;
  --body: 'GuardianTextEgyptian', Georgia, 'Times New Roman', serif;
  --ui: 'GuardianTextSans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --mono: 'Menlo', 'SF Mono', 'Courier New', monospace;

  /* Müller-Brockmann grid — one source of truth for the 1920×1080
     canvas. The chrome margins, the card gutters and the grid-overlay
     instrument all read these, so content and grid can never drift.
     12 columns inside 120px margins on a 12px baseline; a 24px gutter
     lands a 3-up row exactly on 4 + 4 + 4 columns. */
  --grid-margin: 120px;
  --grid-top: 100px;
  --grid-bottom: 80px;
  --grid-cols: 12;
  --grid-gutter: 24px;
  --grid-baseline: 12px;

  /* Motion */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);          /* expo-out: lands softly */
  --ease-in-out: cubic-bezier(0.77, 0, 0.18, 1);      /* bars and draws */
  --spring: cubic-bezier(0.34, 1.4, 0.64, 1);         /* fallback spring */

  /* Light */
  --shadow-card: 0 1px 0 rgba(255,255,255,0.55) inset,
                 0 1px 2px rgba(18,18,18,0.05),
                 0 22px 44px -28px rgba(18,18,18,0.38);
  --shadow-frame: 0 2px 6px rgba(18,18,18,0.08),
                  0 36px 80px -36px rgba(18,18,18,0.45);
  --hairline: rgba(18,18,18,0.08);

  /* Paper-fibre grain (SVG turbulence, tiled) */
  --grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='280' height='280'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* A real spring where the browser supports linear() easing */
@supports (animation-timing-function: linear(0, 1)) {
  :root {
    --spring: linear(
      0, 0.062 2.5%, 0.226 5.4%, 0.431 8.4%, 0.642 11.5%, 0.811 14.4%,
      0.937 17.3%, 1.027 20.3%, 1.077 23%, 1.1 25.8%, 1.104 28.9%,
      1.084 33.8%, 1.041 41%, 1.011 48.3%, 0.997 55.6%, 0.994 63.5%,
      1 81.1%, 1
    );
  }
}

* { box-sizing: border-box; }

html, body { margin: 0; padding: 0; background: #000; }
body {
  font-family: var(--body);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

deck-stage { background: #000; }

/* ============================================================
   3 · Slide frame and materiality
   ============================================================ */
.slide {
  width: 1920px; height: 1080px;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  padding: var(--grid-top) var(--grid-margin) var(--grid-bottom);
  display: flex;
  flex-direction: column;
  position: relative;
  /* Soft cross-fade between slides; the stage flips visibility */
  transition: opacity 360ms var(--ease-out), visibility 0s linear 360ms;
}
.slide[data-deck-active] {
  transition: opacity 420ms var(--ease-out), visibility 0s linear 0s;
}

/* Press vignette — barely-there depth at the slide edges */
.slide::before {
  content: '';
  position: absolute; inset: 0;
  background: radial-gradient(140% 110% at 50% 38%,
              transparent 58%, rgba(18,18,18,0.055) 100%);
  pointer-events: none;
  z-index: 60;
}
/* Paper-fibre grain over everything, including images */
.slide::after {
  content: '';
  position: absolute; inset: 0;
  background-image: var(--grain);
  background-size: 280px 280px;
  opacity: 0.05;
  mix-blend-mode: multiply;
  pointer-events: none;
  z-index: 61;
}

.slide.ink {
  background: radial-gradient(120% 95% at 28% 18%,
              #1c1c1a 0%, var(--ink) 52%, #0b0b0a 100%);
  color: var(--paper);
}
.slide.ink::before {
  background: radial-gradient(140% 110% at 50% 40%,
              transparent 55%, rgba(0,0,0,0.5) 100%);
}
.slide.ink::after {
  mix-blend-mode: screen;
  opacity: 0.045;
}

/* ============================================================
   4 · Chrome — rule band, kicker, footer, progress
   ============================================================ */
.rule-band {
  position: absolute;
  top: 0; left: var(--grid-margin); right: var(--grid-margin);
  display: grid;
  grid-template-columns: 2fr 1fr;
  height: 8px;
  z-index: 2;
}
.rule-band::before { content: ''; background: var(--guardian-blue); }
.rule-band::after  { content: ''; background: var(--guardian-yellow); }
.slide.ink .rule-band::before { background: var(--paper); }

.kicker {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 24px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--news-red);
  margin: 0 0 24px;
}
.slide.ink .kicker { color: var(--guardian-yellow); }

.slide-foot {
  position: absolute;
  bottom: 36px; left: var(--grid-margin); right: var(--grid-margin);
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  font-family: var(--ui);
  font-size: 22px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-mute);
  border-top: 1px solid var(--paper-rule);
  padding-top: 18px;
  z-index: 3;
}
.slide.ink .slide-foot {
  color: rgba(244,239,230,0.55);
  border-top-color: rgba(244,239,230,0.18);
}
.slide-foot .wm { font-weight: 700; letter-spacing: 0.2em; }
.slide-foot .num { font-family: var(--mono); letter-spacing: 0; font-variant-numeric: tabular-nums; }
/* Watermark shows only on the section openers; folio everywhere */
.slide:not(.section-opener) .slide-foot .wm { display: none; }

/* Progress — a quiet red seam along the foot of every slide,
   filled to the deck position by motion.js via --prog */
.deck-progress {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 5px;
  z-index: 62;
  pointer-events: none;
}
.deck-progress i {
  display: block;
  height: 100%;
  width: calc(var(--prog, 0) * 100%);
  background: var(--news-red);
  transition: width 800ms var(--ease-in-out);
}
.slide.ink .deck-progress i { background: var(--guardian-yellow); }

/* ============================================================
   5 · Motion system
   The engine adds .fx-armed to <deck-stage> (so nothing hides if
   JS never runs) and toggles .fx-play on the active slide.
   Each element opts in with data-fx and an inline --d delay.
   ============================================================ */
.fx-armed [data-fx] { opacity: 0; }

.fx-play [data-fx] {
  animation-delay: var(--d, 0ms);
  animation-fill-mode: both;
}
.fx-play [data-fx="rise"]      { animation-name: fxRise;     animation-duration: 680ms; animation-timing-function: var(--ease-out); }
.fx-play [data-fx="fade"]      { animation-name: fxFade;     animation-duration: 620ms; animation-timing-function: ease; }
.fx-play [data-fx="pop"]       { animation-name: fxPop;      animation-duration: 620ms; animation-timing-function: var(--spring); }
.fx-play [data-fx="spring-up"] { animation-name: fxSpringUp; animation-duration: 760ms; animation-timing-function: var(--spring); }
.fx-play [data-fx="photo"]     { animation-name: fxFade;     animation-duration: 1100ms; animation-timing-function: ease; }
.fx-play [data-fx="ghost"]     { animation-name: fxGhost;    animation-duration: 1300ms; animation-timing-function: var(--ease-out); }
.fx-play [data-fx="bar"]       { animation-name: fxBar;      animation-duration: 640ms; animation-timing-function: var(--ease-in-out); transform-origin: left center; }
.fx-play [data-fx="bar-v"]     { animation-name: fxBarV;     animation-duration: 700ms; animation-timing-function: var(--ease-in-out); transform-origin: center top; }

/* Photographic dissolve — the frame fades in while the image
   settles from a barely-there over-zoom, like a print developing */
[data-fx="photo"] { overflow: hidden; }
[data-fx="photo"] img { display: block; }
.fx-play [data-fx="photo"] img {
  animation: fxSettle 1600ms var(--ease-out) var(--d, 0ms) both;
}

@keyframes fxRise     { from { opacity: 0; transform: translateY(22px); } to { opacity: 1; transform: none; } }
@keyframes fxFade     { from { opacity: 0; } to { opacity: 1; } }
@keyframes fxPop      { from { opacity: 0; transform: scale(0.55); } to { opacity: 1; transform: scale(1); } }
@keyframes fxSpringUp { from { opacity: 0; transform: translateY(26px) scale(0.96); } to { opacity: 1; transform: none; } }
@keyframes fxGhost    { from { opacity: 0; transform: translateX(46px); } to { opacity: 1; transform: none; } }
@keyframes fxBar      { from { opacity: 1; transform: scaleX(0); } to { opacity: 1; transform: scaleX(1); } }
@keyframes fxBarV     { from { opacity: 1; transform: scaleY(0); } to { opacity: 1; transform: scaleY(1); } }
@keyframes fxSettle   { from { transform: scale(1.04); } to { transform: scale(1); } }

/* Masked word reveal — motion.js wraps each word of a [data-split]
   element in .w/.wi and staggers --wd across them. The padding /
   negative-margin pairs widen each mask window so ascenders,
   descenders and italic overhangs never clip at rest. */
.w {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  padding: 0.18em 0.11em 0.24em 0.03em;
  margin: -0.18em -0.11em -0.24em -0.03em;
}
.w .wi { display: inline-block; }
.fx-armed .w .wi { transform: translateY(135%); }
.fx-play .w .wi {
  animation: fxWordUp 820ms var(--ease-out) var(--wd, 0ms) both;
}
@keyframes fxWordUp { from { transform: translateY(135%); } to { transform: none; } }

/* The cover's red full stop lands on a spring, a beat late */
.fx-play .q-mark .wi {
  animation-timing-function: var(--spring);
  animation-duration: 900ms;
  animation-delay: calc(var(--wd, 0ms) + 240ms);
}

/* Rule band draws across on the cover and section openers only */
.cover.fx-play .rule-band,
.section-opener.fx-play .rule-band {
  animation: fxBar 600ms var(--ease-in-out) both;
  transform-origin: left center;
}

/* ============================================================
   6 · Typography
   ============================================================ */
.slide-title {
  font-family: var(--display);
  font-weight: 500;
  font-size: 84px;
  line-height: 0.98;
  letter-spacing: -0.02em;
  margin: 0 0 52px;
  color: var(--ink);
  max-width: 26ch;
  text-wrap: balance;
}
.slide.ink .slide-title { color: var(--paper); }
.slide-title em {
  color: var(--news-red);
  font-style: italic;
  font-weight: 500;
}

.slide-subtitle {
  font-family: var(--body);
  font-size: 34px;
  line-height: 1.4;
  color: var(--ink-soft);
  margin: 0 0 52px;
  max-width: 60ch;
}
.slide.ink .slide-subtitle { color: rgba(244,239,230,0.82); }

/* ============================================================
   7 · Cover
   ============================================================ */
.cover {
  padding: 120px 120px 80px;
  justify-content: space-between;
}
.cover .wordmark {
  font-family: var(--display);
  font-weight: 500;
  font-size: 188px;
  line-height: 0.94;
  letter-spacing: -0.03em;
  color: var(--guardian-blue);
  margin: 0;
}
.cover .wordmark em {
  font-style: italic;
  font-weight: 500;
  color: var(--ink);
}
.cover .wordmark .q-mark { color: var(--news-red); font-style: normal; font-weight: 700; }
.cover .kicker .group-tag {
  display: inline-block;
  background: var(--news-red);
  color: var(--paper);
  padding: 4px 12px 6px;
  margin-right: 14px;
  letter-spacing: 0.16em;
}
.cover-meta-row {
  display: grid;
  grid-template-columns: 1.5fr 1fr;
  gap: 80px;
  align-items: end;
}
.cover-framing {
  font-family: var(--body);
  font-weight: 400;
  font-size: 26px;
  line-height: 1.5;
  color: var(--ink-soft);
  letter-spacing: 0;
  max-width: 880px;
  margin: 0;
}
.cover-stat-block { text-align: right; }
.cover-stat-block .stat-line {
  font-family: var(--mono);
  font-size: 24px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin: 0;
}
.cover-stat-block .stat-line strong {
  display: block;
  font-family: var(--body);
  font-weight: 400;
  font-size: 30px;
  line-height: 1.05;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink-soft);
  margin-top: 4px;
}
.cover .slide-foot { border-top: none; padding-top: 0; }

/* ============================================================
   8 · Section openers — ink, ghost numeral, yellow underline
   ============================================================ */
.section-opener {
  justify-content: center;
  padding: 0 120px;
}
.section-opener .chapter-num,
.section-opener .section-kicker,
.section-opener h1,
.section-opener .section-dek { position: relative; z-index: 1; }
.section-opener .chapter-ghost {
  position: absolute;
  right: 48px; bottom: -36px;
  z-index: 0;
  font-family: var(--display);
  font-weight: 900;
  font-size: 640px;
  line-height: 1;
  letter-spacing: -0.05em;
  color: transparent;
  -webkit-text-stroke: 2px rgba(244,239,230,0.085);
  pointer-events: none;
  user-select: none;
}
.section-opener .chapter-num {
  font-family: var(--mono);
  font-size: 26px;
  letter-spacing: 0.2em;
  color: var(--guardian-yellow);
  margin-bottom: 40px;
  text-transform: uppercase;
}
.section-opener .section-kicker {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 28px;
  letter-spacing: 0.24em;
  color: rgba(244,239,230,0.55);
  margin: 0 0 28px;
  text-transform: uppercase;
}
.section-opener h1 {
  font-family: var(--display);
  font-weight: 500;
  font-size: 180px;
  line-height: 0.92;
  letter-spacing: -0.025em;
  color: var(--paper);
  margin: 0 0 40px;
  max-width: 18ch;
}
.section-opener h1 em {
  font-style: italic;
  font-weight: 500;
  color: var(--guardian-yellow);
  position: relative;
}
/* Yellow stroke draws under the italic word once it has landed */
.section-opener h1 em::after {
  content: '';
  position: absolute;
  left: 0.04em; right: 0.12em; bottom: -0.02em;
  height: 0.042em;
  background: var(--guardian-yellow);
  transform: scaleX(0);
  transform-origin: left center;
}
.section-opener.fx-play h1 em::after {
  animation: fxBar 700ms var(--ease-in-out) 1050ms both;
}
.section-opener .section-dek {
  font-family: var(--body);
  font-size: 34px;
  line-height: 1.4;
  color: rgba(244,239,230,0.82);
  max-width: 48ch;
}

/* ============================================================
   9 · Generic body + aims card system
   ============================================================ */
.slide-body {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.aims {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--grid-gutter);   /* 3 cards land exactly on 4 + 4 + 4 columns */
}
.aim {
  padding: 40px 36px;
  background: var(--paper-deep);
  border: 1px solid var(--hairline);
  border-top: 6px solid var(--guardian-blue);
  box-shadow: var(--shadow-card);
  display: flex;
  flex-direction: column;
  gap: 20px;
  min-height: 300px;
}
.aim:nth-child(2) { border-top-color: var(--news-red); }
.aim:nth-child(3) { border-top-color: var(--eco-green); }
.aim:nth-child(4) { border-top-color: var(--ink); }
.aim .aim-num {
  font-family: var(--mono);
  font-size: 24px;
  letter-spacing: 0.12em;
  color: var(--ink-mute);
  text-transform: uppercase;
}
.aim h3 {
  font-family: var(--display);
  font-weight: 500;
  font-size: 52px;
  line-height: 1.05;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0;
}
.aim p {
  font-family: var(--body);
  font-size: 26px;
  line-height: 1.45;
  color: var(--ink-soft);
  margin: 0;
}
.aim p strong { color: var(--ink); font-weight: 700; }

/* In-card image — sits at the bottom of an .aim (Beyond chat) */
.aim-image { margin-top: auto; display: block; }
.aim-image img { display: block; width: 100%; height: auto; object-fit: contain; }

/* Numbered point — shared by the open text blocks on the quantum
   leap and magpie slides: top rule, mono index, serif heading */
.point-num {
  display: block;
  font-family: var(--mono);
  font-size: 22px;
  letter-spacing: 0.12em;
  color: var(--guardian-blue);
  margin: 0 0 12px;
}

/* The mentor & the manager — a diptych split by a drawn hairline */
.duo {
  display: grid;
  grid-template-columns: 1fr 1px 1fr;
  column-gap: 84px;
  align-items: start;
}
.duo-divider { width: 1px; align-self: stretch; background: var(--paper-rule); }
.duo-tag {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 22px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--guardian-blue);
  margin: 0 0 24px;
}
.duo-side:last-child .duo-tag { color: var(--news-red); }
.duo-side h3 {
  font-family: var(--display);
  font-weight: 500;
  font-size: 64px;
  line-height: 1.02;
  letter-spacing: -0.015em;
  color: var(--ink);
  margin: 0 0 26px;
}
.duo-body {
  font-family: var(--body);
  font-size: 28px;
  line-height: 1.55;
  color: var(--ink-soft);
  margin: 0;
}

/* Irreplaceable expertise — the conversation rail: each component
   of a good prompt on the left, answered by the example you'd
   actually type as a speech bubble on the right */
.slide--framework .slide-title { font-size: 52px; margin-bottom: 18px; }
.framework { flex: 1; display: flex; flex-direction: column; justify-content: center; }
.fw-row {
  display: grid;
  grid-template-columns: 1fr 1.15fr;
  column-gap: 84px;
  align-items: center;
  padding: 21px 0;
  border-top: 1px solid var(--paper-rule);
}
.fw-row:first-child { border-top: 2px solid var(--ink); }
.fw-what h3 {
  display: flex;
  align-items: baseline;
  gap: 18px;
  font-family: var(--display);
  font-weight: 500;
  font-size: 30px;
  line-height: 1.06;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0 0 8px;
}
.fw-num {
  font-family: var(--mono);
  font-size: 20px;
  letter-spacing: 0.08em;
  color: var(--guardian-blue);
}
.fw-row:nth-child(2) .fw-num { color: var(--news-red); }
.fw-row:nth-child(3) .fw-num { color: var(--eco-green); }
.fw-row:nth-child(4) .fw-num { color: var(--ink); }
.fw-what p {
  font-family: var(--body);
  font-size: 20px;
  line-height: 1.4;
  color: var(--ink-soft);
  margin: 0;
}

.example-bubble {
  position: relative;
  background: var(--paper-bright);
  border: 1px solid var(--hairline);
  border-radius: 16px;
  padding: 16px 24px 17px;
  box-shadow: 0 8px 22px -10px rgba(18,18,18,0.18);
}
/* Tail points left, back at the component it answers */
.example-bubble::after {
  content: '';
  position: absolute;
  left: -15px;
  top: calc(50% - 9px);
  width: 0; height: 0;
  border-top: 9px solid transparent;
  border-bottom: 9px solid transparent;
  border-right: 15px solid var(--paper-bright);
}
.example-bubble p {
  font-family: var(--body);
  font-style: italic;
  font-size: 20px;
  line-height: 1.38;
  color: var(--ink-soft);
  margin: 0;
}

/* The magpie habit — picture-led triptych: framed photograph,
   then an open numbered text block beneath */
.magpie {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--grid-gutter);   /* same 4 + 4 + 4 column rhythm as .aims */
}
.magpie-photo { box-shadow: var(--shadow-frame); }
.magpie-photo img {
  width: 100%;
  height: 296px;
  object-fit: cover;
  object-position: center;
}
.magpie-text {
  margin-top: 30px;
  border-top: 2px solid var(--ink);
  padding-top: 16px;
}
.magpie-col:nth-child(2) .point-num { color: var(--news-red); }
.magpie-col:nth-child(3) .point-num { color: var(--eco-green); }
.magpie-text h3 {
  font-family: var(--display);
  font-weight: 500;
  font-size: 38px;
  line-height: 1.05;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0 0 12px;
}
.magpie-text p {
  font-family: var(--body);
  font-size: 22px;
  line-height: 1.42;
  color: var(--ink-soft);
  margin: 0;
}

/* ============================================================
   10 · Agenda — editorial contents page
   ============================================================ */
.slide--agenda .slide-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  gap: 36px 80px;
}
.agenda-item { border-top: 2px solid var(--ink); padding-top: 22px; min-height: 0; }
.agenda-num {
  display: block;
  font-family: var(--mono);
  font-size: 22px;
  letter-spacing: 0.08em;
  color: var(--news-red);
  margin: 0 0 14px;
}
.agenda-item h3 {
  font-family: var(--display);
  font-weight: 500;
  font-size: 38px;
  line-height: 1.08;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0 0 12px;
}
.agenda-item p {
  font-family: var(--body);
  font-size: 23px;
  line-height: 1.42;
  color: var(--ink-soft);
  max-width: 44ch;
  margin: 0;
}

/* ============================================================
   11 · Four key rules — the rulebook ledger. Full-width rows
   under hairlines, like the editorial code these quote.
   ============================================================ */
.slide--rules .slide-title { margin-bottom: 28px; }
.rules-list {
  flex: 1;
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.rule-row {
  display: grid;
  grid-template-columns: 200px 1fr;
  column-gap: 48px;
  padding: 24px 0;
  border-top: 1px solid var(--paper-rule);
}
.rule-row:first-child { border-top: 2px solid var(--ink); }
.rule-tag {
  font-family: var(--mono);
  font-size: 21px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--news-red);
  padding-top: 8px;
}
.rule-row h3 {
  font-family: var(--display);
  font-weight: 500;
  font-size: 31px;
  line-height: 1.06;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0 0 8px;
}
.rule-row p {
  font-family: var(--body);
  font-size: 20px;
  line-height: 1.42;
  color: var(--ink-soft);
  margin: 0;
}

/* ============================================================
   12 · AI choice — three step cards + practice panel
   ============================================================ */
.slide--choice .slide-title { font-size: 56px; margin-bottom: 18px; max-width: none; }
.slide--choice .slide-subtitle { font-size: 26px; margin-bottom: 36px; max-width: 80ch; }
.slide--choice .slide-body { display: flex; flex-direction: column; justify-content: center; gap: 40px; }
.ai-choice { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 64px; }
.choice-card {
  background: var(--paper-deep);
  border: 1px solid var(--hairline);
  border-top: 6px solid var(--guardian-blue);
  box-shadow: var(--shadow-card);
  padding: 32px 36px 36px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 16px;
  position: relative;
  min-width: 0;
}
.choice-card:nth-child(2) { border-top-color: var(--news-red); }
.choice-card:nth-child(3) { border-top-color: var(--eco-green); }
.choice-card:not(:last-child)::after {
  content: '\2192';
  position: absolute;
  right: -48px; top: 50%;
  transform: translateY(-50%);
  font-family: var(--display);
  font-weight: 700;
  font-size: 48px;
  color: var(--ink-mute);
  line-height: 1;
}
.fx-armed .choice-card:not(:last-child)::after { opacity: 0; }
.fx-play .choice-card:not(:last-child)::after { animation: fxFade 500ms ease 920ms both; }
.choice-num {
  font-family: var(--display);
  font-weight: 900;
  font-size: 88px;
  line-height: 0.9;
  letter-spacing: -0.03em;
  color: var(--guardian-blue);
  margin-bottom: 4px;
}
.choice-card:nth-child(2) .choice-num { color: var(--news-red); }
.choice-card:nth-child(3) .choice-num { color: var(--eco-green); }
.choice-card h3 {
  font-family: var(--display);
  font-weight: 500;
  font-size: 36px;
  line-height: 1.1;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0;
}
.choice-card p {
  font-family: var(--body);
  font-size: 22px;
  line-height: 1.45;
  color: var(--ink-soft);
  margin: 0;
}
.ai-meta {
  background: var(--paper-deep);
  border: 1px solid var(--hairline);
  border-left: 4px solid var(--guardian-blue);
  box-shadow: var(--shadow-card);
  padding: 24px 36px 26px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ai-meta-eyebrow {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 20px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--guardian-blue);
  margin: 0;
}
.ai-meta-body {
  font-family: var(--body);
  font-size: 21px;
  line-height: 1.45;
  color: var(--ink-soft);
  margin: 0;
}
.ai-meta-body em { color: var(--news-red); font-style: italic; }

/* ============================================================
   13 · The state of AI — stat kit and adoption chart
   ============================================================ */
.slide--appendix .slide-title { font-size: 60px; margin-bottom: 18px; max-width: none; }
.slide--appendix .slide-subtitle { font-size: 26px; margin-bottom: 28px; max-width: 70ch; }
.slide--appendix .slide-body { display: flex; flex-direction: column; justify-content: flex-start; gap: 18px; }

.ax-card {
  background: var(--paper-deep);
  border: 1px solid var(--hairline);
  border-top: 6px solid var(--guardian-blue);
  box-shadow: var(--shadow-card);
  padding: 24px 28px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.ax-card:nth-child(2) { border-top-color: var(--news-red); }
.ax-card-figure {
  font-family: var(--display);
  font-weight: 900;
  font-size: 64px;
  line-height: 0.95;
  letter-spacing: -0.02em;
  color: var(--guardian-blue);
  margin: 0;
  font-variant-numeric: tabular-nums;
}
.ax-card:nth-child(2) .ax-card-figure { color: var(--news-red); }
.ax-card-body {
  font-family: var(--body);
  font-size: 20px;
  line-height: 1.4;
  color: var(--ink-soft);
  margin: 0;
}
.ax-card-eyebrow {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 16px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin: 0 0 4px;
}
.ax-source {
  font-family: var(--ui);
  font-size: 14px;
  letter-spacing: 0.04em;
  color: var(--ink-mute);
  font-style: italic;
  margin: 8px 0 0;
}
.ax-source strong { font-weight: 700; }
.ax-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 24px; }
.ax-pair .ax-card { padding: 18px 28px; }
.ax-pair .ax-card-figure { font-size: 52px; }
.ax-frictions-head {
  font-family: var(--display);
  font-weight: 500;
  font-size: 28px;
  line-height: 1.15;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 6px 0 0;
}
.ax-frictions-head em { color: var(--news-red); font-style: italic; }
.ax-frictions { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.ax-frictions li {
  display: grid;
  grid-template-columns: 14px 1fr;
  gap: 18px;
  padding: 10px 0;
  border-top: 1px solid var(--paper-rule);
  align-items: baseline;
}
.ax-frictions li:first-child { border-top: 2px solid var(--ink); padding-top: 12px; }
.ax-frictions li::before {
  content: '';
  width: 12px; height: 12px;
  background: var(--news-red);
  align-self: start;
  margin-top: 10px;
}
.ax-frictions strong {
  font-family: var(--display);
  font-weight: 500;
  font-size: 22px;
  color: var(--ink);
  display: block;
  margin-bottom: 2px;
}
.ax-frictions span {
  font-family: var(--body);
  font-size: 19px;
  line-height: 1.4;
  color: var(--ink-soft);
}

/* Adoption-speed chart */
.slide--ax-speed .slide-title { font-size: 54px; margin-bottom: 12px; }
.slide--ax-speed .slide-subtitle { font-size: 24px; margin-bottom: 18px; max-width: 70ch; color: var(--ink-mute); }
.ax-chart-big { flex: 1; display: flex; flex-direction: column; gap: 14px; min-height: 0; }
.ax-chart-big svg { display: block; width: 100%; height: 100%; min-height: 0; flex: 1; }
.ax-chart-legend { display: flex; gap: 32px; justify-content: flex-start; }
.ax-chart-legend-item {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--ui);
  font-weight: 700;
  font-size: 17px;
  color: var(--ink);
}
.ax-chart-legend-item::before { content: ''; width: 28px; height: 4px; background: var(--ink-mute); }
.ax-chart-legend-item.is-internet::before { background: var(--guardian-blue-soft); }
.ax-chart-legend-item.is-phone::before { background: var(--ink-mute); }
.ax-chart-legend-item.is-ai::before { background: var(--news-red); }
.ax-axis { font-family: var(--mono); font-size: 15px; fill: var(--ink-mute); }
.ax-axis-y { text-anchor: end; }
.ax-grid { stroke: var(--paper-rule); stroke-width: 1; }
.ax-axis-base { stroke: var(--ink-mute); stroke-width: 1.5; }
.ax-line { fill: none; stroke-width: 3; stroke-linejoin: round; stroke-linecap: round; }
.ax-line--internet { stroke: var(--guardian-blue-soft); }
.ax-line--phone { stroke: var(--ink-mute); }
.ax-line--ai { stroke: var(--news-red); stroke-width: 4; }
.ax-endpoint { font-family: var(--ui); font-weight: 700; font-size: 15px; fill: var(--ink); }
.ax-endpoint--big {
  font-family: var(--display);
  font-size: 44px !important;
  fill: var(--news-red);
  font-weight: 900;
}
.fx-armed .ax-dot { opacity: 0; }
.fx-play .ax-dot { animation: fxFade 300ms ease both; }
.ax-dot--internet { fill: var(--guardian-blue-soft); }
.ax-dot--phone { fill: var(--ink-mute); }
.ax-dot--ai { fill: var(--news-red); }
.fx-play .ax-track--internet .ax-dot:nth-of-type(1) { animation-delay: 300ms; }
.fx-play .ax-track--internet .ax-dot:nth-of-type(2) { animation-delay: 1030ms; }
.fx-play .ax-track--internet .ax-dot:nth-of-type(3) { animation-delay: 1760ms; }
.fx-play .ax-track--internet .ax-dot:nth-of-type(4) { animation-delay: 2500ms; }
.fx-play .ax-track--phone .ax-dot:nth-of-type(1) { animation-delay: 300ms; }
.fx-play .ax-track--phone .ax-dot:nth-of-type(2) { animation-delay: 1030ms; }
.fx-play .ax-track--phone .ax-dot:nth-of-type(3) { animation-delay: 1760ms; }
.fx-play .ax-track--phone .ax-dot:nth-of-type(4) { animation-delay: 2500ms; }
.fx-play .ax-track--ai .ax-dot:nth-of-type(1) { animation-delay: 3200ms; }
.fx-play .ax-track--ai .ax-dot:nth-of-type(2) { animation-delay: 3730ms; }
.fx-play .ax-track--ai .ax-dot:nth-of-type(3) { animation-delay: 4260ms; }
.fx-play .ax-track--ai .ax-dot:nth-of-type(4) { animation-delay: 4800ms; }

/* ============================================================
   14 · Fable — split image / text
   ============================================================ */
.slide--fable .slide-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 72px;
  align-items: center;
}
.fable-frame { box-shadow: var(--shadow-frame); }
.fable-img {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
}
.fable-text .kicker { margin-bottom: 18px; }
.fable-text .slide-title { font-size: 60px; margin-bottom: 28px; max-width: none; }
.fable-body {
  font-family: var(--body);
  font-size: 27px;
  line-height: 1.5;
  color: var(--ink-soft);
  margin: 0;
}

/* ============================================================
   15 · Quantum Leap — image left, stacked cards right
   ============================================================ */
.slide--ql .slide-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 64px;
  align-items: center;
}
.ql-frame { box-shadow: var(--shadow-frame); }
.ql-img { display: block; width: 100%; height: auto; }
.ql-points { display: flex; flex-direction: column; gap: 44px; }
.ql-point { border-top: 2px solid var(--ink); padding-top: 18px; }
.ql-point:nth-child(2) .point-num { color: var(--news-red); }
.ql-point h3 {
  font-family: var(--display);
  font-weight: 500;
  font-size: 38px;
  line-height: 1.05;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0 0 12px;
}
.ql-point p {
  font-family: var(--body);
  font-size: 24px;
  line-height: 1.45;
  color: var(--ink-soft);
  margin: 0;
}

/* ============================================================
   16 · The Strategic Expedition — descending curve timeline
   ============================================================ */
.flow { width: 100%; }
.flow-track { position: relative; height: 240px; }
.flow-curve { display: block; width: 100%; height: 240px; }
.flow-curve .line {
  fill: none;
  stroke: var(--guardian-blue);
  stroke-width: 4;
  stroke-linecap: round;
}
.flow-curve .fill { fill: rgba(5,41,98,0.06); stroke: none; }
.fx-armed .flow-curve .line { stroke-dasharray: 2000; stroke-dashoffset: 2000; }
.fx-play .flow-curve .line { animation: drawCurve 1150ms var(--ease-in-out) 200ms both; }
@keyframes drawCurve { to { stroke-dashoffset: 0; } }
.fx-armed .flow-curve .fill { opacity: 0; }
.fx-play .flow-curve .fill { animation: fxFade 900ms ease 900ms both; }

.flow-node {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 88px;
  height: 88px;
  border-radius: 50%;
  border: 5px solid var(--guardian-blue);
  background: var(--paper);
  box-shadow: 0 10px 24px -12px rgba(18,18,18,0.4);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--mono);
  font-size: 30px;
  font-weight: 700;
  color: var(--guardian-blue);
}
.flow-node.n1 { left: 12.5%; top: 50px;  }
.flow-node.n2 { left: 37.5%; top: 90px;  border-color: var(--news-red);  color: var(--news-red); }
.flow-node.n3 { left: 62.5%; top: 135px; border-color: var(--eco-green); color: var(--eco-green); }
.flow-node.n4 { left: 87.5%; top: 170px; }
/* Nodes pop in place — the pop keyframes compose with the centring */
.fx-play .flow-node[data-fx="pop"] { animation-name: fxNodePop; }
@keyframes fxNodePop {
  from { opacity: 0; transform: translate(-50%, -50%) scale(0.4); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}

.flow-labels {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  margin-top: 30px;
}
.flow-label { text-align: center; padding: 0 28px; }
.flow-label h3 {
  font-family: var(--display);
  font-weight: 500;
  font-size: 40px;
  line-height: 1.05;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0 0 14px;
}
.flow-label p {
  font-family: var(--body);
  font-size: 27px;
  line-height: 1.4;
  color: var(--ink-soft);
  margin: 0;
}

/* ============================================================
   17 · Worked-example (case) slides — ledes and tables
   ============================================================ */
.slide.case .slide-title {
  font-size: 50px;
  line-height: 1.04;
  margin-bottom: 22px;
  max-width: 42ch;
}
.slide.case .slide-body {
  justify-content: flex-start;
  padding-top: 2px;
}
.case-lede {
  font-family: var(--body);
  font-size: 24px;
  line-height: 1.4;
  color: var(--ink-soft);
  max-width: 104ch;
  margin: 0 0 14px;
}
.case-lede strong { color: var(--ink); font-weight: 700; }
.case-emph {
  font-family: var(--body);
  font-style: italic;
  font-size: 25px;
  line-height: 1.35;
  color: var(--ink);
  margin: 8px 0 18px;
}

/* "Material fed in → what it triggered" table */
.feed-table { width: 100%; border-collapse: collapse; margin-top: 72px; }
.feed-table thead th {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 19px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-mute);
  text-align: left;
  padding: 0 26px 14px;
  border-bottom: 2px solid var(--ink);
}
.feed-table thead th:first-child { width: 46%; }
.feed-table tbody td {
  padding: 24px 26px;
  border-bottom: 1px solid var(--paper-rule);
  font-family: var(--body);
  font-size: 23px;
  line-height: 1.34;
  vertical-align: top;
}
.feed-table tbody td:first-child { color: var(--ink-soft); }
.feed-table tbody td:last-child {
  color: var(--ink);
  position: relative;
  padding-left: 54px;
}
.feed-table tbody td:last-child::before {
  content: '→';
  position: absolute;
  left: 22px;
  top: 24px;
  color: var(--news-red);
  font-family: var(--ui);
  font-weight: 700;
}

/* Asked / suggested exchange rows */
.exchanges { flex: 1; display: flex; flex-direction: column; justify-content: space-evenly; gap: 0; margin-top: 4px; }
.exchange {
  display: grid;
  grid-template-columns: 1fr 1.3fr;
  background: var(--paper-deep);
  border: 1px solid var(--hairline);
  box-shadow: var(--shadow-card);
}
.exchange .ask, .exchange .suggest { padding: 16px 26px 18px; }
.exchange .ask { border-left: 4px solid var(--ink-mute); }
.exchange .suggest { background: var(--paper-bright); border-left: 4px solid var(--guardian-blue); }
.exchange .speaker {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 17px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  margin: 0 0 7px;
}
.exchange .ask .speaker { color: var(--ink-mute); }
.exchange .suggest .speaker { color: var(--guardian-blue); }
.exchange p.line {
  font-family: var(--body);
  font-size: 20px;
  line-height: 1.34;
  color: var(--ink);
  margin: 0;
}

/* Benchmark comparison table */
.compare-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 8px;
}
.compare-table thead th {
  background: var(--ink);
  color: var(--paper);
  font-family: var(--ui);
  font-weight: 700;
  letter-spacing: 0.05em;
  text-align: left;
  font-size: 21px;
  padding: 14px 24px;
}
.compare-table thead th:first-child { width: 24%; }
.compare-table tbody td {
  padding: 27px 24px;
  border-bottom: 1px solid var(--paper-rule);
  font-family: var(--body);
  font-size: 22px;
  line-height: 1.32;
  color: var(--ink-soft);
  vertical-align: top;
}
.compare-table tbody tr:nth-child(odd) { background: var(--paper-deep); }
.compare-table tbody td:first-child {
  font-family: var(--display);
  font-weight: 500;
  font-size: 24px;
  letter-spacing: -0.01em;
  color: var(--guardian-blue);
  white-space: nowrap;
}

/* ============================================================
   18 · Research pull-quote (ink)
   ============================================================ */
.slide--research { justify-content: center; }
.research-eyebrow {
  font-family: var(--mono);
  font-size: 26px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(244,239,230,0.5);
  margin: 0 0 52px;
}
.research-quote {
  position: relative;
  font-family: var(--display);
  font-weight: 500;
  font-size: 100px;
  line-height: 1.06;
  letter-spacing: -0.02em;
  color: var(--paper);
  margin: 0;
  max-width: 24ch;
}
.research-quote em { color: var(--guardian-yellow); font-style: italic; font-weight: 500; }
.research-mark {
  font-size: 1.25em;
  line-height: 0;
  color: rgba(244,239,230,0.32);
  margin-right: 0.04em;
  vertical-align: -0.12em;
  display: inline-block;
}
.research-sub {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 26px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(244,239,230,0.5);
  margin: 58px 0 0;
  max-width: 64ch;
}

/* ============================================================
   19 · Worked-example prompt slides — framed screenshot beside
   a console card whose prompt types in live
   ============================================================ */
.slide--prompt .slide-body {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 64px;
  align-items: center;
}
.isw-frame {
  background: #fff;
  border: 1px solid var(--paper-rule);
  border-radius: 10px;
  overflow: hidden;
  box-shadow: var(--shadow-frame);
}
.frame-chrome {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 11px 14px;
  background: var(--paper-bright);
  border-bottom: 1px solid var(--hairline);
}
.frame-chrome i {
  width: 11px; height: 11px;
  border-radius: 50%;
  background: rgba(18,18,18,0.14);
}
.isw-img { display: block; width: 100%; height: auto; }
.prompt-col .kicker { margin-bottom: 16px; }
.prompt-col .slide-title { font-size: 56px; margin-bottom: 28px; max-width: none; }
.prompt-box {
  background: var(--paper-bright);
  border: 1px solid var(--paper-rule);
  border-radius: 12px;
  box-shadow: var(--shadow-card);
  overflow: hidden;
}
.prompt-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 30px 12px;
  border-bottom: 1px solid var(--hairline);
  background: rgba(232,223,208,0.45);
}
.prompt-label {
  font-family: var(--mono);
  font-size: 18px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-mute);
  margin: 0;
}
.prompt-head .frame-chrome { padding: 0; background: none; border: none; }
.prompt-body { padding: 22px 30px 26px; }
.prompt-text {
  font-family: var(--body);
  font-size: 23px;
  line-height: 1.5;
  color: var(--ink);
  margin: 0;
}
.caret {
  display: inline-block;
  width: 3px;
  height: 1.05em;
  background: var(--news-red);
  margin-left: 3px;
  vertical-align: -0.18em;
  animation: caretBlink 1.05s steps(1) infinite;
}
@keyframes caretBlink { 50% { opacity: 0; } }

/* ============================================================
   20 · Getting started — the argument + the genie on-ramp
   ============================================================ */
.slide--start .slide-title { font-size: 60px; margin-bottom: 30px; max-width: none; }
.slide--start .slide-body {
  display: grid;
  grid-template-columns: 1fr 1.08fr;   /* right a touch wider — the prompt is the hero */
  gap: 88px;
  align-items: center;
}
.start-lede {
  font-family: var(--body);
  font-size: 35px;
  line-height: 1.55;
  color: var(--ink-soft);
  margin: 0 0 52px;
}
.start-lede strong { color: var(--ink); font-weight: 700; }
.start-points { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 22px; }
.start-points li {
  position: relative;
  padding-left: 24px;
  font-family: var(--body);
  font-size: 20px;
  line-height: 1.45;
  color: var(--ink-mute);
}
.start-points li::before {
  content: '';
  position: absolute;
  left: 0; top: 11px;
  width: 7px; height: 7px;
  background: var(--ink-mute);
}
.start-points strong { color: var(--ink-soft); font-weight: 600; }
.start-genie-intro {
  font-family: var(--body);
  font-size: 28px;
  line-height: 1.45;
  color: var(--ink-soft);
  margin: 0 0 32px;
}
.start-genie-intro strong { color: var(--ink); font-weight: 700; }
.slide--start .prompt-body { padding: 36px 46px 42px; }
.slide--start .prompt-text { font-size: 28px; line-height: 1.6; }
.start-buy {
  font-family: var(--body);
  font-size: 22px;
  line-height: 1.4;
  color: var(--ink);
  margin: 32px 0 0;
}
.start-buy strong { font-weight: 700; }
.buy-arrow { color: var(--news-red); font-weight: 700; margin-right: 9px; }

/* ============================================================
   21 · Pick a first project — typographic numbered list
   ============================================================ */
.slide--ways .slide-title { font-size: 52px; margin-bottom: 14px; }
.slide--ways .slide-subtitle { font-family: var(--body); font-size: 24px; line-height: 1.4; color: var(--ink-mute); margin: 0 0 22px; max-width: 90ch; }
.slide--ways .slide-body { justify-content: center; }
.ways-list { list-style: none; margin: 0; padding: 0; }
.way {
  display: grid;
  grid-template-columns: 108px 1fr 1.3fr;
  column-gap: 46px;
  align-items: baseline;
  padding: 32px 0;
  border-top: 1px solid var(--paper-rule);
}
.way:last-child { border-bottom: 1px solid var(--paper-rule); }
.way-num {
  font-family: var(--display);
  font-weight: 900;
  font-size: 58px;
  line-height: 0.85;
  color: var(--guardian-blue);
  letter-spacing: -0.01em;
}
.way:nth-child(2) .way-num { color: var(--news-red); }
.way:nth-child(3) .way-num { color: var(--eco-green); }
.way-main h3 {
  font-family: var(--display);
  font-weight: 500;
  font-size: 30px;
  line-height: 1.08;
  color: var(--ink);
  margin: 0 0 12px;
}
.way-why {
  font-family: var(--body);
  font-size: 20px;
  line-height: 1.42;
  color: var(--ink-soft);
  margin: 0;
}
.way-ask {
  font-family: var(--body);
  font-style: italic;
  font-size: 21px;
  line-height: 1.46;
  color: var(--ink);
  margin: 0;
  padding-left: 24px;
  border-left: 3px solid var(--guardian-blue);
}
.way:nth-child(2) .way-ask { border-left-color: var(--news-red); }
.way:nth-child(3) .way-ask { border-left-color: var(--eco-green); }

/* ============================================================
   22 · Chat stream — prompts that became projects
   ============================================================ */
.chat-stream {
  display: flex;
  flex-direction: column;
  gap: 32px;
  align-items: flex-end;
  max-width: 1280px;
  margin: 40px 0 0 auto;
}
.chat-bubble {
  background: var(--paper-deep);
  border: 1px solid var(--hairline);
  border-radius: 28px;
  box-shadow: var(--shadow-card);
  padding: 28px 40px;
  font-family: var(--body);
  font-size: 36px;
  line-height: 1.32;
  color: var(--ink);
  max-width: 100%;
  text-decoration: none;
  display: block;
  transform-origin: bottom right;
  transition: background 200ms ease, color 200ms ease;
}
a.chat-bubble:hover { background: var(--guardian-blue); color: var(--paper); }

/* ============================================================
   23 · Accessibility + print
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  .slide, .slide[data-deck-active] { transition: none; }
  .fx-armed [data-fx],
  .fx-play [data-fx] { opacity: 1 !important; animation: none !important; transform: none !important; clip-path: none !important; }
  .fx-armed .w .wi, .fx-play .w .wi { transform: none !important; animation: none !important; }
  .fx-play [data-fx="photo"] img { animation: none !important; transform: none !important; }
  .fx-armed .flow-curve .line { stroke-dasharray: none; stroke-dashoffset: 0; }
  .fx-armed .flow-curve .fill, .fx-armed .ax-dot,
  .fx-armed .choice-card:not(:last-child)::after { opacity: 1; }
  .section-opener h1 em::after { transform: none; }
  .deck-progress i { transition: none; }
  .caret { display: none; }
}

@media print {
  .slide, .slide[data-deck-active] { transition: none; }
  .fx-armed [data-fx],
  .fx-play [data-fx] { opacity: 1 !important; animation: none !important; transform: none !important; clip-path: none !important; }
  .fx-armed .w .wi, .fx-play .w .wi { transform: none !important; animation: none !important; }
  .fx-play [data-fx="photo"] img { animation: none !important; transform: none !important; }
  .fx-armed .flow-curve .line { stroke-dasharray: none !important; stroke-dashoffset: 0 !important; animation: none !important; }
  .fx-armed .flow-curve .fill, .fx-armed .ax-dot,
  .fx-armed .choice-card:not(:last-child)::after { opacity: 1 !important; animation: none !important; }
  .section-opener h1 em::after { transform: none !important; animation: none !important; }
  .ax-line { stroke-dasharray: none !important; stroke-dashoffset: 0 !important; }
  .deck-progress { display: none; }
  .caret { display: none !important; }
  .slide::after { display: none; }  /* grain muddies print */
}

/* ================================================================
   VIBECODING WORKSHOP — deck-specific components.
   Appended per CLAUDE.md: new components go at the bottom of this
   file, never forked into the HTML. Everything below stays inside
   the existing motion grammar (data-fx + --d), so reduced-motion
   and no-JS fallbacks come for free.
   ================================================================ */

/* ----------------------------------------------------------------
   1 · Activity — the two-panel build brief. Setup steps across the
   top, two starter activities side by side, then the shared "do"
   loop. Adapted from the Board and Trust deck's slide 25.
   ---------------------------------------------------------------- */
.slide--activity .slide-title { font-size: 54px; margin-bottom: 18px; max-width: none; }
.slide--activity .slide-body { justify-content: center; gap: 26px; }

.act-setup,
.act-do {
  display: flex;
  align-items: center;
  gap: 44px;
  padding: 18px 34px;
  background: var(--paper-deep);
  border: 1px solid var(--hairline);
}
.act-setup { border-left: 6px solid var(--guardian-blue); }
.act-do    { border-left: 6px solid var(--news-red); }

.act-setup-lead,
.act-do-lead {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 19px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--news-red);
  white-space: nowrap;
}
.act-setup-lead { color: var(--guardian-blue); }

.act-steps,
.act-do-steps {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 30px;
  list-style: none;
  margin: 0; padding: 0;
  flex: 1;
}
.act-steps li,
.act-do-steps li {
  display: flex;
  align-items: center;
  gap: 13px;
  font-family: var(--body);
  font-size: 23px;
  line-height: 1.25;
  color: var(--ink);
}
.act-step-n,
.act-do-n {
  flex: none;
  width: 33px; height: 33px;
  border-radius: 50%;
  color: var(--paper);
  font-family: var(--mono);
  font-size: 17px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.act-step-n { background: var(--guardian-blue); }
.act-do-n   { background: var(--news-red); }

.act-panels { display: grid; grid-template-columns: 1fr 1fr; gap: var(--grid-gutter); }
.act-panel {
  background: var(--paper-bright);
  border: 1px solid var(--hairline);
  border-top: 6px solid var(--guardian-blue);
  box-shadow: var(--shadow-card);
  padding: 26px 32px 30px;
  display: flex;
  flex-direction: column;
  gap: 15px;
}
.act-panel.a2 { border-top-color: var(--eco-green); }
.act-eyebrow {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--guardian-blue);
  margin: 0;
  display: flex;
  align-items: center;
  gap: 12px;
}
.act-panel.a2 .act-eyebrow { color: var(--eco-green); }
.act-optional {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-mute);
  background: var(--paper);
  border: 1px solid var(--paper-rule);
  padding: 3px 9px;
}
.act-panel h3 {
  font-family: var(--display);
  font-weight: 500;
  font-size: 33px;
  line-height: 1.04;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0;
}
.act-panel .prompt-box { flex: 1; display: flex; flex-direction: column; }
.act-panel .prompt-body { flex: 1; display: flex; align-items: center; padding: 20px 26px 22px; }
.act-panel .prompt-text { font-size: 25px; line-height: 1.4; }

.act-note {
  padding: 16px 28px;
  background: var(--paper-deep);
  border-left: 4px solid var(--guardian-yellow);
  font-family: var(--body);
  font-size: 21px;
  line-height: 1.45;
  color: var(--ink);
  margin: 0;
}
.act-note strong { font-weight: 700; }

/* ----------------------------------------------------------------
   2 · Options ledger — a compact two-column numbered menu. Built for
   the ten self-contained tools; reused for the closing takeaways.
   Denser than .rules-list, which tops out around five rows.
   ---------------------------------------------------------------- */
.opts {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: 56px;
  row-gap: 0;
  list-style: none;
  margin: 0; padding: 0;
}
.opt-row {
  display: flex;
  align-items: baseline;
  gap: 16px;
  padding: 13px 0;
  border-top: 1px solid var(--hairline);
}
.opts > .opt-row:first-child,
.opts > .opt-row:nth-child(2) { border-top: 2px solid var(--ink); }
.opt-n {
  flex: none;
  font-family: var(--mono);
  font-size: 17px;
  font-weight: 700;
  color: var(--guardian-blue);
  min-width: 26px;
  font-variant-numeric: tabular-nums;
}
.opt-row:nth-child(3n+2) .opt-n { color: var(--news-red); }
.opt-row:nth-child(3n)   .opt-n { color: var(--eco-green); }
.opt-main { min-width: 0; }
.opt-main strong {
  display: block;
  font-family: var(--display);
  font-weight: 500;
  font-size: 25px;
  line-height: 1.12;
  color: var(--ink);
}
.opt-main span {
  display: block;
  font-family: var(--body);
  font-size: 19px;
  line-height: 1.34;
  color: var(--ink-soft);
  margin-top: 3px;
}
.opts.wide { grid-template-columns: 1fr; column-gap: 0; }
.opts.wide > .opt-row:nth-child(2) { border-top: 1px solid var(--hairline); }
.opts.wide .opt-main strong { font-size: 27px; }
.opts.wide .opt-main span { font-size: 21px; }

/* ----------------------------------------------------------------
   3 · API ledger — the workshop matrix. Endpoint, what it returns,
   and the LLM move it sets up. Three columns; six rows a slide.
   ---------------------------------------------------------------- */
.api-ledger { width: 100%; border-collapse: collapse; }
.api-ledger thead th {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 17px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-mute);
  text-align: left;
  padding: 0 20px 11px 0;
  border-bottom: 2px solid var(--ink);
}
.api-ledger tbody td {
  padding: 15px 20px 15px 0;
  border-bottom: 1px solid var(--hairline);
  vertical-align: top;
  font-family: var(--body);
  font-size: 20px;
  line-height: 1.34;
  color: var(--ink-soft);
}
.api-ledger tbody td:first-child { width: 30%; }
.api-ledger tbody td:last-child  { width: 32%; padding-right: 0; }
/* The name is the link now: the endpoint itself was noise, and the
   deck's own prompts name APIs rather than quoting URLs at them. Each
   one opens a real example query in a new tab. */
.api-name {
  display: inline-block;
  font-family: var(--display);
  font-weight: 500;
  font-size: 25px;
  line-height: 1.1;
  color: var(--ink);
  text-decoration: none;
}
.api-name:hover { color: var(--guardian-blue); text-decoration: underline; text-underline-offset: 4px; }
.api-name:focus-visible { outline: 3px solid var(--guardian-blue); outline-offset: 3px; }
.api-go {
  font-family: var(--ui);
  font-size: 16px;
  color: var(--ink-mute);
  margin-left: 8px;
  vertical-align: 3px;
}
.api-name:hover .api-go { color: var(--guardian-blue); }
.api-ask { color: var(--ink); font-style: italic; }
.api-ledger tbody tr:last-child td { border-bottom: none; }

/* ----------------------------------------------------------------
   4 · JSON specimen — real response text, shown as the artefact it
   is. Used once, to make "data, not a webpage" concrete.
   ---------------------------------------------------------------- */
.json-spec {
  background: var(--ink);
  border-radius: 10px;
  padding: 28px 34px;
  overflow: hidden;
  box-shadow: var(--shadow-card);
}
.json-spec pre {
  margin: 0;
  font-family: var(--mono);
  font-size: 22px;
  line-height: 1.6;
  color: rgba(244,239,230,0.92);
  white-space: pre-wrap;
  word-break: break-word;
}
.json-spec .k { color: var(--guardian-yellow); }
.json-spec .s { color: #8fd3a5; }
.json-spec .n { color: #9ec4ff; }
.json-url {
  font-family: var(--mono);
  font-size: 19px;
  color: var(--guardian-blue);
  margin: 0 0 14px;
  word-break: break-all;
}

/* ----------------------------------------------------------------
   6 · Solo prompt — the typing-prompt card without the screenshot
   beside it, for the prompts that are the whole point of the slide.
   ---------------------------------------------------------------- */
.slide--prompt-solo .slide-body {
  display: flex;
  flex-direction: column;
  justify-content: center;
}
.slide--prompt-solo .prompt-box { max-width: none; }
.slide--prompt-solo .prompt-text { font-size: 30px; line-height: 1.5; }
.slide--prompt-solo .prompt-body { padding: 30px 38px 34px; }

/* Click-to-copy affordance on any card opted in with data-copy */
[data-copy] { cursor: pointer; position: relative; }
.prompt-box[data-copy]:hover { border-color: var(--guardian-blue-soft); }
.tweak[data-copy]:hover { background: var(--paper); }
[data-copy]:focus-visible { outline: 3px solid var(--guardian-blue); outline-offset: 3px; }
.copy-badge {
  position: absolute;
  top: 12px; right: 16px;
  font-family: var(--ui);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--paper);
  background: var(--eco-green);
  padding: 4px 10px;
  opacity: 0;
  transition: opacity 200ms var(--ease-out);
  pointer-events: none;
}
[data-copied] .copy-badge { opacity: 1; }

@media print {
  .slide--activity .act-panel,
  .slide--activity .act-do,
  .slide--activity .act-note { opacity: 1 !important; transform: none !important; }
  .copy-badge { display: none !important; }
}
@media (prefers-reduced-motion: reduce) {
  .copy-badge { transition: none; }
}

/* ----------------------------------------------------------------
   7 · Fit corrections, measured at 1920×1080 rather than guessed.
   The appendix stacks three and four prompt cards on one slide and
   the API ledger runs six rows; both need a tighter setting than
   the single-prompt slides they inherit from.
   ---------------------------------------------------------------- */
.slide--prompt-solo .slide-body { gap: 20px; }

.slide--appendix-prompts .slide-body { gap: 16px; }
.slide--appendix-prompts .prompt-head { padding: 9px 30px 8px; }
.slide--appendix-prompts .prompt-label { font-size: 15px; letter-spacing: 0.09em; }
.slide--appendix-prompts .prompt-body { padding: 16px 30px 18px; }
.slide--appendix-prompts .prompt-text { font-size: 21px; line-height: 1.42; }

.api-ledger tbody td { padding-top: 20px; padding-bottom: 20px; }

/* ----------------------------------------------------------------
   8 · Cover note — the one-line audience promise, marked with a
   Guardian-yellow highlighter that draws in behind the words after
   the cover has settled. The text is never hidden: only the mark
   animates, so no-JS and reduced-motion both read fine.
   ---------------------------------------------------------------- */
.cover-note-wrap { margin: 0; }
.cover-note {
  font-family: var(--display);
  font-weight: 500;
  font-size: 31px;
  line-height: 1.24;
  letter-spacing: -0.005em;
  color: var(--ink);
  padding: 0 4px;
  background-image: linear-gradient(var(--guardian-yellow), var(--guardian-yellow));
  background-repeat: no-repeat;
  background-position: 0 84%;
  background-size: 0% 44%;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
/* Re-applied each time the cover becomes active, so the mark redraws
   on a return visit without needing to be a [data-fx] element. */
[data-deck-active] .cover-note {
  animation: coverNoteMark 780ms var(--ease-out) 1500ms both;
}
@keyframes coverNoteMark { to { background-size: 100% 44%; } }

@media (prefers-reduced-motion: reduce) {
  .cover-note,
  [data-deck-active] .cover-note { background-size: 100% 44%; animation: none !important; }
}
@media print {
  .cover-note { background-size: 100% 44% !important; animation: none !important; }
}

/* ----------------------------------------------------------------
   9 · Tweaks grid — a menu of things to say next, for the slide
   after a deliberately vague prompt. Six cards, three up, each an
   eyebrow naming the kind of change and the sentence to actually
   type. Eyebrows and top rules cycle blue / red / green.
   ---------------------------------------------------------------- */
.tweaks {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--grid-gutter);
}
.tweak {
  background: var(--paper-bright);
  border: 1px solid var(--hairline);
  border-top: 5px solid var(--guardian-blue);
  box-shadow: var(--shadow-card);
  padding: 24px 28px 27px;
  display: flex;
  flex-direction: column;
  gap: 11px;
}
.tweak:nth-child(3n+2) { border-top-color: var(--news-red); }
.tweak:nth-child(3n)   { border-top-color: var(--eco-green); }
.tweak-kind {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 16px;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--guardian-blue);
  margin: 0;
}
.tweak:nth-child(3n+2) .tweak-kind { color: var(--news-red); }
.tweak:nth-child(3n)   .tweak-kind { color: var(--eco-green); }
.tweak-say {
  font-family: var(--body);
  font-size: 23px;
  line-height: 1.42;
  color: var(--ink);
  margin: 0;
}

/* A single short prompt is the hero of its slide; give it the size to
   match, rather than leaving it rattling around in a wide card. */
.slide--prompt-hero .prompt-body { padding: 38px 44px 42px; }
.slide--prompt-hero .prompt-text { font-size: 44px; line-height: 1.28; }

/* ----------------------------------------------------------------
   10 · Spread — distribute a slide's components through the whole
   body height instead of centring them as one clump. Without this,
   a slide with three short blocks leaves a large void above and
   below while the blocks themselves sit 20px apart, which reads as
   a mistake rather than as breathing room.

   space-evenly (with gap zeroed, since gap would stack on top of
   the distributed space and make the edges tighter than the middle)
   gives an equal rhythm above, between and below.
   ---------------------------------------------------------------- */
.slide.slide--spread .slide-body {
  display: flex;
  flex-direction: column;
  justify-content: space-evenly;
  gap: 0;
}
/* Default paragraph margins on the child blocks skew the distribution,
   so the rhythm comes out uneven. Zero them and let space-evenly do it. */
.slide.slide--spread .slide-body > * { margin: 0; }

/* ----------------------------------------------------------------
   11 · JSON explained — the specimen beside a plain-English reading
   of it. The raw response on its own proves the point that APIs
   return data, but it doesn't teach anyone what the data is for.
   ---------------------------------------------------------------- */
.json-explain {
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  gap: 44px;
  align-items: start;
}
.json-explain .json-spec { padding: 24px 28px; }
.json-explain .json-spec pre { font-size: 19px; line-height: 1.62; }

.json-read-lead {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 17px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--news-red);
  margin: 0 0 14px;
}
.json-read { list-style: none; margin: 0; padding: 0; }
.json-read li {
  padding: 12px 0;
  border-top: 1px solid var(--hairline);
  font-family: var(--body);
  font-size: 20px;
  line-height: 1.36;
  color: var(--ink-soft);
}
.json-read li:first-child { border-top: 2px solid var(--ink); }
.json-read b {
  font-family: var(--mono);
  font-weight: 700;
  font-size: 18px;
  color: var(--guardian-blue);
  display: block;
  margin-bottom: 3px;
}

/* ----------------------------------------------------------------
   12 · Rule pair — the "never do this / do this instead" couplet
   that sits inside a rules-list row when a rule needs an action
   rather than just an explanation.
   ---------------------------------------------------------------- */
.rule-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 18px;
  margin-top: 12px;
}
.rule-pair > div {
  padding: 12px 18px;
  background: var(--paper-deep);
  border-left: 4px solid var(--news-red);
}
.rule-pair > div.do { border-left-color: var(--eco-green); }
.rule-pair-lead {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--news-red);
  margin: 0 0 4px;
}
.rule-pair > div.do .rule-pair-lead { color: var(--eco-green); }
.rule-pair p:last-child {
  font-family: var(--body);
  font-size: 19px;
  line-height: 1.35;
  color: var(--ink);
  margin: 0;
}

/* Rule 01 now carries a never/instead couplet as well as its body, so
   this ledger runs taller than the three-short-rows the base pattern
   assumes. Tighten the rhythm rather than cut the explanation. */
.slide--rules-dense .rule-row { padding: 18px 0; }
.slide--rules-dense .rule-row h3 { font-size: 29px; margin-bottom: 6px; }
.slide--rules-dense .rule-row p { font-size: 19px; line-height: 1.4; }
.slide--rules-dense .rule-pair { margin-top: 10px; gap: 16px; }
.slide--rules-dense .rule-pair > div { padding: 10px 16px; }
.slide--rules-dense .rule-pair p:last-child { font-size: 18px; line-height: 1.34; }

/* ----------------------------------------------------------------
   13 · Question and answer — the web address is the question, and
   it should look like one. A blue-ruled panel carries the address
   at reading size with the part that actually asks the question
   marked in yellow, then the plain-English version of it. The
   response below is labelled as the answer so the pairing is
   unmistakable from the back of a room.
   ---------------------------------------------------------------- */
.qa-lead {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 16px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--guardian-blue);
  margin: 0 0 10px;
}
.qa-ask {
  background: var(--paper-deep);
  border-left: 6px solid var(--guardian-blue);
  padding: 20px 30px 22px;
}
.qa-url {
  font-family: var(--mono);
  font-size: 25px;
  line-height: 1.34;
  color: var(--ink-soft);
  margin: 0 0 12px;
  word-break: break-all;
}
.qa-url mark {
  background: var(--guardian-yellow);
  color: var(--ink);
  font-weight: 700;
  padding: 1px 4px;
}
.qa-gloss {
  font-family: var(--display);
  font-weight: 500;
  font-style: italic;
  font-size: 27px;
  line-height: 1.2;
  color: var(--ink);
  margin: 0;
}
.qa-answer { display: block; }
.qa-answer .qa-lead {
  color: var(--news-red);
  border-top: 2px solid var(--ink);
  padding-top: 12px;
  margin-bottom: 14px;
}

/* ----------------------------------------------------------------
   14 · Build steps — a vertical "here's where we are / here's how we
   make it better" stack. Label on the left, prose on the right, so
   two stages read as a progression down the slide rather than as a
   comparison across it.
   ---------------------------------------------------------------- */
.build-step {
  display: grid;
  grid-template-columns: 270px 1fr;
  column-gap: 40px;
  align-items: center;
  background: var(--paper-deep);
  border-left: 6px solid var(--guardian-blue);
  padding: 22px 32px;
}
.build-step.richer { border-left-color: var(--eco-green); }
.build-lead {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 19px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--guardian-blue);
  margin: 0;
}
.build-step.richer .build-lead { color: var(--eco-green); }
.build-body {
  font-family: var(--body);
  font-size: 22px;
  line-height: 1.42;
  color: var(--ink);
  margin: 0;
}
.build-body strong { font-weight: 700; }

/* ----------------------------------------------------------------
   15 · Challenge — an over-to-you question, thrown to the room. Same
   blue slab as the holding slide's definition of done, so the deck
   has one consistent signal for "this one's yours to answer".
   ---------------------------------------------------------------- */
.challenge {
  background: var(--guardian-blue);
  color: var(--paper);
  padding: 26px 36px 28px;
  display: grid;
  grid-template-columns: 190px 1fr;
  column-gap: 34px;
  align-items: center;
}
.challenge-lead {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--guardian-yellow);
  margin: 0;
}
.challenge-body {
  font-family: var(--display);
  font-weight: 500;
  font-size: 34px;
  line-height: 1.14;
  color: var(--paper);
  margin: 0;
}
.challenge-body em { color: var(--guardian-yellow); font-style: italic; }

/* ----------------------------------------------------------------
   16 · Also try — a yellow-ruled block of alternative asks, for when
   the point is that the example is only one of many things you could
   have asked for.
   ---------------------------------------------------------------- */
.alsotry {
  background: var(--paper-deep);
  border-left: 6px solid var(--guardian-yellow);
  padding: 20px 30px 22px;
}
.alsotry-lead {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 18px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--guardian-blue);
  margin: 0 0 14px;
}
.alsotry-list {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px 48px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.alsotry-list li {
  position: relative;
  padding-left: 26px;
  font-family: var(--body);
  font-size: 21px;
  line-height: 1.36;
  color: var(--ink);
}
.alsotry-list li::before {
  content: '→';
  position: absolute;
  left: 0;
  color: var(--news-red);
  font-weight: 700;
}

/* ----------------------------------------------------------------
   17 · Run sheet — the session at a glance. An ordered list rather
   than a table, because that's what it is: part, how long, what
   happens. No headers; the columns explain themselves.
   ---------------------------------------------------------------- */
.runsheet { list-style: none; margin: 0; padding: 0; }
.runsheet li {
  display: grid;
  grid-template-columns: 220px 190px 1fr;
  column-gap: 44px;
  align-items: baseline;
  padding: 34px 0;
  border-top: 1px solid var(--hairline);
}
.runsheet li:first-child { border-top: 2px solid var(--ink); }
.rs-part {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 22px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--guardian-blue);
}
.rs-time {
  font-family: var(--mono);
  font-size: 22px;
  color: var(--ink-mute);
  font-variant-numeric: tabular-nums;
}
.rs-time mark {
  background: var(--guardian-yellow);
  color: var(--ink);
  font-weight: 700;
  padding: 1px 5px;
}
.rs-what {
  font-family: var(--body);
  font-size: 26px;
  line-height: 1.34;
  color: var(--ink);
}

/* The run sheet is the only thing on its slide, so let it sit centred
   rather than hard against the top with a third of the slide empty. */
.slide.case:has(.runsheet) .slide-body { justify-content: center; }

/* ----------------------------------------------------------------
   19 · Annotated prompt — underline the phrases that are doing the
   work, then explain each one underneath. The underline colour ties
   a phrase to its note, so the eye can pair them without arrows or
   numbers cluttering the prompt itself.
   ---------------------------------------------------------------- */
.pin { box-shadow: inset 0 -4px 0 var(--guardian-blue-soft); }
.pin-2 { box-shadow: inset 0 -4px 0 #7fbf9a; }

.annot { list-style: none; margin: 0; padding: 0; }
.annot li {
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  column-gap: 44px;
  align-items: start;
  padding: 18px 0;
  border-top: 1px solid var(--hairline);
}
.annot li:first-child { border-top: 2px solid var(--ink); }
.annot-bit {
  font-family: var(--body);
  font-style: italic;
  font-size: 21px;
  line-height: 1.36;
  color: var(--ink);
  margin: 0;
  padding-left: 20px;
  border-left: 4px solid var(--guardian-blue);
}
.annot li:nth-child(2) .annot-bit { border-left-color: var(--eco-green); }
.annot-why {
  font-family: var(--body);
  font-size: 21px;
  line-height: 1.4;
  color: var(--ink-soft);
  margin: 0;
}
.annot-why strong { color: var(--ink); font-weight: 700; }

/* ----------------------------------------------------------------
   20 · Probes — a grid of "type this / here's what might go wrong"
   cards. Two up, so four fit without the type getting small. The
   query is set in mono on a tinted chip so it reads as something
   you'd type rather than something you'd read.
   ---------------------------------------------------------------- */
.probes {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--grid-gutter);
}
.probe {
  background: var(--paper-bright);
  border: 1px solid var(--hairline);
  border-top: 5px solid var(--guardian-blue);
  box-shadow: var(--shadow-card);
  padding: 16px 24px 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.probe:nth-child(2) { border-top-color: var(--news-red); }
.probe:nth-child(3) { border-top-color: var(--eco-green); }
.probe:nth-child(4) { border-top-color: var(--guardian-blue-soft); }
.probe-q {
  font-family: var(--display);
  font-weight: 500;
  font-size: 27px;
  line-height: 1.08;
  letter-spacing: -0.01em;
  color: var(--guardian-blue);
  margin: 0;
}
.probe:nth-child(2) .probe-q { color: var(--news-red); }
.probe:nth-child(3) .probe-q { color: var(--eco-green); }
.probe:nth-child(4) .probe-q { color: var(--guardian-blue-soft); }
.probe-a {
  font-family: var(--body);
  font-size: 20px;
  line-height: 1.38;
  color: var(--ink-soft);
  margin: 0;
}
.probe-a strong { color: var(--ink); font-weight: 700; }

/* A note that carries a warning rather than an aside. */
.act-note.warn { border-left-color: var(--news-red); }

/* The never/instead pair standing alone on a slide, rather than nested
   inside a rules ledger row. */
.slide-body > .rule-pair { margin-top: 0; gap: var(--grid-gutter); }
.slide-body > .rule-pair > div { padding: 22px 28px; }
.slide-body > .rule-pair p:last-child { font-size: 21px; line-height: 1.4; }

/* ----------------------------------------------------------------
   21 · Brief — the orientation slide. A hero statement carrying the
   deck's yellow marker, then three open columns rather than cards,
   because this early in the deck the page should feel airy. The
   rules do the dividing; no boxes needed.
   ---------------------------------------------------------------- */
.brief-lede {
  font-family: var(--display);
  font-weight: 500;
  font-size: 62px;
  line-height: 1.08;
  letter-spacing: -0.018em;
  color: var(--ink);
  margin: 0;
  max-width: 26ch;
}
.brief-lede mark {
  background-color: transparent;
  background-image: linear-gradient(var(--guardian-yellow), var(--guardian-yellow));
  background-repeat: no-repeat;
  background-position: 0 86%;
  background-size: 0% 44%;
  color: var(--ink);
  padding: 0 5px;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}
[data-deck-active] .brief-lede mark {
  animation: coverNoteMark 820ms var(--ease-out) 1000ms both;
}

.brief-cols {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--grid-gutter);
}
.brief-col { border-top: 3px solid var(--guardian-blue); padding-top: 18px; }
.brief-col:nth-child(2) { border-top-color: var(--news-red); }
.brief-col:nth-child(3) { border-top-color: var(--eco-green); }
.brief-eyebrow {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 17px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--guardian-blue);
  margin: 0 0 10px;
}
.brief-col:nth-child(2) .brief-eyebrow { color: var(--news-red); }
.brief-col:nth-child(3) .brief-eyebrow { color: var(--eco-green); }
.brief-body {
  font-family: var(--body);
  font-size: 21px;
  line-height: 1.42;
  color: var(--ink-soft);
  margin: 0;
}
.brief-body strong { color: var(--ink); font-weight: 700; }

@media (prefers-reduced-motion: reduce) {
  .brief-lede mark,
  [data-deck-active] .brief-lede mark { background-size: 100% 44%; animation: none !important; }
}
@media print {
  .brief-lede mark { background-size: 100% 44% !important; animation: none !important; }
}

/* ----------------------------------------------------------------
   22 · Epigraph — a full-yellow slide carrying one borrowed line.
   The deck already uses yellow as its "this is the bit that matters"
   marker; this is that gesture at full scale, used exactly once.
   Ink on Guardian yellow, and the chrome inverts to match.
   ---------------------------------------------------------------- */
.slide.yellow {
  background: var(--guardian-yellow);
  color: var(--ink);
}
.slide.yellow .rule-band::before { background: var(--ink); }
.slide.yellow .rule-band::after  { background: var(--news-red); }
.slide.yellow .slide-foot {
  color: rgba(18,18,18,0.5);
  border-top-color: rgba(18,18,18,0.18);
}
.slide.yellow .deck-progress i { background: var(--ink); }

.slide--epigraph .slide-body { justify-content: center; }
.epigraph {
  font-family: var(--display);
  font-weight: 500;
  font-style: italic;
  font-size: 104px;
  line-height: 1.02;
  letter-spacing: -0.028em;
  color: var(--ink);
  margin: 0;
  max-width: 21ch;
}
.epigraph-attr {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 21px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(18,18,18,0.72);
  margin: 46px 0 0;
}

/* ----------------------------------------------------------------
   23 · Pre-share checklist — two questions to answer before an app
   built in twenty minutes goes anywhere near a colleague.
   ---------------------------------------------------------------- */
.preshare-lead {
  font-family: var(--ui);
  font-weight: 700;
  font-size: 19px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--news-red);
  margin: 0 0 14px;
}
.preshare-list {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--grid-gutter);
  list-style: none;
  margin: 0;
  padding: 0;
}
.preshare-list li {
  background: var(--paper-deep);
  border-left: 6px solid var(--news-red);
  padding: 18px 28px 20px;
}
.preshare-list li:nth-child(2) { border-left-color: var(--guardian-blue); }
.preshare-list h3 {
  font-family: var(--display);
  font-weight: 500;
  font-size: 27px;
  line-height: 1.08;
  letter-spacing: -0.01em;
  color: var(--ink);
  margin: 0 0 10px;
}
.preshare-list p {
  font-family: var(--body);
  font-size: 20px;
  line-height: 1.4;
  color: var(--ink-soft);
  margin: 0;
}
.preshare-list strong { color: var(--ink); font-weight: 700; }

/* ----------------------------------------------------------------
   24 · The sharing slide weights its two questions above everything
   else on the page. The four steps are mechanics and recede; the
   checks are the reason the slide exists. Scoped, because .act-setup
   is shared with the activity brief.
   ---------------------------------------------------------------- */
.slide--share .act-setup { padding: 14px 30px; }
.slide--share .act-setup-lead { font-size: 17px; }
.slide--share .act-steps li { font-size: 21px; }
.slide--share .act-step-n { width: 29px; height: 29px; font-size: 15px; }

.slide--share .preshare-lead {
  font-size: 23px;
  letter-spacing: 0.18em;
  margin-bottom: 20px;
}
.slide--share .preshare-list li {
  border-left-width: 8px;
  padding: 32px 40px 36px;
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: 28px;
  align-items: start;
}
.preshare-num {
  font-family: var(--display);
  font-weight: 900;
  font-size: 56px;
  line-height: 0.86;
  letter-spacing: -0.02em;
  color: var(--news-red);
}
.preshare-list li:nth-child(2) .preshare-num { color: var(--guardian-blue); }
.slide--share .preshare-list h3 { font-size: 38px; line-height: 1.04; margin-bottom: 14px; }
.slide--share .preshare-list p { font-size: 25px; line-height: 1.42; color: var(--ink); }

/* A miniature of the click-to-copy badge, for referring to it in prose. */
.chip-copied {
  display: inline-block;
  font-family: var(--ui);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--paper);
  background: var(--eco-green);
  padding: 3px 9px;
  vertical-align: 2px;
}

/* The dense rules ledger uses bare numerals rather than "Rule 01", so
   the tag column no longer needs to be 200px wide. */
.slide--rules-dense .rule-row { grid-template-columns: 96px 1fr; column-gap: 36px; }

/* ----------------------------------------------------------------
   25 · Copy affordance for the small cards — the tweak grid and the
   options ledger. The full-size badge is out of scale on a 70px row,
   and neither showed you they were clickable until you clicked. A
   muted COPY hint appears on hover, and is replaced by the green
   COPIED once you have.
   ---------------------------------------------------------------- */
.tweak .copy-badge,
.opt-row .copy-badge {
  top: 9px;
  right: 12px;
  font-size: 12px;
  letter-spacing: 0.1em;
  padding: 3px 8px;
}
.tweak[data-copy]::after,
.opt-row[data-copy]::after {
  content: 'Copy';
  position: absolute;
  top: 9px;
  right: 12px;
  font-family: var(--ui);
  font-weight: 700;
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-mute);
  background: var(--paper);
  border: 1px solid var(--paper-rule);
  padding: 2px 7px;
  opacity: 0;
  transition: opacity 150ms var(--ease-out);
  pointer-events: none;
}
.tweak[data-copy]:hover::after,
.opt-row[data-copy]:hover::after,
.tweak[data-copy]:focus-visible::after,
.opt-row[data-copy]:focus-visible::after { opacity: 1; }
/* Once copied, the green badge takes over the same spot. */
.tweak[data-copy][data-copied]::after,
.opt-row[data-copy][data-copied]::after { opacity: 0; }

.opt-row[data-copy]:hover .opt-main strong { color: var(--guardian-blue); }

@media (prefers-reduced-motion: reduce) {
  .tweak[data-copy]::after, .opt-row[data-copy]::after { transition: none; }
}
@media print {
  .tweak[data-copy]::after, .opt-row[data-copy]::after { display: none !important; }
}

/* ----------------------------------------------------------------
   26 · Mobile survival.
   The deck is built for a 1920×1080 projector and doesn't pretend
   otherwise on a phone, but it has to at least open and advance.

   Every browser on iOS is WebKit, and WebKit is strict about memory.
   Thirty-four slides each carrying an feTurbulence noise layer under
   mix-blend-mode, plus a vignette and a pile of shadows, is enough to
   get the tab killed outright ("Can't open this page"). All of that
   is decoration, so on small screens it goes, and the inactive slides
   are told to do no rendering work at all.

   content-visibility is safe here: motion.js splits [data-split]
   titles by wrapping DOM nodes, never by measuring them, so a slide
   that has never been rendered still splits correctly.
   ---------------------------------------------------------------- */
@media (max-width: 1024px) {
  .slide::before,
  .slide::after { display: none !important; }

  .slide:not([data-deck-active]) { content-visibility: hidden; }

  .prompt-box, .tweak, .probe, .act-panel, .json-spec, .isw-frame,
  .preshare-list li, .hold-panel, .brief-col { box-shadow: none !important; }

  /* Hover affordances mean nothing on a touchscreen and the hint chip
     would sit there permanently after a tap. */
  .tweak[data-copy]::after,
  .opt-row[data-copy]::after { display: none; }
}
