/*!
 * SDS Motion Forge — standalone scroll bundle
 * Generated from src/categories/ by scripts/build-categories.js — do not edit.
 * Contains: core (tokens, modifiers, reduced-motion, scroll gate) + scroll +
 * cross-category keyframe dependencies. Combining 2+ categories? Use
 * dist/motion.css instead — it ships exactly one copy of core.
 */
/*!
 * SDS Motion Forge — core.css
 * Core — design tokens, utility modifiers, reduced-motion neutralization,
 * and scroll-gate infrastructure shared by every category.
 * Part of the lossless v5 category split — combined entry: src/motion.css
 */

/**
 * SDS Motion Forge — Premium CSS Animation System
 * Version: 5.0.0
 * Author: Salkom Design Studio
 * License: MIT
 * https://github.com/salkomdesignstudio/SDS-Motion-Forge
 *
 * 600+ production-ready CSS animations · Framework-agnostic
 * Text (104) · Buttons (100) · Inputs (100) · Cards (100) · Loaders (100) · Scroll (100)
 *
 * Optional engines (load with defer):
 *   sds-scroll.min.js          — scroll-gate via [data-sds] attribute
 *   motion-interactive.min.js  — cursor-reactive & hover interactive animations
 *
 * ─── HOW TO INSTALL ──────────────────────────────────────────
 *
 * CDN (simplest — paste in <head>):
 *   <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@salkomdesignstudio/sds-motion-forge/dist/motion.min.css">
 *
 * npm + Angular (styles.css or styles.scss):
 *   @import '@salkomdesignstudio/sds-motion-forge/dist/motion.css';
 *
 * npm + React / Next.js (in index.js, _app.js or layout.js):
 *   import '@salkomdesignstudio/sds-motion-forge/dist/motion.css';
 *
 * npm + Vue (in main.js):
 *   import '@salkomdesignstudio/sds-motion-forge/dist/motion.css';
 *
 * npm + Flutter Web (in web/index.html):
 *   <link rel="stylesheet" href="packages/sds_motion_forge/motion.min.css">
 *
 * ─── USAGE ───────────────────────────────────────────────────
 *
 *   <h1 class="sds-velvet-drop">Heading</h1>
 *   <p  class="sds-liquid-rise">Paragraph</p>
 *   <button class="sds-btn-magnetic">Button</button>
 *   <div class="sds-card-float">Card</div>
 *   <span class="sds-loader-orbit"></span>
 *
 * ─── MODIFIERS ───────────────────────────────────────────────
 *
 *   sds-slow       slower animation (1.6× duration)
 *   sds-fast       faster animation (0.5× duration)
 *   sds-delay-1    0.1s delay  (up to sds-delay-10 = 1.0s)
 *   sds-loop       loop forever
 *   sds-once       play once then stop
 *   sds-pause-hover  pause on hover
 *
 * ─── STAGGER / CHILDREN ANIMATIONS ──────────────────────────
 *
 *   Some animations target children (> *). Apply to the PARENT:
 *   <div class="sds-kinetic-wave">
 *     <span>Word</span><span>By</span><span>Word</span>
 *   </div>
 *
 *   Classes that need this: sds-kinetic-wave, sds-stagger-chars,
 *   sds-arc-orbit, sds-signal-wave, sds-card-stagger,
 *   sds-card-cascade, sds-card-slice, sds-loader-dots,
 *   sds-loader-wave, sds-loader-signal, sds-loader-cascade,
 *   sds-loader-grid, sds-scroll-stagger-pop, sds-scroll-stagger-grid,
 *   sds-scroll-cascade
 *
 * ─── SCROLL ANIMATIONS ───────────────────────────────────────
 *
 *   Scroll animations fire when the class is added to the element,
 *   not automatically on scroll. Use one of these two methods:
 *
 *   Method 1 — data-sds-scroll (works everywhere, paste once):
 *   <div data-sds-scroll class="sds-scroll-rise">Content</div>
 *   <script>
 *   (function(){
 *     var io=new IntersectionObserver(function(e){
 *       e.forEach(function(x){if(x.isIntersecting){x.target.classList.add('sds-in');io.unobserve(x.target);}});
 *     },{threshold:0.08,rootMargin:'0px 0px -40px 0px'});
 *     document.querySelectorAll('[data-sds-scroll]').forEach(function(el){io.observe(el);});
 *   })();
 *   </script>
 *
 *   Method 2 — sds-scroll-auto (Chrome 115+, zero JS):
 *   <div class="sds-scroll-auto sds-scroll-rise">Content</div>
 *
 * ─── BUG FIXES IN THIS BUILD ─────────────────────────────────
 *
 *   ✓ sds-loader-progress/data/bar — position:relative added
 *   ✓ will-change on GPU-heavy animations — no jank
 *   ✓ backface-visibility on 3D transforms — no Chrome flicker
 *   ✓ max-width:max-content on typewriter — no text clipping
 *   ✓ prefers-reduced-motion — scroll elements stay visible
 *   ✓ CSS scroll-driven animations via .sds-scroll-auto
 *
 */

/* ============================================================
   DESIGN TOKENS
   Override these in :root to theme SDS Motion to your brand.
   ============================================================ */

:root {
  --sds-primary: #0015d1;
  --sds-primary-dim: rgba(0, 21, 209, 0.08);
  --sds-primary-glow: rgba(0, 21, 209, 0.3);
  --sds-accent: #d10028;
  --sds-success: #00c48c;

  /* ── v5 Motion Token Scale ──────────────────────────────────
     Source of truth: tokens/motion.tokens.json (W3C Design Tokens).
     Regenerate with `npm run build:tokens`. See SPEC.md.        */
  /* @sds-generated-tokens:start — generated from tokens/motion.tokens.json by scripts/generate-tokens.js; do not edit by hand */
  --sds-duration-instant: 0.3s;
  --sds-duration-fast: 0.4s;
  --sds-duration-base: 0.8s;
  --sds-duration-slow: 1.4s;
  --sds-duration-slower: 2.2s;
  --sds-duration-dramatic: 3s;
  --sds-ease-standard: cubic-bezier(0.22, 1, 0.36, 1);
  --sds-ease-decelerate: cubic-bezier(0.16, 1, 0.3, 1);
  --sds-ease-accelerate: cubic-bezier(0.6, -0.28, 0.74, 0.05);
  --sds-ease-emphasized: cubic-bezier(0.215, 0.61, 0.355, 1);
  --sds-ease-spring: cubic-bezier(0.34, 1.56, 0.64, 1);
  --sds-ease-bounce: cubic-bezier(0.68, -0.55, 0.27, 1.55);
  --sds-distance-sm: 24px;
  --sds-distance-md: 48px;
  --sds-distance-lg: 80px;
  /* @sds-generated-tokens:end */

  /* Legacy tokens — permanent public API (R2). They now resolve
     through the v5 scale; computed defaults are unchanged
     (0.8s / cubic-bezier(0.22, 1, 0.36, 1)).                    */
  --sds-duration: var(--sds-duration-base, 0.8s);
  --sds-easing: var(--sds-ease-standard, cubic-bezier(0.22, 1, 0.36, 1));
}

/* ============================================================
   ACCESSIBILITY — REDUCED MOTION
   Matches the user's OS preference. Skips all animation.
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  /* `> *` added in v5 (R5 gate): child-driven effects (kinetic-wave,
     staggers, loader dots/bars) animate plain child elements that carry no
     sds- class of their own — without it they kept moving under reduced
     motion in <= 4.0.3. */
  [class*="sds-"],
  [class*="sds-"] > *,
  [class*="sds-"]::before,
  [class*="sds-"]::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0ms !important;
    transition-duration: 0.01ms !important;
    transition-delay: 0ms !important;
    scroll-behavior: auto !important;
  }
  /* Scroll-animated elements must stay visible under reduced motion */
  [class*="sds-scroll-"],
  [class*="sds-scroll-"] > * {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
    clip-path: none !important;
    -webkit-clip-path: none !important;
  }
}

/* ============================================================
   UTILITY MODIFIERS
   Stack these on any animation class.
   ============================================================ */

/* Delay helpers */

.sds-delay-1 {
  animation-delay: 0.1s !important;
}

.sds-delay-2 {
  animation-delay: 0.2s !important;
}

.sds-delay-3 {
  animation-delay: 0.3s !important;
}

.sds-delay-4 {
  animation-delay: 0.4s !important;
}

.sds-delay-5 {
  animation-delay: 0.5s !important;
}

.sds-delay-6 {
  animation-delay: 0.6s !important;
}

.sds-delay-8 {
  animation-delay: 0.8s !important;
}

.sds-delay-10 {
  animation-delay: 1s !important;
}

/* Duration helpers — override --sds-duration token */

.sds-fast {
  --sds-duration: var(--sds-duration-fast, 0.4s);
}

.sds-normal {
  --sds-duration: var(--sds-duration-base, 0.8s);
}

.sds-slow {
  --sds-duration: var(--sds-duration-slow, 1.4s);
}

.sds-xslow {
  --sds-duration: var(--sds-duration-slower, 2.2s);
}

/* Iteration helpers */

.sds-once {
  animation-iteration-count: 1 !important;
  animation-fill-mode: both !important;
}

/* Cascade to > * so stagger/wave containers (arc-orbit, kinetic-wave, signal-wave,
   stagger-pop, stagger-grid) loop correctly — their animations live on children. */

.sds-loop,
.sds-loop > * {
  animation-iteration-count: infinite !important;
}

.sds-alt,
.sds-alt > * {
  animation-direction: alternate;
  animation-iteration-count: infinite !important;
}

/* Fill modes */

.sds-fill-both {
  animation-fill-mode: both !important;
}

.sds-fill-forward {
  animation-fill-mode: forwards !important;
}

/* Pause on hover */

.sds-pause-hover:hover,
.sds-pause-hover:hover *,
.sds-pause-hover:hover::before,
.sds-pause-hover:hover::after {
  animation-play-state: paused !important;
}

/* ============================================================
   SCROLL ANIMATION ACTIVATION
   ============================================================
   Add data-sds-scroll to your element, then include this
   script once in your page. The animation fires when the
   element enters the viewport.

   <div data-sds-scroll class="sds-scroll-rise">Your content</div>

   <script>
   (function(){
     var io=new IntersectionObserver(function(e){
       e.forEach(function(x){
         if(x.isIntersecting){
           x.target.classList.add('sds-in');
           io.unobserve(x.target);
         }
       });
     },{threshold:0.08,rootMargin:'0px 0px -40px 0px'});
     document.querySelectorAll('[data-sds-scroll]').forEach(function(el){
       io.observe(el);
     });
   })();
   </script>
   ============================================================ */

[data-sds-scroll][class*="sds-scroll-"] {
  opacity: 0;
  animation-play-state: paused;
}

[data-sds-scroll].sds-in[class*="sds-scroll-"] {
  opacity: 1;
  animation-play-state: running;
}

/* CSS Scroll-Driven Animations — Chrome 115+, zero JS */

@supports (animation-timeline: scroll()) {
  .sds-scroll-auto[class*="sds-scroll-"] {
    animation-timeline: view();
    animation-range: entry 0% entry 40%;
    animation-play-state: running;
    opacity: 1;
  }
}

/* ============================================================
   SCROLL GATE — sds-scroll.js engine (data-sds attribute)
   ============================================================
   Requires: <script src="sds-scroll.min.js" defer></script>
   The JS adds "sds-js" to <html> and "sds-play" to each
   [data-sds] element when it enters the viewport.
   ============================================================ */

/* Gate: hidden + paused until JS grants sds-play */

[data-sds]:not(.sds-play) {
  animation-play-state: paused !important;
  animation-delay: -1ms !important;
  opacity: 0 !important;
}

/* Release: visible + running */

[data-sds].sds-play {
  opacity: 1;
  animation-play-state: running !important;
}

/* Fallback: if JS never loads, show content normally */

html:not(.sds-js) [data-sds] {
  opacity: 1 !important;
  animation-play-state: running !important;
}

/* v5 fix (additive): while an element is scroll-gated it is opacity:0, but
   its PAUSED 0% keyframe still applied clip-path/transform — and Chromium
   computes IntersectionObserver geometry AFTER the target's own clip and
   transform. Effects whose first frame fully clips (curtain, clip-left/right,
   radial, ink, scan, split) or moves the box off-screen (velvet, gravity)
   therefore NEVER intersected and never played in <= 4.0.3, with every
   documented scroll method. Neutralizing clip/transform only in the hidden,
   gated state restores the element's real box for the observer; the moment
   sds-play / sds-in lands, these rules stop matching and the animation plays
   from its true 0% frame. */
[data-sds]:not(.sds-play),
[data-sds-scroll][class*="sds-scroll-"]:not(.sds-in) {
  clip-path: none !important;
  -webkit-clip-path: none !important;
  transform: none !important;
}

/*!
 * SDS Motion Forge — scroll.css
 * Scroll / viewport animations (Section 6) + scroll legacy alias.
 * Part of the lossless v5 category split — combined entry: src/motion.css
 */

/* ============================================================
   SECTION 6 — SCROLL / VIEWPORT ANIMATIONS
   Namespace: .sds-scroll-*
   Usage: Add the class via IntersectionObserver when the
   element enters the viewport. The animation fires once on
   class add (fill-mode: both holds the final state).
   ============================================================ */

/* 78 · Viewport Rise --------------------------------------- */

.sds-scroll-rise {
  animation: sds-viewportRise var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-viewportRise {
  from {
    opacity: 0;
    transform: translateY(50px) scale(0.95);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* 79 · Curtain Lift ---------------------------------------- */

.sds-scroll-curtain {
  animation: sds-curtainLift var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-curtainLift {
  from {
    clip-path: inset(0 0 100% 0);
    opacity: 0;
  }
  to {
    clip-path: inset(0 0 0% 0);
    opacity: 1;
  }
}

/* 80 · Scroll Warp ----------------------------------------- */

.sds-scroll-warp {
  animation: sds-scrollWarp 0.9s var(--sds-easing) both;
}

@keyframes sds-scrollWarp {
  from {
    opacity: 0;
    transform: perspective(600px) rotateX(20deg) translateY(30px);
    filter: blur(4px);
  }
  to {
    opacity: 1;
    transform: perspective(600px) rotateX(0) translateY(0);
    filter: blur(0);
  }
}

/* 81 · Momentum Slide -------------------------------------- */

.sds-scroll-slide {
  animation: sds-momentumSlide var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-momentumSlide {
  from {
    opacity: 0;
    transform: translateX(-60px);
  }
  70% {
    transform: translateX(6px);
  }
  100% {
    opacity: 1;
    transform: translateX(0);
  }
}

/* 82 · Scale Reveal ---------------------------------------- */

.sds-scroll-scale {
  animation: sds-scaleReveal var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scaleReveal {
  from {
    opacity: 0;
    transform: scale(0.7);
    filter: blur(8px);
  }
  70% {
    opacity: 1;
    transform: scale(1.02);
    filter: blur(0);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

/* 83 · Radial Expand --------------------------------------- */

.sds-scroll-radial {
  animation: sds-radialExpand 0.9s var(--sds-easing) both;
}

@keyframes sds-radialExpand {
  from {
    clip-path: circle(0% at 50% 100%);
    opacity: 0;
  }
  to {
    clip-path: circle(150% at 50% 100%);
    opacity: 1;
  }
}

/* 84 · Blur Ascend ----------------------------------------- */

.sds-scroll-blur {
  animation: sds-blurAscend var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-blurAscend {
  from {
    opacity: 0;
    transform: translateY(40px);
    filter: blur(16px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
    filter: blur(0);
  }
}

/* 85 · Tilt Reveal ----------------------------------------- */

.sds-scroll-tilt {
  animation: sds-tiltReveal var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-tiltReveal {
  from {
    opacity: 0;
    transform: perspective(400px) rotateX(50deg) translateY(20px);
  }
  to {
    opacity: 1;
    transform: perspective(400px) rotateX(0) translateY(0);
  }
}

/* 86 · Scan Line ------------------------------------------- */

.sds-scroll-scan {
  animation: sds-scanLine var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scanLine {
  from {
    clip-path: inset(0 100% 0 0);
  }
  to {
    clip-path: inset(0 0% 0 0);
  }
}

/* 87 · Stagger Pop (up to 12 children) --------------------- */

.sds-scroll-stagger-pop > * {
  animation: sds-staggerPop 0.7s var(--sds-easing) both;
}

.sds-scroll-stagger-pop > *:nth-child(1) {
  animation-delay: 0s;
}

.sds-scroll-stagger-pop > *:nth-child(2) {
  animation-delay: 0.1s;
}

.sds-scroll-stagger-pop > *:nth-child(3) {
  animation-delay: 0.2s;
}

.sds-scroll-stagger-pop > *:nth-child(4) {
  animation-delay: 0.3s;
}

.sds-scroll-stagger-pop > *:nth-child(5) {
  animation-delay: 0.4s;
}

.sds-scroll-stagger-pop > *:nth-child(6) {
  animation-delay: 0.5s;
}

.sds-scroll-stagger-pop > *:nth-child(7) {
  animation-delay: 0.6s;
}

.sds-scroll-stagger-pop > *:nth-child(8) {
  animation-delay: 0.7s;
}

.sds-scroll-stagger-pop > *:nth-child(9) {
  animation-delay: 0.8s;
}

.sds-scroll-stagger-pop > *:nth-child(10) {
  animation-delay: 0.9s;
}

.sds-scroll-stagger-pop > *:nth-child(11) {
  animation-delay: 1s;
}

.sds-scroll-stagger-pop > *:nth-child(12) {
  animation-delay: 1.1s;
}

@keyframes sds-staggerPop {
  0% {
    opacity: 0;
    transform: scale(0.7) rotate(-4deg);
  }
  60% {
    opacity: 1;
    transform: scale(1.06) rotate(1deg);
  }
  100% {
    opacity: 1;
    transform: scale(1) rotate(0);
  }
}

/* 88 · Depth Enter ----------------------------------------- */

.sds-scroll-depth {
  animation: sds-depthPortal 0.9s var(--sds-easing) both;
}

/* 89 · Shatter Enter --------------------------------------- */

.sds-scroll-shatter {
  animation: sds-shatterIn var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

/* 90 · Phantom Rise ---------------------------------------- */

.sds-scroll-phantom {
  animation: sds-phantomBlur var(--sds-duration-base, 0.8s) ease both;
}

/* 91 · Gravity Land ---------------------------------------- */

.sds-scroll-gravity {
  animation: sds-gravityDrop var(--sds-duration-base, 0.8s) var(--sds-ease-bounce, cubic-bezier(0.68, -0.55, 0.27, 1.55)) both;
}

/* 92 · Liquid Enter ---------------------------------------- */

.sds-scroll-liquid {
  animation: sds-liquidRise var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

/* 93 · Velvet Drop Scroll ---------------------------------- */

.sds-scroll-velvet {
  animation: sds-velvetDrop var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

/* 94 · Stagger Grid (up to 12 children) -------------------- */

.sds-scroll-stagger-grid > * {
  animation: sds-viewportRise 0.6s var(--sds-easing) both;
}

.sds-scroll-stagger-grid > *:nth-child(1) {
  animation-delay: 0s;
}

.sds-scroll-stagger-grid > *:nth-child(2) {
  animation-delay: 0.08s;
}

.sds-scroll-stagger-grid > *:nth-child(3) {
  animation-delay: 0.16s;
}

.sds-scroll-stagger-grid > *:nth-child(4) {
  animation-delay: 0.24s;
}

.sds-scroll-stagger-grid > *:nth-child(5) {
  animation-delay: 0.32s;
}

.sds-scroll-stagger-grid > *:nth-child(6) {
  animation-delay: 0.4s;
}

.sds-scroll-stagger-grid > *:nth-child(7) {
  animation-delay: 0.48s;
}

.sds-scroll-stagger-grid > *:nth-child(8) {
  animation-delay: 0.56s;
}

.sds-scroll-stagger-grid > *:nth-child(9) {
  animation-delay: 0.64s;
}

.sds-scroll-stagger-grid > *:nth-child(10) {
  animation-delay: 0.72s;
}

.sds-scroll-stagger-grid > *:nth-child(11) {
  animation-delay: 0.8s;
}

.sds-scroll-stagger-grid > *:nth-child(12) {
  animation-delay: 0.88s;
}

/* 95 · Orbit Enter ----------------------------------------- */

.sds-scroll-orbit {
  animation: sds-perspSwing var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

/* 96 · Glitch Reveal --------------------------------------- */

.sds-scroll-glitch {
  animation:
    sds-staticBurst 0.6s steps(1) both,
    sds-viewportRise var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

/* 97 · Flip Reveal -------------------------------------- */

.sds-scroll-flip {
  animation: sds-scrollFlip var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scrollFlip {
  from {
    opacity: 0;
    transform: perspective(600px) rotateX(60deg) translateY(30px);
    filter: blur(4px);
  }
  to {
    opacity: 1;
    transform: perspective(600px) rotateX(0) translateY(0);
    filter: blur(0);
  }
}

/* 98 · Zoom Blur ---------------------------------------- */

.sds-scroll-zoom-blur {
  animation: sds-scrollZoomBlur 0.9s var(--sds-easing) both;
}

@keyframes sds-scrollZoomBlur {
  from {
    opacity: 0;
    transform: scale(1.3);
    filter: blur(20px);
  }
  to {
    opacity: 1;
    transform: scale(1);
    filter: blur(0);
  }
}

/* 99 · Split Reveal ------------------------------------- */

.sds-scroll-split {
  animation: sds-scrollSplit 0.9s var(--sds-easing) both;
}

@keyframes sds-scrollSplit {
  from {
    clip-path: polygon(50% 0%, 50% 0%, 50% 100%, 50% 100%);
    opacity: 0;
  }
  to {
    clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%);
    opacity: 1;
  }
}

/* 100 · Morph Rise -------------------------------------- */

.sds-scroll-morph {
  animation: sds-scrollMorph 0.9s var(--sds-easing) both;
}

@keyframes sds-scrollMorph {
  from {
    opacity: 0;
    transform: translateY(40px) skewY(4deg) scaleX(0.94);
  }
  to {
    opacity: 1;
    transform: translateY(0) skewY(0) scaleX(1);
  }
}

/* 101 · Spring ------------------------------------------ */

.sds-scroll-spring {
  animation: sds-scrollSpring 0.9s var(--sds-ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1)) both;
}

@keyframes sds-scrollSpring {
  from {
    opacity: 0;
    transform: translateY(60px) scale(0.8);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* 102 · Clip Left --------------------------------------- */

.sds-scroll-clip-left {
  animation: sds-scrollClipLeft var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scrollClipLeft {
  from {
    clip-path: inset(0 0 0 100%);
    opacity: 0;
  }
  to {
    clip-path: inset(0 0 0 0%);
    opacity: 1;
  }
}

/* 103 · Clip Right -------------------------------------- */

.sds-scroll-clip-right {
  animation: sds-scrollClipRight var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scrollClipRight {
  from {
    clip-path: inset(0 100% 0 0);
    opacity: 0;
  }
  to {
    clip-path: inset(0 0% 0 0);
    opacity: 1;
  }
}

/* 104 · Elastic ----------------------------------------- */

.sds-scroll-elastic {
  animation: sds-scrollElastic 1s var(--sds-ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1)) both;
}

@keyframes sds-scrollElastic {
  0% {
    opacity: 0;
    transform: translateY(80px) scaleY(0.6);
  }
  60% {
    opacity: 1;
    transform: translateY(-8px) scaleY(1.08);
  }
  80% {
    transform: translateY(3px) scaleY(0.97);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scaleY(1);
  }
}

/* 105 · Cinema ------------------------------------------ */

.sds-scroll-cinema {
  animation: sds-scrollCinema 1.2s var(--sds-easing) both;
}

@keyframes sds-scrollCinema {
  from {
    opacity: 0;
    letter-spacing: 0.4em;
    transform: scale(0.85);
    filter: blur(12px);
  }
  to {
    opacity: 1;
    letter-spacing: 0;
    transform: scale(1);
    filter: blur(0);
  }
}

/* 106 · Fog --------------------------------------------- */

.sds-scroll-fog {
  animation: sds-scrollFog 1.2s ease both;
}

@keyframes sds-scrollFog {
  from {
    opacity: 0;
    filter: blur(30px) brightness(2);
    transform: scale(1.1);
  }
  to {
    opacity: 1;
    filter: blur(0) brightness(1);
    transform: scale(1);
  }
}

/* 107 · Neon Reveal ------------------------------------- */

.sds-scroll-neon {
  animation: sds-scrollNeon 1s var(--sds-easing) both;
}

@keyframes sds-scrollNeon {
  0% {
    opacity: 0;
    text-shadow: 0 0 0 var(--sds-primary);
    transform: translateY(20px);
  }
  60% {
    opacity: 1;
    text-shadow:
      0 0 20px var(--sds-primary-glow),
      0 0 40px var(--sds-primary-dim);
    transform: translateY(-3px);
  }
  100% {
    opacity: 1;
    text-shadow: none;
    transform: translateY(0);
  }
}

/* 108 · Prism Reveal ------------------------------------ */

.sds-scroll-prism {
  animation: sds-scrollPrism 1s var(--sds-easing) both;
}

@keyframes sds-scrollPrism {
  0% {
    opacity: 0;
    filter: hue-rotate(180deg) blur(8px) brightness(2);
    transform: scale(0.9);
  }
  60% {
    opacity: 1;
    filter: hue-rotate(30deg) blur(0) brightness(1.1);
    transform: scale(1.02);
  }
  100% {
    opacity: 1;
    filter: hue-rotate(0deg) blur(0) brightness(1);
    transform: scale(1);
  }
}

/* 109 · Charge Reveal ----------------------------------- */

.sds-scroll-charge {
  animation: sds-scrollCharge var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scrollCharge {
  0% {
    opacity: 0;
    transform: translateY(30px);
    filter: brightness(3) blur(6px);
  }
  50% {
    opacity: 1;
    transform: translateY(-4px);
    filter: brightness(1.4) blur(0);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
    filter: brightness(1);
  }
}

/* 110 · Magnetic Pull ----------------------------------- */

.sds-scroll-magnetic {
  animation: sds-scrollMagnetic 0.9s var(--sds-ease-decelerate, cubic-bezier(0.16, 1, 0.3, 1)) both;
}

@keyframes sds-scrollMagnetic {
  0% {
    opacity: 0;
    transform: scale(1.2) translateY(-20px);
    filter: blur(8px);
  }
  60% {
    opacity: 1;
    transform: scale(0.98) translateY(3px);
    filter: blur(0);
  }
  100% {
    opacity: 1;
    transform: scale(1) translateY(0);
  }
}

/* 111 · Wave Rise --------------------------------------- */

.sds-scroll-wave-rise > * {
  animation: sds-viewportRise 0.7s var(--sds-easing) both;
}

.sds-scroll-wave-rise > *:nth-child(1) {
  animation-delay: 0s;
}

.sds-scroll-wave-rise > *:nth-child(2) {
  animation-delay: 0.08s;
}

.sds-scroll-wave-rise > *:nth-child(3) {
  animation-delay: 0.16s;
}

.sds-scroll-wave-rise > *:nth-child(4) {
  animation-delay: 0.24s;
}

.sds-scroll-wave-rise > *:nth-child(5) {
  animation-delay: 0.32s;
}

.sds-scroll-wave-rise > *:nth-child(6) {
  animation-delay: 0.4s;
}

.sds-scroll-wave-rise > *:nth-child(7) {
  animation-delay: 0.48s;
}

.sds-scroll-wave-rise > *:nth-child(8) {
  animation-delay: 0.56s;
}

.sds-scroll-wave-rise > *:nth-child(9) {
  animation-delay: 0.64s;
}

.sds-scroll-wave-rise > *:nth-child(10) {
  animation-delay: 0.72s;
}

.sds-scroll-wave-rise > *:nth-child(11) {
  animation-delay: 0.8s;
}

.sds-scroll-wave-rise > *:nth-child(12) {
  animation-delay: 0.88s;
}

/* 112 · Dissolve ---------------------------------------- */

.sds-scroll-dissolve {
  animation: sds-scrollDissolve 1s ease both;
}

@keyframes sds-scrollDissolve {
  0% {
    opacity: 0;
    filter: blur(16px) saturate(0);
    transform: scale(1.05);
  }
  60% {
    opacity: 1;
    filter: blur(2px) saturate(0.6);
    transform: scale(1.01);
  }
  100% {
    opacity: 1;
    filter: blur(0) saturate(1);
    transform: scale(1);
  }
}

/* 113 · Unfold ------------------------------------------ */

.sds-scroll-unfold {
  will-change: transform, opacity;
  transform-origin: top center;
  animation: sds-scrollUnfold var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scrollUnfold {
  from {
    opacity: 0;
    transform: perspective(500px) rotateX(-70deg) scaleY(0.6);
  }
  to {
    opacity: 1;
    transform: perspective(500px) rotateX(0) scaleY(1);
  }
}

/* 114 · Perspective Left -------------------------------- */

.sds-scroll-perspective-left {
  animation: sds-scrollPerspLeft var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scrollPerspLeft {
  from {
    opacity: 0;
    transform: perspective(600px) rotateY(-50deg) translateX(-30px);
  }
  to {
    opacity: 1;
    transform: perspective(600px) rotateY(0) translateX(0);
  }
}

/* 115 · Bounce ------------------------------------------ */

.sds-scroll-bounce {
  animation: sds-scrollBounce 0.9s var(--sds-ease-emphasized, cubic-bezier(0.215, 0.61, 0.355, 1)) both;
}

@keyframes sds-scrollBounce {
  0% {
    opacity: 0;
    transform: translateY(70px);
  }
  60% {
    opacity: 1;
    transform: translateY(-16px);
  }
  78% {
    transform: translateY(8px);
  }
  90% {
    transform: translateY(-4px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

/* 116 · Ink --------------------------------------------- */

.sds-scroll-ink {
  animation: sds-scrollInk 1s var(--sds-easing) both;
}

@keyframes sds-scrollInk {
  from {
    clip-path: circle(0% at 0% 50%);
    opacity: 0;
  }
  to {
    clip-path: circle(150% at 0% 50%);
    opacity: 1;
  }
}

/* 117 · Snap -------------------------------------------- */

.sds-scroll-snap {
  animation: sds-scrollSnap 0.5s var(--sds-ease-bounce, cubic-bezier(0.68, -0.55, 0.27, 1.55)) both;
}

@keyframes sds-scrollSnap {
  0% {
    opacity: 0;
    transform: scale(1.25) rotate(3deg);
  }
  60% {
    opacity: 1;
    transform: scale(0.95) rotate(-1deg);
  }
  80% {
    transform: scale(1.03) rotate(0.5deg);
  }
  100% {
    opacity: 1;
    transform: scale(1) rotate(0);
  }
}

/* 118 · Spiral ------------------------------------------ */

.sds-scroll-spiral {
  animation: sds-scrollSpiral 0.9s var(--sds-easing) both;
}

@keyframes sds-scrollSpiral {
  0% {
    opacity: 0;
    transform: rotate(-180deg) scale(0.3);
    filter: blur(12px);
  }
  60% {
    opacity: 1;
    transform: rotate(8deg) scale(1.04);
    filter: blur(0);
  }
  80% {
    transform: rotate(-3deg) scale(0.98);
  }
  100% {
    opacity: 1;
    transform: rotate(0) scale(1);
  }
}

/* 119 · Vortex ------------------------------------------ */

.sds-scroll-vortex {
  animation: sds-scrollVortex var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scrollVortex {
  0% {
    opacity: 0;
    transform: perspective(400px) translateZ(-200px) rotate(-20deg) scale(0.5);
    filter: blur(16px);
  }
  60% {
    opacity: 1;
    transform: perspective(400px) translateZ(8px) rotate(4deg) scale(1.03);
    filter: blur(0);
  }
  100% {
    opacity: 1;
    transform: perspective(400px) translateZ(0) rotate(0) scale(1);
  }
}

/* 120 · Skew -------------------------------------------- */

.sds-scroll-skew {
  animation: sds-scrollSkew var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scrollSkew {
  from {
    opacity: 0;
    transform: translateX(-40px) skewX(-12deg) scaleX(0.85);
  }
  to {
    opacity: 1;
    transform: translateX(0) skewX(0) scaleX(1);
  }
}

/* 121 · Punch ------------------------------------------- */

.sds-scroll-punch {
  animation: sds-scrollPunch 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
}

@keyframes sds-scrollPunch {
  0% {
    opacity: 0;
    transform: scale(0.4);
    filter: blur(16px) brightness(3);
  }
  50% {
    opacity: 1;
    transform: scale(1.1);
    filter: blur(1px) brightness(1.3);
  }
  70% {
    transform: scale(0.96);
    filter: blur(0);
  }
  100% {
    opacity: 1;
    transform: scale(1);
    filter: brightness(1);
  }
}

/* 122 · Crystallize ------------------------------------- */

.sds-scroll-crystallize {
  animation: sds-scrollCrystallize 1s ease both;
}

@keyframes sds-scrollCrystallize {
  0% {
    opacity: 0;
    filter: blur(20px) brightness(2) contrast(0.5);
    transform: scale(0.95);
  }
  40% {
    opacity: 1;
    filter: blur(4px) brightness(1.3) contrast(0.8);
    transform: scale(1.02);
  }
  100% {
    opacity: 1;
    filter: blur(0) brightness(1) contrast(1);
    transform: scale(1);
  }
}

/* 123 · Cascade (up to 12 children) -------------------- */

.sds-scroll-cascade > * {
  animation: sds-scrollCascadeChild 0.6s var(--sds-easing) both;
}

.sds-scroll-cascade > *:nth-child(1) {
  animation-delay: 0s;
}

.sds-scroll-cascade > *:nth-child(2) {
  animation-delay: 0.08s;
}

.sds-scroll-cascade > *:nth-child(3) {
  animation-delay: 0.16s;
}

.sds-scroll-cascade > *:nth-child(4) {
  animation-delay: 0.24s;
}

.sds-scroll-cascade > *:nth-child(5) {
  animation-delay: 0.32s;
}

.sds-scroll-cascade > *:nth-child(6) {
  animation-delay: 0.4s;
}

.sds-scroll-cascade > *:nth-child(7) {
  animation-delay: 0.48s;
}

.sds-scroll-cascade > *:nth-child(8) {
  animation-delay: 0.56s;
}

.sds-scroll-cascade > *:nth-child(9) {
  animation-delay: 0.64s;
}

.sds-scroll-cascade > *:nth-child(10) {
  animation-delay: 0.72s;
}

.sds-scroll-cascade > *:nth-child(11) {
  animation-delay: 0.8s;
}

.sds-scroll-cascade > *:nth-child(12) {
  animation-delay: 0.88s;
}

@keyframes sds-scrollCascadeChild {
  from {
    opacity: 0;
    transform: translateY(30px) scale(0.9);
    filter: blur(4px);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
    filter: blur(0);
  }
}

/* 124 · Hologram ---------------------------------------- */

.sds-scroll-hologram {
  animation: sds-scrollHologram 1s var(--sds-easing) both;
}

@keyframes sds-scrollHologram {
  0% {
    opacity: 0;
    transform: translateY(20px);
    filter: hue-rotate(180deg) brightness(2) blur(6px);
  }
  50% {
    opacity: 1;
    filter: hue-rotate(20deg) brightness(1.2) blur(0);
    transform: translateY(-4px);
  }
  100% {
    opacity: 1;
    filter: hue-rotate(0deg) brightness(1);
    transform: translateY(0);
  }
}

/* 125 · Drift ------------------------------------------- */

.sds-scroll-drift {
  animation: sds-scrollDrift 1.2s var(--sds-easing) both;
}

@keyframes sds-scrollDrift {
  from {
    opacity: 0;
    transform: translate(-24px, 24px) rotate(-3deg);
    filter: blur(8px);
  }
  to {
    opacity: 1;
    transform: translate(0, 0) rotate(0);
    filter: blur(0);
  }
}

/* 126 · Streak ------------------------------------------ */

.sds-scroll-streak {
  animation: sds-scrollStreak 0.7s var(--sds-ease-decelerate, cubic-bezier(0.16, 1, 0.3, 1)) both;
}

@keyframes sds-scrollStreak {
  0% {
    opacity: 0;
    transform: translateX(-200px) scaleX(3);
    filter: blur(20px);
  }
  40% {
    opacity: 1;
    filter: blur(4px);
  }
  70% {
    transform: translateX(6px) scaleX(0.98);
    filter: blur(0);
  }
  100% {
    opacity: 1;
    transform: translateX(0) scaleX(1);
  }
}

/* 127 · Elastic Pop ------------------------------------- */

.sds-scroll-elastic-pop {
  animation: sds-scrollElasticPop 0.7s var(--sds-ease-spring, cubic-bezier(0.34, 1.56, 0.64, 1)) both;
}

@keyframes sds-scrollElasticPop {
  0% {
    opacity: 0;
    transform: scale(0.4) rotate(-8deg);
  }
  60% {
    opacity: 1;
    transform: scale(1.1) rotate(3deg);
  }
  80% {
    transform: scale(0.96) rotate(-1deg);
  }
  100% {
    opacity: 1;
    transform: scale(1) rotate(0);
  }
}

/* 128 · Slide Right ------------------------------------- */

.sds-scroll-slide-right {
  animation: sds-scrollSlideRight var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scrollSlideRight {
  from {
    opacity: 0;
    transform: translateX(60px);
  }
  70% {
    transform: translateX(-6px);
  }
  100% {
    opacity: 1;
    transform: translateX(0);
  }
}

/* 129 · Warp Enter -------------------------------------- */

.sds-scroll-warp-in {
  animation: sds-scrollWarpIn 0.9s var(--sds-easing) both;
}

@keyframes sds-scrollWarpIn {
  from {
    opacity: 0;
    transform: perspective(500px) rotateX(25deg) scaleX(0.8) translateY(40px);
    filter: blur(6px);
  }
  to {
    opacity: 1;
    transform: perspective(500px) rotateX(0) scaleX(1) translateY(0);
    filter: blur(0);
  }
}

/* 130 · Bright Flash ------------------------------------ */

.sds-scroll-flash {
  animation: sds-scrollFlash 0.7s ease both;
}

@keyframes sds-scrollFlash {
  0% {
    opacity: 0;
    filter: brightness(5) blur(12px);
    transform: scale(0.9);
  }
  30% {
    opacity: 1;
    filter: brightness(2) blur(2px);
    transform: scale(1.04);
  }
  60% {
    filter: brightness(1.2);
  }
  100% {
    opacity: 1;
    filter: brightness(1) blur(0);
    transform: scale(1);
  }
}

.sds-scroll-fade-up {
  animation: sds-viewportRise var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}


/* ====================================================================
   BATCH 16 � Scroll: Clean Entrances (6) + Drama & Emphasis (6)
   ==================================================================== */

/* 131 � Zoom In ----------------------------------------- */

.sds-scroll-zoom-in {
  animation: sds-scrollZoomIn var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scrollZoomIn {
  from {
    transform: scale(0.5);
    opacity: 0;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}

/* 132 � Zoom Out ---------------------------------------- */

.sds-scroll-zoom-out {
  animation: sds-scrollZoomOut var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scrollZoomOut {
  from {
    transform: scale(1.35);
    opacity: 0;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}

/* 133 � Rotate In --------------------------------------- */

.sds-scroll-rotate-in {
  animation: sds-scrollRotateIn var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scrollRotateIn {
  from {
    transform: rotate(-8deg) translateY(24px);
    opacity: 0;
  }
  to {
    transform: rotate(0deg) translateY(0);
    opacity: 1;
  }
}

/* 134 � Hinge In ---------------------------------------- */

.sds-scroll-hinge-in {
  animation: sds-scrollHingeIn var(--sds-duration-base, 0.8s) var(--sds-easing) both;
  transform-origin: top;
}

@keyframes sds-scrollHingeIn {
  from {
    transform: perspective(600px) rotateX(-55deg);
    opacity: 0;
  }
  to {
    transform: perspective(600px) rotateX(0deg);
    opacity: 1;
  }
}

/* 135 � Roll In ----------------------------------------- */

.sds-scroll-roll-in {
  animation: sds-scrollRollIn var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scrollRollIn {
  from {
    transform: translateX(-60px) rotate(-10deg);
    opacity: 0;
  }
  to {
    transform: translateX(0) rotate(0deg);
    opacity: 1;
  }
}

/* 136 � Rise Right -------------------------------------- */

.sds-scroll-rise-right {
  animation: sds-scrollRiseRight var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scrollRiseRight {
  from {
    transform: translate(-28px, 28px);
    opacity: 0;
  }
  to {
    transform: translate(0, 0);
    opacity: 1;
  }
}

/* 137 � Cinematic --------------------------------------- */

.sds-scroll-cinematic {
  animation: sds-scrollCinematic var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scrollCinematic {
  from {
    clip-path: inset(22% 0);
    transform: scale(1.06);
    opacity: 0.5;
  }
  to {
    clip-path: inset(0% 0);
    transform: scale(1);
    opacity: 1;
  }
}

/* 138 � Kaboom ------------------------------------------ */

.sds-scroll-kaboom {
  animation: sds-scrollKaboom 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

@keyframes sds-scrollKaboom {
  from {
    transform: scale(0);
    opacity: 0;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}

/* 139 � Lean -------------------------------------------- */

.sds-scroll-lean {
  animation: sds-scrollLean var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scrollLean {
  from {
    transform: perspective(400px) rotateY(-20deg) translateX(30px);
    opacity: 0;
  }
  to {
    transform: perspective(400px) rotateY(0deg) translateX(0);
    opacity: 1;
  }
}

/* 140 � Peel -------------------------------------------- */

.sds-scroll-peel {
  animation: sds-scrollPeel var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scrollPeel {
  from {
    clip-path: polygon(0 100%, 100% 100%, 100% 100%, 0 100%);
    opacity: 0.4;
  }
  to {
    clip-path: polygon(0 0, 100% 0, 100% 100%, 0 100%);
    opacity: 1;
  }
}

/* 141 � Stretch ----------------------------------------- */

.sds-scroll-stretch {
  animation: sds-scrollStretchIn var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scrollStretchIn {
  from {
    transform: scaleX(0.08) scaleY(1.3);
    opacity: 0;
  }
  55% {
    transform: scaleX(1.05) scaleY(0.94);
    opacity: 1;
  }
  to {
    transform: scaleX(1) scaleY(1);
    opacity: 1;
  }
}

/* 142 � Jello ------------------------------------------- */

.sds-scroll-jello {
  animation: sds-scrollJello 0.85s ease both;
}

@keyframes sds-scrollJello {
  0% {
    transform: scale(0) skewX(0deg);
    opacity: 0;
  }
  20% {
    transform: scale(1.1) skewX(-8deg);
    opacity: 1;
  }
  40% {
    transform: scale(0.95) skewX(5deg);
  }
  60% {
    transform: scale(1.03) skewX(-3deg);
  }
  80% {
    transform: scale(0.99) skewX(1deg);
  }
  100% {
    transform: scale(1) skewX(0deg);
    opacity: 1;
  }
}


/* ====================================================================
   BATCH 17 � Scroll: 3D Hinges (4) + Filter Reveals (4) + Clip Wipes (4)
   ==================================================================== */

/* 143 � Flip Up ----------------------------------------- */

.sds-scroll-flip-up {
  animation: sds-scrollFlipUp var(--sds-duration-base, 0.8s) var(--sds-easing) both;
  transform-origin: bottom;
}

@keyframes sds-scrollFlipUp {
  from {
    transform: perspective(600px) rotateX(50deg);
    opacity: 0;
  }
  to {
    transform: perspective(600px) rotateX(0deg);
    opacity: 1;
  }
}

/* 144 � Door Left --------------------------------------- */

.sds-scroll-door-left {
  animation: sds-scrollDoorLeft var(--sds-duration-base, 0.8s) var(--sds-easing) both;
  transform-origin: left;
}

@keyframes sds-scrollDoorLeft {
  from {
    transform: perspective(800px) rotateY(-70deg);
    opacity: 0;
  }
  to {
    transform: perspective(800px) rotateY(0deg);
    opacity: 1;
  }
}

/* 145 � Door Right -------------------------------------- */

.sds-scroll-door-right {
  animation: sds-scrollDoorRight var(--sds-duration-base, 0.8s) var(--sds-easing) both;
  transform-origin: right;
}

@keyframes sds-scrollDoorRight {
  from {
    transform: perspective(800px) rotateY(70deg);
    opacity: 0;
  }
  to {
    transform: perspective(800px) rotateY(0deg);
    opacity: 1;
  }
}

/* 146 � Barrel ------------------------------------------ */

.sds-scroll-barrel {
  animation: sds-scrollBarrel 0.9s var(--sds-easing) both;
}

@keyframes sds-scrollBarrel {
  from {
    transform: perspective(600px) rotate3d(1, 1, 0, -90deg);
    opacity: 0;
  }
  to {
    transform: perspective(600px) rotate3d(1, 1, 0, 0deg);
    opacity: 1;
  }
}

/* 147 � Saturate ---------------------------------------- */

.sds-scroll-saturate {
  animation: sds-scrollSaturate var(--sds-duration-base, 0.8s) ease-out both;
}

@keyframes sds-scrollSaturate {
  from {
    filter: saturate(0);
    opacity: 0;
    transform: scale(0.98);
  }
  to {
    filter: saturate(1);
    opacity: 1;
    transform: scale(1);
  }
}

/* 148 � Sepia ------------------------------------------- */

.sds-scroll-sepia {
  animation: sds-scrollSepia var(--sds-duration-base, 0.8s) ease-out both;
}

@keyframes sds-scrollSepia {
  from {
    filter: sepia(1) contrast(0.9);
    opacity: 0;
    transform: scale(0.98);
  }
  to {
    filter: sepia(0) contrast(1);
    opacity: 1;
    transform: scale(1);
  }
}

/* 149 � Overexpose -------------------------------------- */

.sds-scroll-overexpose {
  animation: sds-scrollOverexpose var(--sds-duration-base, 0.8s) ease-out both;
}

@keyframes sds-scrollOverexpose {
  from {
    filter: brightness(4) contrast(0.55);
    opacity: 0.3;
  }
  50% {
    filter: brightness(1.4) contrast(0.9);
    opacity: 0.9;
  }
  to {
    filter: brightness(1) contrast(1);
    opacity: 1;
  }
}

/* 150 � Thermal ----------------------------------------- */

.sds-scroll-thermal {
  animation: sds-scrollThermal var(--sds-duration-base, 0.8s) ease-out both;
}

@keyframes sds-scrollThermal {
  from {
    filter: hue-rotate(120deg) saturate(3);
    opacity: 0;
  }
  45% {
    filter: hue-rotate(40deg) saturate(1.6);
    opacity: 0.85;
  }
  to {
    filter: hue-rotate(0deg) saturate(1);
    opacity: 1;
  }
}

/* 151 � Iris -------------------------------------------- */

.sds-scroll-iris {
  animation: sds-scrollIris var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scrollIris {
  from {
    clip-path: circle(0% at 50% 50%);
    opacity: 0.6;
  }
  to {
    clip-path: circle(150% at 50% 50%);
    opacity: 1;
  }
}

/* 152 � Wipe Up ----------------------------------------- */

.sds-scroll-wipe-up {
  animation: sds-scrollWipeUp var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scrollWipeUp {
  from {
    clip-path: inset(100% 0 0 0);
    opacity: 0.7;
  }
  to {
    clip-path: inset(0% 0 0 0);
    opacity: 1;
  }
}

/* 153 � Wipe Right -------------------------------------- */

.sds-scroll-wipe-right {
  animation: sds-scrollWipeRight var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scrollWipeRight {
  from {
    clip-path: inset(0 100% 0 0);
    opacity: 0.7;
  }
  to {
    clip-path: inset(0 0% 0 0);
    opacity: 1;
  }
}

/* 154 � Drop In ----------------------------------------- */

.sds-scroll-drop-in {
  animation: sds-scrollDropIn var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scrollDropIn {
  0% {
    transform: translateY(-60px) scaleY(0.8);
    opacity: 0;
  }
  65% {
    transform: translateY(8px) scaleY(1.04);
    opacity: 1;
  }
  82% {
    transform: translateY(-3px) scaleY(0.98);
  }
  100% {
    transform: translateY(0) scaleY(1);
    opacity: 1;
  }
}


/* ====================================================================
   BATCH 18 � Scroll: Subtle Motion (5) + Stagger (2) + Kinetic (4)
   ==================================================================== */

/* 155 � Float ------------------------------------------- */

.sds-scroll-float {
  animation: sds-scrollFloat 1.2s cubic-bezier(0.2, 0, 0, 1) both;
}

@keyframes sds-scrollFloat {
  from {
    transform: translateY(6px);
    opacity: 0;
    filter: blur(2px);
  }
  to {
    transform: translateY(0);
    opacity: 1;
    filter: blur(0);
  }
}

/* 156 � Sink -------------------------------------------- */

.sds-scroll-sink {
  animation: sds-scrollSink var(--sds-duration-base, 0.8s) var(--sds-easing) both;
}

@keyframes sds-scrollSink {
  from {
    transform: translateY(-18px) scale(1.02);
    opacity: 0;
  }
  to {
    transform: translateY(0) scale(1);
    opacity: 1;
  }
}

/* 157 � Shudder ----------------------------------------- */

.sds-scroll-shudder {
  animation: sds-scrollShudder 0.7s ease both;
}

@keyframes sds-scrollShudder {
  0%   { transform: translateX(-8px) scaleX(0.92); opacity: 0; }
  15%  { transform: translateX(6px) scaleX(1.04); opacity: 0.8; }
  30%  { transform: translateX(-5px) scaleX(0.97); opacity: 1; }
  50%  { transform: translateX(3px); }
  65%  { transform: translateX(-2px); }
  80%  { transform: translateX(1px); }
  100% { transform: translateX(0); opacity: 1; }
}

/* 158 � Spin Y ------------------------------------------ */

.sds-scroll-spin-y {
  animation: sds-scrollSpinY 0.9s var(--sds-easing) both;
}

@keyframes sds-scrollSpinY {
  from {
    transform: perspective(500px) rotateY(-180deg);
    opacity: 0;
  }
  to {
    transform: perspective(500px) rotateY(0deg);
    opacity: 1;
  }
}

/* 159 � Rubber Band ------------------------------------- */

.sds-scroll-rubber-band {
  animation: sds-scrollRubberBand 0.8s ease both;
}

@keyframes sds-scrollRubberBand {
  0%   { transform: scaleX(0.5) scaleY(1.3); opacity: 0; }
  25%  { transform: scaleX(1.2) scaleY(0.82); opacity: 1; }
  45%  { transform: scaleX(0.9) scaleY(1.1); }
  65%  { transform: scaleX(1.06) scaleY(0.96); }
  80%  { transform: scaleX(0.98) scaleY(1.02); }
  100% { transform: scaleX(1) scaleY(1); opacity: 1; }
}

/* 160 � Stagger Fade � children fade in sequence (requiresChildren) */

.sds-scroll-stagger-fade > * {
  animation: sds-scrollStaggerFadeChild 0.5s ease both;
}
.sds-scroll-stagger-fade > *:nth-child(2) { animation-delay: .1s; }
.sds-scroll-stagger-fade > *:nth-child(3) { animation-delay: .2s; }
.sds-scroll-stagger-fade > *:nth-child(4) { animation-delay: .3s; }
.sds-scroll-stagger-fade > *:nth-child(5) { animation-delay: .4s; }
.sds-scroll-stagger-fade > *:nth-child(6) { animation-delay: .5s; }

@keyframes sds-scrollStaggerFadeChild {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* 161 � Stagger Rise � children rise up in sequence (requiresChildren) */

.sds-scroll-stagger-rise > * {
  animation: sds-scrollStaggerRiseChild 0.6s var(--sds-easing) both;
}
.sds-scroll-stagger-rise > *:nth-child(2) { animation-delay: .1s; }
.sds-scroll-stagger-rise > *:nth-child(3) { animation-delay: .2s; }
.sds-scroll-stagger-rise > *:nth-child(4) { animation-delay: .3s; }
.sds-scroll-stagger-rise > *:nth-child(5) { animation-delay: .4s; }
.sds-scroll-stagger-rise > *:nth-child(6) { animation-delay: .5s; }

@keyframes sds-scrollStaggerRiseChild {
  from { transform: translateY(20px); opacity: 0; }
  to   { transform: translateY(0); opacity: 1; }
}

/* 162 � Glare ------------------------------------------- */

.sds-scroll-glare {
  animation: sds-scrollGlare 0.7s ease-out both;
}

@keyframes sds-scrollGlare {
  0%   { filter: brightness(3.5) contrast(0.5); opacity: 0; transform: scale(1.06); }
  40%  { filter: brightness(1.3) contrast(0.9); opacity: 1; }
  100% { filter: brightness(1) contrast(1); transform: scale(1); opacity: 1; }
}

/* 163 � Skid In ----------------------------------------- */

.sds-scroll-skid-in {
  animation: sds-scrollSkidIn 0.7s cubic-bezier(0.2, 0, 0.3, 1) both;
}

@keyframes sds-scrollSkidIn {
  0%   { transform: translateX(80px); opacity: 0; }
  60%  { transform: translateX(-12px); opacity: 1; }
  80%  { transform: translateX(6px); }
  100% { transform: translateX(0); opacity: 1; }
}

/* 164 � Slingshot --------------------------------------- */

.sds-scroll-slingshot {
  animation: sds-scrollSlingshot 0.8s cubic-bezier(0.34, 1.56, 0.64, 1) both;
}

@keyframes sds-scrollSlingshot {
  0%   { transform: translateX(-40px) scaleX(0.6); opacity: 0; }
  50%  { transform: translateX(12px) scaleX(1.08); opacity: 1; }
  75%  { transform: translateX(-4px) scaleX(0.97); }
  100% { transform: translateX(0) scaleX(1); opacity: 1; }
}

/* 165 � Blink In ---------------------------------------- */

.sds-scroll-blink-in {
  animation: sds-scrollBlinkIn 0.8s linear both;
}

@keyframes sds-scrollBlinkIn {
  0%,19%  { opacity: 0; }
  20%,39% { opacity: 0.3; }
  40%,59% { opacity: 0.6; }
  60%,79% { opacity: 0.85; }
  80%,100% { opacity: 1; }
}


/* ====================================================================
   BATCH 19 � Scroll: Stagger (1) + Reveal FX (5) + Character (5)
   scroll complete at 100/100
   ==================================================================== */

/* 166 � Stagger Slide � children slide from left in sequence (requiresChildren) */

.sds-scroll-stagger-slide > * {
  animation: sds-scrollStaggerSlideChild 0.6s var(--sds-easing) both;
}
.sds-scroll-stagger-slide > *:nth-child(2) { animation-delay: .1s; }
.sds-scroll-stagger-slide > *:nth-child(3) { animation-delay: .2s; }
.sds-scroll-stagger-slide > *:nth-child(4) { animation-delay: .3s; }
.sds-scroll-stagger-slide > *:nth-child(5) { animation-delay: .4s; }
.sds-scroll-stagger-slide > *:nth-child(6) { animation-delay: .5s; }

@keyframes sds-scrollStaggerSlideChild {
  from { transform: translateX(-24px); opacity: 0; }
  to   { transform: translateX(0); opacity: 1; }
}

/* 167 � Neon Pop ---------------------------------------- */

.sds-scroll-neon-pop {
  animation: sds-scrollNeonPop 0.7s ease-out both;
}

@keyframes sds-scrollNeonPop {
  0%   { transform: scale(0.8); opacity: 0; filter: drop-shadow(0 0 0px currentColor); }
  55%  { transform: scale(1.05); opacity: 1; filter: drop-shadow(0 0 14px currentColor); }
  100% { transform: scale(1); opacity: 1; filter: drop-shadow(0 0 4px currentColor); }
}

/* 168 � Pixel In ---------------------------------------- */

.sds-scroll-pixel-in {
  animation: sds-scrollPixelIn 0.8s ease-out both;
}

@keyframes sds-scrollPixelIn {
  from {
    filter: blur(16px);
    transform: scale(1.08);
    opacity: 0.4;
  }
  to {
    filter: blur(0);
    transform: scale(1);
    opacity: 1;
  }
}

/* 169 � Tidal ------------------------------------------- */

.sds-scroll-tidal {
  animation: sds-scrollTidal 0.9s ease both;
}

@keyframes sds-scrollTidal {
  0%   { transform: translateX(-30px); opacity: 0; }
  40%  { transform: translateX(10px); opacity: 1; }
  60%  { transform: translateX(-6px); }
  75%  { transform: translateX(3px); }
  88%  { transform: translateX(-1px); }
  100% { transform: translateX(0); opacity: 1; }
}

/* 170 � Materialize ------------------------------------- */

.sds-scroll-materialize {
  animation: sds-scrollMaterialize 1s steps(4, end) both;
}

@keyframes sds-scrollMaterialize {
  0%   { opacity: 0;    transform: scale(0.9);  filter: blur(8px); }
  25%  { opacity: 0.25; transform: scale(0.93); filter: blur(6px); }
  50%  { opacity: 0.5;  transform: scale(0.96); filter: blur(3px); }
  75%  { opacity: 0.8;  transform: scale(0.99); filter: blur(1px); }
  100% { opacity: 1;    transform: scale(1);    filter: blur(0); }
}

/* 171 � Exhale ------------------------------------------ */

.sds-scroll-exhale {
  animation: sds-scrollExhale 1s cubic-bezier(0.2, 0, 0, 1) both;
}

@keyframes sds-scrollExhale {
  from {
    transform: scale(1.12);
    opacity: 0.6;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
}

/* 172 � Typewriter -------------------------------------- */

.sds-scroll-typewriter {
  animation: sds-scrollTypewriter 0.9s steps(14, end) both;
}

@keyframes sds-scrollTypewriter {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0% 0 0); }
}

/* 173 � Glitch In --------------------------------------- */

.sds-scroll-glitch-in {
  animation: sds-scrollGlitchIn 0.7s ease-out both;
}

@keyframes sds-scrollGlitchIn {
  0%   { transform: translateX(-6px); opacity: 0; filter: hue-rotate(90deg); clip-path: inset(40% 0 10% 0); }
  20%  { transform: translateX(4px);  opacity: 0.6; filter: hue-rotate(-40deg); clip-path: inset(5% 0 30% 0); }
  40%  { transform: translateX(-2px); opacity: 0.85; clip-path: inset(0 0 0 0); filter: hue-rotate(15deg); }
  65%  { transform: translateX(1px); filter: hue-rotate(0deg); }
  100% { transform: translateX(0); opacity: 1; filter: hue-rotate(0deg); clip-path: inset(0 0 0 0); }
}

/* 174 � Unfurl ------------------------------------------ */

.sds-scroll-unfurl {
  animation: sds-scrollUnfurl var(--sds-duration-base, 0.8s) var(--sds-easing) both;
  transform-origin: top left;
}

@keyframes sds-scrollUnfurl {
  from {
    transform: rotate(-12deg) translate(-20px, -20px) scale(0.8);
    opacity: 0;
  }
  60% {
    transform: rotate(3deg) translate(5px, 5px) scale(1.02);
    opacity: 1;
  }
  100% {
    transform: rotate(0deg) translate(0, 0) scale(1);
    opacity: 1;
  }
}

/* 175 � Pop In ------------------------------------------ */

.sds-scroll-pop-in {
  animation: sds-scrollPopIn 0.65s ease both;
}

@keyframes sds-scrollPopIn {
  0%   { transform: scale(0); opacity: 0; }
  55%  { transform: scale(1.15); opacity: 1; }
  75%  { transform: scale(0.94); }
  90%  { transform: scale(1.04); }
  100% { transform: scale(1); opacity: 1; }
}

/* 176 � Contrast In ------------------------------------- */

.sds-scroll-contrast-in {
  animation: sds-scrollContrastIn 0.8s ease-out both;
}

@keyframes sds-scrollContrastIn {
  from {
    filter: contrast(3) brightness(0.6);
    opacity: 0;
    transform: scale(0.97);
  }
  50% {
    filter: contrast(1.4) brightness(0.9);
    opacity: 0.9;
  }
  to {
    filter: contrast(1) brightness(1);
    opacity: 1;
    transform: scale(1);
  }
}

/* ── Cross-category keyframe dependencies ── */
/* dependency: @keyframes sds-depthPortal (defined in cards.css) */
@keyframes sds-depthPortal {
  0% {
    opacity: 0;
    transform: perspective(500px) translateZ(-200px) scale(0.6);
    filter: blur(12px);
  }
  60% {
    opacity: 1;
    transform: perspective(500px) translateZ(8px) scale(1.02);
    filter: blur(0);
  }
  100% {
    opacity: 1;
    transform: perspective(500px) translateZ(0) scale(1);
  }
}
/* dependency: @keyframes sds-shatterIn (defined in text.css) */
@keyframes sds-shatterIn {
  0% {
    opacity: 0;
    transform: scale(2.5) rotate(8deg);
    filter: blur(20px);
  }
  50% {
    opacity: 0.8;
    transform: scale(1.05) rotate(-1deg);
    filter: blur(1px);
  }
  100% {
    opacity: 1;
    transform: scale(1) rotate(0);
    filter: blur(0);
  }
}
/* dependency: @keyframes sds-phantomBlur (defined in text.css) */
@keyframes sds-phantomBlur {
  0% {
    opacity: 0;
    filter: blur(24px) brightness(2);
    transform: scale(1.15);
  }
  40% {
    opacity: 1;
    filter: blur(2px) brightness(1.2);
    transform: scale(1.03);
  }
  100% {
    opacity: 1;
    filter: blur(0) brightness(1);
    transform: scale(1);
  }
}
/* dependency: @keyframes sds-gravityDrop (defined in text.css) */
@keyframes sds-gravityDrop {
  0% {
    opacity: 0;
    transform: translateY(-60px) scaleY(0.5);
  }
  65% {
    opacity: 1;
    transform: translateY(6px) scaleY(1.08);
  }
  82% {
    transform: translateY(-2px) scaleY(0.98);
  }
  100% {
    transform: translateY(0) scaleY(1);
  }
}
/* dependency: @keyframes sds-liquidRise (defined in text.css) */
@keyframes sds-liquidRise {
  0% {
    opacity: 0;
    transform: translateY(30px) scaleX(0.85) skewX(4deg);
    filter: blur(4px);
  }
  50% {
    transform: translateY(-3px) scaleX(1.02) skewX(-1deg);
    filter: blur(0);
    opacity: 1;
  }
  100% {
    opacity: 1;
    transform: translateY(0) scaleX(1) skewX(0);
  }
}
/* dependency: @keyframes sds-velvetDrop (defined in text.css) */
@keyframes sds-velvetDrop {
  0% {
    opacity: 0;
    transform: translateY(-24px) scaleY(0.8);
    filter: blur(6px);
  }
  60% {
    opacity: 1;
    transform: translateY(3px) scaleY(1.02);
    filter: blur(0);
  }
  80% {
    transform: translateY(-1px) scaleY(0.99);
  }
  100% {
    opacity: 1;
    transform: translateY(0) scaleY(1);
    filter: blur(0);
  }
}
/* dependency: @keyframes sds-perspSwing (defined in text.css) */
@keyframes sds-perspSwing {
  0% {
    opacity: 0;
    transform: perspective(500px) rotateY(-70deg);
  }
  60% {
    opacity: 1;
    transform: perspective(500px) rotateY(8deg);
  }
  80% {
    transform: perspective(500px) rotateY(-4deg);
  }
  100% {
    transform: perspective(500px) rotateY(0);
  }
}
/* dependency: @keyframes sds-staticBurst (defined in text.css) */
@keyframes sds-staticBurst {
  0%,
  100% {
    opacity: 1;
    transform: none;
    clip-path: none;
  }
  10% {
    transform: translate(2px, -1px) skewX(2deg);
    clip-path: polygon(0 20%, 100% 20%, 100% 45%, 0 45%);
  }
  20% {
    transform: translate(-2px, 1px) skewX(-1deg);
    clip-path: none;
    opacity: 0.7;
  }
  30% {
    transform: translate(3px, 2px);
    clip-path: polygon(0 60%, 100% 60%, 100% 80%, 0 80%);
  }
  40% {
    transform: none;
    clip-path: none;
    opacity: 1;
  }
}
