/* ==========================================================================
   drops.st — funnel.css
   Mobile-first vertical scroll-snap funnel, 7 slides.
   Respects prefers-reduced-motion. Works with landing.css as base.
   ========================================================================== */

:root {
  /* ─── Color ───────────────────────────────────── */
  --ink:        #0b0b0b;
  --ink-soft:   rgba(11, 11, 11, 0.62);
  --ink-faint:  rgba(11, 11, 11, 0.38);
  --hairline:   rgba(11, 11, 11, 0.08);
  --paper:      #ffffff;
  --paper-tint: #f6f5f2;
  --accent:     #e5472a; /* drop-rain red */
  --dark-bg:    #0a0a0a;
  --dark-fg:    #ffffff;

  /* Tokens previously duplicated in landing.css — single source of truth here.
     --font name MUST match @font-face declaration in landing.css ('Hanken Grotesk'
     with space). funnel.css body still hard-codes 'HankenGrotesk' on line ~41 —
     that's a pre-existing inconsistency, intentionally not touched here. */
  --font: 'Hanken Grotesk', Helvetica, Arial, Verdana, sans-serif;
  --bg:   #fff;
  --fg:   #000;
  --blue: #00c;

  /* ─── Radii ──────────────────────────────────── */
  --radius-pill: 999px;
  --radius-card: 14px;

  /* ─── Type scale ─────────────────────────────── */
  /* Headline floor lowered 28→24 — long copy at 28/lh:1.04 wrapped to 3 lines
     on iPhone SE, eating ~87px before any body content. */
  --step-head:  clamp(24px, 6.5vw, 60px);
  --step-huge:  clamp(44px, min(13vw, 14vh), 100px);
  --step-body:  clamp(15px, 2.3vw, 19px);
  --step-small: 12px;

  /* ─── Spacing scale (4px baseline) ───────────── */
  --space-xs:  4px;
  --space-sm:  8px;
  --space-md:  clamp(12px, 2vw, 16px);
  --space-lg:  clamp(16px, 3vw, 24px);
  --space-xl:  clamp(20px, 4vw, 32px);
  --space-2xl: clamp(28px, 6vw, 48px);
  --space-3xl: clamp(40px, 8vw, 64px);

  /* ─── Slide layout (the main spacing knobs) ─── */
  /* Top padding tuned for `justify-content: flex-start` — content lands at
     ~12% from viewport top, the Stripe/Linear/Vercel "upper-third" feel.
     Floor 60px clears the 56px hamburger button (top:12 + 44 height) on
     short phones; 12vh midpoint resolves to 80px on iPhone SE / 89px on
     iPhone 12 Mini / 96px on desktop; 120px ceiling keeps iPad portrait
     from feeling glued to the top. */
  --slide-pad-x:          clamp(16px, 6vw, 32px);
  --slide-pad-top:        clamp(60px, 12vh, 120px);
  --slide-pad-bottom:     clamp(16px, 3vh, 40px);
  --slide-safe-top:       max(var(--slide-pad-top),    calc(env(safe-area-inset-top, 0px) + 16px));
  --slide-safe-bottom:    max(var(--slide-pad-bottom), calc(env(safe-area-inset-bottom, 0px) + 16px));
  --slide-max-width:      620px;
  --slide-max-width-wide: 1200px;

  /* ─── Gallery component (keys to overflow fix) ─── */
  /* --gallery-pad-top floor bumped 36→60 to match --slide-pad-top floor —
     gallery slides use their own padding token (because the parent .slide gets
     padding:0 to let the gallery layout span full-bleed), but the FOUNDATION
     rule "no slide content under the 56px hamburger zone" still applies. */
  --gallery-gap:          clamp(8px, 1.4vh, 16px);
  --gallery-pad-top:      clamp(32px, 5.5vh, 60px);
  --gallery-pad-bottom:   clamp(8px, 1.6vh, 20px);
  --gallery-text-max:     420px;
  /* min(vw, vh) lets phone frame shrink when EITHER axis is short — iPhone SE killer move.
     Tightened 2026-05-08 (round 3): 40vw/23vh → 36vw/20vh; max 180 → 168.
     With CTAs and checkmark lists overflowing on iPhone SE (172-232px clip on
     gallery slides), every saved px helps. New 135×240 frame is still readable
     and trims ~27px of slide height vs the previous 150×267. */
  --phone-frame-width:    clamp(104px, min(32vw, 18vh), 152px);

  /* ─── Breakpoint constants (documentation only; @media still uses literals) ─── */
  --bp-xs:      360px;
  --bp-sm:      480px;
  --bp-md:      720px;
  --bp-lg:      1024px;
  --bp-h-short: 700px;   /* short-viewport guard threshold (iPhone SE portrait, landscape phones) */

  /* ─── Engine-tile component (slide 4 — features-showcase) ───
     One token per layout phase: phone / tablet+desktop / short viewport.
     Floor 112 protects the radial bloom + pulse beacon geometry; below
     that the cinematic feel collapses (radial gradient under-bleeds). */
  --engine-tile-min-h:    clamp(112px, 13vh, 130px);
  --engine-tile-min-h-md: 150px;
  --engine-tile-min-h-sh: clamp(96px, 12vh, 110px);

  /* ─── Easing ─────────────────────────────────── */
  --ease-out:   cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* Dark-mode auto-switch intentionally DISABLED 2026-04-24:
   user reported that desktop (dark-mode OS) and mobile (light-mode OS) were
   rendering the funnel inconsistently. Brand direction is light-only so the
   NYC street-sign pattern-interrupt always lands. Re-enable only if the
   brand evolves to support both themes deliberately. */

/* Global funnel page overrides */
html, body {
  margin: 0;
  padding: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: 'HankenGrotesk', system-ui, -apple-system, sans-serif;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

.funnel {
  position: relative;
}

/* --- scroll-snap container --------------------------------------------- */

.slides {
  /* `proximity` (not `mandatory`) lets users pan freely inside slides taller
     than the viewport — snap only kicks in near a slide boundary. Combined
     with `scroll-snap-stop: normal` on each slide, multi-slide flings glide
     instead of getting trapped at every slide edge. Foundation fix for the
     "tall slide hides content with no way to scroll" complaint.

     NOTE: do NOT add `scroll-padding-top` here. Tried 2026-05-08, removed
     same day — it leaks 60px of the PREVIOUS slide above the snap-aligned
     slide on every transition (white intro tail above dark gallery, etc).
     Hamburger clearance is handled INSIDE each slide via `--slide-safe-top`
     (60-120px floor, see :root token at line 57) — that's the right layer
     because it scopes clearance to slide content, not to slide chrome. */
  /* `block` (logical axis) instead of `y` — same vertical behavior in LTR/horizontal-tb
     writing-mode, future-proofs for any vertical-text variants and matches the modern
     spec direction. */
  scroll-snap-type: block proximity;
  overflow-y: scroll;
  overflow-x: hidden;
  /* Container uses `dvh` so it grows when iOS URL bar hides — gives users the most
     visible scroll-port. Slide children use `svh` (see .slide rule) so individual
     slides are stable and don't reflow when the bar collapses. */
  height: 100vh;
  height: 100dvh;
  scroll-behavior: smooth;
  overscroll-behavior: contain;       /* prevent rubber-band reveal of bg */
  /* Isolate paint to the snap viewport — repaint cost on multi-slide flings stays
     bounded to the visible region instead of repainting all 7-11 slides. */
  contain: paint;
  will-change: scroll-position;
}

@media (prefers-reduced-motion: reduce) {
  .slides { scroll-behavior: auto; }
}

/* --- slides ------------------------------------------------------------ */

.slide {
  scroll-snap-align: start;
  scroll-snap-stop: normal;       /* was: always — let users glide past tall slides */
  /* `svh` = smallest viewport height — slide stays a stable size even when
     iOS/Android URL bar shows/hides. Prevents snap re-anchoring jitter mid-scroll
     (WebKit Bug 173887) and stops false IO threshold crossings as the bar toggles.
     The container uses `dvh` so the visible scroll-port still gets every pixel. */
  min-height: 100vh;
  min-height: 100svh;
  width: 100%;
  display: flex;
  flex-direction: column;
  /* Top-aligned by default, like a professional landing page (Stripe, Linear,
     Vercel). Audit (2026-05-08, 24 slides × 4 viewports) showed centering
     wasted ~130px above and ~104px below content — a third of the viewport
     was dead whitespace. Top-align makes content position deterministic
     instead of incidental-on-overflow. Pattern-interrupt slides (the poster-
     style "More sales" / "DROPS vs Shopify" full-bleed statements) opt back
     into vertical centering via the override below. */
  justify-content: flex-start;
  align-items: center;
  /* Padding picks the larger of the design token or safe-area-inset on each
     side — same pattern handles portrait notch (top), landscape Dynamic Island
     (left/right) and home indicator (bottom). */
  padding:
    var(--slide-safe-top)
    max(var(--slide-pad-x), env(safe-area-inset-right, 0px))
    var(--slide-safe-bottom)
    max(var(--slide-pad-x), env(safe-area-inset-left, 0px));
  box-sizing: border-box;
  position: relative;
  text-align: center;
  background: var(--paper);
  color: var(--ink);
}

/* Poster-style slides: keep vertical centering. These are dramatic, low-
   density "moment" slides ("$0/mo", "More sales. More bag.", "DROPS vs
   yesterday") where centering reads as an intentional full-bleed statement. */
.slide--pattern_interrupt,
#diagnosis {
  justify-content: safe center;
}

/* Slide 2 (diagnosis) — nudge content slightly above true center for
   visual balance (the eyebrow + headline + sub + open-loop reads heavier
   at the top than the open-loop arrow does at the bottom). Adding bottom
   padding shifts the flex-centered content area upward by ~half the delta. */
#diagnosis {
  padding-bottom: calc(var(--slide-safe-bottom) + clamp(56px, 9vh, 110px));
}

.slide__inner {
  max-width: var(--slide-max-width);
  width: 100%;
}

.slide__logo {
  display: inline-block;
  margin: 0 0 clamp(24px, 5vh, 56px);
}

.slide__eyebrow {
  display: inline-block;
  text-transform: uppercase;
  letter-spacing: 0.16em;
  font-size: 11px;
  color: var(--ink-faint);
  font-weight: 700;
  margin-bottom: clamp(14px, 2vh, 22px);
  padding: 6px 12px;
  border: 1px solid var(--hairline);
  border-radius: var(--radius-pill);
}

.slide__headline {
  font-size: var(--step-head);
  font-weight: 800;
  /* Line-height 1.04→1.10: still tight, but stops the descenders/ascenders
     of multi-line headlines from kissing — saves nothing on 1-line copy
     but improves legibility on the 2-3 line wraps that overflowed. */
  line-height: 1.10;
  letter-spacing: -0.025em;
  margin: 0 0 0.5em;
  max-width: 18ch;
  margin-left: auto;
  margin-right: auto;
  color: var(--ink);
}

.slide__sub {
  font-size: var(--step-body);
  /* Line-height 1.42→1.35 saves ~5px per line of subhead copy. On
     long 5-line subs (autonomous slide), that's ~25px back. */
  line-height: 1.35;
  color: var(--ink-soft);
  max-width: 34ch;
  margin: 0 auto;
}

/* Mobile-only sub size trim: 14px on narrow viewports lets longer subs
   like the diagnosis "Menu, Telegram bot, marketing automation, crypto…"
   wrap to 4 lines instead of 6. */
@media (max-width: 480px) {
  .slide__sub { font-size: 14px; }
}

.slide__footnote {
  margin-top: clamp(18px, 3vh, 32px);
  font-size: 13px;
  color: var(--ink-faint);
}

.slide__open-loop {
  margin-top: clamp(32px, 6vh, 72px);
  font-size: 13px;
  color: var(--ink-faint);
  text-transform: lowercase;
  letter-spacing: 0.04em;
}

/* --- forward cue (downward bounce) ------------------------------------ */

.forward-cue {
  position: absolute;
  bottom: max(3vh, env(safe-area-inset-bottom, 16px));
  left: 50%;
  transform: translateX(-50%);
  color: var(--ink-faint);
  font-size: 20px;
  line-height: 1;
  animation: bob 1.8s ease-in-out infinite;
  pointer-events: none;
}

@keyframes bob {
  0%, 100% { transform: translate(-50%, 0); }
  50%      { transform: translate(-50%, 6px); }
}

@media (prefers-reduced-motion: reduce) {
  .forward-cue { animation: none; }
}

/* --- progress bar + counter (bottom of viewport) --------------------- */

.progress-rail {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  height: 3px;
  background: var(--hairline);
  z-index: 60;
}
.progress-fill {
  height: 100%;
  background: var(--ink);
  transition: width 420ms var(--ease-out);
}

.slide-counter {
  position: fixed;
  bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  left: 14px;
  font-size: 11px;
  color: var(--ink-faint);
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.04em;
  z-index: 60;
  padding: 4px 10px;
  background: var(--paper);
  border-radius: var(--radius-pill);
  border: 1px solid var(--hairline);
}
.counter-sep {
  margin: 0 2px;
  opacity: 0.5;
}

/* --- site header (Telegram link, top-LEFT) ----------------------------
   Anchored left so it never collides with the hamburger (top-right).
   !important on position:fixed beats landing.css's position:relative. */

.site-header.site-header--funnel {
  position: fixed !important;
  top: 14px;
  left: 14px;
  right: auto;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 6px;
  z-index: 55;
  pointer-events: none;
}

.site-header__nav {
  display: flex;
  gap: 6px;
  pointer-events: auto;
}

/* --- persistent header logo (top-LEFT corner) -------------------------
   Replaces the legacy "Telegram" text link. Always-on home anchor that
   crossfades with the hero .slide__logo on slides where show_logo:true.
   The "scale" sensation is produced by the hero logo's own entrance
   animation, not a FLIP swap — simpler, viewport-agnostic, mobile-safe. */

.header-logo {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  /* Generous tap target without enlarging visual footprint */
  padding: 6px 8px;
  margin: -6px -8px;
  border-radius: var(--radius-pill);
  pointer-events: auto;
  /* Smoothly fades out when a hero-logo slide is in view */
  opacity: 1;
  transform: translateY(0) scale(1);
  transition:
    opacity 360ms var(--ease-out),
    transform 480ms var(--ease-out);
  will-change: opacity, transform;
}

.header-logo__img {
  display: block;
  width: 84px;
  height: auto;
  filter: drop-shadow(0 1px 6px rgba(0, 0, 0, 0.18));
  transition: filter 220ms;
}

.header-logo:hover .header-logo__img,
.header-logo:focus-visible .header-logo__img {
  filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 0.32));
  outline: none;
}

@media (min-width: 768px) {
  .header-logo__img { width: 104px; }
}

/* Hero-logo state (set by funnel.js on .funnel when current slide
   contains .slide__logo). Corner logo collapses up-and-out so it doesn't
   compete with the slide's big hero logo. */
.funnel.has-hero-logo .header-logo {
  opacity: 0;
  transform: translateY(-6px) scale(0.6);
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .header-logo {
    transition: opacity 0ms;
    transform: none !important;
  }
  .funnel.has-hero-logo .header-logo {
    transform: none !important;
  }
}

/* --- skip-to-telegram link ------------------------------------------- */

.skip-link {
  position: fixed;
  top: 66px;   /* below burger bottom (12px top + 44px height + 10px gap) */
  right: 14px;
  font-size: 11px;
  color: var(--ink-faint);
  text-decoration: none;
  padding: 3px 10px;
  background: var(--paper);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-pill);
  z-index: 58;
  opacity: 0;
  pointer-events: none;
  transition: opacity 280ms var(--ease-out);
}
.skip-link.is-visible {
  opacity: 1;
  pointer-events: auto;
}

/* --- telegram floating CTA -------------------------------------------
   Uses Telegram brand blue so it stays visible on both light slides
   AND the dark pattern-interrupt slide. 56×56 circular on mobile
   (WCAG / Material FAB sizing), pill with label on desktop. */

.telegram-fab {
  --tg-blue: #229ed9;
  --tg-blue-hover: #1fb2ef;
  position: fixed;
  right: 18px;
  bottom: max(18px, calc(env(safe-area-inset-bottom, 0px) + 14px));
  background: var(--tg-blue);
  color: #ffffff;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 14px 22px;
  border-radius: var(--radius-pill);
  font-size: 15px;
  font-weight: 700;
  line-height: 1;
  text-decoration: none;
  box-shadow: 0 10px 28px rgba(34, 158, 217, 0.38), 0 2px 6px rgba(0,0,0,0.12);
  opacity: 0;
  transform: translateY(16px) scale(0.92);
  transition: opacity 260ms var(--ease-out),
              transform 260ms var(--ease-out),
              box-shadow 200ms var(--ease-out);
  pointer-events: none;
  z-index: 70;
  min-height: 48px;
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent;
}

.telegram-fab svg {
  width: 22px;
  height: 22px;
  flex-shrink: 0;
  display: block;
}

.telegram-fab.is-visible {
  opacity: 1;
  transform: translateY(0) scale(1);
  pointer-events: auto;
}

.telegram-fab:hover {
  background: var(--tg-blue-hover);
  box-shadow: 0 14px 32px rgba(34, 158, 217, 0.48), 0 2px 6px rgba(0,0,0,0.12);
}

.telegram-fab:active {
  transform: translateY(0) scale(0.96);
}

@media (max-width: 640px) {
  .telegram-fab {
    right: 16px;
    bottom: max(16px, calc(env(safe-area-inset-bottom, 0px) + 12px));
    width: 58px;
    height: 58px;
    padding: 0;
    border-radius: 50%;
    gap: 0;
  }
  .telegram-fab svg { width: 26px; height: 26px; }
  .telegram-fab__label { display: none; }
}

/* --- slide types ------------------------------------------------------ */

/* slide: hook — NYC street sign (MUTCD D3-1 style) --------------------
   Built from real MUTCD D3-1 street name sign specs:
   • Aspect ratio ~4:1 wide (horizontal blade, not a square badge)
   • Cap height ~67% of blade height (6"/9" per MUTCD ≤40mph)
   • Single thin inset border (set in from the blade edge) —
     NOT a thick frame; real signs have a hairline inner rule only
   • Black text on white bg = valid MUTCD D3-1 (white background variant
     REQUIRES black legend + black border per §2D.43 ¶17–18)
   • Condensed sans-serif @ weight 900 approximates FHWA Highway Gothic
   Always black-on-white in BOTH light AND dark modes — NYC signs
   do not invert. drops-rain.js still anchors to .home-logo .sign-badge. */

.slide--hook .slide__logo {
  display: flex;
  justify-content: center;
  margin: 0 0 clamp(36px, 8vh, 80px);
}

/* NYC ONE WAY sign style (MUTCD R6-1):
   Black field, pure white Highway Gothic legend, single thin white border.
   Flat, minimal — no moat, no rivets, no shadow theatrics. */
.slide--hook .sign-badge {
  position: relative;
  display: inline-block;
  background: #000000 !important;
  color: #ffffff !important;
  border: 2px solid #ffffff !important;
  border-radius: 5px;
  /* R6-1 aspect ~3:1 with cap-height ~67% of panel */
  padding: 14px 44px;
  /* FHWA Series C surrogate — Overpass is literally a Highway Gothic clone */
  font-family: 'Overpass', 'Helvetica Neue', 'Arial', sans-serif;
  font-weight: 800;
  font-stretch: condensed;
  font-size: clamp(28px, 7.2vw, 42px);
  letter-spacing: 0;
  text-transform: uppercase;
  line-height: 1;
  text-decoration: none;
  /* Near-flat: real signs cast almost no shadow in daylight */
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.18), 0 3px 10px rgba(0, 0, 0, 0.15);
  white-space: nowrap;
  -webkit-font-smoothing: antialiased;
  text-rendering: geometricPrecision;
}

.slide--hook .sign-badge > span {
  position: relative;
  z-index: 2;
  color: #ffffff !important;
  display: inline-block;
  background: transparent !important;
}

/* slide: number_hook — same shape as hook, emphasised number in headline  */
.slide--number_hook .slide__headline {
  font-size: clamp(30px, 7.8vw, 64px);
}

/* slide: mechanism — similar but with open-loop */
.slide--mechanism .slide__headline {
  max-width: 20ch;
}

/* slide: pattern_interrupt (zeros) — ALWAYS the opposite of the rest of
   the deck, in both light AND dark modes. In light mode = dark slide.
   In dark mode = light slide. Pattern interrupt only works if it breaks
   the visual rhythm; it has to invert whatever the body is. */
.slide--pattern_interrupt {
  background: var(--dark-bg);
  color: var(--dark-fg);
}
.slide--pattern_interrupt .zero-line {
  color: var(--dark-fg);
}
.slide--pattern_interrupt .slide__footnote {
  color: rgba(255, 255, 255, 0.56);
  margin-top: clamp(24px, 4vh, 40px);
}

/* Pattern-interrupt dark-mode invert removed — site is light-only,
   so slide 4 stays dark regardless of OS preference. */
.zeros {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(4px, 0.8vh, 10px);
}
.zero-line {
  font-size: var(--step-huge);
  font-weight: 900;
  line-height: 0.95;
  letter-spacing: -0.035em;
  color: var(--dark-fg);
}

/* slide: objection */
.objection-quoted {
  font-size: clamp(20px, 4vw, 28px);
  font-style: italic;
  font-weight: 500;
  color: var(--ink-faint);
  max-width: 22ch;
  margin: 0 auto clamp(18px, 3vh, 32px);
  line-height: 1.3;
}
.objection-answer {
  font-size: clamp(28px, 6.5vw, 52px);
  font-weight: 800;
  letter-spacing: -0.02em;
  line-height: 1.05;
  margin: 0 auto 0.6em;
  max-width: 18ch;
}

/* slide: respect */
.respect-list {
  list-style: none;
  padding: 0;
  /* Margin-top reduced 24→14px floor — the eyebrow+headline+sub above already
     creates separation; 24px floor was double-spacing on tight viewports. */
  margin: clamp(14px, 3vh, 32px) auto 0;
  text-align: left;
  max-width: 28ch;
}
.respect-list li {
  font-size: clamp(15px, 2.3vw, 18px);
  /* lh 1.45→1.35 + padding 14→10px saves 12px per item; team/respect slide on
     iPhone SE was +28 over viewport — this brings it back in fold. */
  line-height: 1.35;
  padding: 10px 0;
  border-bottom: 1px solid var(--hairline);
  position: relative;
  padding-left: 22px;
  color: var(--ink);
}
.respect-list li::before {
  content: '✓';
  position: absolute;
  left: 0;
  top: 10px;
  width: auto;
  height: auto;
  background: none;
  color: var(--accent);
  font-size: 13px;
  font-weight: 800;
  line-height: 1;
}
.respect-list li:last-child {
  border-bottom: none;
}

/* slide: feature_grid (Features page — dense category layouts) */
.slide__headline--compact {
  font-size: clamp(22px, 4.4vw, 34px);
  line-height: 1.12;
  margin-bottom: clamp(8px, 1.5vh, 16px);
  max-width: 28ch;
}
.slide__sub--compact {
  font-size: clamp(14px, 2vw, 16px);
  max-width: 36ch;
  margin: 0 auto clamp(12px, 2vh, 22px);
}
.feature-grid {
  list-style: none;
  padding: 0;
  margin: clamp(14px, 2.5vh, 24px) auto 0;
  max-width: min(640px, 92vw);
  display: grid;
  grid-template-columns: 1fr;
  column-gap: 22px;
  row-gap: 0;
  text-align: left;
}
@media (min-width: 720px) {
  .feature-grid { grid-template-columns: 1fr 1fr; }
}
.feature-grid li {
  font-size: clamp(13px, 1.85vw, 14.5px);
  /* Line-height 1.42→1.35 + padding 9→7px saves 6px per item; on 6-item lists
     that's ~36px back on overflowing feature slides. */
  line-height: 1.35;
  padding: 7px 0 7px 20px;
  border-bottom: 1px solid var(--hairline);
  position: relative;
  color: var(--ink);
}
.feature-grid li::before {
  content: '✓';
  position: absolute;
  left: 0; top: 7px;
  color: var(--accent);
  font-size: 12px;
  font-weight: 800;
  line-height: 1.45;
}
.slide--feature_grid .slide__inner {
  /* Was clamp(48px, 7vh, 72px) / clamp(40px, 6vh, 60px) — added on TOP of the
     parent .slide padding for a combined ~120-130px on iPhone SE. Tightened
     to roughly half that since `safe center` keeps content visible without
     extra breathing room. Mobile floor further tightened in the (max-width:480)
     block below — stacking on .slide's --slide-safe-* was eating ~36px on SE. */
  padding-top: clamp(20px, 3vh, 48px);
  padding-bottom: clamp(16px, 2.5vh, 36px);
}
@media (max-width: 480px) {
  .slide--feature_grid .slide__inner {
    padding-top:    clamp(8px, 1.5vh, 20px);
    padding-bottom: clamp(8px, 1.5vh, 16px);
  }
  .feature-grid li         { padding: 5px 0 5px 18px; }
  .feature-grid li::before { top: 5px; }   /* keep checkmark aligned with new padding */
}

/* slide: cta */
.slide--cta .slide__headline {
  margin-bottom: 0.4em;
}
.cta-primary {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: clamp(20px, 3vh, 32px);
  padding: 18px 36px;
  background: var(--ink);
  color: var(--paper);
  text-decoration: none;
  font-weight: 800;
  font-size: 17px;
  border-radius: var(--radius-pill);
  box-shadow: 0 6px 24px rgba(0,0,0,0.16);
  transition: transform 180ms var(--ease-out), box-shadow 180ms var(--ease-out);
}
.cta-primary:hover {
  transform: translateY(-2px);
  box-shadow: 0 10px 30px rgba(0,0,0,0.22);
}
.cta-assurance {
  margin-top: clamp(14px, 2.4vh, 22px);
  font-size: 13px;
  color: var(--ink-faint);
}
.cta-email {
  margin-top: clamp(28px, 5vh, 52px);
  padding-top: clamp(20px, 3vh, 28px);
  border-top: 1px solid var(--hairline);
}
.cta-email__label {
  font-size: 13px;
  color: var(--ink-soft);
  margin: 0 0 10px;
}
.cta-email__row {
  display: inline-flex;
  gap: 6px;
  align-items: center;
  max-width: 100%;
  flex-wrap: wrap;
  justify-content: center;
}
.cta-email input[type=email] {
  padding: 11px 14px;
  font-size: 14px;
  border: 1px solid var(--hairline);
  border-radius: 8px;
  background: var(--paper);
  color: var(--ink);
  width: 220px;
  max-width: 100%;
  font-family: inherit;
}
.cta-email input[type=email]:focus {
  outline: none;
  border-color: var(--ink);
}
.cta-email button {
  padding: 11px 18px;
  font-size: 14px;
  border: 1px solid var(--ink);
  background: transparent;
  color: var(--ink);
  border-radius: 8px;
  font-family: inherit;
  font-weight: 600;
  cursor: pointer;
  transition: background 180ms, color 180ms;
}
.cta-email button:hover {
  background: var(--ink);
  color: var(--paper);
}
.cta-email__feedback {
  min-height: 18px;
  margin-top: 8px;
  font-size: 12px;
  color: var(--ink-soft);
}
.cta-email__feedback.is-error { color: var(--accent); }
.cta-email__feedback.is-success { color: #2a8e3e; }

.cta-footer {
  margin-top: clamp(40px, 7vh, 80px);
  display: flex;
  gap: 18px;
  justify-content: center;
  font-size: 12px;
  flex-wrap: wrap;
}
.cta-footer a {
  color: var(--ink-faint);
  text-decoration: none;
}
.cta-footer a:hover { color: var(--ink); }

/* Slide entrance animations removed 2026-05-08 — the per-element fade+rise
   on intersection felt dated (2005-era reveal pattern). Modern apps (Linear,
   Vercel, Stripe, Apple) present content instantly when in view; the snap
   transition itself is the only motion needed. .is-visible class still
   toggles for analytics + the existing live-pulse / drop-rain effects that
   key off it, but no longer triggers opacity/transform transitions. */

@media (prefers-reduced-motion: reduce) {
  /* Flatten entrance animations, but DO NOT touch Swiper internals —
     Swiper uses transform on .swiper-wrapper / .swiper-slide / pagination to
     physically move slides. Excluding any class starting with "swiper" keeps
     the carousel functional while still flattening copy fade-ins. */
  .slide *:not([class*="swiper"]) {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}

/* --- exit-intent modal ------------------------------------------------ */

.exit-modal {
  position: fixed;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 200;
  padding: 16px;
}
.exit-modal.is-visible {
  display: flex;
  animation: modalFade 200ms var(--ease-out);
}
.exit-modal__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.42);
  backdrop-filter: blur(2px);
}
.exit-modal__box {
  position: relative;
  background: var(--paper);
  color: var(--ink);
  border-radius: var(--radius-card);
  padding: 32px 24px 24px;
  max-width: 380px;
  width: 100%;
  text-align: center;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.28);
}
.exit-modal__close {
  position: absolute;
  top: 10px;
  right: 14px;
  background: transparent;
  border: 0;
  font-size: 22px;
  color: var(--ink-faint);
  cursor: pointer;
  line-height: 1;
  font-family: inherit;
}
.exit-modal__close:hover { color: var(--ink); }
.exit-modal__headline {
  font-size: 22px;
  font-weight: 800;
  margin: 0 0 8px;
  letter-spacing: -0.02em;
}
.exit-modal__sub {
  color: var(--ink-soft);
  font-size: 14px;
  line-height: 1.4;
  margin: 0 0 18px;
}
.exit-modal__btn {
  display: inline-block;
  background: var(--ink);
  color: var(--paper);
  padding: 12px 22px;
  border-radius: var(--radius-pill);
  text-decoration: none;
  font-weight: 700;
  font-size: 14px;
  margin-bottom: 14px;
}
.exit-modal__email {
  padding-top: 14px;
  border-top: 1px solid var(--hairline);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.exit-modal__email input[type=email] {
  padding: 11px 14px;
  font-size: 14px;
  border: 1px solid var(--hairline);
  border-radius: 8px;
  background: var(--paper);
  color: var(--ink);
  font-family: inherit;
  width: 100%;
  box-sizing: border-box;
}
.exit-modal__email input[type=email]:focus {
  outline: none;
  border-color: var(--ink);
}
.exit-modal__email button {
  padding: 11px 18px;
  font-size: 14px;
  border: 1px solid var(--ink);
  background: transparent;
  color: var(--ink);
  border-radius: 8px;
  cursor: pointer;
  font-family: inherit;
  font-weight: 600;
}
.exit-modal__email button:hover { background: var(--ink); color: var(--paper); }
.exit-modal__feedback {
  font-size: 12px;
  color: var(--ink-soft);
  min-height: 16px;
}
.exit-modal__feedback.is-error   { color: var(--accent); }
.exit-modal__feedback.is-success { color: #2a8e3e; }

@keyframes modalFade {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* --- utilities -------------------------------------------------------- */

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* turn off legacy landing.css list accordion (we no longer render it) */
.list-section, .home-logo:not(.slide__logo) { display: none !important; }

/* ==========================================================================
   CRO Enhancements — stat badges, coin pills, speed strip, trust strip,
   live pulse dot. All animate via the existing .is-visible pattern.
   ========================================================================== */

/* --- inline stat badge (use inside sub copy via |raw) ------------------ */
.stat-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--accent);
  color: #fff;
  font-size: 0.82em;
  font-weight: 800;
  letter-spacing: -0.01em;
  padding: 1px 7px 2px;
  border-radius: 4px;
  line-height: 1.4;
  vertical-align: baseline;
  position: relative;
  top: -1px;
  white-space: nowrap;
}

/* --- live pulse dot on mechanism eyebrow ------------------------------ */
.slide--mechanism .slide__eyebrow {
  position: relative;
  padding-left: 22px;
}
.slide--mechanism .slide__eyebrow::before {
  content: '';
  position: absolute;
  left: 10px;
  top: 50%;
  transform: translateY(-50%);
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #2a8e3e;
}
.slide--mechanism.is-visible .slide__eyebrow::before {
  animation: live-pulse 2.2s ease-in-out infinite;
  animation-delay: 600ms;
}
@keyframes live-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(42, 142, 62, 0.6); opacity: 1; }
  50%       { box-shadow: 0 0 0 5px rgba(42, 142, 62, 0); opacity: 0.8; }
}
@media (prefers-reduced-motion: reduce) {
  .slide--mechanism .slide__eyebrow::before { animation: none; }
}

/* --- coin strip (bank_proof pattern_interrupt) ------------------------- */
.coin-strip {
  display: flex;
  gap: 10px;
  justify-content: center;
  flex-wrap: wrap;
  margin-top: clamp(20px, 3.5vh, 36px);
}
.coin-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 6px 14px;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: var(--radius-pill);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.72);
  white-space: nowrap;
}

.coin-logo {
  width: 18px;
  height: 18px;
  flex-shrink: 0;
  display: inline-block;
  vertical-align: middle;
}
/* Interac SVG is near-black + gold; boost so gold reads on dark bg. */
.coin-logo--interac {
  filter: brightness(1.6);
}

/* Wallet ships with hard-coded white fill (Heroicons solid). Soften slightly
   so it sits at the same visual weight as the white-72% pill text — without
   this it shouts louder than the colored BTC/XMR/Interac brand marks. */
.coin-logo--wallet {
  opacity: 0.82;
}

/* On light-bg coin-strip variant, white wallet would disappear — invert to dark. */
.coin-strip--light .coin-logo--wallet {
  filter: invert(1) brightness(0.35);
  opacity: 1;
}

/* --- speed strip (setup slide) ---------------------------------------- */
.speed-strip {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  row-gap: var(--space-sm);
  flex-wrap: wrap;          /* was nowrap → caused horizontal overflow on 320px screens */
  margin-top: clamp(24px, 4vh, 40px);
}
.speed-step {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  background: var(--paper-tint);
  border: 1px solid var(--hairline);
  border-radius: 10px;
  padding: 8px 14px;
  min-width: 72px;
}
.speed-step__label {
  font-size: 10px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-faint);
}
.speed-step__time {
  font-size: 17px;
  font-weight: 800;
  color: var(--ink);
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
}
.speed-step__connector {
  font-size: 13px;
  color: var(--ink-faint);
  flex-shrink: 0;
  margin-top: -4px;
}
@media (max-width: 390px) {
  .speed-step { min-width: 60px; padding: 7px 10px; }
  .speed-step__time { font-size: 15px; }
}

/* --- feature strip (diagnosis slide, light bg) ------------------------ */
.feature-strip {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  margin-top: clamp(20px, 3.5vh, 32px);
}
.feature-pill {
  display: inline-flex;
  align-items: center;
  padding: 7px 15px;
  background: rgba(0, 0, 0, 0.04);
  border: 1px solid rgba(0, 0, 0, 0.1);
  border-radius: var(--radius-pill);
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  letter-spacing: 0.01em;
  white-space: nowrap;
}

/* --- action strip (autonomous slide) ---------------------------------- */
.action-strip {
  display: flex;
  flex-direction: column;
  gap: 9px;
  margin-top: clamp(22px, 3.5vh, 36px);
  width: 100%;
  text-align: left;
}
.action-pill {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 16px;
  background: rgba(0, 0, 0, 0.03);
  border: 1px solid rgba(0, 0, 0, 0.09);
  border-radius: 10px;
  font-size: clamp(13px, 2.4vw, 15px);
  font-weight: 600;
  color: var(--ink);
}
.action-pill__tag {
  flex-shrink: 0;
  margin-left: 12px;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  background: rgba(229, 71, 42, 0.1);
  padding: 3px 8px;
  border-radius: 4px;
}
/* --- trust strip (cta slide, pre-button) ------------------------------ */
.trust-strip {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: clamp(16px, 2.5vh, 24px) auto 0;
}
.trust-item {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-faint);
}
.trust-item::before {
  content: '✓ ';
  color: var(--accent);
  font-size: 10px;
}
.trust-sep {
  color: var(--ink-faint);
  font-size: 12px;
  opacity: 0.35;
}

/* --- feature-grid highlight row (Features page slides 2-12) ---
   Sits between sub and bullets. Reuses feature-strip / coin-strip /
   speed-strip / action-strip / trust-strip / zero-line classes.    */
.feature-highlight {
  margin-top: clamp(8px, 1.5vh, 14px);
  margin-bottom: clamp(14px, 2.5vh, 22px);
}
.feature-highlight + .feature-grid { margin-top: clamp(10px, 2vh, 18px); }

/* stat: shrink the giant zero-line so it doesn't dominate the slide */
.feature-highlight--stat .zero-line {
  font-size: clamp(38px, 8vw, 72px);
  line-height: 1;
  letter-spacing: -0.04em;
  color: var(--ink);
}

/* coin-strip on light bg (slide 4) — overrides default dark-only theming */
.coin-strip--light .coin-pill {
  border-color: rgba(0,0,0,0.12);
  color: var(--ink);
  background: rgba(0,0,0,0.04);
}

/* keep highlight rows wrapping cleanly on 390px */
@media (max-width: 480px) {
  .feature-highlight.feature-strip,
  .feature-highlight.trust-strip { gap: 6px; }
  .feature-highlight.speed-strip { flex-wrap: wrap; row-gap: 8px; justify-content: center; }
  .feature-highlight .speed-step { padding: 6px 10px; min-width: 0; }
  .feature-highlight .speed-step__label { font-size: 10px; }
  .feature-highlight .action-pill { padding: 10px 12px; font-size: 13px; }
  .feature-highlight.coin-strip { gap: 6px; }
  .feature-highlight.coin-strip .coin-pill { padding: 5px 10px; font-size: 12px; }
}

/* --- Live-pulse green dot on first coin pill (subtle "alive" cue) --- */
.feature-highlight.coin-strip .coin-pill:first-child {
  position: relative;
}
.feature-highlight.coin-strip .coin-pill:first-child::after {
  content: '';
  position: absolute;
  top: 4px;
  right: 4px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #2a8e3e;
  animation: live-pulse 2.2s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .feature-highlight.coin-strip .coin-pill:first-child::after { animation: none; }
}

/* --- Live-pulse green dot on the LAST speed-step (winning state in flow) --- */
.feature-highlight.speed-strip > .speed-step:last-of-type {
  position: relative;
}
.feature-highlight.speed-strip > .speed-step:last-of-type::after {
  content: '';
  position: absolute;
  top: 4px;
  right: 4px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: #2a8e3e;
  animation: live-pulse 2.2s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
  .feature-highlight.speed-strip > .speed-step:last-of-type::after { animation: none; }
}

/* --- Soft cue line: subtle italic hint below sub --- */
.slide__soft-cue {
  font-size: 12px;
  font-weight: 500;
  color: rgba(0, 0, 0, 0.42);
  margin: clamp(2px, 0.5vh, 6px) auto clamp(8px, 1.5vh, 14px);
  max-width: 32ch;
  line-height: 1.45;
  font-style: italic;
  letter-spacing: 0.01em;
}

/* --- Dark theme for feature_grid (slide 2 MONEY IN — scene-change cue) --- */
.slide.slide--feature_grid.slide--dark {
  background: #0b0b0b;
  color: var(--paper, #fff);
}
.slide--feature_grid.slide--dark .slide__eyebrow {
  color: rgba(255, 255, 255, 0.65);
  border-color: rgba(255, 255, 255, 0.18);
}
.slide--feature_grid.slide--dark .slide__headline,
.slide--feature_grid.slide--dark .slide__headline--compact {
  color: var(--paper, #fff);
}
.slide--feature_grid.slide--dark .slide__sub,
.slide--feature_grid.slide--dark .slide__sub--compact {
  color: rgba(255, 255, 255, 0.72);
}
.slide--feature_grid.slide--dark .slide__soft-cue {
  color: rgba(255, 255, 255, 0.5);
}
.slide--feature_grid.slide--dark .feature-grid li {
  color: rgba(255, 255, 255, 0.88);
  border-bottom-color: rgba(255, 255, 255, 0.08);
}
.slide--feature_grid.slide--dark .feature-grid li::before {
  color: var(--accent);
}
/* coin-strip on dark: undo the --light overrides so pills sit on dark bg */
.slide--feature_grid.slide--dark .coin-strip--light .coin-pill {
  border-color: rgba(255, 255, 255, 0.18);
  color: rgba(255, 255, 255, 0.85);
  background: rgba(255, 255, 255, 0.04);
}
/* Interac SVG was tuned with brightness(1.6) for dark — keep it */
.slide--feature_grid.slide--dark .coin-logo--interac {
  filter: brightness(1.6);
}
.slide--feature_grid.slide--dark .forward-cue {
  color: rgba(255, 255, 255, 0.45);
}

/* coin-strip on light bg: SVG was tuned for dark, so unbrighten so colors stay true */
.slide--feature_grid:not(.slide--dark) .coin-strip--light .coin-logo--interac {
  filter: none;
}

/* --- Slide 4 (BUILT TO SELL): 2x2 dark engine tiles with pulse beacons ---
   Cinematic, scannable revenue-engine grid. Each tile = one money-making
   automation. Pulse beacon top-right = "running right now". */
.engines {
  margin: clamp(14px, 2.5vh, 24px) auto clamp(10px, 2vh, 18px);
  max-width: min(560px, 92vw);
  text-align: center;
}
.engines-label {
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  font-weight: 700;
  color: rgba(255, 255, 255, 0.55);
  margin-bottom: clamp(8px, 1.5vh, 12px);
}
.engines-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}
.engine-tile {
  position: relative;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: var(--radius-card);
  padding: 16px 14px 14px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-height: var(--engine-tile-min-h);
  text-align: left;
  overflow: hidden;
}
/* Flat-design replacement for the former ::after radial bloom — a small,
   solid-color accent square at the bottom-right of each tile reads as
   a deliberate flag rather than ambient haze. Same visual purpose
   (mark the tile as an "active" automation) without the gradient. */
.engine-tile::after {
  content: "";
  position: absolute;
  right: 12px;
  bottom: 12px;
  width: 18px;
  height: 3px;
  background: var(--accent);
  opacity: 0.85;
  pointer-events: none;
}
.engine-tile__pulse {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: #2a8e3e;
  z-index: 2;
  box-shadow: 0 0 0 0 rgba(42, 142, 62, 0.55);
  animation: engine-pulse 2.4s ease-in-out infinite;
}
@keyframes engine-pulse {
  0%   { box-shadow: 0 0 0 0   rgba(42, 142, 62, 0.55); }
  70%  { box-shadow: 0 0 0 8px rgba(42, 142, 62, 0); }
  100% { box-shadow: 0 0 0 0   rgba(42, 142, 62, 0); }
}
.engine-tile__name {
  font-size: 17px;
  font-weight: 800;
  color: #fff;
  line-height: 1.15;
  letter-spacing: -0.01em;
}
.engine-tile__outcome {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.72);
  line-height: 1.35;
  flex-grow: 1;
  margin-top: 2px;
}
.engine-tile__timing {
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--accent);
  text-transform: uppercase;
  margin-top: 6px;
  padding-top: 8px;
  border-top: 1px solid rgba(255, 255, 255, 0.10);
}
.engines-footer {
  font-size: 12px;
  font-style: italic;
  color: rgba(255, 255, 255, 0.55);
  margin-top: clamp(10px, 1.5vh, 14px);
}
@media (prefers-reduced-motion: reduce) {
  .engine-tile { opacity: 1; transform: none; transition: none; }
  .engine-tile__pulse { animation: none; }
}
@media (min-width: 720px) {
  .engines-grid { gap: 14px; }
  .engine-tile { padding: 20px 18px 18px; min-height: var(--engine-tile-min-h-md); }
  .engine-tile__name { font-size: 19px; }
}

/* Phones (≤480) — keep 2-col, just shrink chrome.
   The previous `grid-template-columns: 1fr` rule stacked 4 tall tiles vertically
   (~556px) on every phone — the dominant cause of slide-4 overflow on iPhone SE,
   iPhone 14 (393w), and Pixel 6 (360w). 2-col at 375w gives ~152px per tile,
   wide enough for "Welcome bonus" / "Cart drip" / etc. without text-wrap. */
@media (max-width: 480px) {
  .engines-grid     { gap: 8px; }
  .engine-tile      { padding: 12px 10px 10px; }
  .engine-tile__name    { font-size: clamp(15.5px, 4vw, 17px); }
  .engines-label    { margin-bottom: 6px; }
  .engines-footer   { margin-top: 8px; font-size: 11px; }
}

/* Sub-340 fallback: Galaxy Fold cover (280w), iPhone 4 (320w with chrome).
   At <340w 2-col tiles drop below ~140px wide and outcome text wraps to 4+ lines. */
@media (max-width: 339px) {
  .engines-grid { grid-template-columns: 1fr; gap: var(--space-sm); }
}

/* ─────────────────────────────────────────────────────────────────────
   Engine tile — LIGHT variant (slide 5 home page, paper bg).
   Mirrors the dark .engine-tile structure but inverts ink/surface.
   Keeps depth via hairline border + 2-stop shadow + green pulse +
   accent corner flag (brand continuity with /features dark variant).
   Pulse uses #16a34a (Tailwind green-600) — better contrast on paper
   than #2a8e3e and avoids competition with --accent (orange).
   ───────────────────────────────────────────────────────────────────── */
.engines--light { color: var(--ink); }
.engine-tile--light {
  background: var(--paper);
  border: 1px solid var(--hairline);
  box-shadow:
    0 1px 0   rgba(11, 11, 11, 0.04),
    0 6px 14px -8px rgba(11, 11, 11, 0.10);
  transition: transform 180ms ease, box-shadow 180ms ease, border-color 180ms ease;
}
.engine-tile--light::after {
  background: var(--accent);
  opacity: 0.95;
}
.engine-tile--light .engine-tile__pulse {
  background: #16a34a;
  box-shadow: 0 0 0 0 rgba(22, 163, 74, 0.35);
  animation-name: engine-pulse-light;
  animation-duration: 2s;
  animation-timing-function: ease-out;
  animation-iteration-count: infinite;
}
@keyframes engine-pulse-light {
  0%   { box-shadow: 0 0 0 0   rgba(22, 163, 74, 0.35); }
  70%  { box-shadow: 0 0 0 8px rgba(22, 163, 74, 0);    }
  100% { box-shadow: 0 0 0 0   rgba(22, 163, 74, 0);    }
}
.engine-tile--light .engine-tile__name {
  color: var(--ink);
}
.engine-tile--light .engine-tile__outcome {
  color: var(--ink-soft);
}
.engine-tile--light .engine-tile__timing {
  color: var(--accent);
  border-top: 1px solid var(--hairline);
}
.engines-footer--light {
  color: var(--ink-faint);
  font-style: italic;
}
@media (hover: hover) {
  .engine-tile--light:hover,
  .engine-tile--light:focus-within {
    transform: translateY(-1px);
    border-color: rgba(11, 11, 11, 0.14);
    box-shadow:
      0 1px 0    rgba(11, 11, 11, 0.05),
      0 10px 22px -10px rgba(11, 11, 11, 0.16);
  }
}
@media (prefers-reduced-motion: reduce) {
  .engine-tile--light { transition: none; }
  .engine-tile--light:hover,
  .engine-tile--light:focus-within { transform: none; }
  .engine-tile--light .engine-tile__pulse {
    animation: none;
    box-shadow: 0 0 0 3px rgba(22, 163, 74, 0.18);
  }
}

/* ─── Short-viewport guard — scoped to .slide--feature_grid ───
   Fires on iPhone SE portrait (667h), older iPhones (568h), and any
   landscape phone <700h. Tighten margins + tile geometry; for soft-cue
   copy, hide on slides where it RESTATES content (payments/bot) and
   shrink (don't hide) where it carries urgency/FOMO (marketing/usecases).
   Footer trust copy ("Toronto crew picks up — same day.") is shrunk, not
   hidden — load-bearing reassurance for screen readers + design intent. */
@media (max-height: 700px) {
  .slide--feature_grid .slide__inner {
    padding-top:    clamp(6px, 1vh, 14px);
    padding-bottom: clamp(6px, 1vh, 12px);
  }
  .slide--feature_grid .slide__headline--compact {
    line-height: 1.1;
    margin-bottom: 6px;
  }
  .slide--feature_grid .slide__sub--compact { margin-bottom: 10px; }
  .slide--feature_grid .feature-highlight   { margin-top: 4px; margin-bottom: 6px; }
  .slide--feature_grid .engines             { margin-top: 4px; margin-bottom: 4px; }
  .slide--feature_grid .engines-label       { margin-bottom: 6px; font-size: 9px; }
  .slide--feature_grid .engine-tile         {
    min-height: var(--engine-tile-min-h-sh);
    padding: 10px 10px 8px;
  }
  .slide--feature_grid .engine-tile__name   { font-size: 15px; }
  .slide--feature_grid .engines-footer      {
    font-size: 10px;
    opacity: 0.7;
    margin-top: 4px;
  }

  /* Soft-cue: payments + bot restate the headline → hide.
     marketing + usecases carry urgency/FOMO → shrink instead, never hide. */
  #features-payments .slide__soft-cue,
  #features-bot      .slide__soft-cue { display: none; }
  #features-marketing .slide__soft-cue,
  #features-usecases  .slide__soft-cue {
    font-size: 11px;
    opacity: 0.45;
    margin-top: 4px;
  }

  /* Bullet-list density on dense slides (bot, marketing, reports, storefront,
     usecases). Tight padding + line-height closes the last 2-8px overflow on
     iPhone SE for the 6-bullet feature_grid slides. */
  .slide--feature_grid .feature-grid li {
    line-height: 1.28;
    padding: 3px 0 3px 18px;
  }
  .slide--feature_grid .feature-grid li::before { top: 3px; }

  /* Action-pills (slide 5 marketing) + speed-step chrome — compress when short. */
  .slide--feature_grid .feature-highlight .action-pill {
    padding: 8px 10px;
    font-size: 12px;
  }
  .slide--feature_grid .feature-highlight.action-strip { gap: 6px; }
}

/* Pre-existing collision fix (separate from height patch but trivial):
   On <480 phones, .engine-tile__pulse beacon at top:12 right:12 overlaps the
   tile name "Welcome bonus" because it has no right inset. Reserve 24px so
   the 8px dot + 12px inset + 4px gap is preserved on long names. */
@media (max-width: 480px) {
  .engine-tile__name { padding-right: 24px; }
}

/* ===========================================================
   Creds composition (slide 6 — THE CREW v3)
   Stat row + deliverables + FOMO + trust pills.
   Sellers-not-designers pivot. Verified-only numbers.
   ========================================================= */
.creds {
  max-width: 480px;
  margin: clamp(12px, 2.2vh, 20px) auto 0;
}

/* Stat row — pain (red) / win (green) polarity, dark-theme decisive */
.creds-stats {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
  margin-bottom: 14px;
}
.creds-stat {
  text-align: center;
  padding: 12px 6px 10px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.12);
  border-radius: 12px;
}
.creds-stat__num {
  display: block;
  font-size: 28px;
  font-weight: 800;
  color: rgba(255, 255, 255, 0.95);
  line-height: 1;
  letter-spacing: -0.02em;
}
.creds-stat__unit {
  font-size: 14px;
  font-weight: 700;
  margin-left: 2px;
  color: rgba(255, 255, 255, 0.70);
}
/* Pain — coral-red (#FF6B5C). NOT --accent; --accent means "click me" elsewhere. */
.creds-stat--red {
  background: rgba(255, 107, 92, 0.06);
  border-color: rgba(255, 107, 92, 0.28);
}
.creds-stat--red .creds-stat__num  { color: #FF6B5C; }
.creds-stat--red .creds-stat__unit { color: rgba(255, 107, 92, 0.78); }
/* Win — cyan-shifted emerald (#3EE08A), AAA on #0b0b0b. */
.creds-stat--green {
  background: rgba(62, 224, 138, 0.06);
  border-color: rgba(62, 224, 138, 0.30);
}
.creds-stat--green .creds-stat__num  { color: #3EE08A; }
.creds-stat--green .creds-stat__unit { color: rgba(62, 224, 138, 0.80); }
.creds-stat__label {
  display: block;
  margin-top: 6px;
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
  font-weight: 500;
  line-height: 1.25;
}

/* Deliverables — what lands on day 1 */
.creds-deliver {
  background: rgba(255, 255, 255, 0.035);
  border: 1px solid rgba(255, 255, 255, 0.10);
  border-radius: 12px;
  padding: 12px 14px 10px;
  margin-bottom: 10px;
}
.creds-deliver__title {
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.50);
  font-weight: 600;
  margin-bottom: 8px;
  text-align: left;
}
.creds-deliver__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.creds-deliver__row {
  position: relative;
  padding-left: 22px;
  font-size: 14px;
  line-height: 1.35;
  color: rgba(255, 255, 255, 0.92);
  text-align: left;
  font-weight: 500;
}
.creds-deliver__row::before {
  content: "✓";
  position: absolute;
  left: 0;
  top: 0;
  color: rgba(140, 220, 160, 0.95);
  font-size: 14px;
  font-weight: 700;
  line-height: 1.35;
}

/* FOMO line — honest, not gimmicky */
.creds-fomo {
  font-size: 12px;
  color: rgba(255, 255, 255, 0.62);
  font-style: italic;
  text-align: center;
  margin: 10px auto 12px;
  line-height: 1.4;
  max-width: 380px;
}

/* Trust pills */
.creds-trust {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
}
.creds-trust__pill {
  font-size: 11px;
  letter-spacing: 0.04em;
  color: rgba(255, 255, 255, 0.74);
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid rgba(255, 255, 255, 0.13);
  padding: 5px 11px;
  border-radius: 999px;
  white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  .creds-stat,
  .creds-deliver__row { opacity: 1; transform: none; transition: none; }
}
@media (min-width: 720px) {
  .creds { max-width: 580px; }
  .creds-stat__num { font-size: 32px; }
  .creds-deliver__row { font-size: 15px; }
}

/* ─────────────────────────────────────────────────────────────────────
   Hook slide — logo 3D pole sway
   Subtle rotateY oscillation with a tiny rotateX counter-tilt; reads as
   a sign mounted on a pole moving in light wind. GPU-composited (transform
   only). Per memory feedback_user_env_variance: never zero out 3rd-party
   transforms — reduced-motion is scoped to the logo image, not globally.
   ───────────────────────────────────────────────────────────────────── */
.slide--hook .home-logo.slide__logo {
  perspective: 900px;
  transform-style: preserve-3d;
}
.slide--hook .site-logo {
  display: block;
  transform-origin: 50% 50%;
  backface-visibility: hidden;
  animation: logo-pole-sway 3s var(--ease-out) infinite alternate;
}
@keyframes logo-pole-sway {
  0%   { transform: rotateY(-12deg) rotateX(2deg)   translateZ(0); }
  50%  { transform: rotateY(0deg)   rotateX(0deg)   translateZ(0); }
  100% { transform: rotateY(12deg)  rotateX(-2deg)  translateZ(0); }
}
/* Reduced motion: keep a gentler sway running — user explicitly wants the
   sign-on-a-pole feel even with Android "Remove animations" on. Smaller
   amplitude + slower period respects the spirit of reduced motion. */
@media (prefers-reduced-motion: reduce) {
  .slide--hook .site-logo {
    animation: logo-pole-sway-soft 5.5s ease-in-out infinite alternate;
  }
}
@keyframes logo-pole-sway-soft {
  0%   { transform: rotateY(-5deg) rotateX(1deg)   translateZ(0); }
  50%  { transform: rotateY(0deg)  rotateX(0deg)   translateZ(0); }
  100% { transform: rotateY(5deg)  rotateX(-1deg)  translateZ(0); }
}


/* ─────────────────────────────────────────────────────────────────────
   Generic green trust badge — sits at the bottom of any slide that
   declares slide.trust_tagline. Bg-alpha works on both light (paper)
   and dark (pattern_interrupt) slide backgrounds — green border + text
   carry the visual weight either way.
   ───────────────────────────────────────────────────────────────────── */
.slide__trust {
  display: block;
  width: max-content;
  max-width: 32ch;
  margin: clamp(20px, 4vh, 36px) auto 0;
  padding: 10px 18px;
  border-radius: 999px;
  background: rgba(62, 224, 138, 0.10);
  border: 1px solid rgba(62, 224, 138, 0.34);
  color: #3EE08A;
  font-size: clamp(13px, 1.8vw, 15px);
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: 0.01em;
  text-align: center;
}
