/* ==========================================================================
   Core Aerobots LLC — Animations & Keyframes
   
   All motion/animation definitions live here.
   Edit timing, movement, etc. without touching layout styles.
   ========================================================================== */


/* Logo pulse ring */
@keyframes pulse-ring {
  0% {
    transform: scale(1);
    opacity: 1;
  }
  100% {
    transform: scale(1.8);
    opacity: 0;
  }
}

/* Radar sweep in hero */
@keyframes radar-sweep {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

/* Badge blink dot */
@keyframes blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.3; }
}

/* Hero content entrance */
@keyframes fadeSlideUp {
  from {
    opacity: 0;
    transform: translateY(30px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Swarm drone movement patterns */
.drone-node:nth-child(1) { animation: swarm-drift-1 6s ease-in-out infinite; }
.drone-node:nth-child(2) { animation: swarm-drift-2 7s ease-in-out infinite; }
.drone-node:nth-child(3) { animation: swarm-drift-3 5s ease-in-out infinite; }
.drone-node:nth-child(4) { animation: swarm-drift-1 8s ease-in-out infinite reverse; }
.drone-node:nth-child(5) { animation: swarm-drift-2 6s ease-in-out infinite reverse; }
.drone-node:nth-child(6) { animation: swarm-drift-3 7s ease-in-out infinite; }
.drone-node:nth-child(7) { animation: swarm-drift-1 5.5s ease-in-out infinite; }

@keyframes swarm-drift-1 {
  0%, 100% { transform: translate(0, 0); }
  25% { transform: translate(12px, -8px); }
  50% { transform: translate(-5px, 15px); }
  75% { transform: translate(8px, 5px); }
}

@keyframes swarm-drift-2 {
  0%, 100% { transform: translate(0, 0); }
  33% { transform: translate(-10px, 12px); }
  66% { transform: translate(15px, -5px); }
}

@keyframes swarm-drift-3 {
  0%, 100% { transform: translate(0, 0); }
  50% { transform: translate(-8px, -10px); }
}


/* ==========================================================================
   SCROLL-TRIGGERED FADE-IN (applied by main.js)
   ========================================================================== */
/* Hidden state only applies once JS has run (body.js-ready). If JS ever fails
   to load, .fade-in elements stay fully visible — never blank during a demo. */
body.js-ready .fade-in {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.7s ease, transform 0.7s ease;
}

body.js-ready .fade-in.visible {
  opacity: 1;
  transform: translateY(0);
}


/* ==========================================================================
   ACCESSIBILITY — respect "reduce motion" OS setting
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
  .fade-in { opacity: 1; transform: none; }
}
