/* ============================================================
   HAUNT — mobile.css  (opinionated redesign)

   Philosophy: mobile is a DIFFERENT page that shares the same brand.
   Not a desktop reflow. The hero leads with the phone-in-hand product
   shot (auto-cycling feed), copy is compressed to one line, secondary
   sections are hidden or collapsed, and a sticky CTA stays in thumb
   reach. Goal: 5 sections, ~120 words, ~5 vertical "things" before
   the user hits the waitlist.

   Loaded with media="(max-width: 768px)" so it NEVER touches desktop.
   ============================================================ */

@media (max-width: 768px) {

  /* ==== VIEWPORT BASE =========================================
     Prevent horizontal overflow and respect safe-area on notched phones.
     ============================================================ */
  html, body { overflow-x: hidden; }
  body { padding-bottom: calc(24px + env(safe-area-inset-bottom)); }


  /* ==== NAV ===================================================
     Fixed top bar. Keep same styling as desktop but respect notch
     and make sure nav-links (full menu) are hidden on small screens
     while nav-toggle (hamburger) shows.
     ============================================================ */
  .nav {
    padding-top: max(12px, env(safe-area-inset-top)) !important;
    position: fixed !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    z-index: 9999 !important;
    /* Isolate from GSAP pin transforms */
    transform: none !important;
  }
  .nav-links { display: none !important; }


  /* ==== CONTAINER =============================================
     Tighter horizontal gutters. Keeps desktop max-width but caps to
     viewport with 20px safety on either side.
     ============================================================ */
  .container { padding-left: 20px !important; padding-right: 20px !important; }


  /* ==== HERO ==================================================
     Phone on top, copy below. Phone scrubs with scroll (no pin,
     no 3D tilt — those are GPU-heavy on mobile).
     ============================================================ */
  .hero {
    min-height: auto !important;
    padding: calc(88px + env(safe-area-inset-top)) 0 48px !important;
    align-items: flex-start !important;
  }
  .hero-inner {
    display: flex !important;
    flex-direction: column !important;
    grid-template-columns: none !important;
    gap: 32px !important;
    align-items: stretch !important;
  }
  /* Phone first, copy second */
  .hero-copy-col { order: 1 !important; display: block !important; }
  .hero-phone-col { order: 0 !important; }

  /* Phone in document flow, not absolute */
  .hero-phone-col .phone-wrap,
  .phone-wrap {
    position: relative !important;
    top: auto !important;
    right: auto !important;
    left: auto !important;
    width: 240px !important;
    margin: 0 auto !important;
    filter: none !important;
  }
  /* Flat phone on mobile — no 3D tilt (causes scroll lag) but keep scrub working */
  .phone {
    --pw: 240px !important;
    --ph: 506px !important;
    transform-style: flat !important;
  }
  .phone-face-back,
  .phone-face-left,
  .phone-face-right,
  .phone-face-top,
  .phone-face-bottom {
    display: none !important;
  }

  /* Hero typography — scale down from the 96px max */
  .hero-title {
    font-size: clamp(40px, 10.5vw, 56px) !important;
    line-height: 1.02 !important;
    letter-spacing: -0.03em !important;
    margin-bottom: 18px !important;
  }
  .hero-sub {
    font-size: 16px !important;
    line-height: 1.5 !important;
    margin-bottom: 28px !important;
  }
  .hero-cta-row {
    flex-direction: column !important;
    gap: 10px !important;
    margin-bottom: 36px !important;
  }
  .hero-cta-row .btn {
    width: 100% !important;
    min-height: 54px !important;
    justify-content: center !important;
  }

  /* Stats — horizontal row, no dividers on narrow screens */
  .hero-stats {
    padding: 16px 18px !important;
    gap: 14px !important;
    flex-wrap: nowrap !important;
  }
  .hero-stats .stat-div { display: none !important; }
  .hero-stats .stat { flex: 1 1 0 !important; min-width: 0 !important; }
  .stat-num { font-size: 22px !important; }
  .stat-label { font-size: 10px !important; letter-spacing: 0.1em !important; }


  /* ==== SECTION RHYTHM ========================================
     All standard .section blocks get tighter vertical padding.
     ============================================================ */
  .section { padding: 64px 0 !important; }


  /* ==== SECTION TITLES ========================================
     Scale the big section headlines down for mobile widths.
     ============================================================ */
  .section-title {
    font-size: clamp(30px, 7.5vw, 42px) !important;
    line-height: 1.05 !important;
    letter-spacing: -0.02em !important;
    max-width: 100% !important;
    margin-bottom: 16px !important;
  }
  .section-sub {
    font-size: 16px !important;
    line-height: 1.55 !important;
    max-width: 100% !important;
  }


  /* ==== REVEAL SECTION ========================================
     Stack the demo card above the stages on narrow viewports.
     ============================================================ */
  .reveal-section { padding: 56px 0 48px !important; }
  .reveal-demo {
    display: flex !important;
    flex-direction: column !important;
    gap: 20px !important;
    margin-top: 32px !important;
  }
  .reveal-card { padding: 22px 20px !important; }
  .reveal-body { font-size: 17px !important; line-height: 1.5 !important; }
  .reveal-stages {
    display: flex !important;
    flex-direction: column !important;
    gap: 10px !important;
  }
  .reveal-stage {
    padding: 14px 16px !important;
  }


  /* ==== SCENE (how-it-works only) =============================
     Unpin the phone, stack steps above phone.
     ============================================================ */
  .scene-section { padding: 56px 0 !important; }
  .scene-pin-wrap { height: auto !important; padding: 0 !important; }
  .scene-inner {
    display: flex !important;
    flex-direction: column !important;
    grid-template-columns: none !important;
    gap: 32px !important;
    align-items: stretch !important;
  }
  .scene-phone-wrap {
    position: relative !important;
    top: auto !important;
    width: 100% !important;
    max-width: 280px !important;
    margin: 0 auto !important;
  }


  /* ==== PLACES POST GRID ======================================
     Single column on mobile; reacts row pinned to bottom of card.
     ============================================================ */
  .posts-grid {
    grid-template-columns: 1fr !important;
    gap: 12px !important;
    margin-top: 28px !important;
  }
  .post-card { padding: 20px !important; border-radius: 18px !important; }


  /* ==== FOG ===================================================
     Stack the phone vertically below the copy.
     ============================================================ */
  .fog-section { padding: 56px 0 !important; }
  .fog-inner {
    display: flex !important;
    flex-direction: column !important;
    grid-template-columns: none !important;
    gap: 28px !important;
  }
  .fog-phone {
    width: 100% !important;
    max-width: 260px !important;
    margin: 0 auto !important;
    transform: none !important;
  }


  /* ==== CAMPUS MARQUEE ======================================== */
  .campuses-section { padding: 56px 0 !important; }


  /* ==== PRIVATE HAUNTS TILE =================================== */
  .private-section { padding: 24px 0 !important; }
  .private-tile { padding: 24px 20px !important; }
  .private-tile-inner {
    flex-direction: column !important;
    gap: 18px !important;
    align-items: flex-start !important;
  }


  /* ==== BRIDGE ================================================ */
  .bridge-section { padding: 48px 0 32px !important; }
  .bridge-card { padding: 28px 22px !important; }
  .bridge-inner { flex-direction: column !important; gap: 18px !important; align-items: stretch !important; }


  /* ==== LAUNCH / WAITLIST =====================================
     Stack email field above submit button (they're side-by-side
     on desktop). Bigger tap targets.
     ============================================================ */
  .launch-section { padding: 72px 0 80px !important; }
  .waitlist-inner {
    flex-direction: column !important;
    gap: 10px !important;
    padding: 0 !important;
    background: transparent !important;
    border: 0 !important;
  }
  .waitlist-input {
    width: 100% !important;
    min-height: 54px !important;
    padding: 16px 18px !important;
    border-radius: 14px !important;
    font-size: 16px !important;
  }
  .waitlist-btn {
    width: 100% !important;
    min-height: 54px !important;
    padding: 16px 24px !important;
    border-radius: 14px !important;
    font-size: 16px !important;
  }
  .waitlist-counter-num { font-size: 36px !important; }
  .waitlist-share-btns {
    display: flex !important;
    flex-direction: column !important;
    gap: 8px !important;
  }
  .waitlist-share-btn {
    min-height: 48px !important;
    padding: 12px 16px !important;
  }


  /* ==== FOOTER ================================================ */
  .footer { padding: 40px 0 calc(32px + env(safe-area-inset-bottom)) !important; }
  .footer-inner {
    flex-direction: column !important;
    gap: 22px !important;
    align-items: flex-start !important;
  }
  .footer-links {
    flex-wrap: wrap !important;
    gap: 14px 20px !important;
  }
  .footer-link { padding: 6px 0 !important; }


  /* ==== SUB-PAGE HEROES (how-it-works, faq, safety) =========== */
  .subpage-hero { padding: calc(96px + env(safe-area-inset-top)) 0 24px !important; }
  .subpage-title {
    font-size: clamp(34px, 8vw, 48px) !important;
    line-height: 1.02 !important;
    letter-spacing: -0.025em !important;
    margin: 14px 0 14px !important;
  }
  .subpage-sub { font-size: 16px !important; line-height: 1.55 !important; }

  .manifesto { padding: 32px 0 !important; }
  .manifesto-text { font-size: clamp(24px, 6vw, 32px) !important; line-height: 1.12 !important; }
  .manifesto-body { font-size: 16px !important; line-height: 1.55 !important; }


  /* ==== FAQ + SAFETY PAGES ==================================== */
  .faq-page-wrap { padding: calc(104px + env(safe-area-inset-top)) 20px 60px !important; }
  .faq-page-title {
    font-size: clamp(34px, 8vw, 48px) !important;
    line-height: 1.02 !important;
    letter-spacing: -0.025em !important;
    margin: 12px 0 16px !important;
  }
  .safety-grid {
    grid-template-columns: 1fr !important;
    gap: 10px !important;
  }


  /* ==== MOBILE PERF ===========================================
     Strip backdrop-filter blur where it fights Safari compositing.
     Keep it on nav (for the glass effect) but remove from scrolling/
     animated elements.
     ============================================================ */
  .sticky-cta,
  .hero-stats,
  .reveal-stage,
  .app-modes,
  .app-haunt-pill,
  .app-views,
  .btn-ghost,
  .nav-cta,
  .nav-toggle {
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
  }


  /* ==== APP-POST STACKING SAFETY ==============================
     Clip at the phone-screen boundary so the 3-post stack (each
     100% height, 300% total) doesn't bleed outside the phone.
     DO NOT clip on .app-feed itself — it has `inset: 0` (= screen
     height), and the translateY carousel needs the 2nd/3rd posts
     to paint below the visible window so the transform can page
     them up into view. Earlier this file set `overflow: hidden`
     on .app-feed as a 3D-iOS workaround; that killed posts 2+3
     because they stacked outside the feed's padding box and got
     clipped away before the transform could reveal them.
     ============================================================ */
  .phone-screen, .phone-face-front { overflow: hidden !important; }


  /* ============================================================
     OPINIONATED MOBILE REDESIGN — everything below this line is
     not a "patch" but an intentional restructure: phone-first hero,
     compressed type scale, hidden prose, sticky CTA, per-section
     full-bleed colors. The desktop design is unchanged.
     ============================================================ */


  /* ---- 1. HERO — same as desktop, no overrides ---- */


  /* ---- 2. COLLAPSE THE MECHANIC -----------------------------
     Hide both subhead paragraphs and the 4 stage cards. Keep only
     the section title + the live demo card (the visual conveys it
     better than the prose). The "dig deeper" bridge link remains
     as the single path to how-it-works.html. */
  .reveal-section .section-sub {
    display: none !important;
  }
  .reveal-stages {
    display: none !important;
  }
  .reveal-section {
    padding: 56px 0 32px !important;
  }
  .reveal-demo {
    margin-top: 24px !important;
  }


  /* ---- 3. BRIDGE = SINGLE TAP TO LEARN MORE -----------------
     Keep the bridge card but slim it down — it's now the only
     "how it works" path on mobile, so make it look like a CTA. */
  .bridge-section { padding: 32px 0 !important; }
  .bridge-card {
    padding: 24px 20px !important;
    text-align: center !important;
  }
  .bridge-sub { display: none !important; }
  .bridge-title {
    font-size: 22px !important;
    margin-bottom: 4px !important;
  }
  .bridge-link {
    width: 100% !important;
    justify-content: center !important;
    margin-top: 8px !important;
  }


  /* ---- 4. CUT LAUNCH PROSE ----------------------------------
     Headline + counter + form is enough. The 2-sentence paragraph
     is desktop-only context. */
  .launch-section .section-sub {
    display: none !important;
  }
  .launch-section {
    padding: 56px 0 96px !important;
  }


  /* ---- 5. STICKY CTA — ALWAYS VISIBLE FROM SCROLL 0 ---------
     Already wired in main.js to hide once user reaches launch.
     Reserve bottom padding so content isn't covered. */
  body {
    padding-bottom: calc(72px + env(safe-area-inset-bottom)) !important;
  }
  /* Once the sticky CTA is hidden (user has reached the launch section),
     drop the reserved bottom padding so the footer no longer floats above
     an empty dark band. Only applies at this breakpoint. */
  body:has(.sticky-cta.hidden) {
    padding-bottom: env(safe-area-inset-bottom) !important;
  }
  .sticky-cta {
    z-index: 50 !important;
    padding: 12px 16px calc(12px + env(safe-area-inset-bottom)) !important;
    background: linear-gradient(
      to top,
      rgba(7, 7, 13, 0.98) 0%,
      rgba(7, 7, 13, 0.92) 70%,
      rgba(7, 7, 13, 0) 100%
    ) !important;
  }
  .sticky-cta-btn {
    min-height: 52px !important;
    border-radius: 14px !important;
    font-size: 15px !important;
    box-shadow: 0 8px 24px rgba(183, 148, 255, 0.4) !important;
  }


  /* ---- 6. COMPRESSED TYPE SCALE — 3 SIZES ONLY --------------
     display (44-64px) / body (17px) / caption (12px).
     Apply uniformly across hero, sections, subpages so the page
     feels visually consistent instead of a parade of font sizes. */
  .section-title,
  .launch-title {
    font-size: clamp(32px, 8vw, 44px) !important;
    line-height: 1.02 !important;
    letter-spacing: -0.025em !important;
    margin-bottom: 12px !important;
  }
  .section-sub,
  .bridge-sub,
  .subpage-sub,
  .reveal-body,
  .manifesto-body {
    font-size: 17px !important;
    line-height: 1.5 !important;
  }
  .kicker {
    font-size: 11px !important;
    letter-spacing: 0.14em !important;
  }


  /* ---- 7. PER-SECTION FULL-BLEED COLOR BLOCKS ---------------
     Mobile loses desktop's column-based spatial cues. Give each
     section its own background tint so the user feels they're
     swiping through screens, not scrolling a document.
     Uses [data-palette] which is already on the markup. */
  .section-scene[data-palette="hero"] {
    background: linear-gradient(180deg, #07070D 0%, #120A22 100%) !important;
  }
  .section-scene[data-palette="reveal"] {
    background: linear-gradient(180deg, #0A0612 0%, #1F0817 100%) !important;
  }
  .section-scene[data-palette="scene"] {
    background: linear-gradient(180deg, #06060E 0%, #0E0B22 100%) !important;
  }
  .section-scene[data-palette="launch"] {
    background: linear-gradient(180deg, #0A081A 0%, #1E133D 100%) !important;
  }
  /* Nuke the canvas orbs and the bg-shift underlay on mobile — the
     per-section gradients are doing the atmospheric work now, and
     the canvas was already disabled at <720px (main.js:153). */
  #orbs { display: none !important; }
  .bg-shift { display: none !important; }


  /* ---- 8. ACTIVITY TICKER — KILL ON MOBILE ------------------
     Top-of-page ticker eats vertical real estate. The phone-feed
     loop already conveys "things are happening" more vividly. */
  .ticker-wrap { display: none !important; }


  /* ---- 9. SAFETY GRID CARDS — TIGHTER ----------------------- */
  .safety-grid > * {
    padding: 18px 16px !important;
  }


  /* ---- 10. NAV — CLEANER ON MOBILE --------------------------
     Brand left, hamburger right. No CTA pill in the bar (sticky
     CTA at the bottom is the action path). Solid background so
     the phone slides cleanly underneath it on scroll instead of
     showing through a transparent bar. */
  .nav-cta { display: none !important; }
  .scroll-progress { height: 2px !important; }
  .nav,
  .nav.scrolled {
    background: rgba(7, 7, 13, 0.95) !important;
    -webkit-backdrop-filter: blur(12px) !important;
    backdrop-filter: blur(12px) !important;
    border-bottom: 1px solid rgba(255, 255, 255, 0.06) !important;
  }


  /* ---- 11. SPLASH — BULLETPROOF HIDE ON MOBILE -------------
     The splash inside the phone screen ("haunt / anonymous until
     you're not") is a desktop scroll-scrub thing. On any mobile
     viewport, kill it unconditionally so the cycling feed shows
     immediately even if the .has-gsap bootloader gate misfires. */
  /* Splash visible — GSAP scrub fades it out as user scrolls */
  .app-feed { opacity: 1 !important; }
  .app-feed .app-post { visibility: visible !important; }


  /* ---- 12. POST CONTENT FIT FOR 240px PHONE -----------------
     The .app-* layout has hard-pixel positions tuned for a 264px
     desktop phone. At 240px wide:
       - persona-meta gets squeezed (avatar 28 + gap 10 + views-pill ~70
         + side gutters 36 leaves ~96px for the name → "velvet otter 42"
         wraps to two lines, growing the persona row and making the
         whole composition feel cramped)
       - .app-body-wrap centered with top:50% pushed body UP into the
         persona row
       - even after anchoring body-wrap, there was a giant empty void
         between body text and rail icons.
     Fix:
       (a) hide the .app-views pill on mobile — the views count is noisy
           chrome we don't need at this size; lets persona name breathe
       (b) keep persona name on a single line with ellipsis fallback
       (c) shrink body font + clamp to 5 lines
       (d) anchor body-wrap close to persona, with a short height so the
           body sits naturally below persona and rail icons fill the
           lower half — no dead space.
     Also tighten the meta row positions so they fit the smaller
     phone without bleeding into the body zone. */
  .app-top { top: 56px !important; }
  /* 240px phone — chip row + absolute search icon need to both fit.
     Shrink chip padding, font, and the wrap's own padding so the three
     chips clear the search icon on the right. */
  .app-modes { padding: 3px !important; font-size: 9.5px !important; }
  .app-mode { padding: 4px 7px !important; }
  .app-search { right: 10px !important; width: 26px !important; height: 26px !important; }
  .app-search .rail-svg { width: 16px !important; height: 16px !important; }
  .app-haunt-pill,
  .app-escaped-pill { top: 96px !important; }
  .app-persona { top: 134px !important; right: 14px !important; }
  .app-views { display: none !important; }
  .app-persona-name {
    white-space: nowrap !important;
    overflow: hidden !important;
    text-overflow: ellipsis !important;
  }
  .app-body-wrap {
    top: 180px !important;
    bottom: auto !important;
    transform: none !important;
    left: 18px !important;
    right: 56px !important;
  }
  .app-tag { margin-bottom: 6px !important; }
  .app-body {
    font-size: 13.5px !important;
    line-height: 1.3 !important;
    display: -webkit-box !important;
    -webkit-line-clamp: 5 !important;
    -webkit-box-orient: vertical !important;
    overflow: hidden !important;
  }
  /* Pull rail icons closer to the body so the lower phone area
     reads as a tight "post + actions" block instead of a void. */
  .app-rail { bottom: 56px !important; gap: 12px !important; }
  .app-hint { bottom: 24px !important; }


  /* ============================================================
     PHASE 1 — ENGAGEMENT LAYER
     The mobile page was visually correct but inert. This block
     adds the beats that make it feel alive on a thumb: a tappable
     unmask card (the signature product moment), tactile press
     feedback on every control, a scroll-linked progress sliver
     on the sticky CTA, an ambient hero glow, and a view()-timeline
     welcome for the phone mockup. All motion respects
     prefers-reduced-motion.
     ============================================================ */


  /* ---- 13. GLOBAL TAP FEEL ----------------------------------
     Kill iOS/Android default tap highlight (the grey flash) and
     give every tappable a 97% scale press — the single cheapest
     change that makes the site feel native instead of web-y. */
  * { -webkit-tap-highlight-color: transparent; }

  .btn, .btn-primary, .btn-ghost,
  .nav-cta, .nav-drawer-link, .nav-drawer-cta, .nav-link,
  .nav-toggle, .brand,
  .sticky-cta-btn, .waitlist-btn, .waitlist-copy-btn,
  .waitlist-share-btn, .bridge-link, .footer-link,
  .reveal-card.is-tappable, .app-mode, .reveal-stage {
    transition: transform 0.15s cubic-bezier(0.44, 0, 0.25, 1),
                box-shadow 0.2s cubic-bezier(0.44, 0, 0.25, 1),
                opacity 0.2s ease !important;
  }
  .btn:active, .btn-primary:active, .btn-ghost:active,
  .nav-cta:active, .nav-drawer-link:active, .nav-drawer-cta:active,
  .sticky-cta-btn:active, .waitlist-btn:active,
  .waitlist-copy-btn:active, .waitlist-share-btn:active,
  .bridge-link:active, .reveal-card.is-tappable:active {
    transform: scale(0.97) !important;
  }
  .nav-link:active, .footer-link:active, .brand:active {
    opacity: 0.6 !important;
  }


  /* ---- 14. TAP-TO-UNMASK AFFORDANCE -------------------------
     The signature product beat is the anonymous→revealed moment.
     On desktop it auto-loops. On mobile, main.js wires the card
     as a button and we give it a pulsing "tap to unmask" hint.
     Extra bottom padding reserves space under the heat meter so
     the hint doesn't overlap content. */
  .reveal-card.is-tappable {
    cursor: pointer;
    padding-bottom: 46px !important;
    position: relative;
    user-select: none;
    -webkit-user-select: none;
  }
  .reveal-card.is-tappable::after {
    content: "tap to unmask →";
    position: absolute;
    bottom: 14px;
    left: 50%;
    transform: translateX(-50%);
    font-size: 10.5px;
    font-weight: 800;
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--accent);
    animation: tap-hint-pulse 2.2s cubic-bezier(0.44, 0, 0.25, 1) infinite;
    pointer-events: none;
    white-space: nowrap;
  }
  .reveal-card.is-tappable.is-unmasked::after {
    content: "tap to reset ↺";
    color: var(--text-dim);
    animation: none;
    opacity: 0.6;
  }
  @keyframes tap-hint-pulse {
    0%, 100% { opacity: 0.45; transform: translateX(-50%) translateY(0); }
    50%      { opacity: 1;    transform: translateX(-50%) translateY(-2px); }
  }
  @media (prefers-reduced-motion: reduce) {
    .reveal-card.is-tappable::after { animation: none; opacity: 0.8; }
  }


  /* ---- 15. STICKY CTA SCROLL PROGRESS -----------------------
     A 2px neon sliver at the top of the sticky CTA fills as the
     user scrolls. Uses animation-timeline: scroll(root) — zero JS,
     runs on the compositor. Older browsers just miss the flourish. */
  @supports (animation-timeline: scroll(root)) {
    .sticky-cta::before {
      content: "";
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      height: 2px;
      background: linear-gradient(90deg, var(--accent), var(--accent-hot), var(--danger));
      transform-origin: 0 50%;
      transform: scaleX(0);
      animation: sticky-cta-fill linear both;
      animation-timeline: scroll(root);
      pointer-events: none;
      z-index: 2;
    }
    @keyframes sticky-cta-fill {
      to { transform: scaleX(1); }
    }
  }


  /* ---- 16. HERO AMBIENT GLOW --------------------------------
     The hero was a dead dark rectangle after we killed the orb
     canvas and bg-shift. A single slow-rotating radial gradient
     gives neon atmosphere at ~0% battery cost. Skipped under
     reduced-motion and sat behind content via z-index. */
  .hero {
    position: relative;
    overflow: hidden;
    isolation: isolate;
  }
  .hero-inner {
    position: relative;
    z-index: 1;
  }
  @media (prefers-reduced-motion: no-preference) {
    .hero::before {
      content: "";
      position: absolute;
      top: -40%;
      left: -30%;
      width: 160%;
      height: 160%;
      background:
        radial-gradient(ellipse at 28% 38%, rgba(183, 148, 255, 0.22) 0%, rgba(183, 148, 255, 0) 42%),
        radial-gradient(ellipse at 72% 68%, rgba(255, 106, 213, 0.16) 0%, rgba(255, 106, 213, 0) 45%);
      animation: hero-atmosphere 28s linear infinite;
      pointer-events: none;
      z-index: 0;
      will-change: transform;
    }
    @keyframes hero-atmosphere {
      0%   { transform: rotate(0deg); }
      100% { transform: rotate(360deg); }
    }
  }


  /* ---- 17. PHONE WELCOME (view-timeline) --------------------
     On iOS 26+ / Chrome 115+, scrub the phone's entrance as the
     hero enters the viewport. Pure CSS scroll-driven animation,
     zero JS, runs on the compositor. Non-supporting browsers get
     the existing static phone — no visual regression. */
  @supports (animation-timeline: view()) {
    .hero-phone-col .phone-wrap {
      animation: phone-welcome linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 40%;
    }
    @keyframes phone-welcome {
      from { transform: translateY(32px) scale(0.94); opacity: 0.6; }
      to   { transform: translateY(0)    scale(1);    opacity: 1;   }
    }
  }
  @media (prefers-reduced-motion: reduce) {
    @supports (animation-timeline: view()) {
      .hero-phone-col .phone-wrap { animation: none !important; }
    }
  }


}
