/* Opening slide: Vanta Globe with an independent, high-contrast text layer. */
.remark-slide-content.globe-title {
  --muted: color-mix(in srgb, var(--title-slide-text-color) 72%, var(--title-slide-background-color));
  --surface-2: color-mix(in srgb, var(--title-slide-text-color) 7%, var(--title-slide-background-color));
  --border: color-mix(in srgb, var(--title-slide-text-color) 22%, var(--title-slide-background-color));
  position: relative; overflow: hidden; padding: 0; text-align: left;
  background: var(--title-slide-background-color); color: var(--title-slide-text-color);
  font-family: var(--text-font-family), var(--text-font-family-fallback), var(--text-font-base);
}
.globe-title .title-globe, .globe-title .title-shade {
  position: absolute; inset: 0; pointer-events: none;
}
.globe-title .title-globe {
  background: var(--title-slide-background-color);
}
.globe-title .title-shade {
  z-index: 1;
  background: linear-gradient(90deg, var(--title-slide-background-color) 0%, color-mix(in srgb, var(--title-slide-background-color) 96%, transparent) 27%, color-mix(in srgb, var(--title-slide-background-color) 72%, transparent) 46%, transparent 73%);
}
.globe-title .title-copy { position: relative; z-index: 2; padding: 52px 58px 0; }
.globe-title .title-eyebrow {
  font-size: 13px; font-weight: 600; line-height: 1.5; letter-spacing: .19em; color: var(--muted);
  margin-bottom: 32px;
}
.globe-title .title-eyebrow span { color: var(--accent); margin: 0 14px; }
.remark-slide-content.globe-title h1 {
  font-family: var(--header-font-family), var(--header-font-family-fallback);
  font-size: 60px; font-weight: 600;
  line-height: 1.09; letter-spacing: normal; color: var(--title-slide-text-color);
  margin: 0; padding: 0; max-width: 760px;
}
.globe-title h1 em { font-style: normal; color: var(--accent); }
.globe-title .title-deck {
  font-size: 26px; font-weight: 300; line-height: 1.45; color: var(--muted);
  margin: 25px 0 30px;
}
.globe-title .title-presenter { border-left: 2px solid var(--accent); padding-left: 17px; }
.globe-title .title-presenter strong { display: block; font-size: 23px; font-weight: 600; margin-bottom: 8px; }
.globe-title .title-presenter span { display: block; font-size: 18px; line-height: 1.6; color: var(--muted); }
.globe-title .title-footer {
  position: absolute; z-index: 2; bottom: 25px; left: 58px; right: 58px;
  display: flex; justify-content: space-between; border-top: 1px solid var(--border);
  padding-top: 16px; color: var(--muted); font-size: 13px; font-weight: 500; line-height: 1.4; letter-spacing: .16em;
}
.globe-title .title-footer.title-topics {
  justify-content: flex-start; gap: 12px; padding-top: 20px;
  font-size: 14px; letter-spacing: normal; bottom: 30px;
}
.globe-title .title-topics span, .globe-title .closing-links a {
  padding: 9px 16px; border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent); border-radius: 999px;
  background: var(--surface-2); color: var(--title-slide-text-color);
}
 .globe-title .closing-links a { text-decoration: none; }
.globe-title .closing-links a:hover, .globe-title .closing-links a:focus-visible {
  border-color: var(--accent); text-decoration: underline;
}
.remark-slide-content.closing-slide h1 { font-size: 94px; margin: 65px 0 45px; }
.closing-slide .title-deck { margin: 28px 0 36px; }
.globe-title .remark-slide-number { display: none; }
@media print { .globe-title .vanta-canvas { display: none !important; } }

/* A subtle network in the bottom-left quarter of each content slide. */
.remark-slide-content { position: relative; isolation: isolate; }
.slide-net {
  position: absolute; width: 50%; height: 50%; left: 0; bottom: 0;
  z-index: -1; opacity: .18; pointer-events: none; overflow: hidden;
  mask-image: linear-gradient(to right, #000 55%, transparent), linear-gradient(to top, #000 45%, transparent);
  mask-composite: intersect;
}
/* Lift the same network on dark dividers without rebuilding its scene. */
.remark-slide-content.inverse .slide-net {
  opacity: .78;
  filter: brightness(2.2) saturate(1.3);
}
.persistent-net, .persistent-globe { position: absolute; inset: 0; }
@media (prefers-reduced-motion: reduce) { .persistent-net, .persistent-globe { visibility: hidden; } }
.globe-fallback { width: 100%; height: 100%; color: var(--accent); }
.title-globe > .globe-fallback { position: absolute; width: 55%; right: -6%; }
.globe-running > .globe-fallback { visibility: hidden; }
@media print {
  .slide-net .vanta-canvas { display: none !important; }
  .globe-running > .globe-fallback { visibility: visible; }
}

/* ------------------------------------------------------------------ *
 * Pathway-diagram track colors.
 *
 * Tracks 1 and 2 are the theme's own h1/h2 accents, so a diagram matches
 * the slide title it sits under and follows a theme switch for free.
 *
 * Track 3 is deliberately NOT --accent-3. The theme's h3 teal (#4FB99A)
 * measures only dE 13.8 from the h1 blue in normal vision — below the 15
 * floor — and dE 2.7 under tritanopia, so the two tracks would be
 * effectively the same color. This step sits dE 17.1 / 12.1 away and
 * validates all-pairs against this surface. Re-run the dataviz skill's
 * validate_palette.js before changing it.
 * ------------------------------------------------------------------ */

.remark-slide-content {
  --viz-track-1: var(--accent, #3FA5E3);
  --viz-track-2: var(--accent-2, #BC2F5C);
  --viz-track-3: #1baf7a;
}

/* Inlined pathway SVGs size to the slide rather than their intrinsic pt. */
.remark-slide-content .pathway svg {
  display: block;
  width: 100%;
  height: auto;
  max-height: 480px;
  margin: 0 auto;
}
/* Portrait diagrams that sit in a half-width column (the barriers flows) get more
   vertical room, since the column is tall and the width is the tight dimension.
   The negative top margin pulls them up beside the slide's h1 — the right column
   is empty there — so they don't crowd the bottom edge. */
.remark-slide-content .pathway.tall {
  margin-top: -66px;
}
.remark-slide-content .pathway.tall svg {
  max-height: 510px;
}

/* ------------------------------------------------------------------ *
 * Pathway diagram motion.
 *
 * Everything is scoped under `.remark-visible`, which is the class remark
 * puts on the slide currently on screen. That is what makes these run on
 * slide entry rather than once at page load: remark builds every slide's
 * DOM up front, so an unscoped animation would have finished playing long
 * before you navigated to it. Scoping also restarts the build each time
 * you come back to the slide, and keeps the pulse off every other slide's
 * CPU.
 *
 * Only possible because the SVGs are inlined — an <img src="...svg">
 * would be a separate document these rules could not reach.
 * ------------------------------------------------------------------ */

@keyframes pathway-in {
  from { opacity: 0; transform: translateX(-26px); }
  to   { opacity: 1; transform: translateX(0); }
}

/* Columns enter left to right; an arrow arrives with the card it points
   at, and the legend lands once the diagram has settled. */
.remark-visible .pathway svg .col-0 { animation: pathway-in 0.45s ease-out 0.00s both; }
.remark-visible .pathway svg .col-1 { animation: pathway-in 0.45s ease-out 0.22s both; }
.remark-visible .pathway svg .col-2 { animation: pathway-in 0.45s ease-out 0.44s both; }
.remark-visible .pathway svg .legend { animation: pathway-in 0.45s ease-out 0.66s both; }

/* The pivotal course: GIS I in the current core, Spatial Data Science I in
   the proposed one. A ring behind the pill rather than the pill itself, so
   the label never moves. */
@keyframes pulse-ring {
  0%   { opacity: 0.75; transform: scale(1); }
  70%  { opacity: 0;    transform: scale(1.16); }
  100% { opacity: 0;    transform: scale(1.16); }
}

/* A slow breathing of the pill's own fill, so the eye is drawn to it in the
   gap between ring expansions rather than only when a ring is mid-flight. */
@keyframes pill-breathe {
  0%, 100% { fill-opacity: 0.13; }
  50%      { fill-opacity: 0.28; }
}

.remark-visible .pathway svg .pulse-ring {
  /* fill-box makes scale() pivot on the rect's own centre; without it the
     transform origin is the whole SVG viewport and the ring flies away. */
  transform-box: fill-box;
  transform-origin: center;
  animation: pulse-ring 1.7s ease-out 1.1s infinite;
}

/* The echo ring rides half a cycle behind the lead ring, so one wave is always
   on its way out as the next begins. Longhand delay overrides the shorthand
   above; this rule must stay after it (equal specificity, source order wins). */
.remark-visible .pathway svg .pulse-ring--echo {
  animation-delay: 1.95s;
}

.remark-visible .pathway svg .pill-fill {
  animation: pill-breathe 1.7s ease-in-out 1.1s infinite;
}

/* A single element that fades and rises into place. Used where a diagram grows
   one piece at a time across incremental slides — the newest testbed tier, and
   the "built on" chip row under the settled pipeline — rather than rebuilding
   the whole figure on every slide entry. */
@keyframes svg-enter-rise {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}
.remark-visible .pathway svg .enter-rise {
  animation: svg-enter-rise 0.5s ease-out 0.15s both;
}

/* The program-composition bar wipes open left to right, so the geospatial
   core's dominance is watched accumulating rather than presented finished.
   A clip wipe (not a scaleX) keeps the credit numbers undistorted as the edge
   passes over them. */
@keyframes bar-grow {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}
.remark-visible .pathway svg .bar-grow {
  animation: bar-grow 1.1s cubic-bezier(0.65, 0, 0.2, 1) 0.2s both;
}

/* The approval-flow gauntlet builds top to bottom, gate by gate, then the
   "revise & resubmit" feedback loops snap in last — so the friction lands after
   the audience has seen the whole forward path. */
@keyframes flow-in {
  from { opacity: 0; transform: translateY(-12px); }
  to   { opacity: 1; transform: translateY(0); }
}
.remark-visible .pathway svg .flow-0 { animation: flow-in 0.45s ease-out 0.05s both; }
.remark-visible .pathway svg .flow-1 { animation: flow-in 0.45s ease-out 0.30s both; }
.remark-visible .pathway svg .flow-2 { animation: flow-in 0.45s ease-out 0.55s both; }
.remark-visible .pathway svg .flow-3 { animation: flow-in 0.45s ease-out 0.80s both; }
.remark-visible .pathway svg .flow-4 { animation: flow-in 0.45s ease-out 1.05s both; }
.remark-visible .pathway svg .flow-loop { animation: flow-in 0.55s ease-out 1.35s both; }

@media (prefers-reduced-motion: reduce) {
  .remark-visible .pathway svg .col-0,
  .remark-visible .pathway svg .col-1,
  .remark-visible .pathway svg .col-2,
  .remark-visible .pathway svg .legend,
  .remark-visible .pathway svg .pulse-ring,
  .remark-visible .pathway svg .pill-fill,
  .remark-visible .pathway svg .enter-rise,
  .remark-visible .pathway svg .bar-grow,
  .remark-visible .pathway svg [class^="flow-"] {
    animation: none;
  }
}

/* ------------------------------------------------------------------ *
 * The local video clip.
 *
 * Sized inline to the same 625px cap the deck's img-from-source chunk
 * template uses, so it sits in the slide with the same breathing room as
 * every image slide. Not driven by an aspect-ratio box: that was built for
 * the 16:9 YouTube embed this replaced, and the downloaded clip is 4:3
 * (484x360), which letterboxed inside it.
 * ------------------------------------------------------------------ */

.remark-slide-content .slide-video {
  max-width: 100%;
  max-height: 625px;
}

/* ------------------------------------------------------------------ *
 * Course groupings on the proposed-curriculum slide.
 *
 * Blank lines between items of a single markdown list do not group them:
 * that makes the list "loose", and remark then wraps *every* item in a
 * <p>, so all items gain the same extra space and the grouping reads as
 * uniform padding instead. The groups have to be separate <ul> elements.
 *
 * Tight rows inside a group, a clear gap between groups — roughly the
 * ratio that makes three blocks legible at the back of a room.
 * ------------------------------------------------------------------ */

.remark-slide-content ul.course-group {
  margin: 0 0 0.85em 0;
  padding-left: 1.6em;
}

.remark-slide-content ul.course-group:last-of-type {
  margin-bottom: 0;
}

.remark-slide-content ul.course-group li {
  margin: 0 0 0.12em 0;
}

/* ------------------------------------------------------------------ *
 * The vocational/liberal continuum slides.
 *
 * These three slides differ only in their question, and the columns below
 * must sit at the same height on each so that advancing between them
 * changes the question and nothing else. "Where has geospatial education
 * been on this continuum?" wraps to two lines; the other two questions fit
 * on one, which floated their columns upward.
 *
 * An empty second heading does not fix this: two h1 elements stack two
 * line boxes *plus* two sets of margins, which overshoots a single
 * two-line h1. Reserving the space inside the one real heading is exact.
 *
 * line-height is pinned here so min-height is deterministic — the theme
 * leaves h1 line-height to the browser, and 2.4em is only "two lines" if
 * a line is known to be 1.2em.
 * ------------------------------------------------------------------ */

.remark-slide-content.continuum h1 {
  line-height: 1.2;
  min-height: 2.4em;
  margin-bottom: 0.4em;
}

/* ------------------------------------------------------------------ *
 * The continuum as a spectrum, not two columns.
 *
 * The three continuum slides differ only in their question and where the
 * field sits on the axis, so the axis is one shared component and each slide
 * only carries a modifier that moves the marker. The motion is the argument:
 * the field settles on the vocational (left) end, a "durable value" target
 * glows on the concept (right) end, and the AI slide sends the marker
 * travelling across to meet it.
 *
 * Everything is scoped under `.remark-visible` so it replays on slide entry
 * rather than firing once at page load (remark builds all slides up front).
 * Colours are the inverse palette's near-white on the blue inverse ground.
 * ------------------------------------------------------------------ */

.spectrum {
  width: 78%;
  margin: 1.2em auto 0;
}

.spectrum__ends {
  display: flex;
  justify-content: space-between;
  margin-bottom: 0.9em;
}

.spectrum__end {
  line-height: 1.25;
}
.spectrum__end--r {
  text-align: right;
}
.spectrum__end b {
  display: block;
  font-size: 1.7rem;
  font-weight: 700;
  color: var(--inverse-text-color, #EBF6FC);
}
.spectrum__end span {
  font-size: 1.1rem;
  opacity: 0.8;
}

/* The axis. A left-to-right gradient hints the direction of travel before the
   marker even moves; the two end caps anchor it. */
.spectrum__track {
  position: relative;
  height: 6px;
  border-radius: 3px;
  background: linear-gradient(90deg,
    rgba(235, 246, 252, 0.22), rgba(235, 246, 252, 0.55));
}
.spectrum__track::before,
.spectrum__track::after {
  content: "";
  position: absolute;
  top: 50%;
  width: 3px;
  height: 18px;
  border-radius: 2px;
  transform: translateY(-50%);
  background: rgba(235, 246, 252, 0.55);
}
.spectrum__track::before { left: 0; }
.spectrum__track::after  { right: 0; }

/* The marker — where the field actually sits. `left` defaults to --to so that
   with animation disabled (reduced motion) it still renders in its final
   place. Its label rides beneath it. */
.spectrum__marker,
.spectrum__target {
  position: absolute;
  top: 50%;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  transform: translate(-50%, -50%);
}
.spectrum__marker {
  left: var(--to, 50%);
  background: var(--inverse-text-color, #EBF6FC);
  box-shadow: 0 0 0 6px rgba(235, 246, 252, 0.18),
              0 0 16px 3px rgba(235, 246, 252, 0.55);
}
/* Marker label sits below the track, target label above it, so that when the
   marker travels to meet the target on the AI slide the two never overprint. */
.spectrum__marker span {
  position: absolute;
  top: 30px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  font-size: 1.05rem;
  font-weight: 600;
}
.spectrum__target span {
  position: absolute;
  bottom: 30px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  font-size: 1.05rem;
}

/* The target — where durable value lives. A hollow dashed ring, hidden by
   default and shown only on the closing slide that asks where value now lies. */
.spectrum__target {
  left: 82%;
  opacity: 0;
  border: 2px dashed rgba(235, 246, 252, 0.85);
}
.spectrum__target span {
  opacity: 0.85;
  font-weight: 500;
}

.spectrum__note {
  margin-top: 3.2em;
  text-align: center;
  font-size: 1.25rem;
  opacity: 0.92;
}

/* Per-slide travel. The marker interpolates `left` from --from to --to on
   entry; the AI slide is the one that crosses the axis. */
.spectrum--past    { --from: 50%; --to: 18%; }
.spectrum--problem { --from: 34%; --to: 18%; }
.spectrum--ai      { --from: 18%; --to: 82%; }

@keyframes spectrum-travel {
  from { left: var(--from, 50%); }
  to   { left: var(--to, 50%); }
}
/* The opening slide's suspense: the marker jitters nervously around the centre
   — "where HAS it been?" — with small, irregular, non-symmetric darts (paired
   with a linear timing function so each swing is an abrupt constant-velocity
   jerk, not a smooth pendulum), then at ~70% it commits and glides to the
   vocational end. Amplitude kept tight (~±2%) so it reads as a twitch, not a
   swing. The per-frame easing at 70% makes only that last leg smooth. */
@keyframes spectrum-suspense {
  0%   { left: 50%; }
  3%   { left: 48.5%; }
  7%   { left: 51.6%; }
  10%  { left: 49.3%; }
  15%  { left: 52.1%; }
  19%  { left: 48.8%; }
  23%  { left: 51%; }
  27%  { left: 47.9%; }
  32%  { left: 51.5%; }
  36%  { left: 49.1%; }
  41%  { left: 52%; }
  45%  { left: 49.5%; }
  50%  { left: 48.2%; }
  55%  { left: 51.2%; }
  60%  { left: 49%; }
  65%  { left: 50.8%; }
  70%  { left: 49.7%; animation-timing-function: cubic-bezier(0.5, 0, 0.1, 1); }
  100% { left: 18%; }
}
/* The AI-world slide: the same small nervous wavering, but instead of committing
   it slowly *creeps* toward the concept-based (liberal) end — the drift is
   gradual (linear) so it reads as a tendency, not a decision. */
@keyframes spectrum-drift {
  0%   { left: 50%; }
  3%   { left: 49%; }
  7%   { left: 51.5%; }
  10%  { left: 49.1%; }
  15%  { left: 52%; }
  19%  { left: 48.9%; }
  23%  { left: 51%; }
  27%  { left: 48.2%; }
  32%  { left: 51.3%; }
  36%  { left: 49.3%; }
  41%  { left: 50.6%; }
  46%  { left: 49.5%; }
  52%  { left: 50.2%; animation-timing-function: linear; }
  100% { left: var(--to, 82%); }
}
@keyframes spectrum-appear {
  from { opacity: 0; transform: translate(-50%, -50%) scale(0.6); }
  to   { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
@keyframes spectrum-rise {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Opening slide — jitter violently, then settle on the vocational end. Linear
   timing makes each swing an abrupt jerk; the final glide re-eases via the 70%
   keyframe's own timing function. */
.remark-visible .spectrum--past .spectrum__marker {
  animation: spectrum-suspense 6.8s linear 0.4s both;
}
/* "Why is this problematic?" — no motion at all; the marker just rests where
   the opening slide left it (left: var(--to) = the vocational end). */
/* AI-world slide — jitter violently, then creep toward the concept-based end. */
.remark-visible .spectrum--ai .spectrum__marker {
  animation: spectrum-drift 8.5s linear 0.4s both;
}
.remark-visible .spectrum__note {
  animation: spectrum-rise 0.6s ease-out 1.3s both;
}
/* Hold the opening slide's caption back until the marker has committed, so the
   "rooted in tools and skills" answer doesn't spoil the suspense. */
.remark-visible .spectrum--past .spectrum__note {
  animation-delay: 5.4s;
}

@media (prefers-reduced-motion: reduce) {
  .remark-visible .spectrum__marker,
  .remark-visible .spectrum__target,
  .remark-visible .spectrum__note {
    animation: none;
  }
}

/* ------------------------------------------------------------------ *
 * Filmstrip stepper for the traditional core-concept slides.
 *
 * Five image slides that otherwise only differ by one more bullet read as
 * static; a progress rail at the foot of each gives the run a spine, showing
 * how far through the five "things graduates can do" the section has gone.
 * Each slide carries a --N modifier; the rail fills to that step, and the
 * newest segment wipes in left to right on entry.
 * ------------------------------------------------------------------ */

.stepper {
  position: absolute;
  bottom: 30px;
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
  gap: 12px;
}
.stepper .step {
  width: 52px;
  height: 6px;
  border-radius: 3px;
  background: var(--border, #C9CDD2);
  opacity: 0.4;
  transform-origin: left center;
}
.stepper--1 .step:nth-child(-n+1),
.stepper--2 .step:nth-child(-n+2),
.stepper--3 .step:nth-child(-n+3),
.stepper--4 .step:nth-child(-n+4),
.stepper--5 .step:nth-child(-n+5) {
  background: var(--accent, #3FA5E3);
  opacity: 1;
}

@keyframes step-fill {
  from { transform: scaleX(0); opacity: 0; }
  to   { transform: scaleX(1); opacity: 1; }
}
/* Only the step this slide just reached animates; the earlier ones are already
   filled from the previous slide, so replaying them would read as a reset. */
.remark-visible .stepper--1 .step:nth-child(1),
.remark-visible .stepper--2 .step:nth-child(2),
.remark-visible .stepper--3 .step:nth-child(3),
.remark-visible .stepper--4 .step:nth-child(4),
.remark-visible .stepper--5 .step:nth-child(5) {
  animation: step-fill 0.5s ease-out 0.15s both;
}
@media (prefers-reduced-motion: reduce) {
  .remark-visible .stepper .step { animation: none; }
}

/* ------------------------------------------------------------------ *
 * Highlighted core concepts + the dual-image reveal.
 *
 * The follow-up "traditional core concepts" slide highlights the concepts that
 * automation makes trivial and brings up a second image (the red-exclamation
 * broken-links panel) beside the first. `.hl` is a highlighter-pen band; the
 * new image fades up so it reads as arriving on the increment.
 * ------------------------------------------------------------------ */

.remark-slide-content .hl {
  background: linear-gradient(transparent 12%,
    rgba(255, 210, 92, 0.6) 12%, rgba(255, 210, 92, 0.6) 92%, transparent 92%);
  padding: 0 0.12em;
  font-weight: 600;
  border-radius: 2px;
}

.dual-img {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 26px;
}
.dual-img img {
  max-height: 480px;
  max-width: 48%;
  width: auto;
  height: auto;
  object-fit: contain;
}

@keyframes img-appear {
  from { opacity: 0; transform: translateY(14px) scale(0.96); }
  to   { opacity: 1; transform: none; }
}
.remark-visible .img-appear {
  animation: img-appear 0.6s ease-out 0.2s both;
}
@media (prefers-reduced-motion: reduce) {
  .remark-visible .img-appear { animation: none; }
}

/* ------------------------------------------------------------------ *
 * Long code excerpts scroll instead of running off the slide.
 *
 * Same intent as the `.pre` rule in ../style/xaringan/split.css, but
 * applied to the <pre> elements directly. The split.css version needs a
 * wrapper with class="pre", and wrapping a fenced code block in a raw
 * HTML div breaks the fence — the blank line required after <div> ends
 * the HTML block, so the code parses as prose (and MathJax eats the
 * underscores). Styling <pre> avoids the wrapper entirely.
 *
 * overflow-y: auto, not scroll, so short blocks show no scrollbar.
 * ------------------------------------------------------------------ */

.remark-slide-content pre {
  /* Sized from the real box, not by eye: the slide content area measures 681px
     with 16px bottom padding, and a code block starts 94px down (kicker + h1 +
     h3). 681 - 94 - 16 = 571, so 565 fills the column to the bottom edge with a
     hair to spare. The old 20px bottom margin pushed the slide to 710px and
     overflowed it. */
  max-height: 565px;
  overflow-y: auto;
  margin-bottom: 0;
}

/* ------------------------------------------------------------------ *
 * Code in a split column: sized to the column, not shrunk by default.
 *
 * This rule arrived with title.css copied from the r-and-r-infra deck, where
 * it pinned 0.78rem because those Terraform excerpts ran 53 characters and
 * overran the column. This deck has no such block — the widest code line is
 * `  variables = c(medinc = "B19013_001"),` at 39 characters — so the
 * inherited value was shrinking legible code for no reason.
 *
 * 1.05rem is the ceiling, not a guess: the `.pull-right` column measures
 * 509px and a monospace glyph is about 0.6em, so 39 x 0.6 x 21px = 491px,
 * which fills the column without a horizontal scrollbar. Re-derive this if a
 * longer line is ever added to a split-column chunk.
 * ------------------------------------------------------------------ */

.remark-slide-content .pull-right > pre,
.remark-slide-content .pull-right > pre .remark-code {
  font-size: 1.05rem;
}

/* ------------------------------------------------------------------ *
 * .large on a code block is not "+10%": the theme's `.large pre, .large
 * code` rule rebases the code font off body text rather than off
 * --code-font-size, so a fenced block jumps to roughly double. That
 * overflows the split column both ways for the Terraform tree listings
 * (the 9-file infra tree clipped `caller_identity.tf` horizontally and
 * ran past the pre max-height vertically).
 *
 * Pin a size that still reads clearly larger than the main.tf excerpts
 * but fits the column, and drop the max-height since these listings are
 * short enough not to need scrolling.
 * ------------------------------------------------------------------ */

.remark-slide-content .large pre,
.remark-slide-content .large .remark-code {
  font-size: 30px;
  line-height: 1.4;
}

.remark-slide-content .large pre {
  max-height: none;
  overflow-y: visible;
}

/* ------------------------------------------------------------------ *
 * Reference list: hanging indent, so the author name starts each entry
 * flush left and continuation lines tuck under it. Sized to fit the
 * full bibliography on a single slide.
 * ------------------------------------------------------------------ */

.remark-slide-content .refs {
  display: block;
  font-size: 12.5px;
  line-height: 1.25;
}

.remark-slide-content .refs p {
  padding-left: 1.6em;
  text-indent: -1.6em;
  margin: 0 0 0.34em 0;
}

/* DOIs read as quiet trailing metadata, not as pills. */
.remark-slide-content .refs .doi {
  color: var(--muted, #6b7280);
  font-family: var(--mono-font, monospace);
  font-size: 0.88em;
}

/* Legacy expertise: start on slide entry and restart on revisiting.
   Keep selectors and keyframes isolated from the other inline SVGs. */
.expertise-gate .token, .expertise-gate .punchline, .expertise-gate .recognition { opacity: 0; }
.expertise-gate text { font-family: Montserrat, Helvetica, Arial, sans-serif; fill: #292B2E; }
.expertise-gate .token text { font-size: 23px; font-weight: 600; text-anchor: middle; }
.expertise-gate .token rect { rx: 12; stroke-width: 2; }
.expertise-gate .token rect { fill: #FFF3CD; stroke: #D4A528; }
.expertise-gate .left { transform-origin: 180px 300px; }
.expertise-gate .right { transform-origin: 380px 300px; }
.expertise-gate { overflow: hidden; }
.expertise-gate .token text { font-size: 21px; }
.expertise-gate .static-summary { opacity: 0; }
.remark-visible .expertise-gate .leaf { animation: expertise-gate 40s linear infinite; }
.remark-visible .expertise-gate .esri { animation: expertise-esri 40s linear infinite; }
.remark-visible .expertise-gate .arcgis { animation: expertise-arcgis 40s linear infinite; }
.remark-visible .expertise-gate .geopandas { animation: expertise-geopandas 40s linear infinite; }
.remark-visible .expertise-gate .online { animation: expertise-online 40s linear infinite; }
.remark-visible .expertise-gate .r { animation: expertise-r 40s linear infinite; }
.remark-visible .expertise-gate .aws { animation: expertise-aws 40s linear infinite; }
.remark-visible .expertise-gate .postgresql { animation: expertise-postgresql 40s linear infinite; }
.remark-visible .expertise-gate .errors { animation: expertise-errors 40s linear infinite; }
.remark-visible .expertise-gate .postgis { animation: expertise-postgis 40s linear infinite; }
.remark-visible .expertise-gate .arcpy { animation: expertise-arcpy 40s linear infinite; }
.remark-visible .expertise-gate .punchline { animation: expertise-punchline 40s linear infinite; }
.remark-visible .expertise-gate .recognition { animation: expertise-recognition 40s linear infinite; }
@keyframes expertise-esri {
  0.0000% { opacity: 0; transform: translate(-390px, 0px); }
  0.2500% { opacity: 1; transform: translate(-390px, 0px); }
  5.0000% { opacity: 1; transform: translate(0px, 0px); }
  7.5000% { opacity: 1; transform: translate(0px, -265px); }
  8.2500% { opacity: 0; transform: translate(0px, -285px); }
  60.0000% { opacity: 0; transform: translate(390px, 0px); }
  87.5000% { opacity: 0; transform: translate(390px, 0px); }
  100% { opacity: 0; transform: translate(390px, 0px); }
}
@keyframes expertise-arcgis {
  0.0000% { opacity: 0; transform: translate(-390px, 0px); }
  4.7500% { opacity: 1; transform: translate(-390px, 0px); }
  9.5000% { opacity: 1; transform: translate(0px, 0px); }
  12.0000% { opacity: 1; transform: translate(0px, -265px); }
  12.7500% { opacity: 0; transform: translate(0px, -285px); }
  60.0000% { opacity: 0; transform: translate(390px, 0px); }
  87.5000% { opacity: 0; transform: translate(390px, 0px); }
  100% { opacity: 0; transform: translate(390px, 0px); }
}
@keyframes expertise-geopandas {
  0.0000% { opacity: 0; transform: translate(-390px, 0px); }
  9.2500% { opacity: 1; transform: translate(-390px, 0px); }
  14.0000% { opacity: 1; transform: translate(0px, 0px); }
  14.6249% { opacity: 1; transform: translate(0px, -25px); }
  15.2500% { opacity: 1; transform: translate(45px, 0px); }
  18.7500% { opacity: 1; transform: translate(390px, 0px); }
  19.0000% { opacity: 0; transform: translate(410px, 0px); }
  60.0000% { opacity: 0; transform: translate(390px, 0px); }
  87.5000% { opacity: 0; transform: translate(390px, 0px); }
  100% { opacity: 0; transform: translate(390px, 0px); }
}
@keyframes expertise-online {
  0.0000% { opacity: 0; transform: translate(-390px, 0px); }
  13.7500% { opacity: 1; transform: translate(-390px, 0px); }
  18.5000% { opacity: 1; transform: translate(0px, 0px); }
  21.0000% { opacity: 1; transform: translate(0px, -265px); }
  21.7500% { opacity: 0; transform: translate(0px, -285px); }
  60.0000% { opacity: 0; transform: translate(390px, 0px); }
  87.5000% { opacity: 0; transform: translate(390px, 0px); }
  100% { opacity: 0; transform: translate(390px, 0px); }
}
@keyframes expertise-r {
  0.0000% { opacity: 0; transform: translate(-390px, 0px); }
  18.2500% { opacity: 1; transform: translate(-390px, 0px); }
  23.0000% { opacity: 1; transform: translate(0px, 0px); }
  23.6250% { opacity: 1; transform: translate(0px, -25px); }
  24.2500% { opacity: 1; transform: translate(45px, 0px); }
  27.7500% { opacity: 1; transform: translate(390px, 0px); }
  28.0000% { opacity: 0; transform: translate(410px, 0px); }
  60.0000% { opacity: 0; transform: translate(390px, 0px); }
  87.5000% { opacity: 0; transform: translate(390px, 0px); }
  100% { opacity: 0; transform: translate(390px, 0px); }
}
@keyframes expertise-aws {
  0.0000% { opacity: 0; transform: translate(-390px, 0px); }
  22.7500% { opacity: 1; transform: translate(-390px, 0px); }
  27.5000% { opacity: 1; transform: translate(0px, 0px); }
  28.1250% { opacity: 1; transform: translate(0px, -25px); }
  28.7500% { opacity: 1; transform: translate(45px, 0px); }
  32.2500% { opacity: 1; transform: translate(390px, 0px); }
  32.5000% { opacity: 0; transform: translate(410px, 0px); }
  60.0000% { opacity: 0; transform: translate(390px, 0px); }
  87.5000% { opacity: 0; transform: translate(390px, 0px); }
  100% { opacity: 0; transform: translate(390px, 0px); }
}
@keyframes expertise-postgresql {
  0.0000% { opacity: 0; transform: translate(-390px, 0px); }
  27.2500% { opacity: 1; transform: translate(-390px, 0px); }
  32.0000% { opacity: 1; transform: translate(0px, 0px); }
  32.6250% { opacity: 1; transform: translate(0px, -25px); }
  33.2500% { opacity: 1; transform: translate(45px, 0px); }
  36.7500% { opacity: 1; transform: translate(390px, 0px); }
  37.0000% { opacity: 0; transform: translate(410px, 0px); }
  60.0000% { opacity: 0; transform: translate(390px, 0px); }
  87.5000% { opacity: 0; transform: translate(390px, 0px); }
  100% { opacity: 0; transform: translate(390px, 0px); }
}
@keyframes expertise-errors {
  0.0000% { opacity: 0; transform: translate(-390px, 0px); }
  31.7500% { opacity: 1; transform: translate(-390px, 0px); }
  36.5000% { opacity: 1; transform: translate(0px, 0px); }
  39.0000% { opacity: 1; transform: translate(0px, -265px); }
  39.7500% { opacity: 0; transform: translate(0px, -285px); }
  60.0000% { opacity: 0; transform: translate(390px, 0px); }
  87.5000% { opacity: 0; transform: translate(390px, 0px); }
  100% { opacity: 0; transform: translate(390px, 0px); }
}
@keyframes expertise-postgis {
  0.0000% { opacity: 0; transform: translate(-390px, 0px); }
  36.2500% { opacity: 1; transform: translate(-390px, 0px); }
  41.0000% { opacity: 1; transform: translate(0px, 0px); }
  43.1250% { opacity: 1; transform: translate(0px, -265px); }
  43.8750% { opacity: 1; transform: translate(0px, -265px); }
  45.5000% { opacity: 1; transform: translate(0px, 0px); }
  49.0000% { opacity: 1; transform: translate(390px, 0px); }
  49.2500% { opacity: 0; transform: translate(410px, 0px); }
  60.0000% { opacity: 0; transform: translate(390px, 0px); }
  87.5000% { opacity: 0; transform: translate(390px, 0px); }
  100% { opacity: 0; transform: translate(390px, 0px); }
}
@keyframes expertise-arcpy {
  0.0000% { opacity: 0; transform: translate(-390px, 0px); }
  44.7500% { opacity: 1; transform: translate(-390px, 0px); }
  49.5000% { opacity: 1; transform: translate(0px, 0px); }
  50.2500% { opacity: 1; transform: translate(0px, -25px); }
  51.5000% { opacity: 1; transform: translate(95px, 0px); }
  52.6249% { opacity: 1; transform: translate(95px, 0px); }
  53.7500% { opacity: 1; transform: translate(0px, 0px); }
  56.0000% { opacity: 1; transform: translate(0px, -265px); }
  58.0000% { opacity: 1; transform: translate(0px, -265px); }
  58.7500% { opacity: 0; transform: translate(0px, -285px); }
  60.0000% { opacity: 0; transform: translate(390px, 0px); }
  87.5000% { opacity: 0; transform: translate(390px, 0px); }
  100% { opacity: 0; transform: translate(390px, 0px); }
}
@keyframes expertise-gate {
  0.0000% { transform: scaleX(1); }
  4.3750% { transform: scaleX(1); }
  5.0000% { transform: scaleX(0.08); }
  7.5000% { transform: scaleX(0.08); }
  8.1251% { transform: scaleX(1); }
  8.8750% { transform: scaleX(1); }
  9.5000% { transform: scaleX(0.08); }
  12.0000% { transform: scaleX(0.08); }
  12.6250% { transform: scaleX(1); }
  17.8750% { transform: scaleX(1); }
  18.5000% { transform: scaleX(0.08); }
  21.0000% { transform: scaleX(0.08); }
  21.6250% { transform: scaleX(1); }
  35.8750% { transform: scaleX(1); }
  36.5000% { transform: scaleX(0.08); }
  39.0000% { transform: scaleX(0.08); }
  39.6251% { transform: scaleX(1); }
  40.3750% { transform: scaleX(1); }
  41.0000% { transform: scaleX(0.08); }
  45.6250% { transform: scaleX(0.08); }
  46.2500% { transform: scaleX(1); }
  53.1250% { transform: scaleX(1); }
  53.7500% { transform: scaleX(0.08); }
  57.0000% { transform: scaleX(0.08); }
  57.6251% { transform: scaleX(1); }
  59.3751% { transform: scaleX(1); }
  60.0000% { transform: scaleX(0.08); }
  62.5000% { transform: scaleX(0.08); }
  63.1249% { transform: scaleX(1); }
  76.8751% { transform: scaleX(1); }
  77.5000% { transform: scaleX(0.08); }
  81.0000% { transform: scaleX(0.08); }
  81.6250% { transform: scaleX(1); }
  87.5000% { transform: scaleX(1); }
  100% { transform: scaleX(1); }
}
@keyframes expertise-punchline {
  0.0000% { opacity: 0; }
  45.0000% { opacity: 0; }
  45.5000% { opacity: 1; }
  48.2500% { opacity: 1; }
  49.0000% { opacity: 0; }
  60.0000% { opacity: 0; }
  87.5000% { opacity: 0; }
  100% { opacity: 0; }
}
@keyframes expertise-recognition {
  0.0000% { opacity: 0; }
  56.0000% { opacity: 0; }
  56.3749% { opacity: 1; }
  59.0000% { opacity: 1; }
  60.0000% { opacity: 0; }
  87.5000% { opacity: 0; }
  100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .remark-visible .expertise-gate .token,
  .remark-visible .expertise-gate .leaf,
  .remark-visible .expertise-gate .punchline,
  .remark-visible .expertise-gate .recognition,
  .remark-visible .expertise-gate .arcpy rect { animation: none; }
  .expertise-gate .static-summary { opacity: 1; }
  .expertise-gate .esri { opacity: 1; transform: translate(-95px, -295px); }
  .expertise-gate .arcgis { opacity: 1; transform: translate(95px, -295px); }
  .expertise-gate .online { opacity: 1; transform: translate(-95px, -235px); }
  .expertise-gate .errors { opacity: 1; transform: translate(95px, -235px); }
  .expertise-gate .geopandas { opacity: 1; transform: translate(-95px, 0px); }
  .expertise-gate .r { opacity: 1; transform: translate(95px, 0px); }
  .expertise-gate .aws { opacity: 1; transform: translate(-95px, 60px); }
  .expertise-gate .postgresql { opacity: 1; transform: translate(95px, 60px); }
}

/* Final arrivals: StoryMaps, SAM3, then Excel. */
.expertise-gate .sam-caption, .expertise-gate .excel-caption { opacity: 0; }
.remark-visible .expertise-gate .storymaps { animation: expertise-storymaps 40s linear infinite; }
.remark-visible .expertise-gate .sam3 { animation: expertise-sam3 40s linear infinite; }
.remark-visible .expertise-gate .excel { animation: expertise-excel 40s linear infinite; }
.remark-visible .expertise-gate .sam-caption { animation: expertise-sam-caption 40s linear infinite; }
.remark-visible .expertise-gate .excel-caption { animation: expertise-excel-caption 40s linear infinite; }
@keyframes expertise-storymaps {
  0.0000% { opacity: 0; transform: translate(-390px, 0px); }
  55.2500% { opacity: 1; transform: translate(-390px, 0px); }
  60.0000% { opacity: 1; transform: translate(0px, 0px); }
  62.5000% { opacity: 1; transform: translate(0px, -265px); }
  63.2500% { opacity: 0; transform: translate(0px, -285px); }
  87.5000% { opacity: 0; transform: translate(390px, 0px); }
  100% { opacity: 0; transform: translate(390px, 0px); }
}
@keyframes expertise-maplibre {
  0.0000% { opacity: 0; transform: translate(-390px, 0px); }
  60.2500% { opacity: 1; transform: translate(-390px, 0px); }
  65.0000% { opacity: 1; transform: translate(0px, 0px); }
  65.6250% { opacity: 1; transform: translate(0px, -25px); }
  66.2500% { opacity: 1; transform: translate(45px, 0px); }
  69.7500% { opacity: 1; transform: translate(390px, 0px); }
  70.0000% { opacity: 0; transform: translate(410px, 0px); }
  87.5000% { opacity: 0; transform: translate(390px, 0px); }
  100% { opacity: 0; transform: translate(390px, 0px); }
}
@keyframes expertise-excel {
  0.0000% { opacity: 0; transform: translate(-390px, 0px); }
  71.2500% { opacity: 1; transform: translate(-390px, 0px); }
  76.0000% { opacity: 1; transform: translate(0px, 0px); }
  77.5000% { opacity: 1; transform: translate(0px, 0px); }
  80.0000% { opacity: 1; transform: translate(0px, -265px); }
  82.5000% { opacity: 1; transform: translate(0px, -265px); }
  83.2500% { opacity: 0; transform: translate(0px, -285px); }
  87.5000% { opacity: 0; transform: translate(390px, 0px); }
  100% { opacity: 0; transform: translate(390px, 0px); }
}
@keyframes expertise-maplibre-caption {
  0.0000% { opacity: 0; }
  65.2500% { opacity: 0; }
  65.7500% { opacity: 1; }
  69.2500% { opacity: 1; }
  70.0000% { opacity: 0; }
  87.5000% { opacity: 0; }
  100% { opacity: 0; }
}
@keyframes expertise-excel-caption {
  0.0000% { opacity: 0; }
  76.2500% { opacity: 0; }
  76.7500% { opacity: 1; }
  83.5000% { opacity: 1; }
  85.0000% { opacity: 0; }
  87.5000% { opacity: 0; }
  100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .remark-visible .expertise-gate .storymaps,
  .remark-visible .expertise-gate .sam3,
  .remark-visible .expertise-gate .excel,
  .remark-visible .expertise-gate .sam-caption,
  .remark-visible .expertise-gate .excel-caption { animation: none; }
}

.expertise-gate .maplibre-caption { opacity: 0; }
.remark-visible .expertise-gate .maplibre { animation: expertise-maplibre 40s linear infinite; }
.remark-visible .expertise-gate .maplibre-caption { animation: expertise-maplibre-caption 40s linear infinite; }
@keyframes expertise-sam3 {
  0.0000% { opacity: 0; transform: translate(-390px, 0px); }
  65.7500% { opacity: 1; transform: translate(-390px, 0px); }
  70.5000% { opacity: 1; transform: translate(0px, 0px); }
  71.1250% { opacity: 1; transform: translate(0px, -25px); }
  71.7500% { opacity: 1; transform: translate(45px, 0px); }
  75.2500% { opacity: 1; transform: translate(390px, 0px); }
  75.5000% { opacity: 0; transform: translate(410px, 0px); }
  87.5000% { opacity: 0; transform: translate(410px, 0px); }
  100% { opacity: 0; transform: translate(410px, 0px); }
}
@keyframes expertise-sam-caption {
  0.0000% { opacity: 0; }
  70.7500% { opacity: 0; }
  71.2500% { opacity: 1; }
  74.7500% { opacity: 1; }
  75.5000% { opacity: 0; }
  87.5000% { opacity: 0; }
  100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .remark-visible .expertise-gate .maplibre,
  .remark-visible .expertise-gate .maplibre-caption { animation: none; }
}

/* Arrivals are undecided (yellow); color follows the gate decision. */
.remark-visible .expertise-gate .esri rect { animation: expertise-esri-color 40s linear infinite; }
@keyframes expertise-esri-color {
  0.0000% { fill: #FFF3CD; stroke: #D4A528; }
  6.7000% { fill: #FFF3CD; stroke: #D4A528; }
  7.0000% { fill: #EAF5FC; stroke: #3FA5E3; }
  87.5000% { fill: #EAF5FC; stroke: #3FA5E3; }
  100% { fill: #EAF5FC; stroke: #3FA5E3; }
}
.remark-visible .expertise-gate .arcgis rect { animation: expertise-arcgis-color 40s linear infinite; }
@keyframes expertise-arcgis-color {
  0.0000% { fill: #FFF3CD; stroke: #D4A528; }
  11.2000% { fill: #FFF3CD; stroke: #D4A528; }
  11.5000% { fill: #EAF5FC; stroke: #3FA5E3; }
  87.5000% { fill: #EAF5FC; stroke: #3FA5E3; }
  100% { fill: #EAF5FC; stroke: #3FA5E3; }
}
.remark-visible .expertise-gate .geopandas rect { animation: expertise-geopandas-color 40s linear infinite; }
@keyframes expertise-geopandas-color {
  0.0000% { fill: #FFF3CD; stroke: #D4A528; }
  14.3250% { fill: #FFF3CD; stroke: #D4A528; }
  14.6250% { fill: #F9EAF0; stroke: #BC2F5C; }
  87.5000% { fill: #F9EAF0; stroke: #BC2F5C; }
  100% { fill: #F9EAF0; stroke: #BC2F5C; }
}
.remark-visible .expertise-gate .online rect { animation: expertise-online-color 40s linear infinite; }
@keyframes expertise-online-color {
  0.0000% { fill: #FFF3CD; stroke: #D4A528; }
  20.2000% { fill: #FFF3CD; stroke: #D4A528; }
  20.5000% { fill: #EAF5FC; stroke: #3FA5E3; }
  87.5000% { fill: #EAF5FC; stroke: #3FA5E3; }
  100% { fill: #EAF5FC; stroke: #3FA5E3; }
}
.remark-visible .expertise-gate .r rect { animation: expertise-r-color 40s linear infinite; }
@keyframes expertise-r-color {
  0.0000% { fill: #FFF3CD; stroke: #D4A528; }
  23.3250% { fill: #FFF3CD; stroke: #D4A528; }
  23.6250% { fill: #F9EAF0; stroke: #BC2F5C; }
  87.5000% { fill: #F9EAF0; stroke: #BC2F5C; }
  100% { fill: #F9EAF0; stroke: #BC2F5C; }
}
.remark-visible .expertise-gate .aws rect { animation: expertise-aws-color 40s linear infinite; }
@keyframes expertise-aws-color {
  0.0000% { fill: #FFF3CD; stroke: #D4A528; }
  27.8250% { fill: #FFF3CD; stroke: #D4A528; }
  28.1250% { fill: #F9EAF0; stroke: #BC2F5C; }
  87.5000% { fill: #F9EAF0; stroke: #BC2F5C; }
  100% { fill: #F9EAF0; stroke: #BC2F5C; }
}
.remark-visible .expertise-gate .postgresql rect { animation: expertise-postgresql-color 40s linear infinite; }
@keyframes expertise-postgresql-color {
  0.0000% { fill: #FFF3CD; stroke: #D4A528; }
  32.3250% { fill: #FFF3CD; stroke: #D4A528; }
  32.6250% { fill: #F9EAF0; stroke: #BC2F5C; }
  87.5000% { fill: #F9EAF0; stroke: #BC2F5C; }
  100% { fill: #F9EAF0; stroke: #BC2F5C; }
}
.remark-visible .expertise-gate .errors rect { animation: expertise-errors-color 40s linear infinite; }
@keyframes expertise-errors-color {
  0.0000% { fill: #FFF3CD; stroke: #D4A528; }
  38.2000% { fill: #FFF3CD; stroke: #D4A528; }
  38.5000% { fill: #EAF5FC; stroke: #3FA5E3; }
  87.5000% { fill: #EAF5FC; stroke: #3FA5E3; }
  100% { fill: #EAF5FC; stroke: #3FA5E3; }
}
.remark-visible .expertise-gate .postgis rect { animation: expertise-postgis-color 40s linear infinite; }
@keyframes expertise-postgis-color {
  0.0000% { fill: #FFF3CD; stroke: #D4A528; }
  42.5750% { fill: #FFF3CD; stroke: #D4A528; }
  42.8750% { fill: #EAF5FC; stroke: #3FA5E3; }
  43.8250% { fill: #EAF5FC; stroke: #3FA5E3; }
  44.1250% { fill: #F9EAF0; stroke: #BC2F5C; }
  87.5000% { fill: #F9EAF0; stroke: #BC2F5C; }
  100% { fill: #F9EAF0; stroke: #BC2F5C; }
}
.remark-visible .expertise-gate .arcpy rect { animation: expertise-arcpy-color 40s linear infinite; }
@keyframes expertise-arcpy-color {
  0.0000% { fill: #FFF3CD; stroke: #D4A528; }
  49.9500% { fill: #FFF3CD; stroke: #D4A528; }
  50.2500% { fill: #F9EAF0; stroke: #BC2F5C; }
  55.2000% { fill: #F9EAF0; stroke: #BC2F5C; }
  55.5000% { fill: #EAF5FC; stroke: #3FA5E3; }
  87.5000% { fill: #EAF5FC; stroke: #3FA5E3; }
  100% { fill: #EAF5FC; stroke: #3FA5E3; }
}
.remark-visible .expertise-gate .storymaps rect { animation: expertise-storymaps-color 40s linear infinite; }
@keyframes expertise-storymaps-color {
  0.0000% { fill: #FFF3CD; stroke: #D4A528; }
  61.7000% { fill: #FFF3CD; stroke: #D4A528; }
  62.0000% { fill: #EAF5FC; stroke: #3FA5E3; }
  87.5000% { fill: #EAF5FC; stroke: #3FA5E3; }
  100% { fill: #EAF5FC; stroke: #3FA5E3; }
}
.remark-visible .expertise-gate .sam3 rect { animation: expertise-sam3-color 40s linear infinite; }
@keyframes expertise-maplibre-color {
  0.0000% { fill: #FFF3CD; stroke: #D4A528; }
  65.3250% { fill: #FFF3CD; stroke: #D4A528; }
  65.6250% { fill: #F9EAF0; stroke: #BC2F5C; }
  87.5000% { fill: #F9EAF0; stroke: #BC2F5C; }
  100% { fill: #F9EAF0; stroke: #BC2F5C; }
}
.remark-visible .expertise-gate .maplibre rect { animation: expertise-maplibre-color 40s linear infinite; }
@keyframes expertise-sam3-color {
  0.0000% { fill: #FFF3CD; stroke: #D4A528; }
  70.8250% { fill: #FFF3CD; stroke: #D4A528; }
  71.1250% { fill: #F9EAF0; stroke: #BC2F5C; }
  87.5000% { fill: #F9EAF0; stroke: #BC2F5C; }
  100% { fill: #F9EAF0; stroke: #BC2F5C; }
}
.remark-visible .expertise-gate .excel rect { animation: expertise-excel-color 40s linear infinite; }
@keyframes expertise-excel-color {
  0.0000% { fill: #FFF3CD; stroke: #D4A528; }
  79.2000% { fill: #FFF3CD; stroke: #D4A528; }
  79.5000% { fill: #EAF5FC; stroke: #3FA5E3; }
  87.5000% { fill: #EAF5FC; stroke: #3FA5E3; }
  100% { fill: #EAF5FC; stroke: #3FA5E3; }
}
@media (prefers-reduced-motion: reduce) {
  .remark-visible .expertise-gate .token rect { animation: none; }
  .expertise-gate .accepted rect { fill: #EAF5FC; stroke: #3FA5E3; }
  .expertise-gate .blocked rect { fill: #F9EAF0; stroke: #BC2F5C; }
}

/* Terraform is the final arrival: the gate fails instead of deciding. */
.expertise-gate .gate-error { opacity: 0; }
.expertise-gate .gate-error text { fill: #BC2F5C; font-family: monospace; font-size: 17px; }
.expertise-gate .left-failure { transform-origin: 180px 383px; }
.expertise-gate .right-failure { transform-origin: 380px 383px; }
.remark-visible .expertise-gate .terraform { animation: expertise-terraform 40s linear infinite; }
.remark-visible .expertise-gate .gate-error { animation: expertise-gate-error 40s linear infinite; }
.remark-visible .expertise-gate .left-failure { animation: expertise-left-failure 40s linear infinite; }
.remark-visible .expertise-gate .right-failure { animation: expertise-right-failure 40s linear infinite; }
@keyframes expertise-terraform {
  0.0000% { opacity: 0; transform: translate(-390px, 0px); }
  80.2500% { opacity: 1; transform: translate(-390px, 0px); }
  85.0000% { opacity: 1; transform: translate(0px, 0px); }
  85.7500% { opacity: 1; transform: translate(0px, -25px); }
  86.5000% { opacity: 1; transform: translate(0px, 0px); }
  98.5000% { opacity: 1; transform: translate(0px, 0px); }
  99.5000% { opacity: 0; transform: translate(0px, 0px); }
  100.0000% { opacity: 0; transform: translate(0px, 0px); }
}
@keyframes expertise-left-failure {
  0.0000% { transform: none; opacity: 1; }
  85.7500% { transform: none; opacity: 1; }
  86.0000% { transform: translateX(-5px); }
  86.2500% { transform: translateX(5px); }
  86.5000% { transform: translateX(-5px); }
  86.7500% { transform: none; }
  88.0000% { transform: translateY(85px) rotate(-72deg); opacity: .4; }
  98.7500% { transform: translateY(85px) rotate(-72deg); opacity: .4; }
  99.5000% { transform: translateY(85px) rotate(-72deg); opacity: 0; }
  100.0000% { transform: none; opacity: 0; }
}
@keyframes expertise-right-failure {
  0.0000% { transform: none; opacity: 1; }
  85.7500% { transform: none; opacity: 1; }
  86.0000% { transform: translateX(5px); }
  86.2500% { transform: translateX(-5px); }
  86.5000% { transform: translateX(5px); }
  86.7500% { transform: none; }
  88.0000% { transform: translateY(85px) rotate(72deg); opacity: .4; }
  98.7500% { transform: translateY(85px) rotate(72deg); opacity: .4; }
  99.5000% { transform: translateY(85px) rotate(72deg); opacity: 0; }
  100.0000% { transform: none; opacity: 0; }
}
@keyframes expertise-gate-error {
  0.0000% { opacity: 0; }
  86.7500% { opacity: 0; }
  87.5000% { opacity: 1; }
  98.5000% { opacity: 1; }
  99.5000% { opacity: 0; }
  100.0000% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .remark-visible .expertise-gate .terraform,
  .remark-visible .expertise-gate .gate-error,
  .remark-visible .expertise-gate .left-failure,
  .remark-visible .expertise-gate .right-failure { animation: none; }
}

/* The queue remains masked, but crash output spills beyond the diagram. */
.expertise-gate { overflow: visible; }
.expertise-gate .gate-error text { font-size: 17px; }
.remark-visible .expertise-gate .trace-scroll {
  animation: expertise-trace-scroll 40s linear infinite;
}
@keyframes expertise-trace-scroll {
  0%, 87.5% { transform: translateY(0); }
  98.5%, 100% { transform: translateY(-1104px); }
}
@media (prefers-reduced-motion: reduce) {
  .remark-visible .expertise-gate .trace-scroll { animation: none; }
}

/* Hide the entire gate when the traceback takes over. */
.remark-visible .expertise-gate .gate-structure {
  animation: expertise-gate-disappear 40s linear infinite;
}
@keyframes expertise-gate-disappear {
  0%, 86.75% { opacity: 1; }
  87.5%, 100% { opacity: 0; }
}
@media (prefers-reduced-motion: reduce) {
  .remark-visible .expertise-gate .gate-structure { animation: none; }
}

/* Two simple feedback tracks, with visible dashes reversing direction. */
.remark-visible .pathway .approval-track {
  animation: approval-dashes 2s linear 1.9s infinite alternate;
}
.remark-visible .pathway .approval-return {
  animation: approval-return-head 4s steps(1, end) 1.9s infinite;
}
.remark-visible .pathway .approval-send {
  animation: approval-send-head 4s steps(1, end) 1.9s infinite;
}
@keyframes approval-dashes {
  from { stroke-dashoffset: 0; stroke: #BC2F5C; }
  to { stroke-dashoffset: -78; stroke: #3FA5E3; }
}
@keyframes approval-return-head {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}
@keyframes approval-send-head {
  0%, 100% { opacity: 0; }
  50% { opacity: 1; }
}
@media (prefers-reduced-motion: reduce) {
  .remark-visible .pathway .approval-track,
  .remark-visible .pathway .approval-head { animation: none; }
}

/* Question-led overview: use the active xaringan palette and card component. */
.remark-slide-content.questions-overview { padding-top: 48px; }
.questions-overview .kicker { color: var(--inverse-text-color); opacity: .8; }
.remark-slide-content.questions-overview h1 {
  font-size: 46px;
  line-height: 1.15;
  margin-bottom: 40px;
}
.overview-questions { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 22px; }
.questions-overview .overview-question {
  --question-accent: var(--accent, var(--header-color));
  text-align: center;
  position: relative;
  height: 330px;
  margin: 0;
  padding: 28px 24px;
  color: var(--text-color);
  background: var(--background-color);
  border-top: 5px solid var(--question-accent);
  overflow: hidden;
}
.questions-overview .overview-friction { --question-accent: var(--accent-2, #BC2F5C); }
.questions-overview .overview-possibility { --question-accent: var(--accent-3, #4FB99A); }
.overview-number { font-family: var(--mono); font-size: 14px; letter-spacing: .07em; color: var(--muted, var(--text-color)); }
.remark-slide-content.questions-overview .overview-question h2 {
  color: var(--text-color);
  font-size: 38px;
  line-height: 1.15;
  margin: 30px 0 28px;
}
.questions-overview .overview-question p {
  position: absolute;
  bottom: 22px;
  left: 24px;
  right: 24px;
  margin: 0;
  font-size: 20px;
  line-height: 1.4;
  color: var(--text-color);
}
.overview-spectrum { width: 100%; height: 4px; margin-top: 43px; position: relative; background: linear-gradient(90deg, var(--accent, #3FA5E3), var(--accent-2, #BC2F5C)); }
.overview-spectrum span { position: absolute; top: -5px; left: 58%; width: 14px; height: 14px; border-radius: 50%; background: var(--text-color); }
.overview-gate { display: flex; gap: 19px; align-items: center; width: 72%; height: 35px; border-block: 3px solid var(--question-accent); margin-top: 30px; }
.overview-gate span { height: 49px; width: 3px; background: var(--question-accent); }
.overview-build { display: flex; gap: 8px; height: 54px; align-items: flex-end; }
.overview-build span { width: 49px; height: 20px; background: var(--question-accent); transform-origin: bottom; }
.overview-build span:nth-child(2) { height: 36px; }
.overview-build span:nth-child(3) { height: 54px; }
.remark-visible .overview-question { animation: overview-question-in .65s ease-out both; }
.remark-visible .overview-friction { animation-delay: .3s; }
.remark-visible .overview-possibility { animation-delay: .6s; }
.remark-visible .overview-spectrum span { animation: overview-question-seek 1.8s ease-in-out .5s both; }
.remark-visible .overview-build span { animation: overview-question-build .8s ease-out 1.1s both; }
.remark-visible .overview-build span:nth-child(2) { animation-delay: 1.25s; }
.remark-visible .overview-build span:nth-child(3) { animation-delay: 1.4s; }
@keyframes overview-question-in { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes overview-question-seek { from { left: 5%; } to { left: 58%; } }
@keyframes overview-question-build { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@media (prefers-reduced-motion: reduce) {
  .remark-visible .overview-question,
  .remark-visible .overview-spectrum span,
  .remark-visible .overview-build span { animation: none; }
}

/* Debate slides: style the existing lists without altering remark increments. */
.remark-slide-content.debate-cards {
  --debate-accent: var(--accent, var(--header-color));
  padding-top: 42px;
}
.remark-slide-content.debate-liberal { --debate-accent: var(--accent-2, #BC2F5C); }
.debate-cards > ul:first-of-type {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 22px;
  padding: 0;
  margin: 30px 0 0;
  list-style: none;
  counter-reset: debate-point;
}
.debate-cards > ul:first-of-type > li {
  position: relative;
  box-sizing: border-box;
  min-height: 260px;
  margin: 0;
  padding: 66px 24px 24px;
  background: var(--surface-2, #F2EEE2);
  border: 1px solid var(--border, #DED9C9);
  border-top: 5px solid var(--debate-accent);
  border-radius: var(--radius, 12px);
  font-size: 25px;
  line-height: 1.4;
}
.debate-cards > ul:first-of-type > li:nth-child(-n+3)::before {
  counter-increment: debate-point;
  content: '0' counter(debate-point);
  position: absolute;
  top: 20px;
  left: 24px;
  font-family: var(--mono);
  font-size: 17px;
  color: var(--debate-accent);
}
.debate-cards li p { margin: 0; }
.debate-cards > ul + ul { list-style: none; padding: 0; margin: 22px 0 0; }
.debate-cards > ul:first-of-type > li:nth-child(n+4),
.debate-cards > ul + ul > li {
  grid-column: 1 / -1;
  min-height: 0;
  margin: 0;
  padding: 20px 26px;
  border: 1px solid var(--border, #DED9C9);
  border-left: 5px solid var(--debate-accent);
  border-radius: var(--radius, 12px);
  background: color-mix(in srgb, var(--debate-accent) 8%, var(--background-color));
  font-size: 24px;
  line-height: 1.4;
}
.remark-visible .debate-cards > ul:first-of-type > li { animation: overview-question-in .6s ease-out both; }
.remark-visible .debate-cards > ul:first-of-type > li:nth-child(2) { animation-delay: .12s; }
.remark-visible .debate-cards > ul:first-of-type > li:nth-child(3) { animation-delay: .24s; }
/* Once tension is revealed, already-visible cards stay still. */
.remark-visible .debate-cards:has(ul > li:nth-child(4)) > ul:first-of-type > li:nth-child(-n+3),
.remark-visible .debate-cards:has(ul + ul) > ul:first-of-type > li { animation: none; }
.remark-visible .debate-cards > ul + ul > li,
.remark-visible .debate-cards > ul:first-of-type > li:nth-child(n+4) { animation: overview-question-in .5s ease-out both; }
@media (prefers-reduced-motion: reduce) {
  .remark-visible .debate-cards > ul > li { animation: none !important; }
}

/* Center the overview illustrations along with their card text. */
.questions-overview .overview-gate { margin-left: auto; margin-right: auto; justify-content: center; }
.questions-overview .overview-build { justify-content: center; }

/* Continuum sequence: fixed panels and track keep each slide visually aligned.
   All labels and question text remain in the original Rmd. */
.remark-slide-content.continuum { padding-top: 40px; }
.remark-slide-content.continuum h1 {
  font-size: 48px;
  line-height: 1.18;
  min-height: 2.36em;
  max-width: 980px;
  margin: 0 auto 34px;
}
.continuum .spectrum { width: 86%; margin: 0 auto; }
.continuum .spectrum__ends { gap: 100px; margin-bottom: 52px; }
.continuum .spectrum__end {
  width: 38%;
  box-sizing: border-box;
  padding: 24px 28px;
  text-align: center;
  border: 1px solid color-mix(in srgb, var(--inverse-text-color) 22%, transparent);
  border-top: 5px solid var(--accent, #3FA5E3);
  border-radius: var(--radius, 12px);
  background: color-mix(in srgb, var(--inverse-text-color) 7%, transparent);
}
.continuum .spectrum__end--r { border-top-color: var(--accent-2, #BC2F5C); }
.continuum .spectrum__end b {
  font-family: var(--header-font-family), var(--header-font-family-fallback);
  font-size: 38px;
  margin-bottom: 8px;
}
.continuum .spectrum__end span { font-size: 24px; }
.continuum .spectrum__track {
  height: 8px;
  background: linear-gradient(90deg, var(--accent, #3FA5E3), var(--accent-2, #BC2F5C));
}
.continuum .spectrum__track::before,
.continuum .spectrum__track::after { height: 24px; width: 3px; background: var(--inverse-text-color); opacity: .6; }
.continuum .spectrum__marker {
  width: 32px; height: 32px;
  box-shadow: 0 0 0 7px color-mix(in srgb, var(--inverse-text-color) 15%, transparent);
  z-index: 2;
}
.continuum .spectrum__marker span {
  top: 49px;
  padding: 10px 18px;
  border-radius: var(--radius, 12px);
  border: 1px solid color-mix(in srgb, var(--inverse-text-color) 25%, transparent);
  background: color-mix(in srgb, var(--inverse-text-color) 10%, transparent);
  font-size: 23px;
  color: var(--inverse-text-color);
}
.continuum .spectrum__marker span::before {
  content: ''; position: absolute; width: 2px; height: 18px;
  left: 50%; top: -19px;
  background: color-mix(in srgb, var(--inverse-text-color) 45%, transparent);
}
.remark-visible .spectrum--problem .spectrum__end:first-child {
  animation: continuum-concern 2.5s ease-in-out .2s 2;
}
@keyframes continuum-concern {
  0%,100% { box-shadow: 0 0 0 0 transparent; }
  50% { box-shadow: 0 0 0 8px color-mix(in srgb, var(--accent-2, #BC2F5C) 28%, transparent); }
}
.spectrum__origin {
  position: absolute; left: 18%; top: 50%; transform: translate(-50%, -50%);
  width: 32px; height: 32px; box-sizing: border-box;
  border: 2px dashed var(--inverse-text-color); border-radius: 50%; opacity: .45;
}
.spectrum__trail {
  position: absolute; left: 18%; width: 64%; top: 0; height: 8px;
  border-radius: 4px; background: var(--inverse-text-color); opacity: .8;
}
/* Animate native properties with identical timing for a continuous marker/trail. */
.remark-visible .spectrum--ai .spectrum__marker {
  animation: continuum-shift 5.8s linear .4s both;
}
.remark-visible .spectrum--ai .spectrum__trail {
  left: 18%; width: 64%; transform-origin: left center;
  animation: continuum-trail 5.8s linear .4s both;
}
/* Keep the opening hold; ease left and then sweep right without another stop. */
@keyframes continuum-shift {
  0%,15.517% {
    left: 18%;
    animation-timing-function: cubic-bezier(.45, 0, .55, 1);
  }
  36% {
    left: 11%;
    animation-timing-function: cubic-bezier(.4, 0, .2, 1);
  }
  100% { left: 82%; }
}
@keyframes continuum-trail {
  0%,15.517% {
    transform: scaleX(0);
    animation-timing-function: cubic-bezier(.45, 0, .55, 1);
  }
  36% {
    transform: scaleX(-.109375);
    animation-timing-function: cubic-bezier(.4, 0, .2, 1);
  }
  100% { transform: scaleX(1); }
}
/* The following question carries a small, wordless echo of the continuum. */
.continuum-bridge::before {
  content: ''; display: block; width: 260px; height: 6px;
  border-radius: 3px; margin: 0 auto 40px;
  background: linear-gradient(90deg, var(--accent, #3FA5E3), var(--accent-2, #BC2F5C));
}
.remark-visible .continuum-bridge::before { animation: continuum-bridge-in .8s ease-out both; }
@keyframes continuum-bridge-in { from { opacity: 0; transform: scaleX(.3); } to { opacity: 1; transform: scaleX(1); } }
@media (prefers-reduced-motion: reduce) {
  .remark-visible .spectrum--problem .spectrum__end:first-child,
  .remark-visible .spectrum--ai .spectrum__marker,
  .remark-visible .spectrum--ai .spectrum__trail,
  .remark-visible .continuum-bridge::before { animation: none; }
}
.continuum-bridge::before {
  position: absolute;
  top: 28%;
  left: calc(50% - 130px);
  margin: 0;
}
@media (prefers-reduced-motion: reduce) {
  .remark-visible .spectrum--past .spectrum__marker { animation: none; }
}

/* Traditional core concepts: reviewed tool-palette treatment. */
.remark-slide-content.core-palette { padding-top: 36px; }
.core-palette h1 { margin-bottom: 28px; }
.concept-layout { display: grid; grid-template-columns: 56% 40%; gap: 4%; align-items: start; }
.core-palette .concept-palette { list-style: none; padding: 0; margin: 0; display: grid; gap: 8px; }
.core-palette .concept-row {
  display: flex; align-items: center; gap: 18px; min-height: 62px; box-sizing: border-box;
  padding: 9px 16px; border: 1px solid var(--border, #DED9C9);
  border-radius: var(--radius, 12px); background: var(--surface-2, #F2EEE2);
  font-size: 22px; line-height: 1.2; margin: 0; position: relative;
}
.concept-icon { display: grid; place-items: center; width: 42px; height: 42px; flex-shrink: 0; color: var(--accent, #3FA5E3); }
.concept-icon svg { width: 32px; height: 32px; stroke: currentColor; stroke-width: 1.8; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.concept-label { position: relative; }
.concept-figure { margin: 0; height: 412px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border-radius: var(--radius, 12px); border: 1px solid var(--border, #DED9C9); background: var(--background-color); padding: 12px; overflow: hidden; }
.concept-figure img { max-width: 100%; max-height: 100%; object-fit: contain; }
.core-palette .highlighted { border-left: 5px solid var(--accent-2, #BC2F5C); padding-left: 12px; }
.highlighted .concept-label { background: linear-gradient(transparent 14%, rgba(255,210,92,.6) 14%, rgba(255,210,92,.6) 94%,transparent 94%); background-size: 100% 100%; background-repeat: no-repeat; font-weight: 600; }
.error-row .concept-icon { color: var(--accent-2, #BC2F5C); }
.remark-visible .core-palette:not(.core-palette-followup) .concept-row { animation: palette-enter .5s ease-out both; animation-delay: calc(var(--row) * .1s); }
.remark-visible .core-palette-followup .highlighted .concept-label { animation: palette-highlight .6s ease-out .15s both; }
.remark-visible .core-palette-followup .concept-figure { animation: palette-enter .55s ease-out both; }
@keyframes palette-enter { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
@keyframes palette-highlight { from { background-size: 0% 100%; } to { background-size: 100% 100%; } }
@media(prefers-reduced-motion:reduce) { .remark-visible .core-palette .concept-row, .remark-visible .core-palette .concept-label, .remark-visible .core-palette .concept-icon, .remark-visible .core-palette .concept-figure { animation: none !important; } }

/* Threshold concepts keep their existing reveal sequence and live examples. */
.remark-slide-content.threshold-palette { padding-top: 36px; }
.threshold-palette h1 { margin-bottom: 28px; }
.threshold-palette .concept-palette { list-style: none; padding: 0; margin: 0; display: grid; gap: 16px; }
.threshold-palette .concept-row {
  display: flex; align-items: flex-start; gap: 12px;
  box-sizing: border-box; padding: 20px 16px; margin: 0;
  border: 1px solid var(--border, #DED9C9);
  border-left: 5px solid transparent;
  border-radius: var(--radius, 12px);
  background: var(--surface-2, #F2EEE2);
  font-size: 23px; line-height: 1.4;
}
.threshold-palette .concept-current { border-left-color: var(--accent-2, #BC2F5C); }
.threshold-palette .concept-icon { width: 34px; height: 34px; color: var(--accent-2, #BC2F5C); }
.threshold-palette .concept-label strong { display: block; margin-bottom: 6px; }
.remark-visible .threshold-palette .concept-current { animation: palette-enter .55s ease-out both; }
.remark-visible .threshold-palette :is(.pull-right-40, .pull-right-60) { animation: palette-enter .55s ease-out .12s both; }
/* The code example stays legible at its existing size, inside a quiet frame. */
.remark-slide-content.threshold-palette :is(.pull-right-40, .pull-right-60) > pre {
  box-sizing: border-box; margin-top: 0; max-height: 420px;
  padding: 16px 20px; border: 1px solid var(--border, #DED9C9);
  border-radius: var(--radius, 12px);
}
.threshold-palette :is(.pull-right-40, .pull-right-60) .maplibregl-map { border-radius: var(--radius, 12px); }
/* Pin the maplibre attribution to a small size — it can render oversized once
   the map loads on the served build, inheriting the slide's large base font. */
.threshold-palette .maplibregl-ctrl-attrib,
.threshold-palette .maplibregl-ctrl-attrib a { font-size: 11px !important; line-height: 1.5 !important; }
.threshold-palette :is(.pull-right-40, .pull-right-60) > p { margin: 8px 0; }
.threshold-palette :is(.pull-right-40, .pull-right-60) .small { font-size: 15px; }
.threshold-palette :is(.pull-right-40, .pull-right-60) .center > div {
  box-sizing: border-box; height: 412px; max-height: 412px !important;
  border: 1px solid var(--border, #DED9C9); border-radius: var(--radius, 12px);
  padding: 12px; display: flex; align-items: center; justify-content: center;
}
.threshold-palette :is(.pull-right-40, .pull-right-60) img { max-height: 386px !important; object-fit: contain; }
@media (prefers-reduced-motion: reduce) {
  .remark-visible .threshold-palette .concept-current,
  .remark-visible .threshold-palette :is(.pull-right-40, .pull-right-60) { animation: none; }
}
/* Keep all three accumulated concepts within the notebook slide. */
.threshold-palette .concept-palette { gap: 12px; }
.threshold-palette .concept-row { padding: 14px 12px; gap: 10px; font-size: 20px; line-height: 1.35; }
.threshold-palette .concept-icon { width: 30px; height: 30px; }
.threshold-palette .concept-icon svg { width: 28px; height: 28px; }
.threshold-palette .concept-label strong { font-size: 22px; margin-bottom: 4px; }

/* Start each example below the kicker, level with the left heading. */
.threshold-palette :is(.pull-right-40, .pull-right-60) {
  box-sizing: border-box; padding-top: 78px;
}
/* The globe already has space around the sphere inside its map canvas. */
.threshold-palette.threshold-step-2 .pull-right-40 { padding-top: 30px; }
.threshold-palette .pull-left-60 h1 { margin-top: 0; }
.threshold-palette .pull-left-60 .concept-row { padding: 18px; font-size: 23px; }
.threshold-palette .pull-left-60 .concept-label strong { font-size: 25px; }
.threshold-step-3 .pull-right-40 .center > div {
  height: 510px;
  max-height: 510px !important;
  padding: 8px;
}
.threshold-step-3 .pull-right-40 img { max-height: 492px !important; }
.remark-slide-content.threshold-palette .pull-right-60 > pre,
.remark-slide-content.threshold-palette .pull-right-60 > pre .remark-code { font-size: 1.05rem; }

/* Barrier sequence gives the diagrams the larger, 60% column. */
.remark-slide-content.barrier-split { padding-top: 36px; }
.barrier-split .pull-left-40 h1 { margin-top: 0; margin-bottom: 34px; }
.remark-slide-content.barrier-split .pathway.tall { margin-top: 0; }
.remark-slide-content.barrier-split .pathway.tall svg { max-height: 575px; }

/* Consistent 60/40 columns for traditional concepts and the API example. */
.remark-slide-content.core-palette .pull-left-60 h1 {
  font-size: 46px;
  line-height: 1.15;
  margin-top: 0;
  margin-bottom: 26px;
}
.core-palette .pull-right-40 .concept-figure { margin-top: 78px; height: 464px; }
.remark-slide-content.threshold-step-1 .pull-right-40 > pre {
  padding: 12px;
  max-height: 510px;
}
.remark-slide-content.threshold-step-1 .pull-right-40 > pre,
.remark-slide-content.threshold-step-1 .pull-right-40 > pre .remark-code {
  font-size: 16px;
  line-height: 1.45;
}

.barrier-split .barrier-card {
  display: flex; align-items: center; gap: 16px;
  box-sizing: border-box; min-height: 105px; padding: 20px 18px;
  margin: 0 0 16px; border-left: 5px solid transparent;
}
.barrier-split .barrier-card h2 {
  font-family: inherit; font-size: 27px; font-weight: 700;
  color: var(--text-color); line-height: 1.3; margin: 0; padding: 0;
}
.barrier-split .barrier-card .concept-icon { width: 34px; color: var(--accent-2, #BC2F5C); }
.barrier-split .barrier-current { border-left-color: var(--accent-2, #BC2F5C); }
.remark-visible .barrier-split .barrier-current { animation: palette-enter .55s ease-out both; }
@media (prefers-reduced-motion: reduce) {
  .remark-visible .barrier-split .barrier-current { animation: none; }
}

/* Inactive accent strips remain visible against the light card surface. */
.core-palette .concept-row:not(.highlighted),
.threshold-palette .concept-row:not(.concept-current),
.barrier-split .barrier-card:not(.barrier-current) {
  border-left: 5px solid var(--title-slide-background-color, #292B2E);
}
/* Match highlighted row padding so changing state does not move the label. */
.core-palette .concept-row:not(.highlighted) { padding-left: 12px; }

/* Testbed: course transformation, followed by a stable expanding pipeline. */
.remark-slide-content.testbed-slide { padding-top: 42px; }
.testbed-slide .course-card {
  border: 1px solid var(--border, #DED9C9);
  border-left: 6px solid var(--accent-2, #BC2F5C);
  border-radius: var(--radius, 12px);
  background: var(--surface-2, #F2EEE2);
  padding: 18px 26px;
  margin: 18px 0;
  min-height: 84px;
  box-sizing: border-box;
  display: flex; align-items: center;
}
.testbed-slide .course-card h2 {
  display: flex; align-items: center; gap: 30px; font-size: 35px;
  margin: 0; padding: 0; color: var(--text-color); line-height: 1.2;
}
.course-old { position: relative; white-space: nowrap; flex-shrink: 0; }
del.course-old { text-decoration: none; opacity: .55; }
del.course-old::after {
  content: ''; position: absolute; left: -3px; right: -3px; top: 46%; height: 3px;
  background: var(--accent-2, #BC2F5C); transform-origin: left;
}
.course-new { color: var(--accent-2, #BC2F5C); }
.remark-visible .testbed-rename .course-old::after { animation: course-strike .5s ease-out .2s both; }
.remark-visible .testbed-rename .course-new { animation: palette-enter .65s ease-out .65s both; }
.testbed-description {
  display: block; font-size: 22px; line-height: 1.45;
  border-left: 4px solid var(--accent, #3FA5E3);
  padding: 10px 20px; margin: 12px 0 0;
}
.remark-visible .testbed-intro .testbed-description { animation: palette-enter .6s ease-out both; }
.testbed-pipeline .pathway { margin-top: 4px; }
.testbed-pipeline .pathway svg { max-height: 340px; }
.pipeline-packet { opacity: 0; }
.remark-visible .pipeline-packet { animation: pipeline-packet-travel 3.6s linear 1.2s infinite; }
.remark-visible .pipeline-packet.packet-1 { animation-delay: 2.4s; }
@keyframes pipeline-packet-travel {
  0% { opacity: 0; transform: translateX(0); }
  8% { opacity: 1; }
  28% { opacity: 1; transform: translateX(28px); }
  32%,100% { opacity: 0; transform: translateX(28px); }
}
@keyframes course-strike { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@media (prefers-reduced-motion: reduce) {
  .remark-visible .testbed-rename .course-old::after,
  .remark-visible .testbed-rename .course-new,
  .remark-visible .testbed-intro .testbed-description,
  .remark-visible .pipeline-packet { animation: none; }
}

/* Opening and closing details remain readable when the deck is scaled. */
.globe-title .title-eyebrow { font-size: 16px; margin-bottom: 26px; }
.globe-title .title-topics span, .globe-title .closing-links a { font-size: 20px; }
.globe-title .closing-links { justify-content: flex-start; letter-spacing: normal; gap: 12px; }

/* The discussion keeps remark's incremental list, presented as numbered cards. */
.remark-slide-content.discussion-cards { padding-top: 34px; }
.discussion-cards h1 { margin: 0 0 24px; }
.discussion-cards > ul {
  display: grid; grid-template-columns: 1fr 1fr; gap: 18px;
  list-style: none; padding: 0; margin: 0; counter-reset: question;
}
.discussion-cards > ul > li {
  position: relative; box-sizing: border-box; min-height: 126px;
  padding: 24px 24px 24px 70px; margin: 0;
  border: 1px solid color-mix(in srgb, var(--inverse-text-color) 22%, transparent);
  border-left: 4px solid var(--accent); border-radius: 12px;
  background: color-mix(in srgb, var(--title-slide-background-color) 94%, var(--inverse-text-color));
  font-size: 25px; line-height: 1.35;
}
.discussion-cards > ul > li::before {
  counter-increment: question; content: '0' counter(question);
  position: absolute; left: 20px; top: 26px; font-size: 18px;
  color: var(--accent); font-family: var(--mono);
}
.discussion-cards > ul > li:last-child:nth-child(5) { grid-column: 1 / -1; }
.discussion-cards li p { margin: 0; }
/* Tier 1's full-width final card holds one line; trim its vertical padding. */
.discussion-tier-1 > ul > li:last-child { min-height: 0; padding-top: 20px; padding-bottom: 20px; }

/* Match the presentation's scaled geometry on compact/touch displays. */
@media (max-width: 700px), (max-height: 500px) and (pointer: coarse) {
  .slide-net { width: 40%; height: 40%; opacity: .14; }
  .remark-slide-content.inverse .slide-net { opacity: .6; }
  .globe-title .title-globe { opacity: .65; }
}
