@import url("../../_ds/fonts.css");
@import url("../../_ds/theme.css");
@import url("../../_shared/chrome.css");
@import url("../../_shared/components.css");

/* ──────────────────────────────────────────────────────────
   /products/monitor — Pages change. You don't.

   CEO architecture primitive: "Monitor (future): Track
   recurring changes and deliver fresh data."

   Warm-dark canvas (same as Extract / API / Scraping
   Browser).  No light theme — the page lives on the unified
   coder-spoke surface.  Brand accent: purple-7 on the
   editorial mark, with the same wire-bus + drag mechanics
   Extract uses for its hero.
─────────────────────────────────────────────────────────── */


main {
  position: relative;
  z-index: 1;
}

/* Cursor portal scope — only interactive in-page widgets get
   the spinning O.  Back-to-top is the only entry here; the
   scroll-driven mo-track + mo-surfaces-canvas stages are
   aria-hidden visuals with no hover state and no click, so
   the native cursor stays visible over them. */
.back-to-top {
  cursor: pointer;
}

/* ──────────────────────────────────────────────────────────
   Act 1 — Hero
─────────────────────────────────────────────────────────── */

[data-act="1"] {
  position: relative;
  min-height: 100svh;
  min-height: 100vh;
  padding: clamp(96px, 12vh, 140px) clamp(20px, 4vw, 48px) clamp(56px, 8vh, 96px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: var(--background);
  z-index: 1;
}

.am-hero {
  display: flex;
  flex-direction: column;
  /* Left-align the editorial column.  Breaks rhythm with the
     other spoke heroes (all centred) and lets the H1 + sub
     stack feel like the start of a paragraph rather than a
     billboard.  Demo blocks below keep their own centring. */
  align-items: flex-start;
  gap: clamp(48px, 7vh, 80px);
  width: 100%;
  max-width: 1180px;
  margin: 0 auto;
}

.am-hero-text {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  text-align: left;
  /* Container caps line length up to wide-desktop tiers where
     it expands so the H1 doesn't wrap past two lines and the
     sub-paragraph doesn't stack into 3-4 lines at 1920+. */
  max-width: 820px;
  min-width: 0;
}

.am-hero-h1 {
  margin: 0;
  font-family: var(--font-display, "Rawest", system-ui, sans-serif);
  /* Smaller than the other heroes — left-aligned editorial
     tone, not a billboard.  Caps lower so the H1 reads like a
     headline, not a banner. */
  font-size: clamp(40px, 5.2vw, 72px);
  line-height: 1.02;
  letter-spacing: var(--tracking-dense, -0.022em);
  font-weight: 500;
  color: var(--text-primary);
  text-wrap: balance;
}

.am-hero-line { display: block; }

.am-hero-mark {
  font-style: normal;
  color: #7C4FE8;
  white-space: nowrap;
}

.am-hero-sub {
  margin: clamp(20px, 2.4vh, 32px) 0 0;
  max-width: 580px;
  font-family: var(--font-base);
  font-size: var(--mkt-body);
  line-height: 1.55;
  color: var(--text-secondary);
}

/* ── Demo row — Form left, Delivery right on desktop ──── */

.am-hero-demo {
  position: relative;
  display: flex;
  flex-direction: row;
  align-items: stretch;
  justify-content: center;
  gap: clamp(60px, 7vw, 120px);
  width: 100%;
  max-width: 1080px;
  min-width: 0;
}

.am-demo-form,
.am-demo-delivery {
  flex: 1 1 0;
  min-width: 0;
  position: relative;
  background: var(--background);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-display, 20px);
  box-shadow: 0 28px 64px -20px rgba(0, 0, 0, 0.55);
  overflow: hidden;
  cursor: grab;
  transition: box-shadow 240ms cubic-bezier(0.22, 1, 0.36, 1);
  z-index: 2;
}

.am-demo-form.is-dragging,
.am-demo-delivery.is-dragging {
  cursor: grabbing;
  box-shadow: 0 44px 90px -16px rgba(0, 0, 0, 0.7);
}

.am-demo-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 11px 16px;
  background: transparent;
  border-bottom: 1px solid var(--border-subtle);
  font-family: var(--font-code, monospace);
  font-size: 11px;
  letter-spacing: 0.02em;
}

.am-demo-dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--zen-gray-5);
  flex-shrink: 0;
}

.am-demo-bar-name {
  margin-left: 8px;
  color: var(--text-secondary);
  font-weight: 500;
}

.am-demo-bar--delivery .am-demo-bar-name {
  margin-left: 0;
  color: var(--text-primary);
  font-weight: 500;
}

.am-demo-bar-status {
  margin-left: auto;
  padding: 2px 8px;
  border-radius: var(--radius-full, 999px);
  background: rgba(120, 200, 140, 0.14);
  color: var(--zen-green-6, #6FDB97);
  font-weight: 500;
  letter-spacing: 0.05em;
  font-size: 10px;
  text-transform: uppercase;
}

/* Form body */

.am-demo-form-body {
  padding: clamp(18px, 2vh, 24px) clamp(18px, 1.8vw, 22px);
  display: flex;
  flex-direction: column;
  gap: clamp(10px, 1.2vh, 14px);
}

.am-demo-field { position: relative; }

.am-demo-field-row {
  display: inline-flex;
  align-items: baseline;
  gap: 10px;
  padding: 5px 10px;
  border-radius: 6px;
  background: transparent;
  border: 1px solid var(--border-subtle);
  font-family: var(--font-code, monospace);
  font-size: var(--mkt-body-xs);
  transition:
    border-color 240ms cubic-bezier(0.22, 1, 0.36, 1),
    background 240ms cubic-bezier(0.22, 1, 0.36, 1),
    box-shadow 240ms cubic-bezier(0.22, 1, 0.36, 1);
}

.am-demo-field[data-pulsing="true"] .am-demo-field-row {
  border-color: rgba(124, 79, 232, 0.5);
  background: rgba(124, 79, 232, 0.08);
  box-shadow: 0 0 0 4px rgba(124, 79, 232, 0.10);
}

.am-demo-field-tag {
  color: var(--text-quaternary);
  font-weight: 500;
}

.am-demo-field-value {
  color: var(--text-primary);
  letter-spacing: -0.005em;
}

/* Delivery body — stylised CSV preview rows. */

.am-demo-delivery-body {
  padding: clamp(14px, 1.6vh, 18px) clamp(14px, 1.4vw, 18px);
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.am-demo-csv-row {
  display: grid;
  grid-template-columns: minmax(0, 1.2fr) minmax(0, 2fr) minmax(0, 1.4fr) minmax(0, 1.2fr);
  column-gap: 10px;
  padding: 8px 10px;
  border-radius: 6px;
  font-family: var(--font-code, monospace);
  font-size: clamp(10px, 0.78vw, 12px);
  line-height: 1.4;
  color: var(--text-secondary);
}

.am-demo-csv-row--head {
  background: transparent;
  border: 1px solid var(--border-subtle);
  color: var(--text-tertiary);
  font-weight: 500;
  letter-spacing: 0.02em;
}

.am-demo-csv-row--ghost { opacity: 0.55; }

.am-demo-csv-cell {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.am-demo-csv-cell[data-pulsing="true"] {
  background: rgba(124, 79, 232, 0.18);
  color: var(--text-primary);
  border-radius: 3px;
  padding: 0 4px;
  margin: 0 -4px;
}

/* Wire bus */

.am-demo-wires {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible;
  z-index: 4;
}

.am-demo-wire {
  fill: none;
  stroke: url(#am-wire-grad);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-dasharray: var(--wire-len, 400);
  stroke-dashoffset: var(--wire-len, 400);
  transition: stroke-dashoffset 900ms cubic-bezier(0.22, 1, 0.36, 1),
              opacity 240ms ease;
  opacity: 0.85;
}

.am-demo-wire[data-drawn="true"] { stroke-dashoffset: 0; }

.am-demo-wire[data-pulsing="true"] {
  opacity: 1;
  stroke-width: 2;
}

.am-demo-wire-dot {
  fill: #7C4FE8;
  opacity: 0;
  transition: opacity 320ms ease 600ms;
}

.am-demo-wire-dot[data-visible="true"] { opacity: 1; }

/* ── Mobile responsive ──────────────────────────────────── */

@media (max-width: 1023px) {
  [data-act="1"] {
    padding: clamp(80px, 11vh, 120px) clamp(18px, 5vw, 32px) clamp(48px, 8vh, 80px);
  }
  .am-hero { gap: clamp(40px, 6vh, 64px); }
  /* On phone / narrow tablet: two panels stacked vertically.
     Drop the wires (touch + scroll fight + the SVG measured
     positions don't recompute reliably on every viewport
     reflow), drop drag (touch conflicts with native scroll),
     drop the pulse cycle (cycling row highlights without
     visible wires reads as noise).  Just two static cards. */
  .am-hero-demo {
    flex-direction: column;
    align-items: stretch;
    gap: clamp(28px, 4vh, 40px);
    max-width: 480px;
    margin: 0 auto;
  }
  .am-demo-form,
  .am-demo-delivery {
    cursor: default;
    /* Stacked column: size each panel to its content. The base
       `flex: 1 1 0` + overflow:hidden collapses them to ~0 (just the
       border) in an auto-height column, since overflow:hidden zeroes the
       flex auto-minimum. flex:none restores intrinsic height. */
    flex: 0 0 auto;
  }
  .am-demo-form.is-dragging,
  .am-demo-delivery.is-dragging {
    cursor: default;
    box-shadow: 0 28px 64px -20px rgba(0, 0, 0, 0.55);
  }
  .am-demo-wires { display: none; }
  .am-demo-field[data-pulsing="true"] .am-demo-field-row {
    border-color: var(--border-subtle);
    background: transparent;
    box-shadow: none;
  }
  .am-demo-csv-cell[data-pulsing="true"] {
    background: transparent;
    color: var(--text-secondary);
    padding: 0;
    margin: 0;
  }
}

@media (max-width: 600px) {
  .am-hero-h1 {
    font-size: clamp(40px, 11vw, 60px);
    line-height: 1.02;
  }
  .am-hero-sub { font-size: 16px; }
  .am-demo-form-body { padding: 16px; }
  .am-demo-delivery-body { padding: 14px; }
  .am-demo-csv-row {
    grid-template-columns: 1fr;
    row-gap: 2px;
  }
}

@media (max-width: 380px) {
  .am-hero-h1 { font-size: 38px; }
}

/* ── Wide-desktop tiers ─────────────────────────────────── */

@media (min-width: 1600px) {
  .am-hero { max-width: 1380px; }
  .am-hero-text { max-width: 1040px; }
  .am-hero-h1 { font-size: 80px; }
  .am-hero-sub { max-width: 660px; font-size: 18px; }
  .am-hero-demo { max-width: 1200px; }
}

@media (min-width: 1920px) {
  .am-hero { max-width: 1520px; }
  .am-hero-text { max-width: 1180px; }
  .am-hero-h1 { font-size: 88px; }
  .am-hero-sub { max-width: 720px; font-size: 19px; }
  .am-hero-demo { max-width: 1320px; }
}

@media (min-width: 2400px) {
  .am-hero { max-width: 1700px; }
  .am-hero-text { max-width: 1320px; }
  .am-hero-h1 { font-size: 100px; }
  .am-hero-sub { max-width: 800px; font-size: 20px; }
  .am-hero-demo { max-width: 1480px; }
}

/* ──────────────────────────────────────────────────────────
   Act 2 — Spec writes itself

   One scroll-driven mechanic.  Stage is 4 beats tall; inside,
   a sticky frame holds the yaml on the left and a live pane on
   the right.  `--beat` is set by monitor.js as a float 0..4 on
   the stage; yaml lines fade in as --beat crosses their index,
   and the live pane swaps in the consequence card for the
   current beat.

   Surface tokens only.  Brand accents (#7C4FE8 purple-7,
   #7ADAE6 teal-5) inherited from Act 1, no new colours.
─────────────────────────────────────────────────────────── */

[data-act="2"] {
  position: relative;
  z-index: 1;
  background: var(--background);
}

.mo-spec-stage {
  position: relative;
  min-height: 480vh;
  --beat: 0;
}

.mo-spec-frame {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(40px, 6vh, 72px);
  padding: clamp(96px, 12vh, 140px) clamp(20px, 4vw, 48px) clamp(56px, 8vh, 96px);
  max-width: 1240px;
  margin: 0 auto;
  width: 100%;
  min-width: 0;
  /* Exit choreography: as --exit ramps 0→1 (last ~12% of the
     stage's sticky range), the frame blurs, fades and scales
     down so Act 3 (z-index 2, solid bg, margin-top: -100vh)
     mounts cleanly over a softened Act 2.  Same pattern as the
     /api hero → Act 2 handoff. */
  filter: blur(calc(var(--exit, 0) * 14px));
  opacity: calc(1 - var(--exit, 0) * 0.35);
  transform: scale(calc(1 - var(--exit, 0) * 0.04));
  transform-origin: center top;
  transition:
    filter 120ms linear,
    opacity 120ms linear,
    transform 120ms linear;
  will-change: filter, opacity, transform;
}

.mo-spec-head {
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-width: 720px;
}

.mo-spec-h2 {
  margin: 0;
  font-family: var(--font-display, "Rawest", system-ui, sans-serif);
  font-size: var(--mkt-h2);
  line-height: 1.02;
  letter-spacing: var(--tracking-dense, -0.022em);
  font-weight: 500;
  color: var(--text-primary);
  text-wrap: balance;
}


.mo-spec-split {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: clamp(40px, 5vw, 80px);
  align-items: stretch;
  min-height: 0;
  flex: 1 1 auto;
}

/* ── Left: yaml that writes itself ──────────────────────── */

.mo-spec-yaml {
  position: relative;
  margin: 0;
  padding: clamp(22px, 2.4vw, 32px) clamp(22px, 2.2vw, 30px);
  /* No fill — just a subtle border ring.  Reads as a quiet
     code block on the warm-dark canvas.  No hover affordance,
     no purple top accent. */
  background: transparent;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-display, 20px);
  font-family: var(--font-code, "IBM Plex Mono", monospace);
  font-size: var(--mkt-body-sm);
  line-height: 1.85;
  color: var(--text-secondary);
  overflow: hidden;
  display: flex;
  align-items: flex-start;
  min-width: 0;
}

.mo-spec-yaml code {
  display: block;
  white-space: pre;
  min-width: 0;
}

.mo-spec-fname { color: var(--text-quaternary); display: block; }
.mo-spec-comment { color: var(--text-quaternary); }
.mo-spec-cmd { color: #7C4FE8; font-weight: 600; }
.mo-spec-k { color: var(--text-primary); font-weight: 500; }
.mo-spec-v { color: #7ADAE6; }

.mo-spec-bk {
  display: block;
  opacity: 0;
  transform: translateY(4px);
}
.mo-spec-bk[data-beat="0"] {
  opacity: clamp(0, calc((var(--beat) - 0.05) * 4), 1);
  transform: translateY(calc((1 - clamp(0, var(--beat) - 0.05, 1)) * 4px));
}
.mo-spec-bk[data-beat="1"] {
  opacity: clamp(0, calc((var(--beat) - 1.05) * 4), 1);
  transform: translateY(calc((1 - clamp(0, var(--beat) - 1.05, 1)) * 4px));
}
.mo-spec-bk[data-beat="2"] {
  opacity: clamp(0, calc((var(--beat) - 2.05) * 4), 1);
  transform: translateY(calc((1 - clamp(0, var(--beat) - 2.05, 1)) * 4px));
}
.mo-spec-bk[data-beat="3"] {
  opacity: clamp(0, calc((var(--beat) - 3.05) * 4), 1);
  transform: translateY(calc((1 - clamp(0, var(--beat) - 3.05, 1)) * 4px));
}

.mo-spec-caret {
  display: inline-block;
  color: #7C4FE8;
  font-weight: 700;
  margin-left: -0.05em;
  animation: mo-caret-blink 1.05s steps(2, end) infinite;
}

@keyframes mo-caret-blink {
  0%, 50% { opacity: 1; }
  51%, 100% { opacity: 0; }
}

/* ── Right: live pane ───────────────────────────────────── */

.mo-spec-live {
  position: relative;
  min-width: 0;
  min-height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.mo-spec-live-beat {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity 480ms cubic-bezier(0.22, 1, 0.36, 1),
    transform 480ms cubic-bezier(0.22, 1, 0.36, 1);
  pointer-events: none;
}

.mo-spec-live-beat.is-active {
  opacity: 1;
  transform: translateY(0);
}

.mo-spec-url {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 14px 18px;
  border-radius: 999px;
  background: transparent;
  border: 1px solid var(--border-subtle);
  font-family: var(--font-code, monospace);
  font-size: var(--mkt-body);
  color: var(--text-secondary);
  letter-spacing: -0.005em;
}

.mo-spec-url-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #7ADAE6;
  flex-shrink: 0;
}
.mo-spec-url-host { color: var(--text-primary); font-weight: 500; }
.mo-spec-url-path { color: var(--text-tertiary); }

.mo-spec-fields {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: min(320px, 70%);
}

.mo-spec-fields li {
  display: grid;
  grid-template-columns: 70px 1fr;
  align-items: baseline;
  gap: 12px;
  padding: 10px 14px;
  border-radius: 8px;
  background: transparent;
  border: 1px solid var(--border-subtle);
  font-family: var(--font-code, monospace);
  font-size: var(--mkt-body-sm);
  opacity: 0;
  transform: translateX(-8px);
  transition:
    opacity 360ms cubic-bezier(0.22, 1, 0.36, 1),
    transform 360ms cubic-bezier(0.22, 1, 0.36, 1);
  transition-delay: calc(120ms * var(--i));
}

.mo-spec-live-beat.is-active .mo-spec-fields li {
  opacity: 1;
  transform: translateX(0);
}

.mo-spec-field-name { color: var(--text-tertiary); font-weight: 500; }
.mo-spec-field-val { color: var(--text-primary); letter-spacing: -0.005em; }

.mo-spec-clock {
  width: clamp(120px, 18vw, 180px);
  height: clamp(120px, 18vw, 180px);
}

.mo-spec-clock-ring {
  fill: none;
  stroke: var(--border-subtle);
  stroke-width: 2;
}
.mo-spec-clock-arc {
  fill: none;
  stroke: #7C4FE8;
  stroke-width: 3;
  stroke-linecap: round;
  stroke-dasharray: 339;
  stroke-dashoffset: 339;
  transform: rotate(-90deg);
  transform-origin: 60px 60px;
  transition: stroke-dashoffset 1400ms cubic-bezier(0.22, 1, 0.36, 1);
}
.mo-spec-live-beat.is-active .mo-spec-clock-arc {
  stroke-dashoffset: 60;
}

.mo-spec-clock-hand {
  stroke: var(--text-primary);
  stroke-linecap: round;
  transform-origin: 60px 60px;
}
.mo-spec-clock-hand--hr {
  stroke-width: 3;
  transform: rotate(0deg);
  transition: transform 1400ms cubic-bezier(0.22, 1, 0.36, 1);
}
.mo-spec-clock-hand--min {
  stroke-width: 2.5;
  opacity: 0.8;
  transform: rotate(0deg);
  transition: transform 1400ms cubic-bezier(0.22, 1, 0.36, 1) 80ms;
}
.mo-spec-live-beat.is-active .mo-spec-clock-hand--hr { transform: rotate(270deg); }
.mo-spec-live-beat.is-active .mo-spec-clock-hand--min { transform: rotate(360deg); }

.mo-spec-clock-pivot { fill: var(--text-primary); }

.mo-spec-when {
  margin: 0;
  font-family: var(--font-display, system-ui, sans-serif);
  font-size: var(--mkt-lead);
  color: var(--text-secondary);
  letter-spacing: -0.005em;
}
.mo-spec-when em { font-style: normal; color: var(--text-primary); font-weight: 500; }

.mo-spec-deliver {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  flex-wrap: wrap;
}

.mo-spec-deliver-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 14px 8px 10px;
  border-radius: 999px;
  background: transparent;
  border: 1px solid var(--border-subtle);
  font-family: var(--font-code, monospace);
  font-size: 13px;
  color: var(--text-primary);
  letter-spacing: 0.02em;
  white-space: nowrap;
  opacity: 0;
  transform: translateY(8px);
  transition:
    opacity 480ms cubic-bezier(0.22, 1, 0.36, 1),
    transform 480ms cubic-bezier(0.22, 1, 0.36, 1);
  transition-delay: calc(180ms * var(--i));
}

.mo-spec-live-beat.is-active .mo-spec-deliver-chip {
  opacity: 1;
  transform: translateY(0);
}

.mo-spec-deliver-check {
  width: 14px;
  height: 14px;
  flex-shrink: 0;
  color: #7C4FE8;
}

/* Mobile / tablet: drop the sticky scroll choreography.  Sticky
   pinning inside a 100svh frame breaks on phones (URL bar resize)
   and the editorial magic compresses badly under 700px tall
   viewports.  Below 1023px we render the section as a flat
   editorial stack: yaml above, live pane below, every beat
   visible at once.  Same DS, same content, no pin. */

@media (max-width: 1023px) {
  .mo-spec-stage {
    min-height: 0;
    --beat: 4;
    --exit: 0;
  }
  .mo-spec-frame {
    position: static;
    height: auto;
    padding: clamp(80px, 11vh, 120px) clamp(20px, 4vw, 32px) clamp(56px, 9vh, 96px);
    gap: clamp(32px, 5vh, 56px);
    filter: none;
    opacity: 1;
    transform: none;
  }
  .mo-spec-split {
    grid-template-columns: 1fr;
    gap: 32px;
  }
  .mo-spec-yaml { font-size: 13px; }

  .mo-spec-bk[data-beat] {
    opacity: 1;
    transform: none;
  }

  .mo-spec-live {
    position: static;
    min-height: 0;
    display: flex;
    flex-direction: column;
    gap: clamp(28px, 5vh, 48px);
    padding: 8px 0;
  }
  .mo-spec-live-beat {
    position: static;
    inset: auto;
    opacity: 1;
    transform: none;
    padding: 4px 0;
  }
  .mo-spec-live-beat .mo-spec-fields li {
    opacity: 1;
    transform: none;
  }
  .mo-spec-live-beat .mo-spec-clock-arc { stroke-dashoffset: 60; }
  .mo-spec-live-beat .mo-spec-clock-hand--hr { transform: rotate(270deg); }
  .mo-spec-live-beat .mo-spec-clock-hand--min { transform: rotate(360deg); }
  .mo-spec-live-beat .mo-spec-deliver-chip { opacity: 1; transform: none; }
}

@media (max-width: 600px) {
  .mo-spec-h2 { font-size: var(--mkt-h3); }
  .mo-spec-yaml {
    padding: 18px 20px;
    font-size: 12.5px;
    line-height: 1.75;
  }
}

@media (min-width: 1600px) {
  .mo-spec-frame { max-width: 1380px; }
  .mo-spec-head { max-width: 920px; }
  .mo-spec-h2 { font-size: 64px; }
  .mo-spec-yaml { font-size: 18px; line-height: 1.9; }
  .mo-spec-url { font-size: 18px; padding: 16px 20px; }
  .mo-spec-fields li { font-size: 16px; padding: 12px 16px; }
  .mo-spec-when { font-size: 22px; }
}

@media (min-width: 1920px) {
  .mo-spec-frame { max-width: 1520px; }
  .mo-spec-head { max-width: 1040px; }
  .mo-spec-h2 { font-size: 76px; }
  .mo-spec-yaml { font-size: 20px; }
  .mo-spec-url { font-size: 20px; }
  .mo-spec-fields li { font-size: 17px; }
  .mo-spec-when { font-size: 24px; }
}

@media (min-width: 2400px) {
  .mo-spec-frame { max-width: 1700px; }
  .mo-spec-head { max-width: 1160px; }
  .mo-spec-h2 { font-size: 88px; }
  .mo-spec-yaml { font-size: 22px; }
  .mo-spec-url { font-size: 22px; }
  .mo-spec-fields li { font-size: 18px; }
  .mo-spec-when { font-size: 28px; }
}

@media (prefers-reduced-motion: reduce) {
  .mo-spec-bk[data-beat] { opacity: 1; transform: none; }
  .mo-spec-caret { animation: none; opacity: 1; }
  .mo-spec-live-beat { transition: none; }
  .mo-spec-stage { --exit: 0; }
  .mo-spec-frame { filter: none; opacity: 1; transform: none; }
  .mo-track-stage { margin-top: 0; --exit: 0; }
  .mo-track-frame { filter: none; opacity: 1; transform: none; }
}

/* ──────────────────────────────────────────────────────────
   Act 4 — One signal, many surfaces

   Sticky stage with a fixed signal chip on top and a canvas
   below that swaps among four destination surfaces (email,
   slack, webhook JSON, sheet) as the reader scrolls.  Each
   surface has its own visual language — they don't share a
   card chrome — so the eye perceives the same delta landing
   in four different inboxes.

   Single scroll signal (`--beat`, 0..4) drives everything.
   Same DS budget as Act 2/3.
─────────────────────────────────────────────────────────── */

[data-act="4"] {
  position: relative;
  z-index: 3;
  background: var(--background);
}

.mo-surfaces-stage {
  position: relative;
  min-height: 480vh;
  margin-top: -100vh;
  --beat: 0;
}

.mo-surfaces-frame {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  padding: clamp(96px, 12vh, 140px) clamp(20px, 4vw, 48px) clamp(56px, 8vh, 96px);
  max-width: 1240px;
  margin: 0 auto;
  width: 100%;
  min-width: 0;
  /* Same handoff as Act 2 → Act 3 → Act 4: blur + fade + scale
     down as the next act (Act 5) mounts over. */
  filter: blur(calc(var(--exit, 0) * 14px));
  opacity: calc(1 - var(--exit, 0) * 0.35);
  transform: scale(calc(1 - var(--exit, 0) * 0.04));
  transform-origin: center top;
  transition:
    filter 120ms linear,
    opacity 120ms linear,
    transform 120ms linear;
  will-change: filter, opacity, transform;
}

.mo-surfaces-head {
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-width: 760px;
}

.mo-surfaces-h2 {
  margin: 0;
  font-family: var(--font-display, "Rawest", system-ui, sans-serif);
  font-size: var(--mkt-h2);
  line-height: 1.02;
  letter-spacing: var(--tracking-dense, -0.022em);
  font-weight: 500;
  color: var(--text-primary);
  text-wrap: balance;
}

/* Sparkle cluster — anchored to the "Lands" word inside the
   h2.  The .mo-surfaces-mark span gets position: relative so
   the SVG can sit absolute next to "Lands" without taking
   inline width (h2 layout stays untouched).  No parallax. */
.mo-surfaces-mark {
  position: relative;
  white-space: nowrap;
}

.mo-surfaces-stars {
  position: absolute;
  top: -0.35em;
  left: calc(100% + 0.08em);
  width: clamp(32px, 2.6vw, 44px);
  height: auto;
  pointer-events: none;
}

@media (max-width: 600px) {
  .mo-surfaces-stars { width: 26px; }
}

@media (min-width: 1600px) {
  .mo-surfaces-stars { width: 56px; }
}
@media (min-width: 1920px) {
  .mo-surfaces-stars { width: 68px; }
}
@media (min-width: 2400px) {
  .mo-surfaces-stars { width: 82px; }
}


/* Canvas — single sticky pane.  Each .mo-surface is absolutely
   stacked inside; only the active one (--beat == its data-beat)
   is opacity 1 and pointer-active.  No shared card chrome —
   each surface keeps its own visual treatment. */
.mo-surfaces-canvas {
  position: relative;
  /* Hug the bottom of the frame so the surface lives near the
     bottom edge — same compositional anchor as when the
     signal+drop sat between head and canvas. */
  margin-top: auto;
  min-height: clamp(280px, 38vh, 380px);
  min-width: 0;
  overflow: hidden;
}


.mo-surface {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity 460ms cubic-bezier(0.22, 1, 0.36, 1),
    transform 460ms cubic-bezier(0.22, 1, 0.36, 1);
  pointer-events: none;
  font-family: var(--font-base);
}

.mo-surface.is-active {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

/* ── Surface 0 — Email ──────────────────────────────────── */

.mo-surface--email {
  padding: clamp(22px, 2.6vw, 32px) clamp(22px, 2.6vw, 32px);
  background: transparent;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-display, 20px);
  gap: clamp(14px, 1.8vh, 20px);
}

.mo-surface-email-head {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding-bottom: clamp(12px, 1.6vh, 18px);
  border-bottom: 1px solid var(--border-subtle);
}

.mo-surface-email-head p {
  margin: 0;
  display: grid;
  grid-template-columns: 72px 1fr;
  gap: 12px;
  font-family: var(--font-code, monospace);
  font-size: 12.5px;
  line-height: 1.5;
}

.mo-surface-email-tag {
  color: var(--text-quaternary);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  font-size: 10.5px;
  align-self: center;
}

.mo-surface-email-val {
  color: var(--text-secondary);
}

.mo-surface-email-subj {
  color: var(--text-primary);
  font-weight: 500;
  letter-spacing: -0.005em;
}

.mo-surface-email-body {
  padding: clamp(12px, 1.6vh, 18px) 0;
}

.mo-surface-email-row {
  margin: 0;
  display: inline-grid;
  grid-template-columns: 72px auto auto auto;
  align-items: baseline;
  gap: 12px;
  font-family: var(--font-code, monospace);
  font-size: var(--mkt-body);
  letter-spacing: -0.005em;
}

.mo-surface-email-k {
  color: var(--text-tertiary);
  text-transform: lowercase;
}

.mo-surface-email-was {
  color: var(--text-quaternary);
  text-decoration: line-through;
}

.mo-surface-email-arrow {
  color: var(--text-quaternary);
}

.mo-surface-email-now {
  color: #7C4FE8;
  font-weight: 500;
}

.mo-surface-email-foot {
  display: flex;
  justify-content: space-between;
  gap: 16px;
  padding-top: clamp(10px, 1.4vh, 14px);
  border-top: 1px solid var(--border-subtle);
  font-family: var(--font-code, monospace);
  font-size: 11px;
  color: var(--text-quaternary);
  letter-spacing: 0.04em;
}

/* ── Surface 1 — Slack ──────────────────────────────────── */

.mo-surface--slack {
  padding: clamp(22px, 2.6vw, 32px) clamp(22px, 2.6vw, 32px);
  background: transparent;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-medium, 12px);
  gap: clamp(10px, 1.4vh, 14px);
}

.mo-surface-slack-head {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--text-primary);
  font-weight: 500;
}

.mo-surface-slack-channel {
  color: var(--text-primary);
  font-weight: 500;
}

.mo-surface-slack-sep {
  color: var(--text-quaternary);
}

.mo-surface-slack-bot {
  color: var(--text-secondary);
}

.mo-surface-slack-tag {
  padding: 1px 6px;
  border-radius: 3px;
  background: transparent;
  border: 1px solid var(--border-subtle);
  font-family: var(--font-code, monospace);
  font-size: 9.5px;
  letter-spacing: 0.12em;
  color: var(--text-tertiary);
  font-weight: 500;
}

.mo-surface-slack-body {
  border-left: 3px solid #7C4FE8;
  padding-left: clamp(14px, 1.4vw, 18px);
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.mo-surface-slack-line {
  margin: 0;
  font-family: var(--font-base);
  font-size: var(--mkt-body);
  line-height: 1.5;
  color: var(--text-secondary);
  letter-spacing: -0.005em;
}

.mo-surface-slack-link {
  color: #7ADAE6;
  text-decoration: underline;
  text-decoration-color: rgba(122, 218, 230, 0.45);
  text-underline-offset: 3px;
}

.mo-surface-slack-was {
  color: var(--text-quaternary);
  text-decoration: line-through;
  font-family: var(--font-code, monospace);
  font-size: 0.92em;
}

.mo-surface-slack-now {
  color: var(--text-primary);
  font-weight: 500;
  font-family: var(--font-code, monospace);
  font-size: 0.92em;
}

.mo-surface-slack-foot {
  font-family: var(--font-code, monospace);
  font-size: 11px;
  color: var(--text-quaternary);
  letter-spacing: 0.04em;
}

/* ── Surface 2 — Webhook (JSON) ─────────────────────────── */

.mo-surface--webhook {
  padding: 0;
  background: transparent;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-display, 20px);
  overflow: hidden;
}

.mo-surface-webhook-head {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 18px;
  border-bottom: 1px solid var(--border-subtle);
  font-family: var(--font-code, monospace);
  font-size: 12px;
  letter-spacing: 0.02em;
}

.mo-surface-webhook-verb {
  padding: 2px 8px;
  border-radius: 4px;
  background: rgba(124, 79, 232, 0.16);
  color: #7C4FE8;
  font-weight: 500;
  letter-spacing: 0.08em;
  font-size: 10.5px;
}

.mo-surface-webhook-url {
  color: var(--text-secondary);
  letter-spacing: -0.005em;
}

.mo-surface-webhook-status {
  margin-left: auto;
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(122, 218, 230, 0.16);
  color: #7ADAE6;
  font-weight: 500;
  letter-spacing: 0.08em;
}

.mo-surface-webhook-body {
  margin: 0;
  padding: clamp(18px, 2vh, 24px) clamp(18px, 2vw, 24px);
  font-family: var(--font-code, monospace);
  font-size: var(--mkt-body-sm);
  line-height: 1.7;
  color: var(--text-secondary);
  /* clip not auto — same trackpad-hijack reason as .mo-roadmap-terminal. */
  overflow-x: clip;
}

.mo-surface-webhook-body code {
  display: block;
  white-space: pre;
}

.mo-surface-webhook-brace {
  color: var(--text-quaternary);
}
.mo-surface-webhook-key {
  color: var(--text-primary);
}
.mo-surface-webhook-str {
  color: #7ADAE6;
}

/* ── Surface 3 — Sheet ──────────────────────────────────── */

.mo-surface--sheet {
  padding: 0;
  background: transparent;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-medium, 12px);
  overflow: hidden;
}

.mo-surface-sheet {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-code, monospace);
  font-size: var(--mkt-body-sm);
}

.mo-surface-sheet th {
  text-align: left;
  padding: 12px 16px;
  background: transparent;
  border-bottom: 1px solid var(--border-subtle);
  color: var(--text-tertiary);
  font-weight: 500;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.12em;
}

.mo-surface-sheet td {
  padding: 12px 16px;
  border-bottom: 1px solid var(--border-subtle);
  color: var(--text-secondary);
  letter-spacing: -0.005em;
}

.mo-surface-sheet-row--new td {
  background: rgba(124, 79, 232, 0.08);
  color: var(--text-primary);
  font-weight: 500;
  box-shadow: inset 2px 0 0 #7C4FE8;
}

.mo-surface-sheet-foot {
  padding: 10px 16px;
  font-family: var(--font-code, monospace);
  font-size: 11px;
  color: var(--text-tertiary);
  letter-spacing: 0.06em;
}

/* ── Responsive ──────────────────────────────────────────── */

@media (max-width: 1023px) {
  .mo-surfaces-stage {
    min-height: 0;
    margin-top: 0;
    --beat: 0;
    --exit: 0;
  }
  .mo-surfaces-frame {
    position: static;
    height: auto;
    padding: clamp(80px, 11vh, 120px) clamp(20px, 4vw, 32px) clamp(56px, 9vh, 96px);
    gap: clamp(32px, 5vh, 56px);
    filter: none;
    opacity: 1;
    transform: none;
  }
  .mo-surfaces-canvas {
    display: flex;
    flex-direction: column;
    gap: clamp(20px, 3vh, 28px);
    overflow: visible;
    margin-top: 0;
    min-height: 0;
  }
  .mo-surface {
    position: static;
    opacity: 1;
    transform: none;
    pointer-events: auto;
  }
}

@media (max-width: 600px) {
  .mo-surfaces-h2 { font-size: var(--mkt-h3); }
  .mo-surface-email-head p { grid-template-columns: 56px 1fr; }
  .mo-surface-email-row { grid-template-columns: 1fr; row-gap: 0; }
}

@media (min-width: 1600px) {
  .mo-surfaces-frame { max-width: 1380px; }
  .mo-surfaces-head { max-width: 920px; }
  .mo-surfaces-h2 { font-size: 56px; }
  .mo-surface-email-head p { font-size: 14px; }
  .mo-surface-email-row { font-size: 20px; }
  .mo-surface-slack-line { font-size: 18px; }
  .mo-surface-webhook-body { font-size: 16px; }
  .mo-surface-sheet { font-size: 16px; }
}

@media (min-width: 1920px) {
  .mo-surfaces-frame { max-width: 1520px; }
  .mo-surfaces-head { max-width: 1040px; }
  .mo-surfaces-h2 { font-size: 68px; }
  .mo-surface-email-head p { font-size: 15px; }
  .mo-surface-email-row { font-size: 22px; }
  .mo-surface-slack-line { font-size: 19px; }
  .mo-surface-webhook-body { font-size: 17px; }
  .mo-surface-sheet { font-size: 17px; }
}

@media (min-width: 2400px) {
  .mo-surfaces-frame { max-width: 1700px; }
  .mo-surfaces-head { max-width: 1160px; }
  .mo-surfaces-h2 { font-size: 76px; }
  .mo-surface-email-head p { font-size: 16px; }
  .mo-surface-email-row { font-size: 24px; }
  .mo-surface-slack-line { font-size: 20px; }
  .mo-surface-webhook-body { font-size: 18px; }
  .mo-surface-sheet { font-size: 18px; }
}

@media (prefers-reduced-motion: reduce) {
  .mo-surfaces-stage { margin-top: 0; --exit: 0; }
  .mo-surfaces-frame { filter: none; opacity: 1; transform: none; }
  .mo-surface { transition: none; }
}

/* ──────────────────────────────────────────────────────────
   Act 5 — Today, your cron.  Tomorrow, ours.

   Sticky stage; one terminal panel typing itself across four
   beats.  Same scroll-driven `--beat` motor as Act 2/4.  Beat
   spans reveal via clamp(0, (--beat - N) * 4, 1) so the lines
   compose naturally as the reader scrolls.

   No fill, border-subtle.  Brand purple-7 on the command lines
   and caret; teal-5 on the ✓ confirms.  Same DS budget as the
   acts before it.
─────────────────────────────────────────────────────────── */

[data-act="5"] {
  position: relative;
  z-index: 4;
  background: var(--background);
}

.mo-roadmap-stage {
  position: relative;
  /* Shorter than the other 4-beat stages (480vh) because the
     terminal doesn't have a live pane swapping content between
     beats — long inter-beat dead air made the scroll feel
     stuck.  320vh = ~55vh per beat with reveals smoothed out
     across most of each beat's range below. */
  min-height: 320vh;
  margin-top: -100vh;
  --beat: 0;
}

.mo-roadmap-frame {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(40px, 6vh, 72px);
  padding: clamp(96px, 12vh, 140px) clamp(20px, 4vw, 48px) clamp(56px, 8vh, 96px);
  max-width: 1240px;
  margin: 0 auto;
  width: 100%;
  min-width: 0;
  /* Same handoff as the other acts: --exit ramps 0→1 in the
     last 12.5% of the sticky range so Act 6 mounts over a
     softened terminal. */
  filter: blur(calc(var(--exit, 0) * 14px));
  opacity: calc(1 - var(--exit, 0) * 0.35);
  transform: scale(calc(1 - var(--exit, 0) * 0.04));
  transform-origin: center top;
  transition:
    filter 120ms linear,
    opacity 120ms linear,
    transform 120ms linear;
  will-change: filter, opacity, transform;
}

.mo-roadmap-head {
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-width: 760px;
}

.mo-roadmap-h2 {
  margin: 0;
  font-family: var(--font-display, "Rawest", system-ui, sans-serif);
  font-size: var(--mkt-h2);
  line-height: 1.02;
  letter-spacing: var(--tracking-dense, -0.022em);
  font-weight: 500;
  color: var(--text-primary);
  text-wrap: balance;
}

/* Terminal — no fill, border-subtle frame, mono code with the
   ASCII chrome the reader expects from a shell session.
   overflow-x: clip (not auto) because the terminal lines are
   short and never overflow at any viewport tier; auto on macOS
   trackpads hijacks vertical wheel events when the cursor is
   over the panel, freezing the sticky-stage scroll. */
.mo-roadmap-terminal {
  margin: 0;
  padding: clamp(22px, 2.6vw, 36px) clamp(22px, 2.4vw, 32px);
  background: transparent;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-display, 20px);
  font-family: var(--font-code, "IBM Plex Mono", monospace);
  font-size: var(--mkt-body-sm);
  line-height: 1.85;
  color: var(--text-secondary);
  overflow-x: clip;
}

.mo-roadmap-terminal code {
  display: block;
  white-space: pre;
}

.mo-roadmap-bk {
  display: block;
  opacity: 0;
  transform: translateY(4px);
}
/* Reveal smoothed across most of each beat (multiplier 2 vs
   the 4 used in Act 2).  Each block fades in across ~50% of
   its beat-unit so the scroll has continuous motion between
   beats — no static dead air. */
.mo-roadmap-bk[data-beat="0"] {
  opacity: clamp(0, calc((var(--beat) - 0.05) * 2), 1);
  transform: translateY(calc((1 - clamp(0, var(--beat) - 0.05, 1)) * 4px));
}
.mo-roadmap-bk[data-beat="1"] {
  opacity: clamp(0, calc((var(--beat) - 1.05) * 2), 1);
  transform: translateY(calc((1 - clamp(0, var(--beat) - 1.05, 1)) * 4px));
}
.mo-roadmap-bk[data-beat="2"] {
  opacity: clamp(0, calc((var(--beat) - 2.05) * 2), 1);
  transform: translateY(calc((1 - clamp(0, var(--beat) - 2.05, 1)) * 4px));
}
.mo-roadmap-bk[data-beat="3"] {
  opacity: clamp(0, calc((var(--beat) - 3.05) * 2), 1);
  transform: translateY(calc((1 - clamp(0, var(--beat) - 3.05, 1)) * 4px));
}

/* Tokens — same accent budget as the rest of the page. */
.mo-roadmap-prompt {
  color: var(--text-quaternary);
  font-weight: 500;
}
.mo-roadmap-cmd {
  color: #7C4FE8;
  font-weight: 500;
}
.mo-roadmap-ok {
  color: #7ADAE6;
  font-weight: 500;
}
.mo-roadmap-line {
  color: var(--text-primary);
}
.mo-roadmap-comment {
  color: var(--text-quaternary);
}
.mo-roadmap-caret {
  display: inline-block;
  color: #7C4FE8;
  font-weight: 700;
  margin-left: -0.05em;
  animation: mo-caret-blink 1.05s steps(2, end) infinite;
}

/* ── Responsive ──────────────────────────────────────────── */

@media (max-width: 1023px) {
  .mo-roadmap-stage {
    min-height: 0;
    margin-top: 0;
    --beat: 4;
    --exit: 0;
  }
  .mo-roadmap-frame {
    position: static;
    height: auto;
    padding: clamp(80px, 11vh, 120px) clamp(20px, 4vw, 32px) clamp(56px, 9vh, 96px);
    gap: clamp(32px, 5vh, 56px);
    filter: none;
    opacity: 1;
    transform: none;
  }
  .mo-roadmap-bk[data-beat] { opacity: 1; transform: none; }
}

@media (max-width: 600px) {
  .mo-roadmap-h2 { font-size: var(--mkt-h3); }
  .mo-roadmap-terminal {
    padding: 18px 20px;
    font-size: 12.5px;
    line-height: 1.75;
  }
}

@media (min-width: 1600px) {
  .mo-roadmap-frame { max-width: 1380px; }
  .mo-roadmap-head { max-width: 920px; }
  .mo-roadmap-h2 { font-size: 56px; }
  .mo-roadmap-terminal { font-size: 18px; line-height: 1.9; }
}

@media (min-width: 1920px) {
  .mo-roadmap-frame { max-width: 1520px; }
  .mo-roadmap-head { max-width: 1040px; }
  .mo-roadmap-h2 { font-size: 68px; }
  .mo-roadmap-terminal { font-size: 20px; }
}

@media (min-width: 2400px) {
  .mo-roadmap-frame { max-width: 1700px; }
  .mo-roadmap-head { max-width: 1160px; }
  .mo-roadmap-h2 { font-size: 76px; }
  .mo-roadmap-terminal { font-size: 22px; }
}

@media (prefers-reduced-motion: reduce) {
  .mo-roadmap-bk[data-beat] { opacity: 1; transform: none; }
  .mo-roadmap-caret { animation: none; opacity: 1; }
  .mo-roadmap-stage { margin-top: 0; --exit: 0; }
  .mo-roadmap-frame { filter: none; opacity: 1; transform: none; }
}

/* ──────────────────────────────────────────────────────────
   Act 6 — Closer.  Your turn.

   Single-beat sticky frame.  Mirrors the Act 2 spec block but
   empty — fields wait for the reader to fill them.  Caret on
   the target line blinks via the same mo-caret-blink keyframe
   the spec uses.  The run command sits inline below, then the
   CTA stack (button + tagline per brand rule).

   No fill, border-subtle on the spec panel — same family as
   Acts 4/5.  Brand purple-7 on caret + command, teal-5 not
   needed here (no value strings yet — the user writes them).
─────────────────────────────────────────────────────────── */

[data-act="6"] {
  position: relative;
  z-index: 5;
  background: var(--background);
}

.mo-closer-stage {
  position: relative;
  min-height: 200vh;
  margin-top: -100vh;
}

.mo-closer-frame {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: clamp(28px, 4vh, 48px);
  padding: clamp(96px, 12vh, 140px) clamp(20px, 4vw, 48px) clamp(56px, 8vh, 96px);
  max-width: 720px;
  margin: 0 auto;
  width: 100%;
  text-align: center;
}

.mo-closer-h2 {
  margin: 0;
  font-family: var(--font-display, "Rawest", system-ui, sans-serif);
  font-size: var(--mkt-h3);
  line-height: 1.02;
  letter-spacing: var(--tracking-dense, -0.022em);
  font-weight: 500;
  color: var(--text-primary);
}

/* Empty spec — same recipe as the Act 5 terminal: no fill,
   border-subtle ring, mono code, left-aligned content. */
.mo-closer-spec {
  margin: 0;
  width: 100%;
  padding: clamp(22px, 2.6vw, 32px) clamp(22px, 2.4vw, 32px);
  background: transparent;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-display, 20px);
  font-family: var(--font-code, "IBM Plex Mono", monospace);
  font-size: var(--mkt-body-sm);
  line-height: 1.85;
  color: var(--text-secondary);
  text-align: left;
  /* clip not auto — same trackpad-hijack reason as .mo-roadmap-terminal. */
  overflow-x: clip;
}

.mo-closer-spec code {
  display: block;
  white-space: pre;
}

.mo-closer-fname { color: var(--text-quaternary); }
.mo-closer-k { color: var(--text-primary); font-weight: 500; }
.mo-closer-prompt { color: var(--text-quaternary); font-weight: 600; }
.mo-closer-cmd { color: #7C4FE8; font-weight: 600; }
.mo-closer-caret {
  display: inline-block;
  color: #7C4FE8;
  font-weight: 700;
  margin-left: -0.05em;
  animation: mo-caret-blink 1.05s steps(2, end) infinite;
}

/* Layout + tag styles come from .cta-stack + .cta-stack--center
   + .cta-stack-tag in components.css. */

/* ── Responsive ──────────────────────────────────────────── */

@media (max-width: 1023px) {
  .mo-closer-stage {
    min-height: 0;
    margin-top: 0;
  }
  .mo-closer-frame {
    position: static;
    height: auto;
    padding: clamp(80px, 11vh, 120px) clamp(20px, 4vw, 32px) clamp(80px, 10vh, 120px);
  }
}

@media (max-width: 600px) {
  .mo-closer-h2 { font-size: var(--mkt-h4); }
  .mo-closer-spec { padding: 20px 22px; font-size: 12.5px; line-height: 1.75; }
}

@media (min-width: 1600px) {
  .mo-closer-frame { max-width: 820px; }
  .mo-closer-h2 { font-size: 52px; }
  .mo-closer-spec { font-size: 18px; line-height: 1.9; }
}

@media (min-width: 1920px) {
  .mo-closer-frame { max-width: 920px; }
  .mo-closer-h2 { font-size: 60px; }
  .mo-closer-spec { font-size: 20px; }
}

@media (min-width: 2400px) {
  .mo-closer-frame { max-width: 1040px; }
  .mo-closer-h2 { font-size: 68px; }
  .mo-closer-spec { font-size: 22px; }
}

@media (prefers-reduced-motion: reduce) {
  .mo-closer-stage { margin-top: 0; }
  .mo-closer-caret { animation: none; opacity: 1; }
}


/* ──────────────────────────────────────────────────────────
   Act 3 — Track that draws itself

   Sticky stage with a single horizontal time axis.  Scroll
   progress (--draw, 0..1) drives a stroke-dashoffset that
   draws the purple-7 rail left to right.  Each run dot is
   positioned at --x along the rail and reveals once --draw
   crosses its --at threshold.  Delivered runs get a purple
   dot + a small caption; "same" runs get a tiny grey dot
   and nothing else.

   Surfaces via DS tokens.  Accents: #7C4FE8 (purple-7) and
   #7ADAE6 (teal-5) — same hexes already in Act 1 + Act 2.
─────────────────────────────────────────────────────────── */

[data-act="3"] {
  position: relative;
  /* Mounts over Act 2 — higher z-index + solid bg + the
     stage's negative margin pulls Act 3 up 100vh so its sticky
     frame engages exactly when Act 2's sticky frame disengages
     (the /api hero → Act 2 handoff pattern). */
  z-index: 2;
  background: var(--background);
}

.mo-track-stage {
  position: relative;
  min-height: 320vh;
  margin-top: -100vh;
  --draw: 0;
}

.mo-track-frame {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(56px, 8vh, 96px);
  padding: clamp(96px, 12vh, 140px) clamp(20px, 4vw, 48px) clamp(56px, 8vh, 96px);
  max-width: 1240px;
  margin: 0 auto;
  width: 100%;
  min-width: 0;
  /* Same handoff as Act 2 → Act 3: as Act 4 starts mounting,
     `--exit` ramps 0→1 and the frame blurs + fades + scales
     down so the swap reads as a focus pull. */
  filter: blur(calc(var(--exit, 0) * 14px));
  opacity: calc(1 - var(--exit, 0) * 0.35);
  transform: scale(calc(1 - var(--exit, 0) * 0.04));
  transform-origin: center top;
  transition:
    filter 120ms linear,
    opacity 120ms linear,
    transform 120ms linear;
  will-change: filter, opacity, transform;
}

.mo-track-head {
  display: flex;
  flex-direction: column;
  gap: 14px;
  max-width: 760px;
}

.mo-track-h2 {
  margin: 0;
  font-family: var(--font-display, "Rawest", system-ui, sans-serif);
  font-size: var(--mkt-h2);
  line-height: 1.02;
  letter-spacing: var(--tracking-dense, -0.022em);
  font-weight: 500;
  color: var(--text-primary);
  text-wrap: balance;
}

/* The track itself — relative wrapper, 240-280px tall so the
   dates above and the delivery captions below each have a
   well-defined band. */
.mo-track {
  position: relative;
  width: 100%;
  height: clamp(220px, 26vh, 280px);
  min-width: 0;
}

.mo-track-svg {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 100%;
  height: 4px;
}

.mo-track-rail {
  stroke: var(--border-subtle);
  stroke-width: 1.5;
  vector-effect: non-scaling-stroke;
}

.mo-track-draw {
  stroke: #7C4FE8;
  stroke-width: 1.5;
  stroke-linecap: round;
  vector-effect: non-scaling-stroke;
  pathLength: 1;
  stroke-dasharray: 1;
  /* JS sets --draw on the stage; CSS clamps and inverts so 0
     means "fully hidden" (offset 1), 1 means "fully drawn"
     (offset 0). */
  stroke-dashoffset: calc(1 - clamp(0, var(--draw), 1));
}

/* Runs — absolutely positioned at --x along the rail.  Each
   run is a vertical stack: date above, dot at center, caption
   below.  The dot sits exactly on the rail. */
.mo-track-runs {
  position: absolute;
  inset: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.mo-track-run {
  position: absolute;
  left: var(--x);
  top: 0;
  bottom: 0;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0;
  text-align: center;
  opacity: clamp(0, calc((var(--draw) - var(--at) + 0.02) * 20), 1);
  transition: opacity 60ms linear;
}

.mo-track-date {
  font-family: var(--font-code, monospace);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  font-weight: 500;
  margin-bottom: clamp(24px, 4vh, 40px);
  white-space: nowrap;
}

/* Dot variants — "same" sits small and grey on the rail; the
   "delivered" dot is bigger, purple-7 filled, with a soft halo. */
.mo-track-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--text-quaternary);
  position: relative;
  z-index: 2;
  transition:
    width 280ms cubic-bezier(0.22, 1, 0.36, 1),
    height 280ms cubic-bezier(0.22, 1, 0.36, 1),
    background 280ms ease,
    box-shadow 280ms ease;
}

.mo-track-run[data-state="delivered"] .mo-track-dot {
  width: 12px;
  height: 12px;
  background: #7C4FE8;
  box-shadow: 0 0 0 6px rgba(124, 79, 232, 0.16);
}

/* Caption sits under the dot only on delivered runs.  Editorial
   style — mono, field name dim, value primary. */
.mo-track-label {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  margin-top: clamp(24px, 4vh, 40px);
  font-family: var(--font-code, monospace);
  font-size: 12.5px;
  line-height: 1.4;
  white-space: nowrap;
}

.mo-track-label-k {
  color: var(--text-tertiary);
  font-weight: 500;
  letter-spacing: 0.02em;
  text-transform: lowercase;
}
.mo-track-label-v {
  color: var(--text-primary);
  font-weight: 500;
  letter-spacing: -0.005em;
}

/* Legend — quiet typography under the track.  Tiny swatches
   match the dot variants exactly. */
.mo-track-foot {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: clamp(20px, 3vw, 36px);
  font-family: var(--font-code, monospace);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

.mo-track-legend {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.mo-track-swatch {
  display: inline-block;
  border-radius: 50%;
}
.mo-track-swatch--same {
  width: 6px;
  height: 6px;
  background: var(--text-quaternary);
}
.mo-track-swatch--delivered {
  width: 10px;
  height: 10px;
  background: #7C4FE8;
  box-shadow: 0 0 0 3px rgba(124, 79, 232, 0.16);
}

/* No overlay top-line on hover.  The spinning O cursor is the
   only hover feedback — Pablo's preference: change the actual
   line, not stack another one above it. */

/* Responsive — drop sticky on mobile, render as a flat strip
   with all dots already drawn. */
@media (max-width: 1023px) {
  .mo-track-stage {
    min-height: 0;
    margin-top: 0;
    --draw: 1;
    --exit: 0;
  }
  .mo-track-frame { filter: none; opacity: 1; transform: none; }
  .mo-track-frame {
    position: static;
    height: auto;
    padding: clamp(80px, 11vh, 120px) clamp(20px, 4vw, 32px) clamp(56px, 9vh, 96px);
    gap: clamp(32px, 5vh, 56px);
  }
  .mo-track-run { opacity: 1; }
  .mo-track { height: clamp(180px, 24vh, 220px); }
  .mo-track-date { font-size: 10px; margin-bottom: clamp(18px, 3vh, 28px); }
  .mo-track-label { font-size: 11px; margin-top: clamp(18px, 3vh, 28px); }
}

@media (max-width: 600px) {
  /* Some dates collapse off-screen; hide every other date label
     to keep the strip readable.  We still draw the dot, just no
     text caption next to it. */
  .mo-track-run[data-state="same"]:nth-child(odd) .mo-track-date { display: none; }
  .mo-track-h2 { font-size: var(--mkt-h3); }
}

@media (min-width: 1600px) {
  .mo-track-frame { max-width: 1380px; }
  .mo-track-head { max-width: 920px; }
  .mo-track-h2 { font-size: 64px; }
  .mo-track-date { font-size: 13px; }
  .mo-track-label { font-size: 14px; }
}

@media (min-width: 1920px) {
  .mo-track-frame { max-width: 1520px; }
  .mo-track-head { max-width: 1040px; }
  .mo-track-h2 { font-size: 76px; }
  .mo-track-date { font-size: 14px; }
  .mo-track-label { font-size: 15px; }
}

@media (min-width: 2400px) {
  .mo-track-frame { max-width: 1700px; }
  .mo-track-head { max-width: 1160px; }
  .mo-track-h2 { font-size: 88px; }
  .mo-track-date { font-size: 15px; }
  .mo-track-label { font-size: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  .mo-track-stage { --draw: 1; }
  .mo-track-run { opacity: 1; }
}

/* ══════════════════════════════════════════════════════════
   Audience switcher + BU light theme.
   Same mechanism as home / Fetch / Browser Sessions / Extract / Crawl. */
[data-audience-tech][hidden],
[data-audience-bu][hidden] { display: none !important; }

.audience-switch {
  position: fixed;
  top: 50%;
  right: 16px;
  z-index: 250;
  display: grid;
  grid-template-rows: 1fr 1fr;
  border: 1px solid var(--border-subtle);
  border-radius: 999px;
  overflow: hidden;
  background: color-mix(in srgb, var(--background) 88%, transparent);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  will-change: transform;
  transform: translateY(-50%) translateZ(0);
  backface-visibility: hidden;
}
.audience-switch::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 50%;
  background: #7C4FE8;
  z-index: 0;
  transition: transform 320ms cubic-bezier(0.22, 1, 0.36, 1);
  pointer-events: none;
}
body[data-audience="bu"] .audience-switch::before {
  transform: translateY(100%);
}
.audience-switch-btn {
  position: relative;
  z-index: 1;
  appearance: none;
  -webkit-appearance: none;
  background: transparent;
  border: 0;
  padding: 16px 11px;
  cursor: pointer;
  font-family: var(--font-code, var(--font-mono), "IBM Plex Mono", monospace);
  font-size: 9.5px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  transition: color 220ms cubic-bezier(0.22, 1, 0.36, 1);
  writing-mode: vertical-rl;
}
.audience-switch-btn[aria-pressed="true"] { color: #FFFFFF; }

/* Mobile — compact horizontal pill bottom-right. */
@media (max-width: 720px) {
  .audience-switch {
    top: auto;
    bottom: 20px;
    right: 16px;
    transform: translateZ(0);
    grid-template-rows: none;
    grid-template-columns: 1fr 1fr;
  }
  .audience-switch::before {
    top: 0;
    left: 0;
    right: auto;
    bottom: auto;
    width: 50%;
    height: 100%;
  }
  body[data-audience="bu"] .audience-switch::before { transform: translateX(100%); }
  .audience-switch-btn {
    writing-mode: horizontal-tb;
    padding: 10px 18px;
    font-size: 10px;
  }
  /* Hero mark is nowrap by default (keeps the phrase on one line on
     desktop); on phones that forces the H1 wider than the viewport.
     Let it wrap. */
  .am-hero-mark { white-space: normal; }
}

/* ── BU light mode body + chrome ── */
html:not(.dark) body {
  background: var(--background);
  color: var(--text-primary);
}
html:not(.dark) .audience-switch {
  background: var(--zen-gray-1);
  border-color: var(--border-default);
  box-shadow: 0 12px 28px -12px rgba(29, 22, 18, 0.18);
}

/* Mq12 on every heading in BU. */
html:not(.dark) .am-hero-h1,
html:not(.dark) .mo-spec-h2,
html:not(.dark) .mo-track-h2,
html:not(.dark) .mo-surfaces-h2,
html:not(.dark) .mo-roadmap-h2,
html:not(.dark) .mo-closer-h2 {
  font-family: 'Mq12', system-ui, sans-serif;
  font-weight: 500;
}

/* Topbar inversion — defensive yields. */

/* Nav popover light variant. */
html:not(.dark) .nav-dropdown {
  background: #FFFFFF;
  border-color: var(--border-subtle);
  box-shadow: 0 28px 56px -20px rgba(29, 22, 18, 0.18);
}
html:not(.dark) .nav-mega-item > a { color: var(--text-secondary); }
html:not(.dark) .nav-mega-item > a:hover,
html:not(.dark) .nav-mega-item > a:focus-visible {
  background: var(--sunken-hover);
  color: var(--text-primary);
}
html:not(.dark) .nav-mega-item.is-active > a {
  background: var(--sunken-active);
  color: var(--text-primary);
}
html:not(.dark) .nav-mega-item > span { color: var(--text-tertiary); }
html:not(.dark) .nav-mega-item.is-active > span {
  background: var(--sunken-active);
  color: var(--text-secondary);
}
html:not(.dark) .nav-mega-group-label { color: var(--text-tertiary); }
html:not(.dark) .nav-mega-headline {
  background-color: #1D1612;
  border-color: rgba(29, 22, 18, 0.18);
}
html:not(.dark) .nav-mega-preview-desc { color: var(--text-secondary); }

/* Teal text on light bg.  All five hardcoded #7ADAE6 usages sit on
   warm-dark body chrome in dark (terminal-style widgets, mock Slack
   / webhook surfaces, roadmap log) — readable there.  In BU light
   the same teal becomes invisible on the light page bg.  Flip to
   --zen-cyan-7 #1C9E97 (medium-dark teal in the light scope) for
   contrast.  Hardcoded so the value is stable even if the token
   shifts. */
html:not(.dark) .mo-spec-v,
html:not(.dark) .mo-surface-slack-link,
html:not(.dark) .mo-surface-webhook-status,
html:not(.dark) .mo-surface-webhook-str,
html:not(.dark) .mo-roadmap-ok {
  color: #1C9E97;
}

/* ── BU summary widgets ─────────────────────────────────────
   Hairline-bordered key/value lists that replace the dev-jargon
   terminal/JSON/yaml mocks when the audience switcher is in BU
   mode.  Mirrors the .ci-how-step-summary / .pm-how-step-summary
   atom (border + padding + radius surface, monospace small-caps
   key + plain-body value).  Three placements:
     - .mo-surface-summary: sits inside the sticky webhook
       surface (Act 4 beat 2), in the slot the JSON body occupies
       for tech.
     - .mo-roadmap-summary: sits inside Act 5 next to the
       terminal mock; stacked below the H2 for BU.
     - .mo-closer-summary: sits inside Act 6 in the slot
       the closer-spec yaml occupies for tech.
*/
.mo-surface-summary,
.mo-roadmap-summary,
.mo-closer-summary {
  list-style: none;
  margin: 0;
  padding: clamp(18px, 2vh, 24px) clamp(20px, 2vw, 28px);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-display, 20px);
  display: flex;
  flex-direction: column;
  gap: 12px;
  font-family: var(--font-base);
  background: transparent;
}

.mo-surface-summary li,
.mo-roadmap-summary li,
.mo-closer-summary li {
  display: grid;
  grid-template-columns: 96px minmax(0, 1fr);
  gap: 16px;
  align-items: baseline;
  font-size: var(--mkt-body-sm);
  line-height: 1.55;
}

.mo-surface-summary li + li,
.mo-roadmap-summary li + li,
.mo-closer-summary li + li {
  padding-top: 12px;
  border-top: 1px solid var(--border-subtle);
}

.mo-surface-summary-k,
.mo-roadmap-summary-k,
.mo-closer-summary-k {
  font-family: var(--font-code, "IBM Plex Mono", monospace);
  font-size: 11px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

.mo-surface-summary-v,
.mo-roadmap-summary-v,
.mo-closer-summary-v {
  color: var(--text-secondary);
}

.mo-surface-summary-v strong,
.mo-roadmap-summary-v strong,
.mo-closer-summary-v strong {
  color: var(--text-primary);
  font-weight: 600;
}

/* Act 5 roadmap — BU summary sits below the H2 in the sticky
   frame, occupying roughly the same vertical weight as the
   terminal mock. */
.mo-roadmap-summary {
  max-width: 640px;
  margin-inline: auto;
}

/* Act 6 closer — BU summary replaces the yaml spec block.
   Centred so it mirrors the centred closer composition. */
.mo-closer-summary {
  max-width: 560px;
  margin-inline: auto;
  text-align: left;
}
