/* Zeduno — mobile / tablet layer.
   Loaded AFTER landing.css + landing-fx.css (+ page css) on every page.
   Nothing here touches the desktop composition: every rule is inside a
   max-width / hover / touch query. Same design, same animations, restacked.

   Journey on small screens: the stage becomes a sticky panel pinned under
   the nav and the six step texts scroll beneath it — the desktop engine,
   choreography and vignettes are unchanged, only the axis flips. */

/* ============================================================
   0. FOUNDATIONS — consistent across iOS / Android / all browsers
   ============================================================ */
:root { --navh: 64px; --safe-l: env(safe-area-inset-left, 0px); --safe-r: env(safe-area-inset-right, 0px); --safe-b: env(safe-area-inset-bottom, 0px); }

@media (max-width: 1080px) {

  /* NOTHING may clip or scroll-contain the root element here. Any `overflow`
     on <html> makes iOS stop honouring viewport-fit=cover: the page then no
     longer paints into the safe areas, and the status-bar and home-indicator
     strips render as black bands that read as fixed placeholder blocks.
     Horizontal drift is prevented at the source instead — the only over-wide
     things are the fixed decorative layers, which clip themselves (below), and
     touch-action blocks sideways panning outright. background-color is a
     belt-and-braces guard: if some engine still leaves a strip unpainted it is
     the page colour, never black. */
  html { max-width: 100%; background-color: var(--bg); }
  /* body must not be a scroll container either, or position:sticky dies —
     that is what pins the journey stage */
  body { overflow-x: visible; }
  body { touch-action: pan-y pinch-zoom; }
  /* translated deck copies (exit +x) must not extend the scrollable width —
     clip at the content level, never on the root (kills viewport-fit=cover)
     or body (kills the sticky stage). clip ≠ scroll container. */
  main, .lp-footer { overflow-x: clip; }
  /* the drifting atmosphere blobs used to be clipped by body's overflow —
     contain them here instead, now that body must stay a non-scroll box */
  .lp-atmos { overflow: clip; }
  @supports not (overflow: clip) { .lp-atmos { overflow: hidden; } }
  body { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
  /* fixed background-attachment is expensive/buggy on mobile Safari */
  body { background-attachment: scroll; }
  .lp-container { padding-left: max(24px, var(--safe-l)); padding-right: max(24px, var(--safe-r)); }
}
@media (max-width: 560px) {
  .lp-container { padding-left: max(20px, var(--safe-l)); padding-right: max(20px, var(--safe-r)); }
}

/* touch: kill grey flash, keep taps honest */
@media (hover: none) {
  a, button, [role="button"], .ev-claim, .agent-plate { -webkit-tap-highlight-color: transparent; }
  /* every real control clears the 44px minimum on any touch device */
  .lp-btn, .plan-cta, .ent-cta, .dm-send, .bill-toggle button { min-height: 44px; }
  .lp-nav-cta .lp-btn { min-height: 40px; }
  /* hover-lift effects would stick after a tap on touch — neutralise */
  .plan:hover { transform: none; }
  .lp-btn:hover { transform: none; }
  .ent:hover { box-shadow: none; }
}

/* ============================================================
   1. NAV — real mobile menu (built by nav-mobile.js)
   ============================================================ */
.nav-burger { display: none; }
/* the sheet is injected by nav-mobile.js on every page; outside the mobile
   media query it has no styles, so without this it renders as raw links
   below the footer on desktop */
.nav-sheet { display: none; }
/* evidence receipts (built by extras.js): pair wrapper is structural on all
   widths; the receipt itself only renders in the stacked (<=800px) layout */
.ev-pair { display: flex; flex-direction: column; }
.ev-receipt { display: none; }
.ev-hint { display: none; }

@media (max-width: 800px) {
  /* the page runs edge-to-edge under the status bar (viewport-fit=cover) —
     content scrolls all the way to the top edge, no scrim, no masking band */
  .lp-nav { padding-top: max(10px, calc(env(safe-area-inset-top, 0px) + 4px)); }
  .lp-nav-inner { padding: 9px 12px 9px 16px; gap: 10px; }
  .lp-logo svg { height: 17px; }
  /* desktop link row + button pair collapse into the sheet */
  .lp-nav-links, .lp-nav-cta { display: none; }

  .nav-burger {
    display: inline-flex; flex-direction: column; justify-content: center; gap: 5px;
    width: 44px; height: 44px; padding: 0 11px; margin-left: auto;
    background: transparent; border: 0; cursor: pointer; border-radius: var(--radius-sm);
    -webkit-appearance: none; appearance: none;
  }
  .nav-burger i {
    display: block; height: 1.5px; background: var(--ink-soft); border-radius: 2px;
    transition: transform 0.34s var(--ease-out), opacity 0.2s linear, width 0.34s var(--ease-out);
    width: 22px; transform-origin: center;
  }
  .nav-burger i:nth-child(2) { width: 15px; margin-left: auto; }
  .nav-burger[aria-expanded="true"] i:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
  .nav-burger[aria-expanded="true"] i:nth-child(2) { opacity: 0; width: 22px; }
  .nav-burger[aria-expanded="true"] i:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); width: 22px; }

  /* sheet */
  .nav-sheet {
    position: fixed; inset: 0; z-index: 49;
    display: flex; flex-direction: column; justify-content: flex-end;
    padding: 0; pointer-events: none;
  }
  .nav-sheet-scrim {
    position: absolute; inset: 0; background: rgba(6, 5, 12, 0.72);
    opacity: 0; transition: opacity 0.42s var(--ease-out);
    -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  }
  .nav-sheet-panel {
    position: relative; margin: 0 8px calc(8px + var(--safe-b));
    padding: 22px 22px calc(20px + var(--safe-b));
    border-radius: var(--radius-xl);
    background: rgba(17, 15, 27, 0.94);
    -webkit-backdrop-filter: blur(var(--blur-lg)) saturate(1.3); backdrop-filter: blur(var(--blur-lg)) saturate(1.3);
    border: 1px solid var(--border-strong);
    box-shadow: 0 -18px 60px rgba(4, 2, 16, 0.6), inset 0 1px 0 var(--glass-rim);
    transform: translateY(112%); opacity: 0;
    transition: transform 0.52s var(--ease-out), opacity 0.3s linear;
  }
  .nav-sheet.open { pointer-events: auto; }
  .nav-sheet.open .nav-sheet-scrim { opacity: 1; }
  .nav-sheet.open .nav-sheet-panel { transform: none; opacity: 1; }

  .nav-sheet-links { display: flex; flex-direction: column; }
  .nav-sheet-links a {
    display: flex; align-items: center; justify-content: space-between; gap: 14px;
    min-height: 52px; padding: 4px 2px;
    font-family: var(--font-display); font-size: 19px; font-weight: 500; letter-spacing: -0.01em;
    color: var(--ink); text-decoration: none;
    border-bottom: 1px solid var(--border);
    opacity: 0; transform: translateY(10px);
  }
  .nav-sheet.open .nav-sheet-links a { opacity: 1; transform: none; transition: opacity 0.4s var(--ease-out) var(--nd, 0ms), transform 0.44s var(--ease-out) var(--nd, 0ms); }
  .nav-sheet-links a::after {
    content: ""; width: 7px; height: 7px; flex: none;
    border-right: 1.5px solid var(--violet-300); border-top: 1.5px solid var(--violet-300);
    transform: rotate(45deg); opacity: 0.75;
  }
  .nav-sheet-links a:active { color: var(--violet-200); }
  .nav-sheet-ctas { display: flex; flex-direction: column; gap: 10px; margin-top: 20px; }
  .nav-sheet-ctas .lp-btn { width: 100%; justify-content: center; min-height: 48px; font-size: 15px; }
  .nav-sheet-foot {
    margin: 18px 0 0; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.1em;
    text-transform: uppercase; color: var(--faint); text-align: center;
  }
  body.nav-open { overflow: hidden; }
}
@media (max-width: 800px) and (prefers-reduced-motion: reduce) {
  .nav-sheet-panel, .nav-sheet-scrim, .nav-sheet-links a { transition: none; }
}

/* ============================================================
   2. HERO
   ============================================================ */
@media (max-width: 1080px) {
  .lp-hero { min-height: 0; padding-top: 128px; padding-bottom: 76px; }
  .hero-grid { gap: 40px; }
  .hero-console { max-width: 560px; margin-right: 0 !important; }
  /* Candidate cards: the desktop single-row flex (rank·avatar·text·ring) crushes
     the text column at phone/tablet-column widths — names wrap mid-word, the
     role truncates, the mono meta shatters. Restack: identity row up top, meta
     and "why" given the FULL card width below. name/meta/why are nested inside
     .hc-card-main, so it takes display:contents to promote them to grid items. */
  .hc-card { display: grid; grid-template-columns: auto minmax(0, 1fr) auto; grid-template-areas: "ava name ring" "meta meta meta" "why why why"; row-gap: 7px; align-items: center; }
  .hc-card .rank { display: none; }
  .hc-card .hc-ava { grid-area: ava; }
  .hc-card .ring { grid-area: ring; }
  .hc-card .hc-card-main { display: contents; }
  .hc-card-name { grid-area: name; display: block; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .hc-card-name small { display: block; margin-top: 2px; overflow: hidden; text-overflow: ellipsis; }
  .hc-card-meta { grid-area: meta; margin-top: 0; line-height: 1.55; }
  .hc-card-why { grid-area: why; margin-top: 0; align-items: flex-start; }
  .hc-card-why .zdi { margin-top: 2px; }
  /* the suggestion chips under the shortlist half-clip against the console's
     fixed height on narrow screens — drop them there; the cards are the story */
  .hc-chips { display: none; }
}
@media (max-width: 800px) {
  .lp-hero { padding-top: 112px; padding-bottom: 64px; }
  .hero-copy .lp-eyebrow { margin-bottom: 18px; }
  /* the three headline lines stay unbroken — scale to the viewport instead */
  .lp-h1 { font-size: min(7.1vw, 2.85rem); }
  .hero-sub { font-size: 15px; max-width: 46ch; }
  .hero-ctas { gap: 10px; }
  .hero-ctas .lp-btn { min-height: 48px; }
  .hero-proof { font-size: 11px; }
}
@media (max-width: 560px) {
  .lp-hero { padding-top: 104px; }
  .lp-h1 { font-size: min(7.4vw, 2.2rem); }
  .hero-copy .lp-eyebrow { font-size: 10px; letter-spacing: 0.13em; }
  .hero-sub { font-size: 14.5px; line-height: 1.62; }
  .hero-ctas { flex-direction: column; align-items: stretch; }
  .hero-ctas .lp-btn { width: 100%; justify-content: center; }
  /* console: same anatomy, tighter */
  .hc-body { padding: 14px; gap: 12px; }
  .hc-msg { max-width: 100%; }
  .hc-title { font-size: 10.5px; }
}
@media (max-width: 400px) {
  .lp-h1 { font-size: 7.6vw; }
}

/* ============================================================
   3. AGENTS — Zed / Zuno plates
   ============================================================ */
@media (max-width: 800px) {
  .lp-agents { padding: 64px 0 8px; }
  .agent + .agent { margin-top: 30px; padding-top: 30px; }
}
/* no hover on touch: scroll drives the EXACT desktop choreography — the ghost
   Z rests behind the name (desktop base rules untouched) and slides left into
   its slot as each agent reaches the viewport, receding on the way out; the
   name warms white -> violet a beat after the glyph lands, cools back on exit */
@media (hover: none), (max-width: 800px) {
  body.ap-ghost .agent-plate { padding-left: 58px; }
  body.ap-ghost .ap-glyph { left: 58px; transition: transform 0.6s var(--ease-out), opacity 0.55s var(--ease-out), filter 0.55s var(--ease-out); }
  body.ap-ghost .agent.glyph-in .ap-glyph { opacity: 1; filter: none; transform: translateX(-58px) rotate(-8deg) scale(1.05); }
  .ap-name { transition: color 0.4s var(--ease-out); }
  .ap-name::after { transition: transform 0.45s var(--ease-out); }
  .agent.glyph-in .ap-name { color: var(--violet-300); transition: color 1.1s var(--ease-out) 0.45s; }
  .agent.glyph-in .ap-name::after { transform: scaleX(1); transition: transform 0.7s var(--ease-out) 0.5s; }
  .ap-go { display: inline-flex; }
  @media (max-width: 560px) {
    body.ap-ghost .agent-plate { padding-left: 42px; }
    body.ap-ghost .ap-glyph { left: 42px; }
    body.ap-ghost .agent.glyph-in .ap-glyph { transform: translateX(-42px) rotate(-8deg) scale(1.05); }
  }
  @media (prefers-reduced-motion: reduce) { body.ap-ghost .agent.glyph-in .ap-glyph { transform: scale(0.92); } }
}
@media (max-width: 560px) {
  .ap-name { font-size: 30px; }
  .ap-glyph { width: 30px; height: 30px; }
  .agent p { font-size: 14.5px; }
}

/* ============================================================
   4. JOURNEY — sticky stage on top, steps beneath (the big one)
   ============================================================ */
@media (max-width: 1080px) {
  .lp-journey { padding: 56px 0 72px; }
  .jn-head { margin-bottom: 34px; }

  /* flex column so the sticky stage can pin across the WHOLE track
     (a sticky grid item would only stick inside its own row) */
  .jn-track { display: flex; flex-direction: column; gap: 0; align-items: stretch; }

  .jn-stagewrap {
    display: block; order: -1; height: auto;
    position: sticky; top: calc(var(--navh) + 10px); z-index: 3;
    margin: 0 0 4px;
  }
  /* The panel is opaque on small screens so step text can't show through the
     glass as it scrolls under. No backdrop/scrim element — one of those reads
     as a fixed band pinned below the nav. */
  .stage-panel { background: #14121F; }
  .jn-stage { position: static; top: auto; }
  .stage-panel { position: relative; z-index: 1; height: clamp(360px, 56svh, 520px); }
  /* JS sizes the panel to the active vignette; animate between sizes so the
     card reads as expanding when Zuno's follow-up and flag arrive */
  @media (prefers-reduced-motion: no-preference) {
    .stage-panel { transition: height 0.5s var(--ease-out); }
  }

  .jn-steps { padding-left: 0; }
  /* the weaving comet rail is a desktop device: at phone width it steals
     reading width and reads as clutter. Mobile gets a segmented chapter
     rail docked to the pinned panel instead (built in journey.js). */
  .jn-thread { display: none; }
  .jn-steps .jn-step > .jn-num { display: none; }
  /* Every step gets an IDENTICAL band. The active step is chosen by nearest
     centre, while the rail fill is measured across the step's own band — those
     two only agree at the same boundary if the bands are equal, otherwise the
     bar jumps when the active step changes. */
  .jn-steps .jn-step { min-height: 62svh; padding: 24px 0; opacity: 1; display: block; }

  /* ---- step copy as a horizontal deck ----
     The stage is pinned, so copy that scrolls vertically past it fights the
     pin. Each step's copy is instead transform-pinned to a slot under the panel
     and travels sideways only — in from the right, hold, out to the left, on
     the same axis the chapter rail reads on. journey.js writes --x/--y/--o/--s
     every frame; deliberately NO transition here, since easing a value that is
     already scroll-driven lags behind the finger and smears. */
  .jn-copy {
    transform: translate3d(var(--x, 0px), 0, 0) scale(var(--s, 1));
    transform-origin: left center;
    opacity: var(--o, 1);
    will-change: transform, opacity;
    pointer-events: none;
  }
  /* on screen = out of the scroll flow, held by the compositor. Only the slot
     (top) is JS-set, and it changes at most when the panel grows — nothing
     vertical is recomputed per frame, so there is nothing to beat against the
     scroll. */
  .jn-copy.pinned { position: fixed; z-index: 2; }
  @media (prefers-reduced-motion: no-preference) {
    .jn-copy.pinned { transition: top 0.45s var(--ease-out); }
  }
  .jn-copy.live { pointer-events: auto; }
  /* the parts fan slightly against the travel: the headline leads, the agent
     label and body trail it, so the copy arrives as one object with depth
     rather than a flat slab sliding across */
  .jn-copy > .jn-step-agent { transform: translateX(calc(var(--x, 0px) * 0.3)); }
  .jn-copy > h3 { transform: translateX(calc(var(--x, 0px) * 0.12)); }
  .jn-copy > p { transform: translateX(calc(var(--x, 0px) * 0.44)); }

  /* ---- segmented chapter rail ---- */
  .jn-rail { position: relative; z-index: 1; display: flex; gap: 6px; margin: 12px 0 0; padding: 0; }
  .jn-rail-seg {
    flex: 1; display: flex; flex-direction: column; gap: 6px; align-items: stretch;
    background: none; border: 0; padding: 6px 0 0; cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .jn-rail-bar { position: relative; height: 3px; border-radius: 2px; background: rgba(255, 255, 255, 0.10); overflow: hidden; }
  .jn-rail-bar i {
    position: absolute; inset: 0; transform-origin: left center; transform: scaleX(0);
    background: linear-gradient(90deg, var(--violet-300), var(--violet-500));
    border-radius: 2px;
  }
  .jn-rail-seg.done .jn-rail-bar i { transform: scaleX(1); opacity: 0.55; }
  .jn-rail-seg.on .jn-rail-bar { background: rgba(172, 146, 231, 0.18); }
  .jn-rail-seg.on .jn-rail-bar i { opacity: 1; box-shadow: 0 0 10px rgba(147, 118, 219, 0.7); }
  .jn-rail-num {
    font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.1em;
    color: var(--faint); text-align: left; transition: color 0.3s var(--ease-out);
  }
  .jn-rail-seg.done .jn-rail-num { color: var(--muted); }
  .jn-rail-seg.on .jn-rail-num { color: var(--violet-200); }
  @media (prefers-reduced-motion: no-preference) {
    /* opacity only — a transition on transform would lag the scroll and smear
       the fill, which reads as the bar jumping */
    .jn-rail-bar i { transition: opacity 0.3s var(--ease-out); }
  }
}
@media (max-width: 800px) {
  .stage-panel { height: clamp(352px, 57svh, 500px); }
  .jn-step h3 { font-size: 21px; }
  .jn-step p { font-size: 14.5px; }
  .jn-step .jn-step-agent { font-size: 10px; }
}
@media (max-width: 560px) {
  .lp-journey { padding: 48px 0 64px; }
  .jn-num { width: 34px; height: 34px; font-size: 12px; }
  .jn-step h3 { font-size: 19.5px; }
  .jn-step p { font-size: 14px; }
  .stage-panel { height: clamp(340px, 56svh, 470px); }
  .stage-head { padding: 9px 12px; }
  .stage-crumb { font-size: 9.5px; }
  .stage-agent { font-size: 9.5px; }
}

/* ---- vignette compaction: same anatomy, mobile density ---------- */
@media (max-width: 800px) {
  .stage-body { padding: 14px; }
  .vg-note { font-size: 9.5px; letter-spacing: 0.07em; }

  /* 01 describe */
  .composer { padding: 12px; }
  .composer-text { font-size: 13px; line-height: 1.5; }
  .parse-row { gap: 6px; }
  .parse-chip { font-size: 10px; padding: 4px 8px; }
  .send-fab { width: 34px; height: 34px; }

  /* 02 source */
  .scan-title { font-size: 10px; }
  .v2-card { padding: 9px 10px; gap: 9px; }
  .v2-name { font-size: 12.5px; }
  .v2-name small { display: block; margin: 1px 0 0; }
  .v2-meta { font-size: 8.5px; letter-spacing: 0.05em; }
  .v2-why { font-size: 11px; }
  .v2-more { font-size: 9.5px; }
  .hc-ava { width: 30px; height: 30px; font-size: 10.5px; }

  /* 03 pipeline theater */
  .wf-card { padding: 8px 10px; }
  .wf-name { font-size: 12px; }
  .wf-meta { font-size: 8.5px; }
  .wf-reply { padding: 8px 10px; font-size: 11.5px; }
  .kb-toast { padding: 10px 12px; }
  .kb { gap: 8px; }
  .kb-head { font-size: 9px; }
  .kb-pill { padding: 6px 8px; font-size: 11px; }

  /* 04 interview room */
  .tile { height: 96px; }
  .tile-ava { width: 34px; height: 34px; font-size: 11px; }
  .tile-name { font-size: 9.5px; }
  .room-grid { grid-template-columns: 1fr; gap: 10px; }
  .transcript { max-height: 116px; }
  .ts-line { font-size: 11.5px; }
  .zuno-chip { font-size: 10.5px; padding: 8px 10px; }
  .zuno-head { font-size: 9px; }
  .room-wave { height: 26px; }

  /* 05 report */
  .rp-top h4 { font-size: 14px; }
  .rp-meta { font-size: 9px; }
  .rp-rec { padding: 7px 10px; }
  .rp-rec-label { font-size: 9px; }
  .rp-seg span { font-size: 9.5px; padding: 4px 7px; }
  .rp-tldr { font-size: 11px; padding: 9px 10px; }
  .rp-comp-head { font-size: 9.5px; }
  .rp-legend { display: none; }
  .cb-row { padding: 4px 0 6px; }
  .cb-label { font-size: 11px; }
  .cb-score { font-size: 11px; }
  .rp-chip { font-size: 10.5px; padding: 7px 9px; }
  .rp-sig { gap: 7px; }

  /* 06 decide */
  .dec-card { padding: 16px; }
  .dec-name { font-size: 15px; }
  .dec-sub { font-size: 11.5px; }
  .dec-actions { flex-direction: column; }
  .dec-actions .lp-btn { width: 100%; justify-content: center; }
  .dec-done { padding: 11px 12px; }
  .dec-audit { font-size: 9px; }
}
@media (max-width: 430px) {
  /* Zuno's suggested follow-up and flag ARE the point of this step — never hide
     them. The panel now grows to fit instead of everything being squeezed. */
  .tile { height: 88px; }
  .transcript { max-height: 112px; }
  .rp-sig { display: grid; grid-template-columns: 1fr; }
  .v2-cards > .v2-card:nth-child(3) { display: none; }
}

/* ============================================================
   5. EVIDENCE
   ============================================================ */
@media (max-width: 800px) {
  .lp-evidence { padding: 64px 0; }
  .ev-grid { gap: 26px; }
  .ev-claim { padding: 13px 14px; }
  .ev-claim p { font-size: 13.5px; }
  .ev-transcript { padding: 16px 14px; }
  .evt-line { font-size: 12.5px; }
  .ev-caption { font-size: 10px; }
  /* — receipts: the transcript panel folds away; tapping a claim pulls its
     exact transcript moment out INTO the claim. Expansion is a 0fr->1fr grid
     row (height animates without measuring); the cite chip "stamps" and a
     marker sweep runs across the quoted words once the receipt is open. */
  .ev-transcript { display: none; }
  /* receipt opening — "paper feed": the sheet unrolls out of the claim
     (grid 0fr->1fr), the content rides the reveal edge in a beat behind it,
     header then quote cascading; a violet print-edge glows along the feed
     line while it moves and dies as the sheet settles; the timestamp drops
     in last, taking the handoff from the claim's stamped cite chip; then
     the marker sweep runs across the quoted words. */
  .ev-receipt { display: grid; grid-template-rows: 0fr; opacity: 0; }
  .ev-receipt.show { grid-template-rows: 1fr; opacity: 1; margin-top: 10px; }
  .evr-in { position: relative; min-height: 0; overflow: hidden; border: 1px solid var(--border-violet); border-radius: var(--radius-md); background: var(--surface-1); }
  .ev-receipt.risk .evr-in { border-color: rgba(232, 193, 90, 0.4); }
  .evr-edge { position: absolute; left: 0; right: 0; bottom: 0; height: 1.5px; opacity: 0; pointer-events: none; background: linear-gradient(90deg, transparent, var(--violet-300) 28%, var(--violet-100) 50%, var(--violet-300) 72%, transparent); }
  .ev-receipt.risk .evr-edge { background: linear-gradient(90deg, transparent, var(--warning) 50%, transparent); }
  .evr-head { display: flex; align-items: baseline; justify-content: space-between; gap: 10px; margin: 0; padding: 11px 14px 0; font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--muted); }
  .evr-head em { font-style: normal; color: var(--faint); letter-spacing: 0.08em; }
  .evr-quote { display: flex; gap: 12px; padding: 10px 14px 14px; }
  .evr-quote time { flex: none; font-family: var(--font-mono); font-size: 10px; color: var(--violet-300); padding-top: 3px; }
  .evr-quote b { display: block; font-family: var(--font-mono); font-size: 9px; font-weight: 600; letter-spacing: 0.1em; color: var(--muted); margin-bottom: 5px; }
  .evr-mark { font-size: 13.5px; line-height: 1.62; color: var(--ink); background-image: linear-gradient(transparent 64%, rgba(124, 92, 200, 0.34) 64%); background-repeat: no-repeat; background-size: 0% 100%; box-decoration-break: clone; -webkit-box-decoration-break: clone; }
  .ev-receipt.show .evr-mark { background-size: 100% 100%; }
  .ev-claim .cite { transition: transform 0.32s var(--ease-out), background 0.32s var(--ease-out); }
  .ev-claim { flex-wrap: wrap; }
  .ev-hint { display: flex; align-items: center; gap: 5px; flex-basis: 100%; margin: 2px 0 0 28px; font-family: var(--font-mono); font-size: 9.5px; letter-spacing: 0.12em; text-transform: uppercase; color: var(--violet-300); opacity: 0.85; }
  .ev-hint i { font-style: normal; font-size: 8px; transition: transform 0.3s var(--ease-out); }
  .ev-claim.open .ev-hint { opacity: 0.55; color: var(--muted); }
  .ev-claim.open .ev-hint i { transform: rotate(180deg); }
  .ev-claim.open { border-color: var(--border-violet); background: var(--brand-tint); }
  .ev-claim.open .cite { transform: translateY(2px) scale(0.94); background: var(--brand-tint-strong); }
  @media (prefers-reduced-motion: no-preference) {
    .ev-receipt { transition: grid-template-rows 0.52s var(--ease-out), opacity 0.26s linear, margin-top 0.52s var(--ease-out); }
    .evr-head, .evr-quote { opacity: 0; transform: translateY(-10px); transition: opacity 0.2s linear, transform 0.24s var(--ease-out); }
    .ev-receipt.show .evr-head { opacity: 1; transform: none; transition: opacity 0.3s var(--ease-out) 0.1s, transform 0.44s var(--ease-out) 0.1s; }
    .ev-receipt.show .evr-quote { opacity: 1; transform: none; transition: opacity 0.3s var(--ease-out) 0.17s, transform 0.44s var(--ease-out) 0.17s; }
    .evr-quote time { opacity: 0; transform: translateY(-7px); }
    .ev-receipt.show .evr-quote time { opacity: 1; transform: none; transition: opacity 0.26s var(--ease-out) 0.3s, transform 0.36s var(--ease-out) 0.3s; }
    .ev-receipt.show .evr-edge { animation: evrFeed 0.64s var(--ease-out); }
    .evr-mark { transition: background-size 0.7s var(--ease-out) 0.4s; }
    .ev-receipt:not(.show) .evr-mark { transition: none; }
    @keyframes evrFeed { 0% { opacity: 1; } 72% { opacity: 0.85; } 100% { opacity: 0; } }
  }
}
/* touch: tapping a claim highlights its transcript line (hover can't) */
@media (hover: none) {
  .ev-claim { cursor: pointer; }
  .ev-claim:active { border-color: var(--border-violet); }
}

/* ============================================================
   6. PRINCIPLES + CTA
   ============================================================ */
@media (max-width: 800px) {
  /* principles as a ledger: a hairline spine threads three numbered seals,
     each row sliding in as it reaches the viewport — same index language as
     the journey rail and the receipts, instead of three flat text stacks */
  .lp-principles { padding: 60px 0 64px; }
  .pr-item { position: relative; padding: 4px 0 26px 52px; }
  .pr-grid { border-top: 0; }
  .pr-item + .pr-item { margin-top: 0; padding: 4px 0 26px 52px; border-top: 0; }
  .pr-item::before { content: ""; position: absolute; left: 17px; top: 0; bottom: 0; width: 1px; background: var(--border); }
  .pr-item:first-child::before { top: 6px; }
  .pr-item:last-child::before { display: none; }
  .pr-num { display: flex; align-items: center; min-height: 35px; margin: 0 0 6px; font-family: var(--font-mono); font-size: 10.5px; letter-spacing: 0.15em; text-transform: uppercase; color: var(--brand-light); }
  .pr-num b {
    position: absolute; left: 0; top: 0; z-index: 1;
    width: 35px; height: 35px; display: grid; place-items: center;
    background: var(--surface-1); border: 1px solid var(--border-strong); border-radius: 10px;
    font-weight: 600; font-size: 11px; color: var(--violet-200);
    box-shadow: 0 0 0 5px var(--bg);
  }
  .pr-num span { display: inline-block; }
  .pr-num span::before { content: none; }
  .pr-item h3 { font-size: 19.5px; }
  .pr-item p { max-width: none; font-size: 14px; }
  @media (prefers-reduced-motion: no-preference) {
    .pr-item[data-reveal] { opacity: 0; transform: translateY(16px); transition: opacity 0.5s linear var(--rd, 0ms), transform 0.6s var(--ease-out) var(--rd, 0ms); }
    .pr-item[data-reveal] .pr-num b { opacity: 0; transform: scale(0.6) rotate(-8deg); transition: opacity 0.34s var(--ease-out) calc(var(--rd, 0ms) + 180ms), transform 0.42s var(--ease-out) calc(var(--rd, 0ms) + 180ms); }
    .pr-item[data-reveal]::before { transform: scaleY(0); transform-origin: top; transition: transform 0.7s var(--ease-out) calc(var(--rd, 0ms) + 260ms); }
    .pr-item[data-reveal].is-in { opacity: 1; transform: none; }
    .pr-item[data-reveal].is-in .pr-num b { opacity: 1; transform: none; }
    .pr-item[data-reveal].is-in::before { transform: none; }
    /* exit: same motion reversed, but each row leaves the moment IT leaves the
       viewport — no group stagger on the way out */
    .pr-item[data-reveal]:not(.is-in) { transition: opacity 0.38s linear, transform 0.44s var(--ease-out); }
    .pr-item[data-reveal]:not(.is-in) .pr-num b { transition: opacity 0.3s var(--ease-out), transform 0.34s var(--ease-out); }
    .pr-item[data-reveal]:not(.is-in)::before { transition: transform 0.5s var(--ease-out); }
  }
  .lp-cta { padding: 76px 0 84px; }
  .cta-mark { width: 68px; height: 68px; border-radius: 19px; margin-bottom: 30px; }
  .cta-row { flex-direction: column; align-items: stretch; width: 100%; max-width: 340px; }
  .cta-row .lp-btn { width: 100%; justify-content: center; min-height: 48px; }
}

/* ============================================================
   7. FOOTER (curtain rise works as-is; layout restacks)
   ============================================================ */
@media (max-width: 800px) {
  .lp-footer { padding-top: 52px; }
  .foot-grid { gap: 34px; }
  .foot-logo svg { height: 20px; }
  .foot-links { gap: 26px 34px; }
  .foot-col-head { font-size: 11px; }
  .foot-meta { flex-direction: column; align-items: flex-start; gap: 10px; font-size: 10.5px; }
  /* Margin, not padding: padding here would make the absolutely-positioned
     stroke and sheen layers (inset: 0) a different size from the in-flow base,
     which is what offset the strokes from the letters. */
  .foot-markwrap { margin: 34px 16px calc(6px + var(--safe-b)); padding: 0; }
}
@media (max-width: 700px) {
  /* The dead space to the right was not the column structure — .foot-links is a
     flex item inside .foot-grid and was sizing to its content, so the whole nav
     block sat in a narrow band with the rest of the row empty. Full width, and
     the two columns pair equal-length sections: the two single-link sections
     share the first row, the two four-link sections share the second, so every
     row lands level with no hanging column. */
  .foot-links {
    width: 100%; margin-left: 0;
    display: grid; grid-template-columns: 1fr 1fr;
    gap: 30px 22px; align-items: start;
  }
  .foot-col { min-width: 0; gap: 9px; }
  .foot-col-head { margin-bottom: 3px; font-size: 10.5px; letter-spacing: 0.15em; }
  .foot-col a { min-height: 32px; display: inline-flex; align-items: center; font-size: 14.5px; }
}

/* ============================================================
   8. PRICING PAGE
   ============================================================ */
@media (max-width: 800px) {
  .pg-hero { padding-top: 118px; }
  .pg-h1 { font-size: min(8vw, 2.5rem); }
  .pg-lead { font-size: 15px; }
  .plan-cat { font-size: 10px; }
  .plan { padding: 22px 18px 20px; }
  .plan-cta { min-height: 46px; }
  .pg-compare { padding: 56px 0 24px; }
  .pg-cta { padding: 64px 0 76px; }
}
@media (max-width: 620px) {
  /* the free-months tag must never push the toggle off-screen */
  .bill-wrap { flex-direction: column; align-items: center; gap: 12px; }
  .bill-note { position: static !important; margin: 0; opacity: 0 !important; transform: translateY(7px) scale(0.9) !important; visibility: hidden; filter: none; transition: opacity 0.35s var(--ease-out), transform 0.5s cubic-bezier(0.34, 1.56, 0.4, 1), visibility 0s 0.35s; }
  .bill-note.lit { opacity: 1 !important; transform: none !important; visibility: visible; transition: opacity 0.3s var(--ease-out), transform 0.5s cubic-bezier(0.34, 1.56, 0.4, 1), visibility 0s; }
  .bill-toggle button { min-height: 42px; }
  /* comparison table scrolls horizontally instead of crushing */
  .pg-table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: thin; }
  .pg-table { min-width: 560px; }
}

/* ============================================================
   9. DEMO PAGE
   ============================================================ */
@media (max-width: 800px) {
  .dm-hero { padding-top: 112px; padding-bottom: 72px; }
  .dm-h1 { font-size: min(8vw, 2.4rem); }
  .dm-card { padding: 20px 18px; }
  .dm-field input, .dm-field textarea { font-size: 16px; } /* ≥16px stops iOS zoom-on-focus */
  .dm-send { min-height: 50px; }
  .dm-beats li { font-size: 13.5px; }
}

/* ============================================================
   10. LEGAL PAGES — TOC becomes a collapsible bar (privacy.js)
   ============================================================ */
@media (max-width: 960px) {
  .pv-hero { padding-top: 112px; }
  .pv-h1 { font-size: min(8vw, 2.4rem); }
  .pv-layout { padding-top: 34px; }
  .pv-mtoc { display: block; }
}
.pv-mtoc { display: none; margin: 0 0 30px; }
.pv-mtoc summary {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 13px 16px; cursor: pointer; list-style: none;
  background: var(--surface-1); border: 1px solid var(--border); border-radius: var(--radius-md);
  font-family: var(--font-mono); font-size: 11px; letter-spacing: 0.1em; text-transform: uppercase; color: var(--ink-soft);
}
.pv-mtoc summary::-webkit-details-marker { display: none; }
.pv-mtoc summary::after {
  content: ""; width: 7px; height: 7px; flex: none;
  border-right: 1.5px solid var(--violet-300); border-bottom: 1.5px solid var(--violet-300);
  transform: rotate(45deg) translateY(-2px); transition: transform 0.3s var(--ease-out);
}
.pv-mtoc[open] summary::after { transform: rotate(-135deg) translateY(-2px); }
.pv-mtoc[open] summary { border-radius: var(--radius-md) var(--radius-md) 0 0; border-bottom-color: transparent; }
.pv-mtoc-list {
  display: flex; flex-direction: column;
  padding: 6px 16px 14px; margin: 0;
  background: var(--surface-1); border: 1px solid var(--border); border-top: 0;
  border-radius: 0 0 var(--radius-md) var(--radius-md);
}
.pv-mtoc-list a {
  padding: 9px 0; font-size: 13.5px; color: var(--muted); text-decoration: none;
  border-bottom: 1px solid var(--border);
}
.pv-mtoc-list a:last-child { border-bottom: 0; }
.pv-mtoc-list a:active { color: var(--violet-200); }
@media (max-width: 560px) {
  .pv-body h2 { font-size: 19px; }
  .pv-body p, .pv-body li { font-size: 14.5px; }
  .pv-table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
}

/* ============================================================
   11. LANDSCAPE PHONES — short viewports
   ============================================================ */
@media (max-width: 1080px) and (max-height: 560px) and (orientation: landscape) {
  .jn-stagewrap { position: static; }
  .stage-panel { height: 340px; }
  /* deck is off in short landscape (journey.js gates on min-height): copy sits
     back in normal flow, so it must not stay pinned or faded */
  .jn-copy { transform: none; opacity: 1; pointer-events: auto; position: static; }
  .jn-copy > .jn-step-agent, .jn-copy > h3, .jn-copy > p { transform: none; }
  .jn-steps .jn-step { min-height: 0; padding: 40px 0; }
  .lp-hero { padding-top: 96px; }
}

/* ============================================================================
   HERO ENTRANCE — unconditional on mobile
   ----------------------------------------------------------------------------
   Desktop runs this off body.is-loaded, which extras.js adds after two rAFs.
   On a phone that class can land well after first paint (script execution is
   the slow part on a throttled device), so the hero was already on screen
   before its animation was allowed to begin — everything appeared, then the
   headline moved. Running it unconditionally means the entrance starts at
   first paint instead.

   The values below mirror the desktop body.is-loaded set exactly, so when the
   class does arrive the computed animations are identical and nothing
   restarts.

   The last rule is load-bearing: the headline rises as ONE block here, but the
   JS still swaps the H1 into word spans to measure line fit. That swap has to
   stay invisible — no per-word animation, no hidden state left behind.
   ========================================================================= */
@media (max-width: 800px) and (prefers-reduced-motion: no-preference) {
  .lp-nav-inner { animation: lp-navin 0.8s var(--ease-out) 0.1s backwards; }
  .hero-copy .lp-eyebrow { animation: lp-rise 0.8s var(--ease-out) 0.05s backwards; }
  .lp-hero .lp-h1 { animation: lp-rise 0.85s var(--ease-out) 0.16s backwards; }
  .hero-sub { animation: lp-rise 0.8s var(--ease-out) 0.3s backwards; }
  .hero-ctas { animation: lp-rise 0.8s var(--ease-out) 0.42s backwards; }
  .hero-proof { animation: lp-rise 0.8s var(--ease-out) 0.54s backwards; }
  .hero-console { animation: lp-consolein 1s var(--ease-out) 0.35s backwards; }
  .hero-scrollcue { animation: lp-fadein 1.2s var(--ease-out) 1.5s backwards; }
  .hero-canvas, .hero-beam { animation: lp-fadein 1.6s var(--ease-out) 0.25s backwards; }
  .lp-h1 .w, .lp-h1.is-anim .w { animation: none !important; opacity: 1 !important; transform: none !important; }
}
