/* =====================================================
   Animations — Reusable keyframes + utility classes
   ===================================================== */

/* Reveal primitives — toggle .is-in to play */
.reveal{opacity:0;transition:opacity var(--d-3) var(--ease-out),transform var(--d-3) var(--ease-out),filter var(--d-3) var(--ease-out),clip-path var(--d-4) var(--ease-out)}
.reveal.is-in{opacity:1;transform:none;filter:none;clip-path:none}

/* Direction presets */
.fade-up{transform:translate3d(0,40px,0)}
.fade-down{transform:translate3d(0,-40px,0)}
.fade-left{transform:translate3d(-40px,0,0)}
.fade-right{transform:translate3d(40px,0,0)}
.scale-in{transform:scale(.92)}
.blur-in{filter:blur(14px);transform:scale(1.04)}
.mask-up{clip-path:inset(100% 0 0 0)}
.mask-down{clip-path:inset(0 0 100% 0)}
.mask-center{clip-path:inset(0 50% 0 50%)}

/* Stagger — children animate one after another */
[data-stagger] > *{transition-delay:calc(var(--stagger-i,0) * 70ms)}
.stagger-children > *{opacity:0;transform:translate3d(0,28px,0);transition:opacity .6s var(--ease-out),transform .6s var(--ease-out)}
.stagger-children.is-in > *{opacity:1;transform:none}
.stagger-children.is-in > *:nth-child(1){transition-delay:0ms}
.stagger-children.is-in > *:nth-child(2){transition-delay:80ms}
.stagger-children.is-in > *:nth-child(3){transition-delay:160ms}
.stagger-children.is-in > *:nth-child(4){transition-delay:240ms}
.stagger-children.is-in > *:nth-child(5){transition-delay:320ms}
.stagger-children.is-in > *:nth-child(6){transition-delay:400ms}
.stagger-children.is-in > *:nth-child(7){transition-delay:480ms}
.stagger-children.is-in > *:nth-child(8){transition-delay:560ms}
.stagger-children.is-in > *:nth-child(9){transition-delay:640ms}
.stagger-children.is-in > *:nth-child(10){transition-delay:720ms}
.stagger-children.is-in > *:nth-child(11){transition-delay:800ms}
.stagger-children.is-in > *:nth-child(12){transition-delay:880ms}

/* Letter stagger (set on heading) */
.split-text .char{display:inline-block;transform:translate3d(0,80%,0);opacity:0;transition:transform .8s var(--ease-out),opacity .5s var(--ease-out)}
.split-text.is-in .char{transform:none;opacity:1}
.split-text .word{display:inline-block;overflow:hidden;vertical-align:bottom}

/* Continuous animations */
@keyframes spin-slow{to{transform:rotate(360deg)}}
.spin-slow{animation:spin-slow 18s linear infinite}

@keyframes ken-burns{0%{transform:scale(1.05) translate3d(0,0,0)}100%{transform:scale(1.15) translate3d(-2%,-2%,0)}}
.ken-burns{animation:ken-burns 16s ease-in-out infinite alternate}

@keyframes marquee{from{transform:translateX(0)}to{transform:translateX(-50%)}}
.marquee{animation:marquee 30s linear infinite}
.marquee:hover{animation-play-state:paused}

@keyframes pulse-ring{
  0%{box-shadow:0 0 0 0 rgba(30,183,191,.45)}
  70%{box-shadow:0 0 0 20px rgba(30,183,191,0)}
  100%{box-shadow:0 0 0 0 rgba(30,183,191,0)}
}
.pulse-ring{animation:pulse-ring 2.5s var(--ease-out) infinite}

@keyframes shimmer{
  0%{background-position:-1000px 0}
  100%{background-position:1000px 0}
}
.shimmer{background:linear-gradient(90deg,transparent 0%,rgba(255,255,255,.4) 50%,transparent 100%);background-size:1000px 100%;animation:shimmer 2s linear infinite}

@keyframes float-y{0%,100%{transform:translateY(0)}50%{transform:translateY(-12px)}}
.float-y{animation:float-y 6s ease-in-out infinite}

@keyframes draw-check{to{stroke-dashoffset:0}}
@keyframes draw-circle{to{stroke-dashoffset:0}}

@keyframes blob-morph{
  0%,100%{border-radius:60% 40% 30% 70%/60% 30% 70% 40%}
  33%{border-radius:30% 60% 70% 40%/50% 60% 30% 60%}
  66%{border-radius:70% 30% 50% 60%/40% 70% 60% 30%}
}
.blob-morph{animation:blob-morph 14s ease-in-out infinite}

@keyframes ripple{
  to{transform:scale(4);opacity:0}
}

/* Click ripple utility (auto-appends .ripple on .ripple-target) */
.ripple-target{position:relative;overflow:hidden}
.ripple-element{
  position:absolute;border-radius:50%;
  background:rgba(255,255,255,.45);
  pointer-events:none;
  transform:scale(0);
  animation:ripple .7s var(--ease-out) forwards;
}

/* Success check */
.success-check{width:64px;height:64px;border-radius:50%;background:var(--c-success);display:grid;place-items:center;color:#fff;animation:pop-in .6s var(--ease-spring)}
.success-check svg{width:30px;height:30px;stroke-dasharray:48;stroke-dashoffset:48;animation:draw-check .5s .3s var(--ease-out) forwards}
@keyframes pop-in{0%{transform:scale(0);opacity:0}60%{transform:scale(1.1)}100%{transform:scale(1);opacity:1}}

/* Toast slide-in */
.toast{position:fixed;bottom:24px;right:24px;background:var(--c-ink);color:var(--c-bg);padding:1rem 1.4rem;border-radius:var(--r-md);box-shadow:var(--sh-3);z-index:9999;display:flex;align-items:center;gap:.8rem;max-width:380px;transform:translateY(140%);opacity:0;transition:transform .55s var(--ease-spring),opacity .4s var(--ease-out)}
.toast.is-in{transform:none;opacity:1}
.toast--success{border-left:4px solid var(--c-success)}
.toast--error{border-left:4px solid var(--c-error)}

/* Skeleton shimmer */
.skeleton{background:linear-gradient(90deg,rgba(0,0,0,.06) 25%,rgba(0,0,0,.12) 50%,rgba(0,0,0,.06) 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:var(--r-sm)}

/* Parallax helper */
[data-parallax]{will-change:transform}

/* Hero split-reveal */
.split-reveal{position:relative;overflow:hidden}
.split-reveal::before,.split-reveal::after{content:"";position:absolute;top:0;width:50%;height:100%;background:var(--c-bg);z-index:2;transition:transform 1.2s var(--ease-in-out)}
.split-reveal::before{left:0;transform-origin:left}
.split-reveal::after{right:0;transform-origin:right}
.split-reveal.is-in::before{transform:scaleX(0)}
.split-reveal.is-in::after{transform:scaleX(0)}

/* Magnetic wrapper — JS adds inline transform */
.magnetic{transition:transform .35s var(--ease-out);will-change:transform}

/* Page transition (View Transitions) */
@supports (view-transition-name: root){
  ::view-transition-old(root){animation:fade-out .25s var(--ease-out) forwards}
  ::view-transition-new(root){animation:fade-in .4s var(--ease-out) forwards}
}
@keyframes fade-out{to{opacity:0}}
@keyframes fade-in{from{opacity:0}}

/* Glitch text */
.glitch{position:relative;display:inline-block}
.glitch::before,.glitch::after{content:attr(data-text);position:absolute;left:0;top:0;width:100%;overflow:hidden;opacity:.8}
.glitch::before{color:var(--c-teal);transform:translate3d(2px,0,0);clip-path:inset(0 0 60% 0);animation:glitch-1 3s infinite linear alternate-reverse}
.glitch::after{color:var(--c-purple);transform:translate3d(-2px,0,0);clip-path:inset(60% 0 0 0);animation:glitch-2 2.4s infinite linear alternate-reverse}
@keyframes glitch-1{0%,100%{transform:translate3d(2px,0,0)}50%{transform:translate3d(-3px,0,0)}}
@keyframes glitch-2{0%,100%{transform:translate3d(-2px,0,0)}50%{transform:translate3d(3px,0,0)}}
