/* ============================================================
   Motion layer (experiment). Paired with motion.js.
   - StringTune writes scroll and cursor state into CSS variables (--progress, --magnetic-x,
     --tilt-x, ...); the rules below turn those into movement. CSS-first, JS-light.
   - anime.js plays the timed choreography (hero intro, section reveals, illustrations).
   Everything is scoped to html.du-motion, which the inline gate in each page's <head> adds
   only when the visitor has not asked for reduced motion. Without it the site is static.
   ============================================================ */

/* Page-to-page crossfade (cross-document View Transitions). The header stays put. */
@media (prefers-reduced-motion: no-preference){
  @view-transition{navigation:auto;}
  ::view-transition-old(root),::view-transition-new(root){animation-duration:.32s;animation-timing-function:cubic-bezier(.22,1,.36,1);}
  #root > header,#site-header > header{view-transition-name:du-header;}
}

/* ---- Intro gate: hero content waits (at most ~1.5s) for the intro timeline ---- */
.du-intro .du-hero-wide .du-container > div:first-child > *,
.du-intro .du-hero-wide .du-container > div:nth-child(2),
.du-intro .du-demo-hero .du-container > div:first-child > *,
.du-intro .du-demo-frame,
.du-intro .du-demo-chapters > *{opacity:0;}

/* Split text: words ride up out of a clip mask */
.du-motion .du-split-word{display:inline-block;will-change:transform;}

/* ---- Nav ---- */
.du-motion header{transition:box-shadow .3s var(--ease-out),background-color .3s var(--ease-out);}
.du-motion header.du-scrolled{background:rgba(255,255,255,.94) !important;box-shadow:0 1px 0 rgba(10,15,28,.04),0 10px 30px -18px rgba(10,15,28,.28);}
/* The demo pill's play button breathes, so the eye finds it */
.du-motion .du-nav-demo-play::before{content:"";position:absolute;inset:0;border-radius:50%;background:var(--blue-700);animation:du-ping 2.8s cubic-bezier(.22,1,.36,1) infinite;z-index:-1;}
.du-nav-demo-play{isolation:isolate;}
@keyframes du-ping{0%{transform:scale(1);opacity:.45}70%,100%{transform:scale(2.1);opacity:0}}

/* ---- Magnetic buttons (StringTune magnetic): CSS `translate` stacks with the button's own transform ---- */
.du-motion [string~="magnetic"]{translate:calc(var(--magnetic-x,0) * 1px) calc(var(--magnetic-y,0) * 1px);}

/* ---- Hero: a brighter grid that follows the cursor ---- */
.du-hero-spot{position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity .6s var(--ease-out);
  background-image:linear-gradient(to right,rgba(9,72,182,.22) 1px,transparent 1px),linear-gradient(to bottom,rgba(9,72,182,.22) 1px,transparent 1px);
  background-size:46px 46px;
  -webkit-mask-image:radial-gradient(260px 260px at var(--mx,50%) var(--my,30%),#000,transparent 70%);
  mask-image:radial-gradient(260px 260px at var(--mx,50%) var(--my,30%),#000,transparent 70%);}
.du-hero-spot::after{content:"";position:absolute;inset:0;background:radial-gradient(220px 220px at var(--mx,50%) var(--my,30%),rgba(42,121,200,.10),transparent 70%);}
@media (hover:hover) and (pointer:fine){ .du-motion .du-spot-on > .du-hero-spot{opacity:1;} }
/* Background grid drifts slower than the page (StringTune parallax) */
.du-hero-grid{will-change:transform;}

/* ---- How it works: the account thread ----
   A line down the middle of the five rows fills as you read (StringTune progress on .du-rows),
   and each row's node lights up as the fill reaches it. Side-by-side layout only. */
.du-rows{position:relative;}
.du-thread,.du-thread-node{display:none;}
@media (min-width:1281px){
  .du-motion .du-thread{display:block;position:absolute;left:50%;top:46px;bottom:46px;width:2px;margin-left:-1px;background:rgba(255,255,255,.12);border-radius:2px;pointer-events:none;z-index:0;}
  .du-motion .du-thread-fill{position:absolute;inset:0;transform-origin:top;transform:scaleY(var(--progress,0));border-radius:inherit;
    background:linear-gradient(180deg,rgba(156,195,236,0),rgba(156,195,236,.7) 30%,#fff);}
  .du-motion .du-thread-tip{position:absolute;left:50%;top:calc(var(--progress,0) * 100%);width:10px;height:10px;margin:-5px 0 0 -5px;border-radius:50%;background:#fff;
    box-shadow:0 0 0 5px rgba(156,195,236,.22),0 0 24px 6px rgba(156,195,236,.55);opacity:calc(min(1, var(--progress,0) * 40));}
  .du-motion .du-thread-node{display:block;position:absolute;left:50%;top:50%;width:14px;height:14px;margin:-7px 0 0 -7px;border-radius:50%;z-index:2;
    background:#0B3C9C;border:2px solid rgba(255,255,255,.28);transition:background-color .4s var(--ease-out),border-color .4s var(--ease-out),box-shadow .6s var(--ease-out),transform .6s cubic-bezier(.34,1.56,.64,1);}
  .du-motion .du-value-row.is-lit .du-thread-node{background:#fff;border-color:#fff;transform:scale(1.15);box-shadow:0 0 0 6px rgba(156,195,236,.25),0 0 30px 4px rgba(156,195,236,.5);}
}

/* ---- Illustration tiles: hover tilt (StringTune tilt) with a soft glare ---- */
.du-motion .du-tilt{transform:perspective(1400px) rotateX(calc(var(--tilt-y,0) * -1deg)) rotateY(calc(var(--tilt-x,0) * 1deg));transform-style:preserve-3d;position:relative;}
.du-motion .du-tilt::after{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;z-index:6;
  background:radial-gradient(480px 340px at calc(50% + var(--tilt-x,0) * 6%) calc(50% - var(--tilt-y,0) * 6%),rgba(255,255,255,.22),transparent 60%);
  opacity:calc(min(1, (max(var(--tilt-x,0), var(--tilt-x,0) * -1) + max(var(--tilt-y,0), var(--tilt-y,0) * -1)) * .5));mix-blend-mode:soft-light;}
/* Voice waveforms keep talking while their tile is on screen */
.du-motion .du-ill .du-wave rect{transform-box:fill-box;transform-origin:center;animation:du-wave 1s ease-in-out infinite alternate;animation-delay:calc(var(--i) * -137ms);animation-play-state:paused;}
.du-motion .du-ill.is-live .du-wave rect{animation-play-state:running;}
@keyframes du-wave{0%{transform:scaleY(.55)}100%{transform:scaleY(1.1)}}

/* ---- Stats: the rule above them draws in from the left ---- */
.du-motion .du-stats{position:relative;border-top-color:transparent !important;}
.du-motion .du-stats::before{content:"";position:absolute;left:0;right:0;top:-1px;height:1px;background:var(--line-inverse);transform:scaleX(0);transform-origin:left;transition:transform 1.4s cubic-bezier(.22,1,.36,1);}
.du-motion .du-stats.is-in::before{transform:scaleX(1);}

/* ---- FAQ: the answer settles in as its row opens ---- */
.du-motion #faq [style*="grid-template-rows"] p{transition:opacity .36s var(--ease-out) .06s,transform .46s var(--ease-out) .04s;}
.du-motion #faq [style*="grid-template-rows: 0fr"] p{opacity:0;transform:translateY(-8px);transition-delay:0s;}
.du-motion #faq button:hover > span:first-child{color:var(--blue-700) !important;}
.du-motion #faq button > span:first-child{transition:color .2s var(--ease-out);}

/* ---- Closing CTA: the card opens up as it scrolls in, and a light follows the cursor ---- */
.du-motion .du-cta-card{clip-path:inset(calc((1 - min(1, var(--progress,1) * 2.2)) * 6%) round var(--radius-2xl));will-change:clip-path;}
.du-cta-glow{position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity .5s var(--ease-out);
  background:radial-gradient(420px 320px at var(--cx,50%) var(--cy,50%),rgba(156,195,236,.30),transparent 70%);}
.du-cta-grid-hi{position:absolute;inset:0;pointer-events:none;opacity:0;transition:opacity .5s var(--ease-out);
  background-image:linear-gradient(to right,rgba(255,255,255,.34) 1px,transparent 1px),linear-gradient(to bottom,rgba(255,255,255,.34) 1px,transparent 1px);background-size:34px 34px;
  -webkit-mask-image:radial-gradient(220px 220px at var(--cx,50%) var(--cy,50%),#000,transparent 70%);
  mask-image:radial-gradient(220px 220px at var(--cx,50%) var(--cy,50%),#000,transparent 70%);}
@media (hover:hover) and (pointer:fine){ .du-motion .du-cta-card.du-spot-on .du-cta-glow,.du-motion .du-cta-card.du-spot-on .du-cta-grid-hi{opacity:1;} }

/* ---- Demo page ---- */
.du-motion .du-demo-glow{animation:du-breathe 7s ease-in-out infinite;}
@keyframes du-breathe{0%,100%{opacity:.85;transform:translateX(-50%) scale(1)}50%{opacity:1;transform:translateX(-50%) scale(1.04)}}

/* ---- Blog: cover charts grow in once their card has arrived ---- */
.du-motion .b-cover-fill{transform-origin:left;transition:transform 1.1s cubic-bezier(.22,1,.36,1) .25s;}
.du-motion .b-cover-row:nth-child(2) .b-cover-fill{transition-delay:.33s;}
.du-motion .b-cover-row:nth-child(3) .b-cover-fill{transition-delay:.41s;}
.du-motion .b-cover-row:nth-child(4) .b-cover-fill{transition-delay:.49s;}
.du-motion .du-wait .b-cover-fill{transform:scaleX(0);transition:none;}
