/* Presentation styles. Tokens first (the only place colours and sizes are defined), then layout, then components.
   Colour is the part of the talk: each part has one hue family, four shades of it (--s1 main, --s2 light, --s3 deep,
   --s4 soft) set per slide below; dialogs use one standard grey.
   No box-shadows: depth comes from surface steps and hairlines. Animation touches only transform / opacity / clip-path. */

:root {
  --canvas: #0e100f;
  --panel: #191919;
  --hairline: #42433d;
  --muted: #7c7c6f;          /* 16px and up only: 4.5:1 on the canvas */
  --text: #fffce1;
  --dg: #b8b8aa;             /* the grey of dialog text */
  /* the five hue families, four shades each: main, light, deep, soft */
  --white-1: #fffce1; --white-2: #d9d7c2; --white-3: #b4b29d; --white-4: #96947f;
  --green-1: #abff84; --green-2: #d9ffc7; --green-3: #0ae448; --green-4: #62d96f;
  --blue-1: #00bae2; --blue-2: #8fe3f5; --blue-3: #3d8bff; --blue-4: #7eb6ff;
  --pink-1: #fec5fb; --pink-2: #ffe4fd; --pink-3: #ff6fe0; --pink-4: #f09ae6;
  --orange-1: #ff8709; --orange-2: #ffc27a; --orange-3: #e85d04; --orange-4: #ffa94d;
  --radius: 8px;
  --pill: 100px;
  /* spacing shrinks with the screen's height, so every chapter fits one screen at 1440x900 and up */
  --gap-text: clamp(16px, 2.5vh, 24px);   /* between text blocks */
  --gap-panel: clamp(24px, 4vh, 44px);    /* before and after a panel (cards, timeline, diagram, SQL, columns) */
  --gap-grid: 16px;                       /* between panels in a grid */
  --pad-y: clamp(24px, 5vh, 72px);        /* chapter top; the bottom keeps at least the fixed counter's 56px */
  --font: Figtree, "Inter Tight", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: ui-monospace, "Cascadia Code", Consolas, Menlo, monospace;
}

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; background: var(--canvas); }
body {
  margin: 0; background: var(--canvas); color: var(--text);
  font: 400 19px/1.4 var(--font); -webkit-font-smoothing: antialiased;
  font-variant-numeric: tabular-nums;
}
h1, h2, h3, p { margin: 0; }
a { color: inherit; }
:focus-visible { outline: 2px solid var(--s1, var(--text)); outline-offset: 3px; }

/* ---------- layout ---------- */
.chapter {
  min-height: 100vh; min-height: 100svh;
  display: flex; align-items: center;
  padding: var(--pad-y) 24px max(var(--pad-y), 56px); border-bottom: 1px solid var(--hairline);
}
.inner { width: 100%; max-width: 1280px; margin: 0 auto; }
.cols { display: grid; grid-template-columns: 1fr 1fr; gap: 56px; align-items: start; }
/* Lists used as panels drop their browser margins at zero specificity, so the stack spacing below always wins
   (a plain `.cards { margin: 0 }` declared later used to cancel it and glue panels to the text above). */
:where(.cards, .timeline, .list, .arch-flow, .guards, .chips) { list-style: none; margin: 0; padding: 0; }
.stack > * + * { margin-top: var(--gap-text); }
.stack > * + :is(.cards, .timeline, .arch, .sql-panel, .cols, .placeholder-note, .strip),
.stack > :is(.cards, .timeline, .arch, .sql-panel, .cols, .placeholder-note) + * { margin-top: var(--gap-panel); }
/* answer chapters: the narrative and "How we know" on the left, the live SQL on the right */
.cols.answer { grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr); align-items: stretch; }
/* the strip sits at the foot of the text column, level with the bottom of the panel beside it */
.cols.answer > .stack:first-child { display: flex; flex-direction: column; }
.cols.answer > .stack:first-child > .strip { margin-top: auto; }
.cols.answer > .stack:first-child > :nth-last-child(2) { margin-bottom: var(--gap-panel); }
.stack > .sub + * { margin-top: 18px; }
.p1, .eng { --c: var(--s1); } .p2 { --c: var(--s3); } .p3 { --c: var(--s4); }

/* the part's colour: slide 1 white, 2-5 green, 6-9 blue, 10-12 pink, 13-15 orange. Everything on a slide takes its
   shades from --s1..--s4; --sec (the main one) drives the eyebrows, the wipe, the navigation dots and the top bar */
#c1 { --s1: var(--white-1); --s2: var(--white-2); --s3: var(--white-3); --s4: var(--white-4); --sec: var(--s1);
  --accent: linear-gradient(114deg, var(--s1), var(--s2)); }
#c2, #c3, #c4, #c5 { --s1: var(--green-1); --s2: var(--green-2); --s3: var(--green-3); --s4: var(--green-4); --sec: var(--s1);
  --accent: linear-gradient(114deg, var(--s1), var(--s2)); }
#c6, #c7, #c8, #c9 { --s1: var(--blue-1); --s2: var(--blue-2); --s3: var(--blue-3); --s4: var(--blue-4); --sec: var(--s1);
  --accent: linear-gradient(114deg, var(--s1), var(--s2)); }
#c10, #c11, #c12 { --s1: var(--pink-1); --s2: var(--pink-2); --s3: var(--pink-3); --s4: var(--pink-4); --sec: var(--s1);
  --accent: linear-gradient(114deg, var(--s1), var(--s2)); }
#c13, #c14, #c15 { --s1: var(--orange-1); --s2: var(--orange-2); --s3: var(--orange-3); --s4: var(--orange-4); --sec: var(--s1);
  --accent: linear-gradient(114deg, var(--s1), var(--s2)); }
/* slide 13's cost column and each column of slide 14 take their own shade of the part's orange */
#c13 .cols > .stack:last-child { --c: var(--s3); }
#c14 .cols > .stack:first-child { --c: var(--s1); }
#c14 .cols > .stack:last-child { --c: var(--s3); }
#c14 .list li b { color: var(--c, var(--text)); }
.eyebrow { font: 600 16px/1 var(--mono); color: var(--sec, var(--text)); letter-spacing: .04em; margin-bottom: 24px; }
.eyebrow .br { display: inline-block; }
/* the title is sized by width and height, so it stays on two lines and leaves room for the cards below */
h1.display { font-size: clamp(56px, min(11vw, 16vh), 176px); line-height: .9; letter-spacing: -.02em; font-weight: 600; padding-bottom: .1em; /* room for the marker under the descenders */ }
/* cover: a bold typographic title, then the author line */
/* cover: the title is the page's loudest thing, three huge lines, the last one filled with the accent gradient */
.cover h1.display { font-size: clamp(56px, min(13vw, 17vh), 210px); line-height: .9; letter-spacing: -.03em; font-weight: 600; padding-bottom: 0; }
/* each title line sits in a mask; the line rises out of it (app.js). Padding keeps descenders inside the mask. */
.line { display: block; overflow: hidden; padding-bottom: .14em; margin-bottom: -.14em; }
.line-in { display: inline-block; }
.grad { background: var(--accent); -webkit-background-clip: text; background-clip: text; color: transparent; padding: 0 .06em .14em 0; /* the gradient paints only inside the box, so the "y" tail needs room */ }
/* the wipe, into a chapter that opens a part (slides 2, 6, 10 and 13): a panel in the part's colour crosses carrying its title (app.js) */
.wipe { position: fixed; inset: 0; z-index: 15; pointer-events: none; display: none; align-items: center; padding: 0 6vw;
  background: var(--accent); color: var(--canvas); clip-path: inset(0 100% 0 0); }
.wipe-label { font-size: clamp(40px, 8vw, 120px); line-height: .95; font-weight: 600; letter-spacing: -.03em; max-width: 14ch; }
/* cover layout: the title under the eyebrow, a hairline footer pinned to the bottom (name and role left, pills right);
   two big question marks sit behind everything, clipped by the section, so there is never a horizontal scroll */
.cover { position: relative; overflow: hidden; }
.cover-in { position: relative; z-index: 1; align-self: stretch; display: flex; flex-direction: column; }
.cover-in > .byline { margin-top: auto; }
.cover h1.display { margin-top: clamp(8px, 3vh, 36px); margin-bottom: clamp(20px, 4vh, 48px); }
.q { position: absolute; font-size: min(112vh, 130vw); line-height: 1; font-weight: 600; pointer-events: none; user-select: none; }
.q-fill { right: -1vw; top: -14vh; background: var(--accent); -webkit-background-clip: text; background-clip: text; color: transparent; opacity: .16; }
.q-out { right: 14vw; top: -6vh; -webkit-text-stroke: 2px var(--hairline); color: transparent; }
.byline { display: flex; align-items: flex-end; justify-content: space-between; flex-wrap: wrap; gap: 20px;
  border-top: 1px solid var(--hairline); padding-top: clamp(14px, 2.4vh, 24px); }
.byline-name { font-size: clamp(24px, 2.2vw, 34px); line-height: 1.1; font-weight: 600; letter-spacing: -.01em; }
.byline-role { font-size: 20px; color: var(--muted); margin-top: 6px; }
.byline-links { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; }
.byline-links .btn { text-decoration: none; }
@media (min-width: 901px) { .cover { padding-right: 56px; } } /* clear of the fixed progress rail */
/* only with motion allowed: the title gradient slides and the question marks drift slowly; otherwise all static */
@media (prefers-reduced-motion: no-preference) {
  /* the title passes through every part's colour (the five run twice so the slide loops without a jump) */
  .cover .grad { background: linear-gradient(114deg, var(--white-1), var(--green-1), var(--blue-1), var(--pink-1), var(--orange-1), var(--white-1), var(--green-1), var(--blue-1), var(--pink-1), var(--orange-1), var(--white-1)); background-size: 200% 100%;
    -webkit-background-clip: text; background-clip: text; animation: grad-slide 14s linear infinite; }
  .q-fill { animation: q-drift-a 19s ease-in-out infinite alternate; }
  .q-out { animation: q-drift-b 23s ease-in-out infinite alternate; }
}
@keyframes grad-slide { to { background-position: -100% 0; } /* the gradient repeats every half of its width, so this loops without a jump */ }
@keyframes q-drift-a { from { transform: translate3d(0, 0, 0) rotate(0deg); opacity: .12; } to { transform: translate3d(-1.5vw, 3vh, 0) rotate(7deg); opacity: .2; } }
@keyframes q-drift-b { from { transform: translate3d(0, 0, 0) rotate(0deg); } to { transform: translate3d(2vw, -2.5vh, 0) rotate(-8deg); } }
h2 { font-size: clamp(34px, min(5vw, 7vh), 66px); line-height: 1; letter-spacing: -.02em; font-weight: 600; }
.lede { font-size: 23px; max-width: 60ch; }
.muted { color: var(--muted); font-size: 16px; }
.placeholder-note { border: 1px dashed var(--hairline); border-radius: var(--radius); padding: 16px 20px; color: var(--muted); font-size: 16px; }
.big-number { font-size: clamp(56px, 9vw, 101px); line-height: .95; font-weight: 600; color: var(--c, var(--text)); letter-spacing: -.02em; }

/* marker sweep behind a key phrase, in the chapter's colour */
.mark {
  --wash: color-mix(in srgb, var(--c, var(--s1)) 38%, transparent); /* translucent so cream text stays readable */
  background: linear-gradient(var(--wash), var(--wash)) no-repeat left 88% / var(--sweep, 100%) 38%;
  color: var(--text); padding: 0 .1em;
}

/* ---------- progress rail ---------- */
.progress { position: fixed; inset: 0 0 auto 0; height: 3px; background: transparent; z-index: 20; pointer-events: none; }
body.wiping .progress-fill { background: var(--canvas); transition: none; } /* black while a wipe crosses */
.progress-fill { height: 100%; background: var(--sec-now, var(--text)); transition: background-color .4s; transform: scaleX(0); transform-origin: left; }
.rail { position: fixed; right: 20px; top: 50%; transform: translateY(-50%); z-index: 20; }
.rail ol { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 14px; }
.rail a {
  display: block; width: 10px; height: 10px; border-radius: 50%;
  border: 1px solid var(--sec, var(--muted)); transition: transform .2s, background-color .2s, border-color .2s;
}
.rail a:hover { background: var(--sec, var(--text)); }
.rail a[aria-current="true"] { background: var(--sec, var(--text)); border-color: var(--sec, var(--text)); transform: scale(1.5); }
.rail li { position: relative; }
.rail-tip {
  position: absolute; right: 22px; top: 50%; transform: translateY(-50%); white-space: nowrap; pointer-events: none;
  font: 600 13px/1 var(--mono); letter-spacing: .04em; padding: 6px 10px; border-radius: 6px;
  background: var(--canvas); border: 1px solid var(--hairline); opacity: 0; transition: opacity .15s;
}
.rail li:hover .rail-tip, .rail a:focus-visible + .rail-tip { opacity: 1; }
.counter {
  position: fixed; left: 24px; bottom: 20px; z-index: 20;
  font: 600 16px/1 var(--mono); color: var(--muted); background: var(--canvas); padding: 6px 0;
}
.counter b { color: var(--text); font-weight: 600; }
.counter .hint { margin-left: 16px; opacity: .8; }

/* ---------- buttons ---------- */
.btn {
  font: 600 16px/1 var(--font); color: var(--text); background: transparent; cursor: pointer;
  border: 1px solid var(--text); border-radius: var(--pill); padding: 12px 24px;
  transition: background-color .2s, color .2s;
}
.btn:hover { background: var(--text); color: var(--canvas); }
.btn.primary { /* the one coloured control: gradient stroke */
  border: 1px solid transparent;
  background: linear-gradient(var(--canvas), var(--canvas)) padding-box, var(--accent) border-box;
}
.btn.primary:hover { background: var(--accent) border-box; color: var(--canvas); }

/* call to action: the gradient stroke turns slowly (an angle registered with @property, so it can be animated) */
@property --angle { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
.btn.cta {
  display: inline-block; text-decoration: none; border: 2px solid transparent; padding: 14px 32px;
  background: linear-gradient(var(--canvas), var(--canvas)) padding-box,
              conic-gradient(from var(--angle), var(--s1), var(--s2), var(--s1)) border-box;
  animation: spin 6s linear infinite;
}
.btn.cta:hover { background: conic-gradient(from var(--angle), var(--s1), var(--s2), var(--s1)) border-box; color: var(--canvas); }
@keyframes spin { to { --angle: 360deg; } }

/* year steps (chapter 6): a pressed step is filled in the prompt's colour */
.steps { display: flex; gap: 12px; flex-wrap: wrap; }
.btn.step[aria-pressed="true"] { background: var(--c, var(--text)); border-color: var(--c, var(--text)); color: var(--canvas); }

/* ---------- "How we know" strip ---------- */
.strip { padding-top: var(--gap-text); border-top: 1px solid var(--hairline); }
.strip-title { font: 600 14px/1 var(--mono); color: var(--s1); letter-spacing: .04em; margin-bottom: 16px; }
/* chips in a row share one height (stretch), so an open chip never leaves its neighbours short */
.chips { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gap-grid); align-items: stretch; }
.chip { background: var(--panel); border: 1px solid var(--hairline); border-radius: var(--radius); }
.chip[open] { border-color: var(--s1); }
.chip summary {
  list-style: none; cursor: pointer; padding: 18px 24px; display: flex; align-items: baseline; gap: 12px;
  font-weight: 600; font-size: 16px;
}
.chip summary::-webkit-details-marker { display: none; }
.chip summary .tag { color: var(--s1); font-family: var(--mono); font-size: 14px; margin-left: auto; }
.chip summary::after { content: "+"; color: var(--muted); font-family: var(--mono); width: 1ch; text-align: center; }
.chip[open] summary::after { content: "–"; }
.chip .chip-body { padding: 4px 24px 24px; color: var(--muted); font-size: 16px; line-height: 1.5; }
/* Beside a SQL panel there is no room for a chip to grow, so on wide screens its text opens as a card over the
   narrative above the chips, one at a time (`name` on the <details> makes the group exclusive). */
@media (min-width: 901px) {
  .answer .chips { position: relative; }
  .answer .chip summary { padding: 16px 18px; }
  .answer .chip-body {
    position: absolute; left: 0; right: 0; bottom: calc(100% + 10px); z-index: 5;
    background: var(--panel); border: 1px solid var(--s1); border-radius: var(--radius); padding: 20px 24px;
  }
}

/* ---------- prompt answers (P1 first): the executive answer, its takeaways, the next questions ---------- */
.exec-q { font-weight: 600; }
.takeaways { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; font-size: 16px; line-height: 1.4; }
.takeaways b { font: 600 13px/1 var(--mono); color: var(--c, var(--text)); margin-right: 6px; }
/* a word that opens a decision's detail: reads as a link, behaves as a button (the dialog opens over this slide) */
.ref {
  font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer;
  text-decoration: underline; text-decoration-color: var(--s1); text-underline-offset: 3px;
}
.ref:hover { color: var(--s1); }
.eda-facts a { text-decoration-color: var(--s1); text-underline-offset: 3px; }
/* the follow-ups: smaller and muted, each with a button that loads its query into the panel */
.next ol { list-style: none; margin: 10px 0 0; padding: 0; display: grid; gap: 8px; }
.next li { font-size: 15px; line-height: 1.4; color: var(--muted); }
.next .nq { color: var(--text); font-weight: 600; }
.sql-ref, .qchip {
  font: 600 12px/1 var(--mono); color: var(--c, var(--s1)); background: none; cursor: pointer;
  border: 1px solid var(--hairline); border-radius: var(--pill); padding: 4px 10px;
}
.sql-ref:hover, .qchip:hover { border-color: var(--c, var(--s1)); }
/* "How we know" as four buttons into one dialog, each opening it at its row */
.know { display: grid; grid-template-columns: repeat(4, 1fr); gap: 10px; }
.know-btn {
  display: flex; align-items: baseline; justify-content: space-between; gap: 8px; cursor: pointer;
  font: 600 16px/1 var(--font); color: var(--text); background: var(--panel);
  border: 1px solid var(--hairline); border-radius: var(--radius); padding: 14px 14px;
}
.know-btn .tag { color: var(--s1); font: 400 12px/1 var(--mono); }
.know-btn:hover { border-color: var(--s1); }
/* query chips on the panel: the pressed one is filled; the follow-ups' chips are dashed, a step back */
.qchips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.qchip { font-size: 11px; padding: 6px 8px; color: var(--text); }
.qchip.next-q { border-style: dashed; color: var(--muted); }
.qchip[aria-pressed="true"] { background: var(--c, var(--s1)); border-color: var(--c, var(--s1)); border-style: solid; color: var(--canvas); }
.sql-panel:has(.qchips) { padding: 20px 24px 22px; }
.sql-panel:has(.qchips) .sql-editor { min-height: 0; font-size: 13px; line-height: 1.4; padding: 12px 14px; }
.sql-panel:has(.qchips) .sql-actions { margin-top: 12px; }
.sql-panel:has(.qchips) .sql-actions .btn { padding: 9px 20px; }
.sql-panel:has(.qchips) .sql-out:not(:empty) { margin-top: 16px; }
/* tables under query chips run compact, so a follow-up's result fits where the main chart was */
.sql-panel:has(.qchips) .rrow { padding: 2px 8px; font-size: 13px; line-height: 1.25; }
.sql-panel:has(.qchips) .rhead { font-size: 12px; padding-bottom: 4px; }
.sql-note { margin-top: 10px; color: var(--muted); font-size: 13px; line-height: 1.4; }
.sql-note:empty { display: none; }
/* P2's follow-up tables on a phone: a long column name breaks instead of running into the next one */
@media (max-width: 900px) { #c11 .rhead span { overflow-wrap: anywhere; } }
/* P2's left column: room between the answer, its takeaways and the follow-ups */
#c11 .takeaways { margin-top: 14px; gap: 10px; }
#c11 .next ol { gap: 10px; }
/* P3's follow-up queries are longer than its main one: past 11 lines the editor scrolls instead of pushing the slide */
#c12 .sql-editor { max-height: calc(11 * 1.4em + 26px); overflow-y: auto; }

/* ---------- cards, timeline, lists (narrative chapters) ---------- */
.lede.wide { max-width: 70ch; font-size: 21px; }
h3 { font-size: 23px; line-height: 1.15; font-weight: 600; margin: 0; }
h3.sub { font: 600 14px/1 var(--mono); color: var(--c, var(--text)); letter-spacing: .04em; text-transform: uppercase; }
.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: var(--gap-grid); }
.cards.cards-1 { grid-template-columns: 1fr; }
/* two columns of single-card stacks (chapter 8): the columns share their rows (subgrid), so cards side by side match */
@media (min-width: 901px) {
  .cols:has(> .stack > .cards-1) { grid-template-rows: auto repeat(3, auto); row-gap: var(--gap-grid); }
  .cols:has(> .stack > .cards-1) > .stack { display: grid; grid-row: span 4; grid-template-rows: subgrid; }
  .cols:has(> .stack > .cards-1) > .stack > * { margin-top: 0; }
  .cols:has(> .stack > .cards-1) .cards-1 { grid-row: span 3; grid-template-rows: subgrid; }
}
/* slide 14: both columns end at the same height; the shorter list spreads its extra space over its six items */
@media (min-width: 901px) {
  #c14 .cols { align-items: stretch; }
  #c14 .cols > .stack { display: flex; flex-direction: column; }
  #c14 .list { flex: 1; display: flex; flex-direction: column; }
  #c14 .list li { flex: 1; }
}
.card { background: var(--panel); border: 1px solid var(--hairline); border-radius: var(--radius); padding: 24px 28px; }
.card.p1, .card.p2, .card.p3 { border-top: 2px solid var(--c); }
.card-k { font: 600 14px/1 var(--mono); color: var(--c, var(--s1)); letter-spacing: .04em; margin-bottom: 16px; }
.card-v { font-size: 44px; line-height: 1; font-weight: 600; letter-spacing: -.02em; color: var(--c, var(--text)); margin-bottom: 14px; }
.card-t { font-size: 16px; line-height: 1.5; color: var(--muted); }
.questions .card-t { font-size: 19px; line-height: 1.4; color: var(--text); }
/* the evidence line sits at the foot of each column, so the four lines start on one row */
.timeline { display: grid; grid-template-columns: repeat(4, 1fr); gap: 32px; }
.timeline.timeline-2 { grid-template-columns: repeat(2, 1fr); column-gap: 48px; row-gap: 24px; }
.timeline-2 .tl { gap: 10px; padding-top: 16px; }
.timeline-2 .tl .tl-ev { padding-top: 10px; }
.tl { border-top: 2px solid var(--s1); padding: 20px 0 0; display: flex; flex-direction: column; gap: 14px; }
.tl-when { font: 600 14px/1 var(--mono); color: var(--s1); }
/* slide 4: traps with no setting to choose (checked, or stated as a limit) read apart from the decisions */
.tl.trap { border-top-color: var(--s2); }
.tl.trap .tl-when { color: var(--s2); }
/* slide 7: the budget and language-model decisions, in the cost colour of the architecture's guards */
.tl p { font-size: 16px; line-height: 1.5; }
.tl .tl-ev { color: var(--muted); margin-top: auto; padding-top: 14px; border-top: 1px solid var(--hairline); }
.tl .tl-ev:has(.more) { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }

/* EDA details: a button on each decision opens a native modal dialog with the chart, the method and the links */
.more {
  flex: none; font: 600 14px/1 var(--mono); color: var(--s1); background: none; cursor: pointer;
  border: 1px solid var(--hairline); border-radius: var(--pill); padding: 4px 12px;
}
.more::after { content: " +"; }
.more:hover { border-color: var(--s1); }
body:has(dialog[open]) { overflow: hidden; }
.eda {
  width: min(1040px, calc(100vw - 32px)); max-height: calc(100vh - 48px); overflow: auto;
  background: var(--panel); color: var(--text); border: 1px solid var(--hairline); border-radius: var(--radius);
  padding: 28px 32px;
}
/* dialogs: one standard grey for every coloured text and rule (their plots are images and keep their colours); the one
   live panel in the D4 dialog keeps the green of its slide */
.eda { --s1: var(--dg); --s2: var(--dg); --s3: var(--dg); --s4: var(--dg); --sec: var(--dg); --c: var(--dg);
  --accent: linear-gradient(114deg, var(--dg), var(--dg)); }
#eda-d4 .sql-panel { --s1: var(--green-1); --s2: var(--green-2); --s3: var(--green-3); --s4: var(--green-4); --c: var(--green-1);
  --accent: linear-gradient(114deg, var(--green-1), var(--green-2)); }
.eda::backdrop { background: rgb(14 16 15 / .85); }
.eda-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 16px; margin-bottom: 20px; }
.eda-head .tl-when { margin-bottom: 10px; }
.eda-close {
  flex: none; width: 40px; height: 40px; font: 400 24px/1 var(--font); color: var(--text); background: none;
  border: 1px solid var(--hairline); border-radius: var(--pill); cursor: pointer;
}
.eda-close:hover { border-color: var(--s1); }
.eda figure { margin: 0 0 24px; }
.eda img { display: block; width: 100%; height: auto; }
.eda figcaption { margin-top: 12px; color: var(--muted); font-size: 16px; line-height: 1.5; }
.eda-facts { display: grid; grid-template-columns: 7.5rem 1fr; gap: 12px 20px; margin: 0; }
.eda-facts dt { font: 600 14px/1.6 var(--mono); color: var(--s1); }
.eda-facts dd { margin: 0; font-size: 16px; line-height: 1.5; }
.eda-list { margin: 0; padding-left: 20px; }
.eda-list li + li { margin-top: 10px; }
.eda-list b { font-weight: 600; }
.eda-links { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; margin: 24px 0 0; padding: 0; }
.eda-links a {
  display: inline-block; font-size: 14px; text-decoration: none; padding: 8px 14px;
  border: 1px solid var(--hairline); border-radius: var(--pill);
}
.eda-links a:hover { border-color: var(--s1); }
.eda-facts .eda-links { margin: 0; } /* inside the facts grid, as the "GitHub repo" row */
/* the decision told as an answer to an executive: closes the dialog, under a hairline */
.eda-exec { margin-top: 28px; padding-top: 24px; border-top: 1px solid var(--hairline); }
.eda-exec h4 { margin: 0 0 14px; font: 600 14px/1.6 var(--mono); color: var(--s1); }
.eda-exec p, .eda-exec li { margin: 0 0 12px; font-size: 16px; line-height: 1.5; }
.eda-exec .eda-q { font-weight: 600; }
.eda-exec ul { margin: 16px 0 0; padding-left: 20px; }
.eda-exec li:last-child { margin-bottom: 0; }
.eda-exec li b { font-weight: 600; }
/* the specs dialog: each acceptance criterion as id | plain words over how it is checked, with the test kinds as tags */
.ac-spec { margin: 0; color: var(--muted); }
.ac-spec + .ac-list { margin-top: 10px; }
.ac-list + .ac-spec { margin-top: 14px; }
/* why the spec exists, between its links line and its criteria */
.ac-intro { margin: 8px 0 0; }
.ac-intro + .ac-list { margin-top: 12px; }
.ac-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 12px; }
.ac-list li { display: grid; grid-template-columns: 4.5rem 1fr; column-gap: 12px; }
.ac-id { grid-row: span 2; font: 600 13px/1.85 var(--mono); color: var(--s1); }
.ac-what, .ac-how { margin: 0; min-width: 0; }
#specs code { overflow-wrap: anywhere; } /* long test names would push the dialog sideways at phone width */
.ac-how { color: var(--muted); font-size: 15px; }
.ac-how a { color: var(--text); }
.ac-k {
  display: inline-block; margin-right: 6px; font: 600 11px/1 var(--mono); color: var(--text); white-space: nowrap;
  border: 1px solid var(--hairline); border-radius: var(--pill); padding: 3px 7px; vertical-align: 1px;
}
.ac-k.warn { color: var(--s2); border-color: var(--s2); }
.ac-k.scan { color: var(--muted); border-style: dashed; }
.ac-k.gap { color: var(--canvas); background: var(--s2); border-color: var(--s2); }
.list li { padding: 14px 0; border-bottom: 1px solid var(--hairline); font-size: 16px; line-height: 1.5; color: var(--muted); }
.list li b { color: var(--text); font-weight: 600; }

/* ---------- architecture diagram: layers in flow order, guards highlighted by the buttons ---------- */
.chapter.dense { --pad-y: clamp(24px, 3.5vh, 56px); --gap-panel: clamp(20px, 3vh, 44px); }
.arch > * + * { margin-top: var(--gap-text); }
.arch-head { display: flex; align-items: flex-end; justify-content: space-between; gap: 24px 48px; flex-wrap: wrap; }
.arch-head .lede { flex: 1 1 480px; max-width: 58ch; }
.arch-head .steps { flex: 0 1 auto; max-width: 100%; } /* may wrap on a phone instead of widening the page */
.arch-flow { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
/* guards sit at the foot of each node, so the badges of a row line up */
.arch-node {
  min-width: 0; overflow-wrap: anywhere; background: var(--panel); border: 1px solid var(--hairline); border-radius: var(--radius);
  padding: 16px 18px; display: flex; flex-direction: column; gap: 6px; transition: opacity .3s;
}
.arch-k { font: 600 13px/1 var(--mono); color: var(--s1); }
.arch-t { font-weight: 600; font-size: 16px; line-height: 1.2; }
.arch-d { font-size: 14px; line-height: 1.35; color: var(--muted); }
.arch-node .guards { margin-top: auto; padding-top: 6px; display: flex; flex-wrap: wrap; gap: 6px; }
.g { --g: var(--s1); font: 400 12px/1.3 var(--mono); color: var(--muted); border: 1px solid var(--hairline); border-radius: var(--pill); padding: 4px 10px; transition: opacity .3s, color .3s, border-color .3s; }
.g::before { content: ""; display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--g); margin-right: 7px; }
.g.cost { --g: var(--text); }
.g.leak { --g: var(--s2); }
.btn[data-guard="cost"] { --c: var(--text); }
.btn[data-guard="leak"] { --c: var(--s2); }
/* each guard button says where the guard lives; picking one swaps the lede for that detail (all variants share one grid cell, so the height never jumps) */
.step-where { display: block; font: 400 11px/1.2 var(--mono); opacity: .75; margin-top: 3px; }
.arch-lede { display: grid; }
.arch-lede > span { grid-area: 1 / 1; visibility: hidden; }
.arch-lede code { line-height: 1; } /* keeps the code variant at two lines' height */
.arch:not([data-show="test"]):not([data-show="cost"]):not([data-show="leak"]) .al-none,
.arch[data-show="test"] .al-test, .arch[data-show="cost"] .al-cost, .arch[data-show="leak"] .al-leak { visibility: visible; }
.arch[data-show="test"] .g.test, .arch[data-show="cost"] .g.cost, .arch[data-show="leak"] .g.leak { color: var(--text); border-color: var(--g); }
.arch[data-show="test"] .g:not(.test), .arch[data-show="cost"] .g:not(.cost), .arch[data-show="leak"] .g:not(.leak) { opacity: .25; }
.arch[data-show="test"] .arch-node:not(:has(.g.test)),
.arch[data-show="cost"] .arch-node:not(:has(.g.cost)),
.arch[data-show="leak"] .arch-node:not(:has(.g.leak)) { opacity: .4; }

/* ---------- slide 6, the stack: one card per piece, its cost on the last line ---------- */
.stack-cards { grid-template-columns: repeat(3, 1fr); }
.stack-cards .card { display: flex; flex-direction: column; padding: 20px 24px; }
.stack-t { font-size: 19px; line-height: 1.2; font-weight: 600; margin-bottom: 10px; }
.stack-c { margin-top: auto; padding-top: 12px; font: 600 13px/1.3 var(--mono); color: var(--text); }
.stack-c::before { content: ""; display: inline-block; width: 7px; height: 7px; border-radius: 50%; background: var(--text); margin-right: 8px; }

/* ---------- slide 9: two views (tables and keys, the pipeline); without JS both show, one under the other ---------- */
.views > * + * { margin-top: var(--gap-text); }
.js .views[data-view="tables"] [data-view-panel="pipeline"],
.js .views[data-view="pipeline"] [data-view-panel="tables"] { display: none; }
.view > * + * { margin-top: 14px; }
/* data model: tables as cards in four columns; a key keeps its colour everywhere (filled = the table's own key) */
.dm > * + * { margin-top: 14px; }
.dm-head { display: flex; align-items: center; justify-content: space-between; gap: 12px 32px; flex-wrap: wrap; }
.dm-head .muted { flex: 1 1 420px; max-width: 70ch; }
.dm-cols { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.dm-col .arch-k { margin-bottom: 10px; }
:where(.dm-list, .dag-notes) { list-style: none; margin: 0; padding: 0; }
.dm-list { display: grid; gap: 8px; }
.dm-t { min-width: 0; background: var(--panel); border: 1px solid var(--hairline); border-radius: var(--radius); padding: 9px 12px; transition: opacity .3s; }
.dm-n { font: 600 13px/1.3 var(--mono); overflow-wrap: anywhere; }
.dm-g { font-size: 13px; line-height: 1.3; color: var(--muted); margin-top: 2px; }
.dm-k { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.k { --kc: var(--hairline); font: 400 11px/1.4 var(--mono); color: var(--text); border: 1px solid var(--kc); border-radius: var(--pill); padding: 1px 8px; transition: opacity .3s; }
.k.pk { background: var(--kc); color: var(--canvas); }
.k:not(.kq, .ka, .ku, .kt).pk { color: var(--text); }
.kq { --kc: var(--s1); } .ka { --kc: var(--s3); } .ku { --kc: var(--s4); } .kt { --kc: var(--s2); }
.k-btn.kq { --c: var(--s1); } .k-btn.ka { --c: var(--s3); } .k-btn.ku { --c: var(--s4); } .k-btn.kt { --c: var(--s2); }
.k-btn { font-family: var(--mono); font-size: 14px; padding: 9px 16px; }
.dm[data-show="kq"] .dm-t:not([data-keys~="kq"]), .dm[data-show="ka"] .dm-t:not([data-keys~="ka"]),
.dm[data-show="ku"] .dm-t:not([data-keys~="ku"]), .dm[data-show="kt"] .dm-t:not([data-keys~="kt"]) { opacity: .25; }
.dm[data-show="kq"] .k:not(.kq), .dm[data-show="ka"] .k:not(.ka),
.dm[data-show="ku"] .k:not(.ku), .dm[data-show="kt"] .k:not(.kt) { opacity: .3; }
/* the pipeline: an SVG drawn at 1200 wide; on a phone it keeps its size and scrolls inside its own box */
.dag-wrap { overflow-x: auto; }
.dag { display: block; width: 100%; height: auto; }
.dag text { fill: var(--text); font: 600 15px var(--font); }
.dag text.s { fill: var(--muted); font: 400 12px var(--font); }
.dag .lane text { fill: var(--muted); font: 600 13px var(--mono); }
.dag .n rect { fill: var(--panel); stroke: var(--s1); stroke-width: 1.5; }
.dag .n.manual rect { stroke: var(--text); stroke-dasharray: 6 4; }
.dag .edges path { fill: none; stroke: var(--muted); stroke-width: 1.5; marker-end: url(#dag-arr); }
.dag marker path { fill: var(--muted); }
.dag-notes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px 32px; }
.dag-notes li { font-size: 15px; line-height: 1.45; color: var(--muted); }
.dag-notes b { color: var(--text); font-weight: 600; }

/* ---------- live SQL panel ---------- */
.sql-panel { background: var(--panel); border: 1px solid var(--hairline); border-radius: var(--radius); padding: 24px 28px 28px; }
.sql-head { display: flex; justify-content: space-between; gap: 12px; font: 600 14px/1 var(--mono); color: var(--muted); margin-bottom: 16px; }
.sql-head .sql-status[data-state="ready"] { color: var(--c, var(--s1)); }
.sql-head .sql-status[data-state="error"] { color: var(--s3); }
/* the editor grows with its query where the browser can (field-sizing); the min-heights fit each default query */
.sql-editor {
  display: block; width: 100%; min-height: 150px; field-sizing: content; resize: vertical; background: var(--canvas); color: var(--text);
  border: 1px solid var(--hairline); border-radius: var(--radius); padding: 16px;
  font: 400 14px/1.45 var(--mono); tab-size: 2; font-variant-ligatures: none; /* show >= as typed */
}
.sql-editor:focus { outline: none; border-color: var(--c, var(--s1)); }
.sql-panel[data-render="table"] .sql-editor { min-height: 172px; }
.sql-actions { display: flex; gap: 12px; align-items: center; margin-top: 18px; }
.sql-actions .meta { margin-left: auto; color: var(--muted); font-size: 14px; font-family: var(--mono); }
/* a number panel draws its result outside the panel, so its output box is empty and takes no room */
.sql-out:not(:empty) { margin-top: 24px; }
.sql-panel[data-render="table"] .sql-out { min-height: 80px; }
.sql-error { color: var(--s3); font: 400 14px/1.4 var(--mono); white-space: pre-wrap; }

.rtable { position: relative; width: 100%; }
.rrow, .rhead { display: grid; grid-template-columns: 2.2rem minmax(0, 1.6fr) 5.5rem minmax(0, 2fr); gap: 12px; align-items: center; }
.rhead { color: var(--muted); font-size: 14px; font-family: var(--mono); padding: 0 8px 8px; border-bottom: 1px solid var(--hairline); }
.rrow { padding: 4px 8px; border-bottom: 1px solid var(--hairline); font-size: 15px; line-height: 1.3; }
.rrow:hover { background: rgba(255, 252, 225, .05); }
.rrow .rk { color: var(--muted); font-family: var(--mono); }
.rrow .bar { height: 8px; border-radius: 4px; background: var(--c, var(--s1)); transform-origin: left; }
.rrow .bar-cell { display: flex; align-items: center; gap: 10px; }
.rrow .bar-cell span { font-family: var(--mono); font-size: 14px; color: var(--muted); min-width: 4.5ch; }
.rrow:hover .bar { filter: brightness(1.15); }
.rtable.two :is(.rrow, .rhead) { grid-template-columns: 2.2rem minmax(0, 1.4fr) 0 minmax(0, 1fr); }
/* a result split by its "list" column: blocks side by side, the second (lowest, fewest) in cream instead of the prompt colour */
.rgroups { display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
.rgroups .rblock + .rblock { --c: var(--text); }
.rblock-t { font: 600 13px/1 var(--mono); color: var(--c, var(--s1)); margin: 0 0 6px; }
.rgroups .rrow, .rgroups .rhead { gap: 8px; font-size: 14px; }
/* a range chart keeps one wide axis: its blocks stack instead of sitting side by side */
.rgroups.stacked { grid-template-columns: 1fr; gap: 8px; }
.rgroups.stacked .rblock-t { margin-bottom: 2px; }
/* range chart: label, value, then a track with the interval line, the dot and an optional dashed baseline */
.rg-row { display: grid; grid-template-columns: minmax(0, 1fr) 3.4rem minmax(0, 1.6fr); gap: 10px; align-items: center; height: 13px; }
.rg-label { font: 400 12px/1 var(--mono); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rg-v { font: 400 12px/1 var(--mono); color: var(--muted); text-align: right; }
.rg-head .rg-v { font-size: 10px; color: var(--c, var(--s1)); }
.rg-track { position: relative; height: 100%; background: linear-gradient(var(--hairline), var(--hairline)) left center / 100% 1px no-repeat; }
.rg-track[style*="--b"]::before { content: ""; position: absolute; top: 0; bottom: -1px; left: var(--b); border-left: 1px dashed color-mix(in srgb, var(--text) 55%, transparent); }
.rg-line { position: absolute; top: 50%; height: 2px; margin-top: -1px; background: var(--c, var(--s1)); opacity: .5; border-radius: 1px; }
.rg-dot { position: absolute; top: 50%; width: 8px; height: 8px; margin: -4px 0 0 -4px; border-radius: 50%; background: var(--c, var(--s1)); }

/* ---------- responsive and accessibility ---------- */
@media (max-width: 900px) {
  .cols, .cols.answer, .chips, .timeline, .timeline.timeline-2, .dag-notes { grid-template-columns: 1fr; }
  .arch-flow, .stack-cards, .dm-cols { grid-template-columns: 1fr 1fr; }
  .dag { min-width: 860px; }
}
@media (max-width: 600px) {
  .arch-flow, .stack-cards, .dm-cols { grid-template-columns: 1fr; }
  .rail, .counter .hint { display: none; }
  .chapter { padding: 72px 16px; }
  body { font-size: 17px; }
  .rrow, .rhead { grid-template-columns: 1.6rem minmax(0, 1.5fr) 4.5rem minmax(0, 1.5fr); gap: 8px; }
  .rgroups { grid-template-columns: 1fr; }
  .know { grid-template-columns: 1fr 1fr; }
  .takeaways { grid-template-columns: 1fr; gap: 2px; }
  .takeaways dd { margin-bottom: 6px; }
  .eda { padding: 20px 16px; }
  .eda-facts { grid-template-columns: 1fr; gap: 4px; }
  .eda-facts dd { margin-bottom: 10px; }
  .ac-list li { grid-template-columns: 1fr; }
  .ac-id { grid-row: auto; }
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition-duration: .001ms !important; }
  .btn.cta { animation: none; }
}
@media print { .rail, .counter, .progress { display: none; } .chapter { min-height: 0; break-after: page; } }
