/* ==========================================================================
   WasiCo Technologies — Motion
   CSS-driven entrance + ambient motion. Scroll reveals are driven by GSAP
   (animations.js) with an IntersectionObserver fallback. Everything here is
   neutralised under prefers-reduced-motion.
   ========================================================================== */

/* ---------- Keyframes ---------- */
@keyframes rise-in {
  from {
    opacity: 0;
    transform: translateY(18px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@keyframes line-up {
  from {
    transform: translateY(105%);
  }
  to {
    transform: none;
  }
}
@keyframes fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}
@keyframes visual-in {
  from {
    opacity: 0;
    transform: translateY(26px) scale(0.98);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
@keyframes float-y {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-10px);
  }
}
@keyframes grid-drift {
  from {
    transform: translateY(0);
  }
  to {
    transform: translateY(64px);
  }
}
@keyframes glow-drift {
  0%,
  100% {
    transform: translate3d(0, 0, 0) scale(1);
  }
  50% {
    transform: translate3d(40px, 30px, 0) scale(1.08);
  }
}
@keyframes dash-flow {
  to {
    stroke-dashoffset: -60;
  }
}
@keyframes draw {
  to {
    stroke-dashoffset: 0;
  }
}
@keyframes ping {
  0% {
    transform: scale(1);
    opacity: 0.7;
  }
  80%,
  100% {
    transform: scale(2.6);
    opacity: 0;
  }
}
@keyframes grow-y {
  from {
    transform: scaleY(0);
  }
}
@keyframes grow-x {
  from {
    transform: scaleX(0);
  }
}
@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}
@keyframes border-spin {
  to {
    --angle: 360deg;
  }
}
@keyframes beam-move {
  0% {
    transform: translateY(-100%);
    opacity: 0;
  }
  20%,
  80% {
    opacity: 1;
  }
  100% {
    transform: translateY(140%);
    opacity: 0;
  }
}

/* ---------- Hero entrance (CSS so it never waits on a CDN) ---------- */
.hero .hero-badge {
  animation: rise-in 0.8s var(--ease-out) 0.05s both;
}
.hero h1 .line > span {
  animation: line-up 1s var(--ease-out) both;
}
.hero h1 .line:nth-child(1) > span {
  animation-delay: 0.12s;
}
.hero h1 .line:nth-child(2) > span {
  animation-delay: 0.22s;
}
.hero h1 .line:nth-child(3) > span {
  animation-delay: 0.32s;
}
.hero .hero-lead {
  animation: rise-in 0.9s var(--ease-out) 0.45s both;
}
.hero .hero-ctas {
  animation: rise-in 0.9s var(--ease-out) 0.55s both;
}
.hero .hero-values li {
  animation: rise-in 0.8s var(--ease-out) both;
}
.hero .hero-values li:nth-child(1) {
  animation-delay: 0.7s;
}
.hero .hero-values li:nth-child(2) {
  animation-delay: 0.78s;
}
.hero .hero-values li:nth-child(3) {
  animation-delay: 0.86s;
}
.hero-visual .stage {
  animation: visual-in 1.2s var(--ease-out) 0.3s both;
}
.page-hero [data-hero-in] {
  animation: rise-in 0.9s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 90ms + 80ms);
}

/* ---------- Ambient hero motion ---------- */
.hero-bg .grid-layer {
  animation: grid-drift 14s linear infinite;
}
.hero-bg .glow-a {
  animation: glow-drift 18s ease-in-out infinite;
}
.hero-bg .glow-b {
  animation: glow-drift 22s ease-in-out -6s infinite reverse;
}
.hero-bg .beam {
  animation: beam-move 7s var(--ease) 1.5s infinite;
}

.float-panel .float-inner {
  animation: float-y 7s ease-in-out infinite;
}
.p-erp .float-inner {
  animation-duration: 8s;
  animation-delay: -2.5s;
}
.p-hr .float-inner {
  animation-duration: 9s;
  animation-delay: -5s;
}

.hero-lines path {
  animation: dash-flow 3.5s linear infinite;
}
.live-dot::after {
  animation: ping 2s cubic-bezier(0, 0, 0.2, 1) infinite;
}

/* Chart line draw + bar growth on load */
.draw-line {
  stroke-dasharray: 600;
  stroke-dashoffset: 600;
  animation: draw 2.2s var(--ease-out) 0.9s forwards;
}
.hero .bars span,
.is-inview .bars span {
  animation: grow-y 1s var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * 60ms + 0.6s);
}
.hero .progress > span,
.is-inview .progress > span {
  animation: grow-x 1.2s var(--ease-out) 0.8s both;
}

/* Pause ambient loops when the hero is off-screen (toggled in JS) */
.is-paused .grid-layer,
.is-paused .glow,
.is-paused .beam,
.is-paused .float-inner,
.is-paused .hero-lines path,
.is-paused .live-dot::after {
  animation-play-state: paused;
}

/* Animated gradient border on hover */
.border-anim:hover::after,
.border-anim:focus-within::after {
  animation: border-spin 4s linear infinite;
}

.btn.is-loading .spinner {
  animation: spin 0.7s linear infinite;
}

/* ---------- Scroll reveal states ----------
   Uses the individual `translate` property so reveals never fight with
   hover effects that use `transform`. */
.js [data-reveal] {
  opacity: 0;
  translate: 0 26px;
}
.js [data-reveal="fade"] {
  translate: none;
}
/* Final state (GSAP adds .is-visible on complete; IO fallback transitions to it) */
.js [data-reveal].is-visible {
  opacity: 1;
  translate: none;
  transition:
    opacity 0.8s var(--ease-out),
    translate 0.9s var(--ease-out),
    transform var(--dur-3) var(--ease-out),
    box-shadow var(--dur-3) var(--ease),
    border-color var(--dur-3) var(--ease),
    background-color var(--dur-3) var(--ease);
  transition-delay: calc(var(--stagger, 0) * 80ms), calc(var(--stagger, 0) * 80ms), 0s, 0s, 0s, 0s;
}
/* Safety net: show everything if scripts never initialise */
.no-anim [data-reveal] {
  opacity: 1 !important;
  translate: none !important;
}

/* ---------- Reduced motion ---------- */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    transition-delay: 0ms !important;
  }
  .js [data-reveal] {
    opacity: 1 !important;
    translate: none !important;
  }
  .draw-line {
    stroke-dashoffset: 0;
  }
  .live-dot::after {
    display: none;
  }
}
