/* Veris flow: scroll-linked motion shared by every page.
   Content arrives as it scrolls in and settles back as it scrolls out, tied to the scroll position
   (scrubbed, reversible), so a page reads as one continuous piece rather than a stack of sections.
   Scroll timelines run off the main thread. Browsers without them get a one-shot reveal (flow.js).
   Only opacity, translate, scale, rotate, filter and clip-path animate; the individual transform
   properties never fight the hover/press `transform` rules already on these elements. */

/* ---- Ambient light: one space you move through, drifting with the page ---- */
body::before {
  content: ""; position: fixed; z-index: -1; pointer-events: none;
  left: 50%; top: 50%; width: 140vmax; height: 140vmax; margin: -70vmax 0 0 -70vmax;
  background:
    radial-gradient(closest-side at 72% 28%, rgba(46,255,213,.05), transparent 72%),
    radial-gradient(closest-side at 26% 74%, rgba(16,37,31,.7), transparent 72%);
}

/* ---- Reading progress on the nav hairline ---- */
.nav::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--mint) 30%, var(--mint));
  transform-origin: 0 50%; scale: 0 1; opacity: .7; pointer-events: none;
}

/* Headings are split into words by flow.js */
.fw { display: inline-block; }

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .has-motion body::before { animation: f-amb linear both; animation-timeline: scroll(root); }
    .has-motion .nav::after { animation: f-bar linear both; animation-timeline: scroll(root); }

    /* ---- Hero: drifts back and fades as you scroll away, returns as you come back ---- */
    .has-motion .hero > .wrap:first-child,
    .has-motion .chero__txt {
      animation: f-hero linear both; animation-timeline: scroll(root); animation-range: 0 75vh;
    }
    .has-motion .hero > .stage {
      animation: f-stage linear both; animation-timeline: view(); animation-range: exit -10% exit 90%;
      transform-origin: 50% 0;
    }
    .has-motion .cdemo {
      animation: rise 900ms var(--out) 200ms both, f-stage linear forwards;
      animation-timeline: auto, view(); animation-range: normal, exit 0% exit 100%;
      transform-origin: 50% 0;
    }

    /* ---- Every section: sinks back and dims as it leaves the top, under the one arriving ---- */
    .has-motion section:not(.hero):not(.chero):not(.faq) > .wrap {
      animation: f-out linear forwards; animation-timeline: view(); animation-range: exit 0% exit 100%;
      transform-origin: 50% 100%;
    }

    /* ---- Section titles light word by word as they rise into view ---- */
    .has-motion .title.is-split { view-timeline: --fh block; }
    .has-motion .title.is-split .fw {
      animation: f-word var(--out) backwards; animation-timeline: --fh;
      animation-range: cover calc(var(--w, 0) * 2.2%) cover calc(24% + var(--w, 0) * 2.2%);
    }
    .has-motion :is(.sec-hd__lead, .plat__lead, .faq__hd p, .priv__ft, .plat__fine, .dev__links, .ctab__ft) {
      animation: f-in var(--out) backwards; animation-timeline: view(); animation-range: entry 10% cover 34%;
    }

    /* ---- Cards and rows: rise in, slightly staggered across a row ---- */
    .has-motion :is(.proof__list, .bento, .pgrid, .blog__grid, .cprob__list, .guar, .cget__states, .go__steps) > *,
    .has-motion :is(.faq__q, .cget__code, .ctab, .uses__all) {
      animation: f-in var(--out) backwards; animation-timeline: view();
      animation-range: entry 0% cover calc(32% + var(--i, 0) * 4%);
    }
    .has-motion :is(.proof__list, .bento, .pgrid, .blog__grid, .cprob__list, .guar, .cget__states, .go__steps) > :nth-child(2) { --i: 1; }
    .has-motion :is(.proof__list, .bento, .pgrid, .blog__grid, .cprob__list, .guar, .cget__states, .go__steps) > :nth-child(3) { --i: 2; }
    .has-motion :is(.proof__list, .bento, .pgrid, .blog__grid, .cprob__list, .guar, .cget__states, .go__steps) > :nth-child(4) { --i: 3; }
    .has-motion .proof__list > * { --fy: 24px; }
    .has-motion .faq__q { --fy: 28px; }

    /* Photos drift inside their frames */
    .has-motion .pgrid .pcard__img { scale: 1.12; animation: f-par linear both; animation-timeline: view(); }

    /* ---- Big panels: the editor tilts up into place, the closing panel opens out ---- */
    .has-motion .dev > .wrap { perspective: 1600px; }
    .has-motion .ide {
      animation: f-win var(--out) backwards; animation-timeline: view(); animation-range: entry 0% cover 42%;
      transform-origin: 50% 0;
    }
    .has-motion .go__panel {
      animation: f-open var(--out) backwards; animation-timeline: view(); animation-range: entry 0% cover 45%;
    }
    .has-motion .layers__in {
      animation: f-in var(--out) backwards; animation-timeline: view(); animation-range: entry 0% entry 60%;
    }
    .has-motion .layers__stage { animation: f-glow linear both; animation-timeline: view(); animation-range: entry 0% cover 30%; }

    /* Phones and narrow screens: shorter travel, no blur, swipe rows animate as one */
    @media (max-width: 720px) {
      .has-motion .title.is-split .fw { animation-name: f-word-s; }
      .has-motion :is(.pgrid, .blog__grid) > * { animation: none; }
      .has-motion :is(.pgrid, .blog__grid) { animation: f-in var(--out) backwards; animation-timeline: view(); animation-range: entry 0% cover 30%; }
      .has-motion .pgrid .pcard__img { animation: none; scale: none; }
      .has-motion .hero > .wrap:first-child, .has-motion .chero__txt { animation-name: f-hero-s; }
    }
  }
}

@keyframes f-amb  { from { rotate: 0deg; translate: 0 -6vh; } to { rotate: 140deg; translate: 0 6vh; } }
@keyframes f-bar  { to { scale: 1 1; } }
@keyframes f-hero { 0%, 22% { opacity: 1; translate: 0 0; scale: 1; filter: blur(0); } 100% { opacity: 0; translate: 0 22vh; scale: .96; filter: blur(10px); } }
@keyframes f-hero-s { 0%, 22% { opacity: 1; translate: 0 0; } 100% { opacity: 0; translate: 0 14vh; } }
@keyframes f-stage { 0%, 25% { opacity: 1; scale: 1; } 100% { opacity: .1; scale: .9; } }
@keyframes f-out  { 0%, 45% { opacity: 1; scale: 1; translate: 0 0; } 100% { opacity: 0; scale: .93; translate: 0 12vh; } }
@keyframes f-word { from { opacity: .06; translate: 0 .45em; filter: blur(8px); } }
@keyframes f-word-s { from { opacity: .08; translate: 0 .35em; } }
@keyframes f-in   { from { opacity: 0; translate: 0 var(--fy, 64px); scale: .96; } }
@keyframes f-par  { from { translate: 0 -5%; } to { translate: 0 5%; } }
@keyframes f-win  { from { opacity: 0; translate: 0 14vh; scale: .92; rotate: x 16deg; } }
@keyframes f-open { from { clip-path: inset(10% 7% 0 7% round 48px); opacity: .3; translate: 0 8vh; } to { clip-path: inset(0 0 0 0 round 32px); } }
@keyframes f-glow { from { opacity: .3; scale: .9; } }

/* ---- Fallback (no scroll timelines): one-shot rise when an element first comes into view ---- */
.flow-io [data-flow] { opacity: 0; translate: 0 40px; transition: opacity 700ms var(--out), translate 900ms var(--out); transition-delay: calc(var(--i, 0) * 70ms); }
.flow-io [data-flow].is-flown { opacity: 1; translate: none; }
