/*
 * /compare/apify — minimal monochrome 4-act spoke.
 *
 * Same overall style as the Bright Data spoke (per CEO
 * direction — per-act BG transitions arrive in later spokes).
 * What's different per the page-identity mandate:
 *   - Page signature: "the catalog" (vs BD's "the wiring")
 *   - Act 2 inverts the bar logic: Apify SHRINKS (coverage),
 *     Zenrows holds FULL width (any URL)
 *   - Act 3 rhythm-break direction inverts: header pulled LEFT
 *     (BD pulled right), and the Apify Actor list (left col)
 *     is the offset-down column (BD offset the right col)
 *   - Act 4 closer mark is a 3-cell grid (vs BD's single wire)
 *
 * Universal chrome lives in ../../_shared/chrome.css.
 */

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

main { width: 100%; max-width: 100vw; position: relative; }

/* ───────────────────────────────────────────────────────────
   Act 1 — Pick a scraper.  Or write the one call.
─────────────────────────────────────────────────────────── */

.ap-act-1 {
  position: relative;
  min-height: 100vh;
  padding: clamp(96px, 14vh, 160px) clamp(20px, 4vw, 56px) clamp(72px, 10vh, 120px);
  background: var(--background);
  color: var(--text-primary);
  display: flex;
  align-items: center;
  justify-content: center;
}

.ap-act-1-frame {
  width: 100%;
  max-width: 1280px;
  display: flex;
  flex-direction: column;
  gap: clamp(40px, 5vw, 64px);
}

/* Hero is asymmetric.  Two-column grid: kicker + H1 anchor
   LEFT (the "lead" column, cols 1-7 mental grid), sub sits
   RIGHT (cols 8-12) and baselines against the H1's last line
   via `align-items: end`.  The two text blocks share the
   same bottom rule but live on opposite ends of the page —
   the alignment break is the layout, not a typography trick. */
.ap-hero--split {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: clamp(20px, 3vw, 56px);
  align-items: end;
}

.ap-hero-lead {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: clamp(14px, 1.6vw, 24px);
}

.ap-hero-kicker { margin: 0; }

.ap-hero-h1 {
  margin: 0;
  font-family: var(--font-display, var(--font-base));
  font-size: var(--mkt-hero-xl);
  line-height: 1.02;
  letter-spacing: -0.028em;
  font-weight: 500;
  color: var(--text-primary);
  max-width: 16ch;
  text-wrap: balance;
}

/* Second phrase in italic — visually "answers" the first
   line.  Italic carries the lift; weight drops 100 so it
   reads as a continuation, not a header re-statement. */
.ap-hero-h1-em {
  font-style: normal;
  font-weight: 500;
  color: var(--text-primary);
}

.ap-hero-sub {
  margin: 0;
  /* Sub sits in the right column, baselined to the H1's last
     line.  text-align right so the right edge stays clean
     and the eye reads it as a counterweight to the H1. */
  text-align: right;
  font-family: var(--font-base);
  font-size: var(--mkt-body);
  line-height: 1.55;
  color: var(--text-secondary);
  /* Push the sub to the right edge of its column. */
  margin-left: auto;
  max-width: 48ch;
}

/* Phone — the split collapses; sub jumps under the H1 and
   reverts to text-align: left so it doesn't look orphaned
   against an off-axis right edge on a narrow screen. */
@media (max-width: 760px) {
  .ap-hero--split {
    grid-template-columns: 1fr;
    gap: 18px;
    align-items: stretch;
  }
  .ap-hero-sub {
    text-align: left;
    margin-left: 0;
    max-width: 64ch;
  }
}

/* ── Stage widget (draggable before / after) ────────────────
   Full-width, big.  Two layers stack inside .ap-stage-frame:
     • .ap-stage-layer--zr  (bottom — always rendered)
     • .ap-stage-layer--ap  (top — clipped from the LEFT by
                              --reveal-x; drag handle controls
                              this var)
   The vertical handle sits at var(--reveal-x); dragging right
   reveals more Zenrows; left brings the Apify catalog back.
   Pattern modelled on /workflows/lead-enrichment Act 2.

   Both layers carry the same outer structure (header bar +
   body + foot) so the layouts align at the divider.  Only
   the Zenrows layer carries the orange→purple mesh bar — the
   wash IS the brand cue, so the divider is also a brand divider. */
.ap-stage {
  --reveal-x: 50%;
  position: relative;
  width: 100%;
  margin: 0 auto;
  user-select: none;
  isolation: isolate;
}

/* The inner frame holds both layers and clips them at its
   own bounds.  Height is fixed so the two layers align — no
   height jitter as the user drags. */
.ap-stage-frame {
  position: relative;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg, 16px);
  overflow: hidden;
  height: clamp(440px, 56vh, 640px);
}

/* Both layers share the same absolute inset so they stack
   pixel-perfect.  Apify gets z-index 2 + clip-path; Zenrows
   stays at z-index 1, always fully drawn. */
.ap-stage-layer {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  background: var(--background);
}

.ap-stage-layer--zr { z-index: 1; }
.ap-stage-layer--ap {
  z-index: 2;
  clip-path: inset(0 0 0 var(--reveal-x));
  transition: clip-path 60ms linear;
}
.ap-stage.is-dragging .ap-stage-layer--ap { transition: none; }

/* ── Header bars ───────────────────────────────────────── */
.ap-stage-bar {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 16px;
  /* Fixed min-height so both layer headers render at the same
     height regardless of inline content (the Zenrows tag is a
     pill with extra padding; the Apify tag is plain text). */
  min-height: 48px;
  border-bottom: 1px solid var(--border-subtle);
  overflow: hidden;
  isolation: isolate;
  flex-shrink: 0;
}

/* Mesh bar — only on the Zenrows layer.  Same orange-5 →
   purple-5 + 4 drifting bubbles pattern from the firecrawl /
   BD spokes. */
/* Mesh palette matches the /workflows/lead-enrichment hero
   terminal: green-7 → cyan-7 linear base + four drifting
   bubbles (green / cyan / purple / yellow).  Reads more
   "pipeline" than the orange/purple wash used elsewhere. */
.ap-stage-mesh {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  overflow: hidden;
  background: linear-gradient(
    135deg,
    var(--zen-green-7, #3FA371) 0%,
    var(--zen-cyan-7, #2BA8B8) 100%
  );
}

.ap-stage-mesh-bubble {
  position: absolute;
  width: 65%;
  height: 280%;
  border-radius: 50%;
  filter: blur(34px);
  transform: translateZ(0);
  backface-visibility: hidden;
  opacity: 0.9;
  will-change: transform;
}

.ap-stage-mesh-bubble[data-bubble="1"] { background: var(--zen-green-6, #6ED49A);  top: -90%;  left: -10%; animation: ap-bub-1 7s  ease-in-out infinite alternate; }
.ap-stage-mesh-bubble[data-bubble="2"] { background: #7ADAE6;   top: -80%;  left: 35%;  animation: ap-bub-2 9s  ease-in-out infinite alternate; }
.ap-stage-mesh-bubble[data-bubble="3"] { background: var(--zen-purple-6, #9B6FFF); top: -100%; left: 55%;  animation: ap-bub-3 11s ease-in-out infinite alternate; }
.ap-stage-mesh-bubble[data-bubble="4"] { background: var(--zen-yellow-6, #F5C56A); top: -85%;  left: 18%;  animation: ap-bub-4 13s ease-in-out infinite alternate; }

@keyframes ap-bub-1 { 0% { transform: translate(0,0); } 100% { transform: translate(55%, 20%); } }
@keyframes ap-bub-2 { 0% { transform: translate(0,0); } 100% { transform: translate(-40%, 30%); } }
@keyframes ap-bub-3 { 0% { transform: translate(0,0); } 100% { transform: translate(45%, -25%); } }
@keyframes ap-bub-4 { 0% { transform: translate(0,0); } 100% { transform: translate(-30%, -20%); } }

.ap-stage-bar > *:not(.ap-stage-mesh) { position: relative; z-index: 1; }

.ap-stage-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.32);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.18);
  flex-shrink: 0;
}

.ap-stage-bar--zr .ap-stage-dot { background: rgba(255, 255, 255, 0.5); }

.ap-stage-bar-name {
  margin-left: 8px;
  font-family: var(--font-code, "IBM Plex Mono"), monospace;
  font-size: 12px;
  font-weight: 600;
  color: var(--text-primary);
}

.ap-stage-bar--zr .ap-stage-bar-name { color: #FFFFFF; }

.ap-stage-bar-tag {
  margin-left: auto;
  font-family: var(--font-base);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  white-space: nowrap;
}

.ap-stage-bar-tag--zr {
  color: #5BE0AC;
  padding: 3px 8px;
  border-radius: 999px;
  background: rgba(91, 224, 172, 0.1);
  border: 1px solid rgba(91, 224, 172, 0.32);
}

/* ── Layer bodies ──────────────────────────────────────── */
.ap-stage-body {
  position: relative;
  flex: 1;
  padding: clamp(24px, 2.6vw, 36px);
  overflow: hidden;
}

.ap-stage-body--ap {
  display: flex;
  align-items: stretch;
}

.ap-stage-body--zr {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  justify-content: center;
  gap: 12px;
  max-width: 720px;
  margin: 0 auto;
}

/* Catalog grid — same as before but stretches to fill the
   layer body so the widget feels big.  The empty-pill stays
   dashed-amber as the punchline. */
.ap-stage-body--ap .ap-catalog {
  width: 100%;
  align-self: center;
}

/* ── Footers ───────────────────────────────────────────── */
.ap-stage-foot {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px 14px;
  padding: 12px 16px;
  border-top: 1px solid var(--border-subtle);
  flex-shrink: 0;
}

.ap-stage-credit {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.12);
}

/* Zenrows credit — brand purple so it carries the wedge. */
.ap-stage-credit--zr {
  color: #C7B0FF;
  background: rgba(124, 79, 232, 0.14);
  border-color: rgba(124, 79, 232, 0.4);
}

.ap-stage-includes {
  font-size: 12px;
  color: var(--text-tertiary);
  line-height: 1.4;
}

/* ── Draggable handle ──────────────────────────────────────
   Vertical rail at var(--reveal-x).  Knob is the affordance;
   the line is the divider continuation through the frame.
   Handle extends ~10px above and below the frame so the rail
   reads as a control independent of the layer edges. */
.ap-stage-handle {
  position: absolute;
  /* Frame is the first child of .ap-stage now; handle line
     extends 10px above and below the frame so the rail reads
     as a control independent of the layer edges. */
  top: -10px;
  bottom: -10px;
  left: var(--reveal-x);
  width: 48px;
  transform: translateX(-50%);
  z-index: 5;
  cursor: ew-resize;
  display: flex;
  align-items: center;
  justify-content: center;
  outline: none;
  touch-action: none;
}

.ap-stage-handle:focus-visible .ap-stage-handle-knob {
  border-color: var(--text-primary);
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.2);
}

.ap-stage-handle-line {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 50%;
  width: 1px;
  background: rgba(255, 255, 255, 0.32);
  transform: translateX(-0.5px);
}

.ap-stage-handle-knob {
  position: relative;
  width: clamp(40px, 3.6vw, 52px);
  height: clamp(40px, 3.6vw, 52px);
  border-radius: 50%;
  background: var(--background);
  border: 1px solid var(--border, var(--border-subtle));
  color: var(--text-secondary);
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 8px 20px -10px rgba(0, 0, 0, 0.7);
  transition:
    border-color 200ms ease,
    color 200ms ease,
    transform 200ms cubic-bezier(0.22, 1, 0.36, 1);
}

.ap-stage-handle-knob svg {
  width: 18px;
  height: 18px;
}

.ap-stage-handle:hover .ap-stage-handle-knob,
.ap-stage.is-dragging .ap-stage-handle-knob {
  border-color: var(--text-primary);
  color: var(--text-primary);
  transform: scale(1.06);
}

/* Subtle hint pulse on first reveal — same pattern as the
   lead-enrichment compare slider. */
@keyframes ap-stage-hint {
  0%, 100% { transform: scale(1); }
  40% { transform: scale(1.08); }
}
.ap-stage.is-revealed:not(.is-dragging):not(:hover) .ap-stage-handle-knob {
  animation: ap-stage-hint 1.6s ease-in-out 0.6s 2;
}

/* ── Apify catalog grid ────────────────────────────────────
   3×3 grid of Actor pills.  Each pill stagger-fades in on
   IO entry; the empty-state "your-target? build it" pill
   sits in the last slot with dashed border to call out the
   gap in coverage. */
.ap-catalog {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  align-content: start;
  flex: 1;
}

.ap-actor {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  padding: 10px 12px;
  border-radius: var(--radius-md, 10px);
  border: 1px solid var(--border-subtle);
  background: rgba(255, 255, 255, 0.015);
  font-family: var(--font-base);
  opacity: 0;
  transform: translateY(6px);
  transition:
    opacity 480ms cubic-bezier(0.22, 1, 0.36, 1),
    transform 480ms cubic-bezier(0.22, 1, 0.36, 1);
}

.ap-act-1.is-in .ap-actor { opacity: 1; transform: none; }

.ap-act-1.is-in .ap-actor[data-i="0"] { transition-delay: 120ms; }
.ap-act-1.is-in .ap-actor[data-i="1"] { transition-delay: 200ms; }
.ap-act-1.is-in .ap-actor[data-i="2"] { transition-delay: 280ms; }
.ap-act-1.is-in .ap-actor[data-i="3"] { transition-delay: 360ms; }
.ap-act-1.is-in .ap-actor[data-i="4"] { transition-delay: 440ms; }
.ap-act-1.is-in .ap-actor[data-i="5"] { transition-delay: 520ms; }
.ap-act-1.is-in .ap-actor[data-i="6"] { transition-delay: 600ms; }
.ap-act-1.is-in .ap-actor[data-i="7"] { transition-delay: 680ms; }
.ap-act-1.is-in .ap-actor[data-i="8"] { transition-delay: 800ms; }

.ap-actor-name {
  font-size: 12px;
  font-weight: 500;
  color: var(--text-primary);
  letter-spacing: -0.005em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  width: 100%;
  font-family: var(--font-code, "IBM Plex Mono"), monospace;
}

.ap-actor-runs {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

/* Empty-state actor pill — dashed border + amber accent so
   the gap in coverage reads as the punchline of the catalog. */
.ap-actor--empty {
  border-style: dashed;
  border-color: rgba(247, 188, 107, 0.4);
}
.ap-actor--empty .ap-actor-name { color: rgba(247, 188, 107, 0.85); }
.ap-actor--empty .ap-actor-runs { color: #F7BC6B; }

/* ── Zenrows state body content ─────────────────────────── */
.ap-zr-call,
.ap-zr-json {
  margin: 0;
  font-family: var(--font-code, "IBM Plex Mono"), monospace;
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-primary);
  white-space: pre-wrap;
  word-break: break-word;
}

.zr-fn { color: #C7B0FF; }
.zr-s  { color: #F7BC6B; }
.json-k { color: #C7B0FF; }
.json-s { color: #F7BC6B; }

.ap-zr-arrow {
  align-self: center;
  font-size: 14px;
  color: var(--text-tertiary);
  line-height: 1;
}

/* ───────────────────────────────────────────────────────────
   Act 2 — Coverage shape.

   Inverted vs BD: Apify bar SHRINKS as level rises (catalog
   coverage drops with niche-ness), Zenrows holds at FULL
   width (any URL).
─────────────────────────────────────────────────────────── */

.ap-act-2 {
  position: relative;
  background: var(--background);
  color: var(--text-primary);
  padding: clamp(96px, 12vh, 160px) clamp(20px, 4vw, 56px);
  display: flex;
  align-items: center;
  justify-content: center;
}

.ap-act-2-frame {
  width: 100%;
  max-width: 980px;
  display: flex;
  flex-direction: column;
  gap: clamp(40px, 5vw, 64px);
}

.ap-act-2-head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: clamp(14px, 1.6vw, 22px);
  max-width: 64ch;
}

.ap-act-2-h2 {
  margin: 0;
  font-family: var(--font-display, var(--font-base));
  font-size: var(--mkt-h2);
  line-height: 1.04;
  letter-spacing: -0.028em;
  font-weight: 500;
  color: var(--text-primary);
  text-wrap: balance;
}

.ap-act-2-sub {
  margin: 0;
  font-family: var(--font-base);
  font-size: var(--mkt-body);
  line-height: 1.55;
  color: var(--text-secondary);
  max-width: 60ch;
}

.ap-cov {
  display: flex;
  flex-direction: column;
  gap: clamp(32px, 4vw, 56px);
}

.ap-cov-rail {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(8px, 1vw, 16px);
  align-items: center;
}

.ap-cov-chip {
  appearance: none;
  -webkit-appearance: none;
  background: none;
  border: none;
  padding: 6px 2px 8px;
  font-family: var(--font-base);
  font-size: 13px;
  font-weight: 500;
  letter-spacing: -0.005em;
  color: var(--text-tertiary);
  cursor: pointer;
  position: relative;
  transition: color 220ms ease;
}

.ap-cov-chip::after {
  content: "";
  position: absolute;
  left: 2px;
  right: 2px;
  bottom: 0;
  height: 1px;
  background: var(--text-primary);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 280ms cubic-bezier(0.22, 1, 0.36, 1);
}

.ap-cov-chip:hover { color: var(--text-secondary); }

.ap-cov[data-ap-level="0"] .ap-cov-chip[data-ap-level="0"],
.ap-cov[data-ap-level="1"] .ap-cov-chip[data-ap-level="1"],
.ap-cov[data-ap-level="2"] .ap-cov-chip[data-ap-level="2"],
.ap-cov[data-ap-level="3"] .ap-cov-chip[data-ap-level="3"] {
  color: var(--text-primary);
}

.ap-cov[data-ap-level="0"] .ap-cov-chip[data-ap-level="0"]::after,
.ap-cov[data-ap-level="1"] .ap-cov-chip[data-ap-level="1"]::after,
.ap-cov[data-ap-level="2"] .ap-cov-chip[data-ap-level="2"]::after,
.ap-cov[data-ap-level="3"] .ap-cov-chip[data-ap-level="3"]::after {
  transform: scaleX(1);
}

.ap-cov-rows {
  display: flex;
  flex-direction: column;
  gap: clamp(20px, 2.4vw, 32px);
}

.ap-cov-row {
  display: grid;
  grid-template-columns: 120px 1fr 200px;
  gap: clamp(16px, 2vw, 28px);
  align-items: center;
}

.ap-cov-label {
  font-family: var(--font-base);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

.ap-cov-track {
  position: relative;
  display: block;
  height: 2px;
  background: var(--border-subtle);
  border-radius: 1px;
}

.ap-cov-fill {
  position: absolute;
  inset: 0 auto 0 0;
  width: var(--w, 100%);
  background: var(--text-primary);
  border-radius: 1px;
  transition: width 480ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* Apify SHRINKS as level rises (catalog coverage drops). */
.ap-cov[data-ap-level="0"] .ap-cov-fill--ap { --w: 100%; }
.ap-cov[data-ap-level="1"] .ap-cov-fill--ap { --w: 48%; }
.ap-cov[data-ap-level="2"] .ap-cov-fill--ap { --w: 18%; }
.ap-cov[data-ap-level="3"] .ap-cov-fill--ap { --w: 8%; }

/* Zenrows holds at full width (any URL). */
.ap-cov-fill--zr { --w: 100%; }

.ap-cov-caption {
  font-family: var(--font-base);
  font-size: 12px;
  letter-spacing: 0.01em;
  color: var(--text-tertiary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

@media (max-width: 720px) {
  .ap-cov-row { grid-template-columns: 1fr; gap: 8px; }
  .ap-cov-caption { white-space: normal; }
}

/* ───────────────────────────────────────────────────────────
   Act 3 — What you stop browsing.

   Rhythm-break + alignment-break.  Header LEFT (BD pulled it
   right — opposites so back-to-back acts don't read as a
   recipe).  Two columns on a diagonal: Apify Actor list LEFT
   pushed DOWN ~48-88px, ZR primitives RIGHT anchored top.
   Hover a ZR primitive: matching Apify Actors brighten via
   .is-active; non-matching dim via .is-hot on the wrap.
─────────────────────────────────────────────────────────── */

.ap-act-3 {
  position: relative;
  background: var(--background);
  color: var(--text-primary);
  padding: clamp(96px, 12vh, 160px) clamp(20px, 4vw, 56px);
  display: flex;
  align-items: center;
  justify-content: center;
}

.ap-act-3-frame {
  width: 100%;
  max-width: 1080px;
  display: flex;
  flex-direction: column;
  gap: clamp(56px, 6vw, 96px);
}

/* Header pulled to the RIGHT edge — alignment-break from
   Acts 1 + 2 (which anchor left).  H1 and sub share the same
   right-edge gutter so they read as a single column counter-
   weighted against the catalog column below on the left. */
.ap-act-3-head {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
  gap: clamp(14px, 1.6vw, 22px);
  max-width: 64ch;
  margin-left: auto;
}

.ap-act-3-h2 {
  margin: 0;
  font-family: var(--font-display, var(--font-base));
  font-size: var(--mkt-h2);
  line-height: 1.04;
  letter-spacing: -0.028em;
  font-weight: 500;
  color: var(--text-primary);
  text-wrap: balance;
}

.ap-act-3-sub {
  margin: 0;
  font-family: var(--font-base);
  font-size: var(--mkt-body);
  line-height: 1.55;
  color: var(--text-secondary);
  max-width: 52ch;
}

.ap-stop {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(40px, 6vw, 96px);
  align-items: start;
}

.ap-stop-col {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}

/* Apify col offset DOWN (BD spoke offset the right col;
   here it's the left).  Source row (ZR primitive) is on
   the right and anchored top — the user's eye finds the
   source first, then scans the offset target list. */
.ap-stop-col--ap {
  padding-top: clamp(48px, 5vw, 88px);
}

.ap-stop-actor {
  padding: 16px 0;
  border-top: 1px solid var(--border-subtle);
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 12px;
  transition: opacity 320ms ease, color 320ms ease;
}

.ap-stop-actor:last-child {
  border-bottom: 1px solid var(--border-subtle);
}

.ap-stop-actor-name {
  font-family: var(--font-code, "IBM Plex Mono"), monospace;
  font-size: var(--mkt-body);
  font-weight: 500;
  letter-spacing: -0.005em;
  color: var(--text-primary);
  transition: color 320ms ease;
}

.ap-stop-actor-price {
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  white-space: nowrap;
}

.ap-stop-actor--empty .ap-stop-actor-name { color: rgba(247, 188, 107, 0.85); }
.ap-stop-actor--empty .ap-stop-actor-price { color: #F7BC6B; }

.ap-stop-prim {
  position: relative;
  padding: 18px 0;
  border-top: 1px solid var(--border-subtle);
  display: flex;
  flex-direction: column;
  gap: 4px;
  cursor: pointer;
  transition: color 220ms ease;
}

.ap-stop-prim:last-child {
  border-bottom: 1px solid var(--border-subtle);
}

.ap-stop-prim-name {
  font-family: var(--font-code, "IBM Plex Mono"), monospace;
  font-size: var(--mkt-lead);
  font-weight: 500;
  letter-spacing: -0.005em;
  color: var(--text-primary);
  transition: color 220ms ease;
}

.ap-stop-prim-hint {
  font-family: var(--font-base);
  font-size: 12px;
  letter-spacing: 0.01em;
  color: var(--text-tertiary);
}

/* Source row mark — BD spoke put it on the LEFT (source was
   on the left there); here the source is on the right so the
   mark sits on the right edge, scaling out from the row. */
.ap-stop-prim::after {
  content: "";
  position: absolute;
  right: -16px;
  top: 50%;
  width: 8px;
  height: 1px;
  background: var(--text-primary);
  transform: translateY(-50%) scaleX(0);
  transform-origin: left;
  transition: transform 280ms cubic-bezier(0.22, 1, 0.36, 1);
}

.ap-stop-prim.is-source::after { transform: translateY(-50%) scaleX(1); }

.ap-stop.is-hot .ap-stop-actor { opacity: 0.32; }
.ap-stop.is-hot .ap-stop-actor.is-active { opacity: 1; }

.ap-stop-actor.is-active .ap-stop-actor-name { color: #FFFFFF; }
.ap-stop-actor.is-active .ap-stop-actor-price { color: #FFFFFF; }

@media (max-width: 720px) {
  .ap-stop { grid-template-columns: 1fr; gap: 32px; }
  .ap-stop-col--ap { padding-top: 0; }
  .ap-stop-actor { padding: 12px 0; }
  .ap-stop-prim { padding: 14px 0; }
  .ap-stop-prim::after { display: none; }
}

/* ───────────────────────────────────────────────────────────
   Act 4 — Closer.

   Centred brand-return.  3-cell catalog mark (vs BD's single
   wire) — quiet echo of Act 1's grid in miniature.  Cells
   scale in with stagger on IO entry.
─────────────────────────────────────────────────────────── */

.ap-act-4 {
  position: relative;
  background: var(--background);
  color: var(--text-primary);
  padding: clamp(120px, 18vh, 220px) clamp(20px, 4vw, 56px);
  display: flex;
  align-items: center;
  justify-content: center;
}

.ap-act-4-frame {
  width: 100%;
  max-width: 920px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: clamp(24px, 2.6vw, 36px);
}

.ap-act-4-kicker { margin: 0; }

.ap-act-4-h2 {
  margin: 0;
  font-family: var(--font-display, var(--font-base));
  font-size: var(--mkt-hero);
  line-height: 1.02;
  letter-spacing: -0.03em;
  font-weight: 500;
  color: var(--text-primary);
  max-width: 18ch;
  text-wrap: balance;
}

.ap-act-4-em {
  font-style: normal;
  font-weight: 500;
  color: var(--text-primary);
}

.ap-act-4-cta {
  margin-top: clamp(8px, 1vw, 16px);
  gap: 14px;
}

.ap-act-4-secondary {
  font-family: var(--font-base);
  font-size: var(--text-small, 13px);
  font-weight: 600;
  color: var(--text-primary);
  text-decoration: underline;
  text-underline-offset: 4px;
  text-decoration-thickness: 1.5px;
  text-decoration-color: rgba(255, 255, 255, 0.3);
  transition: text-decoration-color 180ms;
}

.ap-act-4-secondary:hover { text-decoration-color: rgba(255, 255, 255, 0.8); }

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

/* Widget stays at width: 100% of the frame at every tier —
   no max-width cap.  At wide-desktop the frame itself grows
   (clamp(1280→1480→1680→2000)) and the stage grows with it. */
@media (min-width: 1600px) {
  .ap-act-1-frame { max-width: 1480px; gap: 80px; }
  
  .ap-hero-sub { font-size: 22px; }
  .ap-stage-frame { height: clamp(480px, 56vh, 700px); }
  .ap-catalog { gap: 12px; }
}

@media (min-width: 1920px) {
  .ap-act-1-frame { max-width: 1680px; }
  
  .ap-hero-sub { font-size: 24px; }
  .ap-stage-frame { height: clamp(540px, 58vh, 760px); }
}

@media (min-width: 2400px) {
  .ap-act-1-frame { max-width: 2000px; }
  
  .ap-hero-sub { font-size: 26px; }
  .ap-stage-frame { height: clamp(620px, 60vh, 840px); }
}

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

@media (max-width: 600px) {
  .ap-act-1 { padding-top: clamp(80px, 14vh, 120px); }
  
  .ap-hero-sub { font-size: 15px; }
  .ap-stage-frame { height: clamp(360px, 60vh, 480px); }
  .ap-stage-bar { gap: 8px; padding: 10px 14px; }
  .ap-stage-bar-tag { display: none; }
  .ap-stage-body { padding: 16px; }
  .ap-catalog { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ap-actor { padding: 8px 10px; }
  .ap-actor-name { font-size: 11px; }
  .ap-actor-runs { font-size: 9px; }
  .ap-zr-call, .ap-zr-json { font-size: 12px; }
  .ap-stage-foot { padding: 10px 14px; }
  .ap-stage-includes { font-size: 11px; }
  .ap-act-4 { padding: clamp(80px, 14vh, 140px) clamp(20px, 4vw, 56px); }
  
}

/* ══════════════════════════════════════════════════════════
   BU light overrides.  --font-display auto-flips to Mq12 via
   DS-level override.
═══════════════════════════════════════════════════════════ */
html:not(.dark) body {
  background: var(--zen-gray-3);
  color: var(--text-primary);
}

html:not(.dark) .ap-stage-dot { background: rgba(29, 22, 18, 0.32); }
html:not(.dark) .ap-stage-bar--zr .ap-stage-dot { background: rgba(29, 22, 18, 0.5); }
html:not(.dark) .ap-stage-credit {
  background: rgba(29, 22, 18, 0.04);
  border-color: rgba(29, 22, 18, 0.12);
}
html:not(.dark) .ap-stage-handle:focus-visible .ap-stage-handle-knob {
  box-shadow: 0 0 0 2px rgba(29, 22, 18, 0.2);
}
html:not(.dark) .ap-stage-handle-line { background: rgba(29, 22, 18, 0.32); }
html:not(.dark) .ap-actor { background: rgba(29, 22, 18, 0.015); }
html:not(.dark) .ap-act-4-secondary { text-decoration-color: rgba(29, 22, 18, 0.3); }
html:not(.dark) .ap-act-4-secondary:hover { text-decoration-color: rgba(29, 22, 18, 0.8); }
