/* ============================================================
   TECHCELER — animations.css
   CSS keyframes + reveal base states (GSAP enhances these)
   ============================================================ */

/* ---------- Scroll reveal (IntersectionObserver toggles .is-in) ---------- */
[data-reveal] {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.6s cubic-bezier(0.22, 1, 0.36, 1),
    transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
  will-change: opacity, transform;
}
[data-reveal].is-in {
  opacity: 1;
  transform: none;
}
[data-reveal="left"] {
  transform: translateX(-40px);
}
[data-reveal="right"] {
  transform: translateX(40px);
}
[data-reveal="zoom"] {
  transform: scale(0.94);
}
[data-reveal].is-in {
  transform: none;
}

/* stagger via inline --d delay */
[data-reveal] {
  transition-delay: var(--d, 0ms);
}

/* ---------- Hero word reveal (GSAP target) ---------- */
.word {
  display: inline-block;
}
.word-wrap {
  display: inline-block;
  overflow: visible; /* never clip at rest — descenders (g, y, p) must show */
  vertical-align: top;
}
/* Clip mask is applied by JS only DURING the reveal animation */
.word-wrap.is-masking {
  overflow: hidden;
}

/* ---------- Marquee ---------- */
.marquee {
  overflow: hidden;
  white-space: nowrap;
  display: flex;
}
.marquee__track {
  display: inline-flex;
  align-items: center;
  gap: 0;
  animation: marquee 26s linear infinite;
  will-change: transform;
}
.marquee:hover .marquee__track {
  animation-play-state: paused;
}
@keyframes marquee {
  to {
    transform: translateX(-50%);
  }
}

/* ---------- Gradient button pulse ---------- */
@keyframes ctaPulse {
  0%,
  100% {
    box-shadow: 0 4px 20px rgba(123, 94, 167, 0.3);
  }
  50% {
    box-shadow: 0 4px 30px rgba(255, 77, 139, 0.5);
  }
}
.pulse {
  animation: ctaPulse 2.6s ease-in-out infinite;
}

/* ---------- Floating decorative cards ---------- */
@keyframes floatY {
  0%,
  100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-18px);
  }
}
.float {
  animation: floatY 7s ease-in-out infinite;
}
.float.slow {
  animation-duration: 10s;
}
.float.delay {
  animation-delay: -3s;
}

/* ---------- Animated gradient mesh drift ---------- */
@keyframes meshDrift {
  0%,
  100% {
    transform: translate(0, 0) scale(1);
  }
  50% {
    transform: translate(30px, -20px) scale(1.08);
  }
}
.mesh-blob.drift {
  animation: meshDrift 14s ease-in-out infinite;
}
.mesh-blob.drift.alt {
  animation-duration: 18s;
  animation-direction: reverse;
}

/* ---------- Dot grid overlay ---------- */
.dot-grid {
  position: absolute;
  inset: 0;
  background-image: radial-gradient(
    rgba(255, 255, 255, 0.12) 1px,
    transparent 1px
  );
  background-size: 30px 30px;
  mask-image: radial-gradient(ellipse at 50% 40%, #000 30%, transparent 75%);
  -webkit-mask-image: radial-gradient(
    ellipse at 50% 40%,
    #000 30%,
    transparent 75%
  );
  pointer-events: none;
}

/* ---------- Tilt base ---------- */
.tilt {
  transform-style: preserve-3d;
  transition: transform 0.25s ease;
  will-change: transform;
}
.tilt__inner {
  transform: translateZ(30px);
}

/* ---------- Count-up shimmer underline ---------- */
.counter {
  font-variant-numeric: tabular-nums;
}

@media (prefers-reduced-motion: reduce) {
  .marquee__track,
  .pulse,
  .float,
  .mesh-blob.drift {
    animation: none !important;
  }
}
