/*
 * lanobots-animations.css
 * Scroll-reveal utilities + shared keyframes.
 * Triggered by IntersectionObserver adding .lb-revealed to .lb-reveal-*.
 * All animations are suppressed with prefers-reduced-motion.
 *
 * Usage:
 *   <div class="lb-reveal-up">...</div>
 *   JS: IntersectionObserver → el.classList.add('lb-revealed')
 */

/* ============================================================
   BASE REVEAL SETUP
   ============================================================ */
.lb-reveal-up,
.lb-reveal-down,
.lb-reveal-left,
.lb-reveal-right,
.lb-reveal-fade,
.lb-reveal-mask {
  opacity: 0;
  transition-timing-function: var(--ease-out);
  transition-duration: var(--dur-slow);
  transition-property: opacity, transform;
  /* will-change removed from default — added only when animating */
}

/* Stagger siblings using CSS custom property set by JS */
.lb-reveal-up,
.lb-reveal-down,
.lb-reveal-left,
.lb-reveal-right,
.lb-reveal-fade {
  transition-delay: var(--stagger-delay, 0ms);
}

/* ============================================================
   INITIAL STATES
   ============================================================ */
.lb-reveal-up    { transform: translateY(28px); }
.lb-reveal-down  { transform: translateY(-20px); }
.lb-reveal-left  { transform: translateX(-28px); }
.lb-reveal-right { transform: translateX(28px); }
.lb-reveal-fade  { transform: none; }

/* Mask: clip-path wipe reveal */
.lb-reveal-mask {
  opacity: 1;   /* mask uses clip not opacity */
  clip-path: inset(0 100% 0 0);
  transition-property: clip-path;
  transition-timing-function: var(--ease-out);
  transition-duration: var(--dur-slow);
  transition-delay: var(--stagger-delay, 0ms);
}

/* ============================================================
   REVEALED STATE — added by IntersectionObserver
   ============================================================ */
.lb-revealed {
  opacity: 1;
  transform: none;
  clip-path: inset(0 0% 0 0);
}

/* ============================================================
   STAGGER HELPER — data-stagger="0..5" → JS reads value * 80ms
   Pure-CSS fallback: :nth-child-based stagger inside a container
   ============================================================ */
.lb-stagger-group > *:nth-child(1)  { --stagger-delay:   0ms; }
.lb-stagger-group > *:nth-child(2)  { --stagger-delay:  80ms; }
.lb-stagger-group > *:nth-child(3)  { --stagger-delay: 160ms; }
.lb-stagger-group > *:nth-child(4)  { --stagger-delay: 240ms; }
.lb-stagger-group > *:nth-child(5)  { --stagger-delay: 320ms; }
.lb-stagger-group > *:nth-child(6)  { --stagger-delay: 400ms; }
.lb-stagger-group > *:nth-child(7)  { --stagger-delay: 480ms; }
.lb-stagger-group > *:nth-child(8)  { --stagger-delay: 560ms; }

/* ============================================================
   KEYFRAMES — used globally
   ============================================================ */

/* Ticker / marquee */
@keyframes lb-ticker {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* Slow float */
@keyframes lb-float {
  0%, 100% { transform: translateY(0);    }
  50%       { transform: translateY(-8px); }
}

/* Subtle pulse glow */
@keyframes lb-pulse-glow {
  0%, 100% { opacity: 0.5; filter: blur(0px);   }
  50%       { opacity: 1;   filter: blur(2px);   }
}

/* Spinning orb */
@keyframes lb-spin-slow {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* Blink cursor */
@keyframes lb-blink {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0; }
}

/* Shimmer sweep — for skeleton loaders / placeholder elements */
@keyframes lb-shimmer {
  0%   { background-position: -400px 0; }
  100% { background-position:  400px 0; }
}
.lb-shimmer {
  background: linear-gradient(
    90deg,
    var(--lb-panel) 25%,
    rgba(255, 255, 255, 0.05) 50%,
    var(--lb-panel) 75%
  );
  background-size: 800px 100%;
  animation: lb-shimmer 1.8s infinite linear;
}

/* Scan-line (media page) */
@keyframes lb-scanline {
  0%   { transform: translateY(-100%); }
  100% { transform: translateY(100vh); }
}

/* Fade-in used for instant-appear elements */
@keyframes lb-fadein {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* ============================================================
   UTILITY ANIMATION CLASSES
   Apply directly without JS when you just need a once-off anim.
   ============================================================ */
.lb-anim-float {
  animation: lb-float 5s ease-in-out infinite;
}
.lb-anim-spin-slow {
  animation: lb-spin-slow 20s linear infinite;
}
.lb-anim-blink {
  animation: lb-blink 1.1s step-end infinite;
}
.lb-anim-pulse-glow {
  animation: lb-pulse-glow 2.5s ease-in-out infinite;
}

/* ============================================================
   REDUCED MOTION — override EVERYTHING
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  /* Disable all reveal transitions */
  .lb-reveal-up,
  .lb-reveal-down,
  .lb-reveal-left,
  .lb-reveal-right,
  .lb-reveal-fade,
  .lb-reveal-mask {
    opacity: 1;
    transform: none;
    clip-path: inset(0 0% 0 0);
    transition: none;
  }
  .lb-revealed {
    transition: none;
  }

  /* Stop all keyframe animations */
  .lb-anim-float,
  .lb-anim-spin-slow,
  .lb-anim-blink,
  .lb-anim-pulse-glow,
  .lb-shimmer {
    animation: none;
  }

  /* Stop ticker/marquee */
  [class*="lb-ticker"],
  [class*="lb-marquee"] {
    animation: none;
  }

  /* Remove hover transforms that rely on transitions */
  .lb-panel:hover,
  .lb-btn:hover,
  .lb-btn--primary:hover,
  .lb-btn--secondary:hover {
    transform: none;
    transition: none;
  }
}
