/* =============================================================================
   ANIMATIONS.CSS — keyframes, entrance/reveal states, ambient motion
   Everything animates transform/opacity only. Reveal states are gated:
   - they apply only when JS is running (html.js)
   - they are switched off by html.no-reveal (JS failed / timed out)
   - they are switched off by prefers-reduced-motion (see bottom of file)
   ============================================================================= */

/* -------------------------------------------------------------- KEYFRAMES */
@keyframes spin { to { transform: rotate(360deg); } }
@keyframes fade-up { from { opacity: 0; transform: translateY(16px); } to { opacity: 1; transform: none; } }
@keyframes reveal-up { from { opacity: 0; transform: translate3d(0, 32px, 0); } to { opacity: 1; transform: none; } }
@keyframes reveal-zoom { from { opacity: 0; transform: scale(.92) translate3d(0, 24px, 0); } to { opacity: 1; transform: none; } }
@keyframes reveal-from-right { from { opacity: 0; transform: translate3d(40px, 0, 0); } to { opacity: 1; transform: none; } }
@keyframes reveal-from-left { from { opacity: 0; transform: translate3d(-40px, 0, 0); } to { opacity: 1; transform: none; } }
@keyframes hero-in { from { opacity: 0; transform: translate3d(0, 22px, 0); } to { opacity: 1; transform: none; } }
@keyframes card-in { from { opacity: 0; transform: translate3d(0, 28px, 0) scale(.97); } to { opacity: 1; transform: none; } }
@keyframes dialog-in { from { opacity: 0; transform: translate3d(0, 24px, 0) scale(.97); } to { opacity: 1; transform: none; } }
@keyframes backdrop-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes marquee { from { transform: translate3d(0, 0, 0); } to { transform: translate3d(-50%, 0, 0); } }
@keyframes badge-pop { 0% { opacity: 0; transform: scale(.3) rotate(-18deg); } 70% { opacity: 1; transform: scale(1.12) rotate(4deg); } 100% { opacity: 1; transform: none; } }
@keyframes badge-pulse { 0% { box-shadow: 0 14px 28px -12px rgba(10, 116, 230, .8), 0 0 0 0 rgba(10, 116, 230, .55); } 70%, 100% { box-shadow: 0 14px 28px -12px rgba(10, 116, 230, .8), 0 0 0 1.1rem rgba(10, 116, 230, 0); } }
@keyframes seal-wobble { 0%, 100% { transform: rotate(-8deg) scale(1); } 50% { transform: rotate(-4deg) scale(1.05); } }
@keyframes win-float-1 { 0%, 100% { transform: translate3d(0, 0, 0) rotate(-9deg); } 50% { transform: translate3d(1.2rem, -1.4rem, 0) rotate(-7deg); } }
@keyframes win-float-2 { 0%, 100% { transform: translate3d(0, 0, 0) rotate(7deg); } 50% { transform: translate3d(-1rem, 1.2rem, 0) rotate(9deg); } }
@keyframes win-float-3 { 0%, 100% { transform: translate3d(0, 0, 0) rotate(5deg); } 50% { transform: translate3d(1rem, -1rem, 0) rotate(3deg); } }
@keyframes glow-drift { 0%, 100% { transform: translate3d(0, 0, 0) scale(1); } 50% { transform: translate3d(-4rem, 3rem, 0) scale(1.08); } }
@keyframes shard-float { 0%, 100% { transform: translate3d(0, 0, 0) rotate(0); } 50% { transform: translate3d(0, -1.6rem, 0) rotate(3deg); } }
@keyframes call-ring { 0% { box-shadow: 0 0 0 0 rgba(0, 206, 233, .55); } 70%, 100% { box-shadow: 0 0 0 .8rem rgba(0, 206, 233, 0); } }

/* ------------------------------------------------------------ HERO ENTRANCE */
.js .hero-in { opacity: 0; animation: hero-in .9s var(--ease) calc(var(--i, 0) * 110ms + 120ms) forwards; }
.js .offer-form { animation: fade-up 1s var(--ease) .55s backwards; }
.js .offer-badge { animation: badge-pop .9s var(--ease) 1s backwards, badge-pulse 3s ease-out 2.2s infinite; }

/* ------------------------------------------------- AMBIENT BACKGROUND MOTION */
.hero__win--1 { animation: win-float-1 14s ease-in-out infinite; }
.hero__win--2 { animation: win-float-2 17s ease-in-out -4s infinite; }
.hero__win--3 { animation: win-float-3 15s ease-in-out -7s infinite; }
.hero__glow { animation: glow-drift 18s ease-in-out infinite; }
.hero__shard { animation: shard-float 9s ease-in-out infinite; }
.call__icon { animation: call-ring 2.8s ease-out infinite; }
.seal { animation: seal-wobble 4s ease-in-out infinite; }

/* ----------------------------------------------------------- SCROLL REVEALS */
/* Hidden state only exists while JS runs and the reveal system is healthy. */
.js:not(.no-reveal) [data-reveal]:not(.is-in) { opacity: 0; }
.js:not(.no-reveal) [data-reveal].is-in { animation: reveal-up .9s var(--ease) backwards; }
.js:not(.no-reveal) [data-reveal="zoom"].is-in { animation-name: reveal-zoom; }
.js:not(.no-reveal) [data-reveal="left"].is-in { animation-name: reveal-from-right; }
.js:not(.no-reveal) [data-reveal="right"].is-in { animation-name: reveal-from-left; }

.js:not(.no-reveal) [data-stagger]:not(.is-in) > * { opacity: 0; }
.js:not(.no-reveal) [data-stagger].is-in > * { animation: reveal-up .85s var(--ease) backwards; animation-delay: calc(var(--si, 0) * 110ms); }

/* Split-word heading reveal (JS wraps each word in .w > .w__i) */
.w { display: inline-block; vertical-align: top; overflow: hidden; padding-bottom: .14em; margin-bottom: -.14em; }
.w__i { display: inline-block; will-change: transform; }
.js:not(.no-reveal) [data-split].is-split:not(.is-in) .w__i { transform: translate3d(0, 112%, 0); }
.js:not(.no-reveal) [data-split].is-split .w__i { transition: transform .95s var(--ease); transition-delay: calc(var(--wi, 0) * 45ms); }
.js:not(.no-reveal) [data-split].is-split.is-in .w__i { transform: none; }

/* ------------------------------------------------------- PRICING TRANSITIONS */
.pricing-grid[data-pending] .price-card { opacity: 0; }
.pricing-grid.is-entering .price-card { animation: card-in .65s var(--ease) backwards; animation-delay: calc(var(--ci, 0) * 85ms); }
.pricing-grid.is-leaving { opacity: 0; transform: translate3d(0, 10px, 0); transition: opacity .2s ease, transform .2s ease; }

/* Cursor-follow spotlight highlight */
.price-card::before, .stat-card::before { content: ''; position: absolute; inset: 0; z-index: 0; border-radius: inherit; pointer-events: none; background: radial-gradient(320px circle at var(--mx, 50%) var(--my, 0%), rgba(0, 180, 216, .13), transparent 62%); opacity: 0; transition: opacity .35s; }
.price-card:hover::before, .stat-card:hover::before { opacity: 1; }
.price-card > *, .stat-card > * { position: relative; z-index: 1; }

/* ------------------------------------------------------ PORTFOLIO TRANSITIONS */
.work-card.is-showing { animation: card-in .55s var(--ease) backwards; animation-delay: calc(var(--ci, 0) * 55ms); }
.work-card[hidden] { display: none !important; }

/* -------------------------------------------------------------- TESTIMONIALS */
.carousel__slide { transition: opacity .6s var(--ease); }
.carousel__slide:not(.is-active) { opacity: .25; }

/* ------------------------------------------------------------------- DIALOG */
.project-dialog[open] { animation: dialog-in .5s var(--ease); }
.project-dialog[open]::backdrop { animation: backdrop-in .4s ease; }
.pd__media img { transition: opacity .35s ease; }
.pd__media img.is-swapping { opacity: 0; }

/* -------------------------------------------------------------- FORM STATUS */
.form-status:not([hidden]) { animation: fade-up .5s var(--ease); }
.offer-form.is-success, .dark-form.is-success { animation: card-in .6s var(--ease); }

/* ======================================================= REDUCED MOTION ==== */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .001ms !important; animation-iteration-count: 1 !important; animation-delay: 0s !important;
    transition-duration: .001ms !important; transition-delay: 0s !important; scroll-behavior: auto !important;
  }
  .js .hero-in, .js [data-reveal], .js [data-stagger] > *, .js .offer-form, .js .offer-badge { opacity: 1 !important; transform: none !important; }
  .js [data-split] .w__i { transform: none !important; }
  .js .pricing-grid[data-pending] .price-card { opacity: 1; }
  .carousel__slide, .carousel__slide:not(.is-active) { opacity: 1; }
  /* the technology strip becomes a static, wrapped list */
  .platforms__track { width: auto; flex-wrap: wrap; justify-content: center; }
  .platforms__dup { display: none; }
  .platforms__list { flex: 0 1 auto; max-width: 100%; flex-wrap: wrap; justify-content: center; row-gap: .9rem; }
  .platforms__viewport { padding-inline: 1rem; }
}

/* JS failed or reveal system timed out: show everything */
.no-reveal [data-reveal], .no-reveal [data-stagger] > *, .no-reveal .pricing-grid[data-pending] .price-card, .no-reveal .hero-in, .no-reveal .offer-form { opacity: 1 !important; animation: none !important; transform: none !important; }
.no-reveal [data-split] .w__i { transform: none !important; transition: none !important; }
