/* ============================================================
   Home page non-critical animations
   ============================================================
   Loaded *non-blocking* from app/page.tsx via a `<link rel="preload"
   as="style">` (which primes the cache) plus a tiny inline
   `document.createElement('link')` injector that appends a
   `<link rel="stylesheet">` to <head> after the HTML parser has
   moved past it. Browsers treat a stylesheet appended that late as
   non-render-blocking, so the home page's critical paint isn't
   gated on the ~9 KB of keyframes and decorative selectors below.
   None of these rules affect above-the-fold layout — they only kick
   in once the user scrolls into the bento grid, the platforms
   marquee, the use-case marquee, or any section beyond the hero.

   When this file fails to load (or hasn't loaded yet), every
   selector becomes a no-op. The fallback states are:
     - `.animate-scroll-*` → no animation, marquee tracks render
       static (still legible, content is duplicated for tiling).
     - `.scroll-reveal` → unknown selector, sections paint normally
       (opacity 1, transform 0). No flash.
     - `.cv-auto` → no `content-visibility: auto`, sections paint
       eagerly. Slight perf cost, no visual change.
     - Bento card `@keyframes` → cards render in their *rest* state
       (i.e. whatever inline classes / Tailwind utilities are
       present without the keyframes running). FeaturesGrid gates
       almost every bento animation behind `group-hover:`, so at
       rest the cards are visible at their static layout — the
       missing animation only manifests if the user hovers in the
       brief window before this file loads. The one exception is
       `thinking-dots`, which runs unconditionally on the typing
       indicator dots in the chat card; without the keyframes those
       degrade to static circles instead of pulsing — still legible.

   Keep in lockstep with /src/components/home/* — anything that
   binds to one of these classes lives below the fold.
   ============================================================ */

/* ---------- Marquee animations ---------- */

@keyframes scroll-platforms {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(-50%);
  }
}

@keyframes scroll-left {
  0% {
    transform: translateX(0);
  }
  100% {
    transform: translateX(-50%);
  }
}

@keyframes scroll-right {
  0% {
    transform: translateX(-50%);
  }
  100% {
    transform: translateX(0);
  }
}

.animate-scroll-left {
  animation: scroll-left 60s linear infinite;
}

.animate-scroll-right {
  animation: scroll-right 60s linear infinite;
}

.animate-scroll-platforms {
  animation: scroll-platforms 40s linear infinite;
}

.use-case-marquee-mask {
  mask-image: linear-gradient(to right, transparent, black 8%, black 92%, transparent);
  -webkit-mask-image: linear-gradient(to right, transparent, black 8%, black 92%, transparent);
}

/* Pause marquees on hover (desktop) and when off-screen (mobile + desktop).
   `[data-paused]` on `.animate-scroll-platforms` is set by
   <PlatformsCarousel>'s IntersectionObserver — pausing while scrolled
   out of view avoids tile-rasterization stalls on iOS Safari under
   memory pressure. */
.use-case-marquee-mask:hover .animate-scroll-left,
.use-case-marquee-mask:hover .animate-scroll-right,
.animate-scroll-platforms:hover,
.animate-scroll-platforms[data-paused] {
  animation-play-state: paused;
}

/* ---------- Bento card animations (FeaturesGrid) ---------- */

@keyframes handoff-reveal {
  0% {
    opacity: 0;
    max-height: 0;
    padding-top: 0;
    padding-bottom: 0;
  }
  15%,
  100% {
    opacity: 1;
    max-height: 80px;
    padding-top: 10px;
    padding-bottom: 10px;
  }
}

@keyframes handoff-reveal-system {
  0% {
    opacity: 0;
    max-height: 0;
    padding-top: 0;
    padding-bottom: 0;
  }
  15%,
  100% {
    opacity: 1;
    max-height: 50px;
    padding-top: 6px;
    padding-bottom: 6px;
  }
}

@keyframes thinking-dots {
  0%,
  80%,
  100% {
    transform: scale(0.8);
    opacity: 0.5;
  }
  40% {
    transform: scale(1);
    opacity: 1;
  }
}

@keyframes chat-user-once {
  0% {
    opacity: 1;
    transform: translateY(0);
  }
  10% {
    opacity: 0;
    transform: translateY(10px);
  }
  25% {
    opacity: 1;
    transform: translateY(0);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes typing-once {
  0%,
  30% {
    opacity: 0;
    transform: translateY(5px);
  }
  40%,
  60% {
    opacity: 1;
    transform: translateY(0);
  }
  70%,
  100% {
    opacity: 0;
    transform: translateY(0);
  }
}

@keyframes chat-bot-once {
  0% {
    opacity: 1;
    transform: translateY(0);
  }
  10%,
  65% {
    opacity: 0;
    transform: translateY(10px);
  }
  80%,
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes chat-bot-pulse {
  0%,
  100% {
    box-shadow: 0 4px 15px rgba(163, 230, 53, 0.15);
  }
  50% {
    box-shadow: 0 4px 25px rgba(163, 230, 53, 0.3);
  }
}

@keyframes question-cycle {
  0%,
  3% {
    opacity: 0;
  }
  6%,
  14% {
    opacity: 1;
  }
  17%,
  100% {
    opacity: 0;
  }
}

@keyframes typewriter {
  0% {
    width: 0;
  }
  100% {
    width: 100%;
  }
}

@keyframes results-reveal {
  0% {
    opacity: 0;
    transform: translateY(6px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes badge-appear {
  0% {
    transform: scale(0);
  }
  50% {
    transform: scale(1.3);
  }
  70% {
    transform: scale(0.9);
  }
  100% {
    transform: scale(1);
  }
}

@keyframes badge-bounce-loop {
  0%,
  100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.2);
  }
}

@keyframes check-appear {
  0% {
    opacity: 0;
    transform: scale(0);
  }
  50% {
    transform: scale(1.2);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

/* Sync card hover animations — checkmarks reset then appear with staggered delays */
.group:hover .sync-check {
  opacity: 0;
  transform: scale(0);
  animation: check-appear 0.3s ease forwards;
  animation-delay: var(--check-delay, 0s);
}

/* Sync status bar — hidden by default, fades up on hover */
.sync-status {
  opacity: 0;
  transform: translateY(6px);
}

.group:hover .sync-status {
  animation: fade-up 0.4s ease 2.1s forwards;
}

/* Sync dot — hidden by default, pulses on hover */
.sync-dot {
  opacity: 0;
}

.group:hover .sync-dot {
  animation: dot-pulse 1s ease 2.5s infinite;
}

@keyframes fade-up {
  0% {
    opacity: 0;
    transform: translateY(6px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
  }
}

@keyframes dot-pulse {
  0%,
  100% {
    opacity: 1;
    transform: scale(1);
    box-shadow: 0 0 0 0 rgba(163, 230, 53, 0.4);
  }
  50% {
    opacity: 1;
    transform: scale(1.1);
    box-shadow: 0 0 0 6px rgba(163, 230, 53, 0);
  }
}

/* ---------- Scroll-reveal (CSS-only, desktop) ---------- */
/* `.scroll-reveal` elements fade and rise as they enter the viewport via
   the native `animation-timeline: view()` API. Pure CSS — no JS, no
   IntersectionObserver, no main-thread cost. First applied at
   <DemoVideoSection> (4th section), so it's safely below the initial
   viewport on every device. Safari and `prefers-reduced-motion` users
   see the element's final state immediately. */
@keyframes scroll-reveal-rise {
  from {
    opacity: 0;
    transform: translate3d(0, 16px, 0);
  }
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
}

@media (min-width: 768px) and (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .scroll-reveal {
      animation: scroll-reveal-rise linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 25%;
    }
  }
}

/* ---------- content-visibility paint throttling ---------- */
/* Lets the browser skip layout/paint/render for off-screen sections. The
   canonical fix for long pages on iOS Safari where compositor memory
   pressure causes tile-rasterization stalls when scrolling. Never applied
   to above-the-fold sections — only to the bottom half of the home page. */
@supports (content-visibility: auto) {
  .cv-auto {
    content-visibility: auto;
    contain-intrinsic-size: 0 800px;
  }
}

/* ---------- Reduced-motion overrides for marquees ---------- */
/* Mirrors the override block in globals.css — keeping it here so that
   when this file loads, marquee animations turn off correctly for users
   with `prefers-reduced-motion: reduce`. The `*` blanket override in
   globals.css handles transition/animation duration globally. */
@media (prefers-reduced-motion: reduce) {
  .animate-scroll-left,
  .animate-scroll-right,
  .animate-scroll-platforms {
    /* biome-ignore lint/complexity/noImportantStyles: needs to defeat the unconditional `animation:` declarations on these classes above; mirrors the same pattern in globals.css for `.animate-blob*`. */
    animation: none !important;
  }
}
