/* Custom styling layered on top of whichever reveal.js theme is active. */

:root {
  /* Brand colours derive from the ACTIVE reveal theme's variables, so switching
     theme (deck picker / per-slide data-theme) changes text, headings and
     accents — not just the slide background. Two groups stay fixed on purpose:
       • over-image slides (title / montage / divider-bliss) keep explicit light
         text further down, since they sit on dark photos regardless of theme;
       • the fixed light cards (kanban cards, ctx cells) use --card-ink/-muted so
         their text stays readable even on dark themes (e.g. dracula/night). */
  --accent: var(--r-link-color);
  --ink: var(--r-main-color);
  --muted: color-mix(in srgb, var(--r-main-color) 62%, transparent);
  /* Text that always sits on a fixed light card/cell background. */
  --card-ink: #1a202c;
  --card-muted: #5a6573;
  /* Canvas is 1920x1080 (2x the original 960x540 tuning). The white theme pins
     --r-main-font-size: 40px regardless of canvas height, so at 1080 it would
     render at half the intended relative size. Double it to 80px — every
     em-based size (headings, leads, bullets) scales off this automatically.
     The absolute-px values below are likewise doubled from their 540 tuning. */
  --r-main-font-size: 80px;
}

.reveal {
  font-family: var(--r-main-font, "Helvetica Neue", Helvetica, Arial, sans-serif);
  color: var(--ink);
}

/* Global centering is off (see index.html) so content slides top-anchor and
   fill the full height. Re-center the display-type slides that should stay
   vertically centered. NB: reveal sets `display: block` inline on the active
   slide, so `!important` is required to win over it. */
.reveal .title-slide,
.reveal .divider,
.reveal .statement {
  height: 100%;
  display: flex !important;
  flex-direction: column;
  justify-content: center;
}

/* Content slides top-anchor (plain block default) and fill from the top. */
.reveal .slide-left {
  height: 100%;
}

.reveal h1,
.reveal h2,
.reveal h3 {
  font-weight: 600;
  text-transform: none;
  letter-spacing: -0.01em;
  /* Headings adopt the theme accent (--accent = the active theme's
     --r-link-color) so titles pop on every theme: blue on white/solarized,
     pink on dracula, etc. Over-image headings (.title-slide, .divider-bliss)
     keep their explicit white via more-specific rules below. */
  color: var(--accent);
}

/* On the solarized-LIGHT slides, use the dark solarized base02 (#073642) for
   headings instead of the bright link-blue. Scoped to slides with no data-theme
   (the light default) and excludes the over-image title/bliss slides that set
   their own colour. */
.reveal section:not([data-theme]):not(.title-slide):not(.divider-bliss) :is(h1, h2, h3) {
  color: #1c5a86;
}

/* Left-aligned content slides (Google-Slides style). */
.reveal .slide-left {
  text-align: left;
}
.reveal .slide-left h2 {
  text-align: left;
  margin-bottom: 0.4em;
}
.reveal .slide-left ul,
.reveal .slide-left ol {
  display: block;
  width: 100%;
  font-size: 0.78em;
}
.reveal .slide-left li {
  color: var(--muted);
  margin: 0.2em 0;
  line-height: 1.25;
}
.reveal .slide-left ul ul li,
.reveal .slide-left ol ul li {
  font-size: 0.85em;
}

/* Section divider: big centered word. */
.reveal .divider h1 {
  font-size: 2.6em;
  font-weight: 500;
}

/* "Background" divider over the Windows XP Bliss wallpaper — white text with a
   shadow so it stays legible across the bright sky and grass. */
.reveal .divider-bliss h1 {
  color: #fff;
  text-shadow: 0 2px 16px rgba(0, 0, 0, 0.75);
}

/* Big statement slide. */
.reveal .statement h1 {
  font-size: 1.9em;
  font-weight: 700;
  line-height: 1.15;
}
.reveal .statement .sub {
  color: var(--muted);
  font-size: 1.1em;
  margin-top: 0.6em;
}

/* Closing statement: smaller, brighter headline so the callback line plus the
   pillars recap and contact/Q&A lines all fit one dark slide. */
.reveal .statement.close h1 {
  font-size: 1.3em;
  color: #eee8d5; /* Solarized base2 — brighter than the base1 heading default */
}
/* Cream heading on the dark statement/divider slides (matches the closing slide).
   section.cream (0,2,2) is loaded after the theme's heading rule, so it wins. */
.reveal section.cream h1 {
  color: #eee8d5;
}
.reveal .statement.close .sub {
  font-size: 0.62em;
  margin-top: 0.5em;
}
.reveal .statement.close .contact {
  color: var(--muted);
  font-size: 0.5em;
  margin-top: 0.35em;
}
.reveal .statement.close .qr-cap {
  color: var(--muted);
  font-size: 28px;
  text-align: center;
}
/* Social links list on the closing slide (inline SVG icons — offline-safe). */
.reveal .statement.close .links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 16px;
  text-align: left;
}
.reveal .statement.close .links li {
  display: flex;
  align-items: center;
  gap: 16px;
  color: var(--muted);
  font-size: 30px;
  line-height: 1;
}
.reveal .statement.close .links svg {
  width: 30px;
  height: 30px;
  flex: 0 0 30px;
  color: #93a1a1;
}

/* Title slide over the factory background. */
.reveal .title-slide h1 {
  font-family: "Courier New", monospace;
  color: #fff;
  font-size: 2.4em;
  font-weight: 700;
  text-shadow: 0 2px 18px rgba(0, 0, 0, 0.85);
  margin-bottom: 0.1em;
}
.reveal .title-slide .sub {
  font-family: "Courier New", monospace;
  color: #e6f0ff;
  font-size: 1.2em;
  text-shadow: 0 2px 14px rgba(0, 0, 0, 0.9);
}

/* Note for anyone reading this deck on the web rather than watching it given:
   the live-demo iframes have nothing to point at here. */
.reveal .title-slide .disclaimer {
  max-width: 30em;
  margin: 1.2em auto 0;
  padding: 0.6em 0.9em;
  border-left: 3px solid #b58900;
  background: rgba(0, 43, 54, 0.72);
  color: #93a1a1;
  font-family: "Courier New", monospace;
  font-size: 0.5em;
  line-height: 1.5;
  text-align: left;
  text-shadow: none;
}

/* Two-column layout: text beside an image. The flex row, gap, and cross-axis
   alignment now come from the layout vocabulary on the container
   (data-lay="row", data-gap, data-align="center" — or "start" for the old
   .cols.top slides) so the columns are editable in the canvas Properties panel.
   Only child sizing + the overflow guard remain here. */
.reveal .cols > * {
  flex: 1;
  min-width: 0;
}
.reveal .cols img {
  margin: 0;
  border-radius: 6px;
  /* px (not vh) so it scales with the slide box, not the viewport. */
  max-height: 720px;
}

/* Code blocks. */
.reveal pre {
  width: 100%;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.25);
  font-size: 0.5em;
}
.reveal pre code {
  max-height: 720px;
  padding: 1em;
  border-radius: 6px;
}

/* Code beside bullets: give the code more room and shrink it so no
   line is clipped. */
.reveal .cols pre {
  flex: 1.7;
  font-size: 0.32em;
}
/* The soul-config snippet (System prompt / Persona / Soul) has short lines,
   so it takes the full 0.5em code size instead of the beside-bullets shrink.
   No top margin: these slides top-anchor and the snippet is tall, so the
   theme's 20px pre margin pushed the code + bullets onto the bottom edge. */
.reveal .cols pre[data-id="soul-code"] {
  font-size: 0.5em;
  margin-top: 0;
}
.reveal .cols pre code {
  white-space: pre;
  overflow-x: auto;
}
.reveal .cols ul {
  flex: 1;
}

/* Logo strip on the Harness slide. Row layout (gap/align/justify) now via
   data-lay="row" on the container; only the top spacing remains here. */
.reveal .logos {
  margin-top: 1.5em;
}
.reveal .logos img {
  margin: 0;
  height: 180px;
  width: auto;
  object-fit: contain;
  border-radius: 8px;
}

/* Prior-art image grid: the 3-column grid, gap, and item alignment now come
   from data-lay="grid" data-cols="3" data-gap data-align="center"; the wide
   tile uses data-span="2" instead of the old .span2 rule. Visual only here. */
.reveal .grid img {
  margin: 0;
  width: 100%;
  border-radius: 6px;
}

/* Full-bleed image credit line. */
.reveal .credit {
  position: absolute;
  bottom: 0.4em;
  left: 0;
  right: 0;
  text-align: center;
  font-size: 0.4em;
  color: var(--muted);
}

/* Industrialisation montage: wordless full-bleed historical photos. Keep the
   credit legible where it sits over a dark image. */
.reveal .montage .credit {
  color: rgba(255, 255, 255, 0.72);
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.9);
}

/* Intro line under a heading. */
.reveal .lead {
  color: var(--muted);
  font-size: 0.8em;
  margin: 0 0 0.6em;
}
.reveal .divider .sub {
  color: var(--muted);
  font-size: 0.9em;
  margin-top: 0.4em;
}
.reveal .statement code {
  font-size: 0.9em;
}

/* Design-choice slides: a bold mechanism statement, then the attack it kills
   (or the property it buys). Stripped to two lines so the docked live board —
   shown on every one of these slides — carries the visual weight. */
.reveal .choice .mechanism {
  text-align: left;
  font-size: 0.84em;
  line-height: 1.34;
  color: var(--ink);
  margin: 0.1em 0 0.7em;
}
.reveal .choice .mechanism strong {
  color: var(--accent);
}
.reveal .choice .consequence {
  text-align: left;
  font-size: 0.72em;
  line-height: 1.34;
  color: var(--muted);
  margin: 0;
}
/* The leading tag: red for an attack the choice BLOCKS, accent-blue for a
   property it BUYS / why it matters (.good). */
.reveal .choice .consequence .tag {
  display: inline-block;
  font-size: 0.82em;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: #c53030;
  margin-right: 0.45em;
}
.reveal .choice .consequence.good .tag {
  color: var(--accent);
}

/* Two-column choice grid — still used by the Souls slide (identity vs.
   behaviour). The six principle slides above were stripped to mechanism +
   consequence; this remains for the side-by-side comparison layout. */
.reveal .choice h3 {
  text-align: left;
  font-size: 0.7em;
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0 0 0.2em;
}
/* Souls two-column grid: the 2-column grid + gap now come from
   data-lay="grid" data-cols="2" data-gap; only the text styling and top-packing
   of rows remain here. */
.reveal .choice-grid {
  text-align: left;
  align-content: start;
}
.reveal .choice-grid p {
  color: var(--muted);
  font-size: 0.62em;
  line-height: 1.32;
  margin: 0;
}
/* Choice slides sit beside the docked board (a 32vw right gutter), so the
   columns are narrow and the text wraps tall. Keep the title tight and the
   cue compact so nothing clips off the bottom. */
.reveal .choice h2 {
  font-size: 1.4em;
  line-height: 1.1;
  margin-bottom: 0.3em;
}
.reveal .choice .board-cue {
  margin-top: 0.6em;
  padding-top: 0.4em;
  border-top: 1px solid #e2e8f0;
  text-align: left;
  font-size: 0.55em;
  color: var(--muted);
}
.reveal .choice .board-cue code {
  font-size: 0.95em;
  color: var(--accent);
}

/* Under-the-hood (mechanism) slides: compact comparison table. */
.reveal .slide-left table {
  width: 100%;
  margin: 0.2em 0 0.6em;
  border-collapse: collapse;
  font-size: 0.62em;
}
.reveal .slide-left th,
.reveal .slide-left td {
  text-align: left;
  padding: 0.3em 0.6em;
  border: none;
  border-bottom: 1px solid #e2e8f0;
}
.reveal .slide-left thead th {
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.85em;
}
/* Reveal renders line-numbered code as a <table> (one row per line). Stop the
   comparison-table borders above from drawing a separator under every code
   line — most visible in Firefox as white horizontal rules in the snippet. */
.reveal .slide-left pre table,
.reveal .slide-left pre tr,
.reveal .slide-left pre td,
.reveal .slide-left pre th {
  border: none;
  background: none;
}

/* A single emphasized takeaway line under a mechanism slide's bullets. */
.reveal .takeaway {
  margin-top: 0.7em;
  padding-top: 0.5em;
  border-top: 1px solid #e2e8f0;
  text-align: left;
  font-size: 0.62em;
  line-height: 1.4;
  color: var(--muted);
}
.reveal .takeaway strong {
  color: var(--accent);
}

/* The provenance commit trailer: soft-wrapped so no line is clipped. It is
   the hero of its slide (the bullets are just labels), so it runs larger
   than ordinary code. */
.reveal pre.trailer {
  font-size: 0.4em;
}
.reveal pre.trailer code {
  white-space: pre-wrap;
  word-break: break-word;
}

/* Dense under-the-hood slides (sandbox, broker, distributed, provenance) carry
   a table or code block plus several substantial bullets, so they need tighter
   type than the default slide-left to fit the 540px-high slide. */
.reveal .dense h2 {
  font-size: 1.4em;
  line-height: 1.1;
  margin-bottom: 0.3em;
}
.reveal .dense .lead {
  font-size: 0.72em;
  margin-bottom: 0.35em;
}
.reveal .dense ul {
  font-size: 0.64em;
}
.reveal .dense li {
  line-height: 1.28;
  margin: 0.26em 0;
}
.reveal .dense .takeaway {
  margin-top: 0.5em;
  padding-top: 0.4em;
  font-size: 0.6em;
}
.reveal .dense table {
  font-size: 0.56em;
  margin-bottom: 0.25em;
}
.reveal .dense th,
.reveal .dense td {
  padding: 0.18em 0.55em;
}

/* Role flow — "how software gets built today": a PM card hands a spec to the
   SE pipeline. Drawn in the same visual language as the factory DAG (mermaid,
   s25) — blue node = human, light bordered cells = pipeline stages — so the
   later slide reads as "same pipeline, agents in the seats". */
.reveal .roleflow {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 40px;
  margin-top: 1.4em;
}
.reveal .roleflow .rf-actor {
  background: #2b6cb0;
  border-radius: 10px;
  padding: 32px 38px;
  max-width: 500px;
  text-align: left;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.16);
}
.reveal .roleflow .rf-actor h3 {
  color: #fff;
  font-size: 0.52em;
  margin: 0 0 0.3em;
  text-align: left;
}
.reveal .roleflow .rf-actor p {
  color: rgba(255, 255, 255, 0.92);
  font-size: 0.4em;
  line-height: 1.3;
  margin: 0;
}
.reveal .roleflow .rf-actor .rf-inputs {
  color: rgba(255, 255, 255, 0.66);
  font-size: 0.34em;
  margin-top: 0.7em;
}
.reveal .roleflow .rf-arrow {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.reveal .roleflow .rf-arrow-label {
  font-size: 0.36em;
  font-weight: 700;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--accent);
}
.reveal .roleflow .rf-arrow-line {
  font-size: 0.9em;
  line-height: 1;
  color: #5a6573; /* mermaid lineColor — same as the DAG edges */
}
.reveal .roleflow .rf-se {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
}
.reveal .roleflow .rf-pipeline {
  display: flex;
  align-items: center;
  gap: 14px;
}
.reveal .roleflow .rf-stage {
  background: #eef5fb;
  border: 2px solid #2b6cb0;
  border-radius: 8px;
  padding: 20px 24px;
  font-size: 0.4em;
  color: var(--card-ink);
  white-space: nowrap;
}
.reveal .roleflow .rf-step {
  font-size: 0.5em;
  color: #5a6573;
}
.reveal .roleflow .rf-se-label {
  font-size: 0.38em;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--accent);
  margin: 0;
}

/* Kanban mock board — a generic Agile illustration (no screenshot needed). */
.reveal .kanban {
  display: grid;
  grid-template-columns: repeat(5, 1fr);
  gap: 20px;
  margin-top: 0.3em;
}
.reveal .kanban .col {
  background: #f7fafc;
  border: 1px solid #e2e8f0;
  border-radius: 8px;
  padding: 16px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.reveal .kanban .col h3 {
  font-size: 0.5em;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--accent);
  margin: 0 0 0.2em;
  text-align: left;
}
.reveal .kanban .card {
  background: #fff;
  border: 1px solid #cbd5e0;
  border-left: 3px solid var(--accent);
  border-radius: 5px;
  padding: 12px 14px;
  font-size: 0.4em;
  color: var(--card-ink);
  text-align: left;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
  line-height: 1.25;
}
.reveal .kanban .card .tag {
  display: block;
  color: var(--card-muted);
  font-size: 0.85em;
  margin-top: 6px;
}

/* Append-only context buffer — a fragment-stepped illustration. The presenter
   advances beats with the arrow keys; CSS sibling triggers do the transforms. */
/* This slide is a flex column so the buffer can sit centred (margin: auto)
   with the title pinned at the top. !important beats reveal's inline
   display:block on the active slide (same reason as the centered-slide rule). */
.reveal .ctx-slide {
  display: flex !important;
  flex-direction: column;
}
.reveal .ctx-buffer {
  display: flex;
  gap: 10px;
  align-items: stretch;
  flex-wrap: nowrap;
  border: 2px solid var(--accent);
  border-radius: 8px;
  background: #002b36; /* Solarized base03 — matches the code snippets */
  padding: 20px;
  min-height: 132px;
  /* Fixed capacity width = "the context window" (100% of capacity); cells fill
     it left-to-right. margin: auto centres the whole window on the slide. Cell
     width below is tuned so the beat-2 fill lands exactly on the 80% line. */
  position: relative;
  width: 1680px;
  max-width: 96%;
  margin: auto;
}
.reveal .ctx-buffer .ctx-cell {
  /* Fixed width (not min-width) so 8 cells + gaps land right at the 80% line in
     a 1680px window: 8×152 + 7×10 ≈ 1290px ≈ 80% of the ~1640px content area. */
  flex: 0 0 auto;
  width: 152px;
  padding: 18px 12px;
  background: #073642; /* Solarized base02 */
  border: 1px solid #586e75; /* base01 */
  border-radius: 5px;
  font-size: 0.42em;
  text-align: center;
  color: #93a1a1; /* base1 */
  font-family: "Courier New", monospace;
}
.reveal .ctx-buffer .ctx-cell.sys {
  background: var(--accent);
  color: #002b36;
  border-color: var(--accent);
}
.reveal .ctx-buffer .ctx-cell.dz {
  background: rgba(220, 50, 47, 0.2);
  border-color: #dc322f; /* Solarized red */
  color: #e8908b;
}
/* Dumb zone: the window past 60%. Cells that fill into here are degraded.
   Absolutely positioned so it overlays the cells without taking a flex slot. */
.reveal .ctx-buffer .ctx-dz-zone {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 60%;
  right: 0;
  background: rgba(220, 50, 47, 0.12);
  border-left: 2px dashed #dc322f;
  border-radius: 0 6px 6px 0;
  pointer-events: none;
}
.reveal .ctx-buffer .ctx-dz-zone::after {
  content: "60% · dumb zone";
  position: absolute;
  top: -44px;
  left: -2px;
  font-size: 30px;
  letter-spacing: 0.03em;
  color: #dc322f;
  white-space: nowrap;
}
/* Compaction threshold at 80%: crossing this is what triggers the collapse. */
.reveal .ctx-buffer .ctx-limit {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 80%;
  border-left: 2px solid #b58900;
  pointer-events: none;
}
.reveal .ctx-buffer .ctx-limit::after {
  content: "80% · compact";
  position: absolute;
  bottom: -44px;
  left: -2px;
  font-size: 30px;
  letter-spacing: 0.03em;
  color: #b58900; /* Solarized yellow */
  white-space: nowrap;
}
/* ctx-original is a transparent flex pass-through so its cells lay out in the
   buffer row; the compaction trigger collapses it and reveals the summary. */
.reveal .ctx-original {
  display: contents;
}
.reveal .ctx-compressed,
.reveal .ctx-post {
  display: none;
}
.reveal .compact-trigger.visible ~ .ctx-buffer .ctx-original {
  display: none;
}
.reveal .compact-trigger.visible ~ .ctx-buffer .ctx-compressed {
  display: inline-flex;
  align-items: center;
  padding: 18px 28px;
  background: rgba(181, 137, 0, 0.15);
  border: 1px dashed #b58900;
  border-radius: 5px;
  color: #cb9e2e;
  font-size: 0.42em;
  font-family: "Courier New", monospace;
}
.reveal .compact-trigger.visible ~ .ctx-buffer .ctx-post {
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Toolbelt — six tool-family cards (the point is the families, not the full
   inventory; the complete list lives in the speaker notes). */
.reveal .toolbelt {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 28px;
  margin-top: 0.5em;
}
.reveal .toolbelt .tb-card {
  background: #f7fafc;
  border: 1px solid #e2e8f0;
  border-left: 3px solid var(--accent);
  border-radius: 8px;
  padding: 24px 28px;
  text-align: left;
}
.reveal .toolbelt .tb-card h3 {
  font-size: 0.5em;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--accent);
  margin: 0 0 0.3em;
  text-align: left;
}
/* Featured full-width card (the explore sub-agent) under the 3×2 tool grid. */
.reveal .toolbelt .tb-card.tb-wide {
  grid-column: 1 / -1;
}
.reveal .toolbelt .tb-chips {
  font-family: "Courier New", monospace;
  font-size: 0.38em;
  color: var(--card-ink);
  line-height: 1.4;
  margin: 0;
}

/* Gate-failure flow — red gate → typed findings → Brief-fed retry. Same
   boxed-flow language as .roleflow / the mermaid DAG; colour carries the
   story (red failure in, green learning loop out). */
.reveal .gateflow {
  display: flex;
  align-items: stretch;
  justify-content: center;
  gap: 28px;
  margin-top: 1.2em;
}
.reveal .gateflow .gf-step {
  flex: 0 1 480px;
  background: #eef5fb;
  border: 2px solid #2b6cb0;
  border-radius: 10px;
  padding: 28px 32px;
  text-align: left;
}
.reveal .gateflow .gf-step h3 {
  font-size: 0.5em;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--accent);
  margin: 0 0 0.3em;
  text-align: left;
}
.reveal .gateflow .gf-step p {
  font-size: 0.4em;
  color: var(--card-muted);
  line-height: 1.35;
  margin: 0;
}
.reveal .gateflow .gf-red {
  background: rgba(197, 48, 48, 0.07);
  border-color: #c53030;
}
.reveal .gateflow .gf-red h3 {
  color: #c53030;
}
.reveal .gateflow .gf-green {
  background: rgba(47, 133, 90, 0.08);
  border-color: #2f855a;
}
.reveal .gateflow .gf-green h3 {
  color: #2f855a;
}
.reveal .gateflow .gf-arrow {
  align-self: center;
  font-size: 0.8em;
  line-height: 1;
  color: #5a6573;
}

/* Mermaid diagrams. The source text is hidden until mermaid swaps in an SVG;
   constrain the SVG so reveal scales it within the slide. */
.reveal .mermaid {
  text-align: center;
  background: none;
  box-shadow: none;
  margin: 0.4em 0;
  /* avoid a flash of unstyled diagram source before render */
  color: transparent;
}
.reveal .mermaid svg {
  /* Mermaid pins an inline max-width to the diagram's intrinsic size (useMaxWidth),
     which leaves it small on a 1920-wide slide. Override so it scales to fill the
     column; height:auto keeps the aspect ratio, max-height guards tall diagrams. */
  width: 100% !important;
  max-width: 100% !important;
  height: auto;
  max-height: 620px;
}
/* Give edge labels a solid backing (slide bg) with a little breathing room so
   the arrow line is masked behind the text instead of striking through it. */
.reveal .mermaid .edgeLabel,
.reveal .mermaid .edgeLabel rect,
.reveal .mermaid .edgeLabel .labelBkg {
  fill: #fdf6e3 !important;
  background-color: #fdf6e3 !important;
}
.reveal .mermaid .edgeLabel foreignObject > div,
.reveal .mermaid .edgeLabel .label {
  padding: 0 4px;
}
/* Embedded live-demo iframes (spec wizard, deployed result). */
.reveal .demo-frame {
  width: 100%;
  /* px (not vh) so the iframe scales with the slide box, not the viewport. */
  height: 600px;
  border: 1px solid #cbd5e0;
  border-radius: 8px;
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.18);
  background: #fff;
}
.reveal .demo-frame.tall {
  height: 640px;
}

/* These were live iframes pointed at a local harness during the talk. On the
   web there is nothing to point them at, so they keep their composition and
   say what they showed instead. Sizes are px: the slide is a fixed 1920x1080
   box that reveal scales, so px here track the slide, not the viewport. */
.reveal .demo-frame.placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  padding: 48px;
  text-align: center;
  background: #002b36;
  border: 1px dashed #657b83;
  box-shadow: none;
  font-family: "Courier New", monospace;
}
.reveal .demo-frame.placeholder .ph-tag {
  color: #b58900;
  font-size: 22px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}
.reveal .demo-frame.placeholder .ph-what {
  color: #eee8d5;
  font-size: 40px;
  font-weight: 700;
  line-height: 1.2;
}
.reveal .demo-frame.placeholder .ph-desc {
  max-width: 30em;
  margin: 0;
  color: #93a1a1;
  font-size: 24px;
  line-height: 1.6;
  text-wrap: balance;
}

/* The dock is small; one line only. */
.reveal .board-placeholder,
.board-placeholder {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  padding: 12px 16px;
  background: #002b36;
  border-top: 1px dashed #586e75;
}
/* The dock lives outside .slides, so it isn't scaled by reveal — these px are
   real px, and the caption has to fit the dock's own width. */
.board-placeholder p {
  margin: 0;
  max-width: 100%;
  color: #93a1a1;
  font-family: "Courier New", monospace;
  font-size: 12px;
  line-height: 1.6;
  text-align: center;
}

/* Persistent board dock — fixed overlay outside .slides, corner-pinned.
   Mounts once; toggled per-slide via .visible (see index.html script). */
#board-dock {
  position: fixed;
  right: 18px;
  bottom: 18px;
  width: 30vw;
  max-width: 440px;
  height: 26vh;
  min-height: 220px;
  z-index: 40;
  border-radius: 10px;
  overflow: hidden;
  background: #fff;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.32);
  border: 1px solid #cbd5e0;
  opacity: 0;
  transform: translateY(12px);
  pointer-events: none;
  transition: opacity 0.35s ease, transform 0.35s ease;
}
#board-dock.visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}
#board-dock .board-dock-bar {
  display: flex;
  align-items: center;
  gap: 7px;
  height: 22px;
  line-height: 22px;
  padding: 0 10px;
  font-size: 11px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: #fff;
  background: var(--accent);
}
/* Pulsing red "live camera" indicator in the dock title bar. */
#board-dock .live-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #ff3b30;
  box-shadow: 0 0 0 0 rgba(255, 59, 48, 0.7);
  animation: live-dot-pulse 1.4s ease-out infinite;
}
@keyframes live-dot-pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(255, 59, 48, 0.7);
    opacity: 1;
  }
  70% {
    box-shadow: 0 0 0 6px rgba(255, 59, 48, 0);
    opacity: 0.6;
  }
  100% {
    box-shadow: 0 0 0 0 rgba(255, 59, 48, 0);
    opacity: 1;
  }
}
@media (prefers-reduced-motion: reduce) {
  #board-dock .live-dot {
    animation: none;
  }
}
#board-dock iframe {
  display: block;
  /* Render at 2x then zoom to 0.5 so the board content shows at half scale
     (4x more visible) while the iframe still fills the dock below the bar. */
  width: 200%;
  height: calc(200% - 44px);
  border: 0;
  zoom: 0.5;
}

/* Keep slide content clear of the docked board when it's showing.
   Driven by a body class because #board-dock is not a CSS sibling of
   .reveal (it's rendered after it). */
body.dock-visible .reveal .dock-aware {
  /* Room on the right so the corner board never overlaps text. Must be a
     percentage (of the 960-wide slide), NOT vw: vw resolves against the
     browser viewport, so on a wide monitor it crushes the columns to a few
     characters. % stays constant whatever the screen width. */
  padding-right: 34%;
}
