/* ==========================================================================
   JVR700 — Animation layer
   1. Keyframes
   2. Scroll-reveal system
   3. Ambient / looping animations
   4. Reduced-motion fallbacks
   ========================================================================== */

/* ============ 1. KEYFRAMES ============ */
@keyframes spinCw   { to { transform: rotate(360deg); } }
@keyframes spinCcw  { to { transform: rotate(-360deg); } }

@keyframes blobDrift {
  0%   { transform: translate3d(0, 0, 0) scale(1); }
  33%  { transform: translate3d(38px, -26px, 0) scale(1.08); }
  66%  { transform: translate3d(-24px, 24px, 0) scale(.95); }
  100% { transform: translate3d(0, 0, 0) scale(1); }
}

@keyframes floatY {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-14px); }
}

/* Uses the `translate` property so elements keeping a base `transform`
   (rotated phones) can float without losing their tilt. */
@keyframes floatT {
  0%, 100% { translate: 0 0; }
  50%      { translate: 0 -16px; }
}

@keyframes phoneIn {
  from { opacity: 0; transform: scale(.9) translateY(34px); }
  to   { opacity: 1; transform: none; }
}

@keyframes ringPulse {
  0%   { transform: scale(.72); opacity: .9; }
  70%  { opacity: 0; }
  100% { transform: scale(1.5); opacity: 0; }
}

@keyframes marqueeSlide {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

@keyframes gradSlide {
  0%   { background-position: 0% 50%; }
  100% { background-position: 200% 50%; }
}

@keyframes numPulse {
  0%, 100% { transform: translateY(0) scale(1); }
  12%      { transform: translateY(-6px) scale(1.14); }
  26%      { transform: translateY(0) scale(1); }
}

@keyframes toastCycle {
  0%, 12%    { transform: translateY(160%); opacity: 0; }
  22%, 68%   { transform: translateY(0); opacity: 1; }
  82%, 100%  { transform: translateY(160%); opacity: 0; }
}

@keyframes tickPop {
  0%, 18%   { transform: scale(0); }
  30%       { transform: scale(1.28); }
  40%, 100% { transform: scale(1); }
}

@keyframes rowGlow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(247, 136, 31, .32); }
  50%      { box-shadow: 0 0 0 6px rgba(247, 136, 31, 0); }
}

@keyframes opHop {
  0%, 88%, 100% { transform: translateY(0); }
  94%           { transform: translateY(-5px); }
}

@keyframes shimmer {
  0%   { transform: translateX(-130%); }
  60%, 100% { transform: translateX(130%); }
}

@keyframes barGrow {
  from { transform: scaleY(0); opacity: .4; }
  to   { transform: scaleY(1); opacity: 1; }
}

@keyframes lineGrow {
  from { transform: scaleX(0); }
  to   { transform: scaleX(1); }
}

@keyframes sparkSlide {
  from { background-position: 0 0, 0 0; }
  to   { background-position: 44px 0, 0 0; }
}

@keyframes fadeUpIn {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes glowBreathe {
  0%, 100% { opacity: .45; transform: translateX(-50%) scale(1); }
  50%      { opacity: .75; transform: translateX(-50%) scale(1.1); }
}

/* ============ 2. SCROLL-REVEAL SYSTEM ============ */
[data-reveal] {
  opacity: 0;
  transition:
    opacity .85s var(--ease),
    transform .85s var(--ease),
    filter .85s var(--ease);
  will-change: opacity, transform;
}
.reveal        { transform: translateY(38px); }
.reveal-left   { transform: translateX(-46px); }
.reveal-right  { transform: translateX(46px); }
.reveal-scale  { transform: scale(.9) translateY(26px); }

[data-reveal].is-visible {
  opacity: 1;
  transform: none;
  will-change: auto;
}

/* Cards stagger naturally by grid order when no explicit delay is set */
.cards .card[data-reveal]:nth-child(4n+2) { transition-delay: .08s; }
.cards .card[data-reveal]:nth-child(4n+3) { transition-delay: .16s; }
.cards .card[data-reveal]:nth-child(4n+4) { transition-delay: .24s; }

/* ============ 3. AMBIENT / LOOPING ANIMATIONS ============ */

/* Preloader */
.preloader__ring span:nth-child(1) { animation: spinCw 1.1s linear infinite; }
.preloader__ring span:nth-child(2) { animation: spinCcw 1.5s linear infinite; }
.preloader__ring span:nth-child(3) { animation: spinCw 1.9s linear infinite; }
.preloader__logo { animation: fadeUpIn .9s var(--ease) both; }
.preloader__text { animation: fadeUpIn .9s .15s var(--ease) both; }

/* Hero background */
.blob--1 { animation: blobDrift 17s ease-in-out infinite; }
.blob--2 { animation: blobDrift 21s ease-in-out infinite reverse; }
.blob--3 { animation: blobDrift 25s ease-in-out infinite 1.5s; }
.hero__glow { animation: glowBreathe 9s ease-in-out infinite; }

/* Animated gradient text */
.text-grad,
.hero__count-num {
  background-size: 220% auto;
  animation: gradSlide 7s linear infinite;
}
.hero__count-num { animation: gradSlide 7s linear infinite, numPulse 4.5s ease-in-out infinite; }

/* Hero phone + floating chips.
   The entrance runs first, then the float loop takes over via its delay. */
.phone {
  animation:
    phoneIn 1s var(--ease) .4s both,
    floatY 6.5s ease-in-out 1.4s infinite;
}
.pulse-ring { animation: ringPulse 3.6s ease-out infinite; }
[data-float] { animation: floatY 5s ease-in-out infinite; }
.float-card--rate { animation-delay: -2.4s; }
.why__badge { animation-delay: -1.2s; }

.pscreen__toast { animation: toastCycle 7s ease-in-out infinite 1.4s; }
.pscreen__toast .tick { animation: tickPop 7s ease-in-out infinite 1.4s; }
.plan-row.is-active { animation: rowGlow 2.6s ease-in-out infinite; }
.op { animation: opHop 5s ease-in-out infinite; }
.op--2 { animation-delay: .18s; }
.op--3 { animation-delay: .36s; }
.op--4 { animation-delay: .54s; }

.pscreen__btn {
  position: relative;
  overflow: hidden;
}
.pscreen__btn::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(110deg, transparent 30%, rgba(255, 255, 255, .5) 50%, transparent 70%);
  animation: shimmer 3.4s ease-in-out infinite;
}

/* Marquees — paused on hover so labels stay readable */
.marquee__track { animation: marqueeSlide 34s linear infinite; }
.marquee:hover .marquee__track { animation-play-state: paused; }
.tmarquee__track { animation: marqueeSlide 46s linear infinite; }
.tmarquee:hover .tmarquee__track { animation-play-state: paused; }

/* Chart bars grow once their card scrolls into view */
.bars span { transform: scaleY(0); }
.why__media.is-visible .bars span { animation: barGrow .95s var(--ease) forwards; }
.why__media.is-visible .bars span:nth-child(1) { animation-delay: .05s; }
.why__media.is-visible .bars span:nth-child(2) { animation-delay: .13s; }
.why__media.is-visible .bars span:nth-child(3) { animation-delay: .21s; }
.why__media.is-visible .bars span:nth-child(4) { animation-delay: .29s; }
.why__media.is-visible .bars span:nth-child(5) { animation-delay: .37s; }
.why__media.is-visible .bars span:nth-child(6) { animation-delay: .45s; }
.why__media.is-visible .bars span:nth-child(7) { animation-delay: .53s; }

.app__chart i { transform: scaleY(0); transform-origin: bottom; }
.app__visual.is-visible .app__chart i { animation: barGrow .9s var(--ease) forwards; }
.app__visual.is-visible .app__chart i:nth-child(2) { animation-delay: .1s; }
.app__visual.is-visible .app__chart i:nth-child(3) { animation-delay: .2s; }
.app__visual.is-visible .app__chart i:nth-child(4) { animation-delay: .3s; }
.app__visual.is-visible .app__chart i:nth-child(5) { animation-delay: .4s; }

.app__spark { animation: sparkSlide 2.6s linear infinite; }
.app__phone--front { animation: floatT 7s ease-in-out 0s infinite; }
.app__phone--back { animation: floatT 7s ease-in-out -3.5s infinite; }

/* Nav / mobile panel item entrance */
.nav.is-open .nav__list li,
.nav.is-open .nav__cta {
  animation: fadeUpIn .5s var(--ease) both;
}
.nav.is-open .nav__list li:nth-child(1) { animation-delay: .06s; }
.nav.is-open .nav__list li:nth-child(2) { animation-delay: .12s; }
.nav.is-open .nav__list li:nth-child(3) { animation-delay: .18s; }
.nav.is-open .nav__list li:nth-child(4) { animation-delay: .24s; }
.nav.is-open .nav__list li:nth-child(5) { animation-delay: .30s; }
.nav.is-open .nav__list li:nth-child(6) { animation-delay: .36s; }
.nav.is-open .nav__cta { animation-delay: .42s; }

/* Form success flash */
.is-flash {
  animation: rowGlow 1.2s ease-out 1;
}

/* ============ 4. REDUCED-MOTION FALLBACKS ============ */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: .01ms !important;
    animation-delay: 0s !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }

  [data-reveal] { opacity: 1 !important; transform: none !important; }
  .bars span,
  .app__chart i { transform: scaleY(1); }
  .pscreen__toast { opacity: 1; transform: none; }
  .marquee__track,
  .tmarquee__track { animation: none; }
}
