/* ============================================================
   Lev — Motion System
   Restrained, GPU-only animation. Animates ONLY transform & opacity.
   Tokens come straight from the brief; all timing/easing references
   live here so individual components don't redefine them.
   ============================================================ */

:root {
  /* Easings */
  --lev-ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --lev-ease-pop: cubic-bezier(0.34, 1.56, 0.64, 1);

  /* Durations */
  --lev-dur-reveal: 600ms;
  --lev-dur-pop:    450ms;
  --lev-dur-lift:   200ms;
  --lev-dur-pill:   180ms;
  --lev-dur-accord: 350ms;

  /* Stagger */
  --lev-stagger: 90ms;
}

/* ============================================================
   REVEAL — opacity 0→1, translateY(24px)→0 (or X for slide-in).
   Triggered by adding `.is-in` (handled by IntersectionObserver).
   Per-child stagger via inline `style="--i: N"`.
   ============================================================ */

.lev-reveal {
  opacity: 0;
  transform: translate3d(0, 24px, 0);
  transition:
    opacity    var(--lev-dur-reveal) var(--lev-ease-out),
    transform  var(--lev-dur-reveal) var(--lev-ease-out);
  transition-delay: calc(var(--i, 0) * var(--lev-stagger));
  will-change: opacity, transform;
}
.lev-reveal.is-in { opacity: 1; transform: none; }

/* Slide-from-right variant — used for phones in the dark feature rows
   and the About-section phone. */
.lev-reveal--right { transform: translate3d(40px, 0, 0); }
.lev-reveal--right.is-in { transform: none; }

/* Slide-from-left variant — symmetric. */
.lev-reveal--left  { transform: translate3d(-40px, 0, 0); }
.lev-reveal--left.is-in { transform: none; }

/* Scale + fade — used for the hero phone settling in. */
.lev-reveal--scale { transform: scale(0.94); }
.lev-reveal--scale.is-in { transform: none; }

/* ============================================================
   POP — chips, badges, checkmarks. Slight overshoot.
   ============================================================ */

.lev-pop {
  opacity: 0;
  transform: scale(0.9);
  transition:
    opacity   var(--lev-dur-pop) var(--lev-ease-pop),
    transform var(--lev-dur-pop) var(--lev-ease-pop);
  transition-delay: calc(var(--i, 0) * var(--lev-stagger));
  will-change: opacity, transform;
}
.lev-pop.is-in { opacity: 1; transform: none; }

/* ============================================================
   HOVER LIFT — cards, badges, store tiles.
   Pure transform (no shadow on Lev brand — see DS guide §3.shadows),
   so we lift via translate only. We DO allow a tiny color-less shadow
   on store badges + glow halos, but not on brand surfaces.
   ============================================================ */

.lev-hover-lift {
  transition: transform var(--lev-dur-lift) ease-out;
  will-change: transform;
}
.lev-hover-lift:hover  { transform: translateY(-4px); }
.lev-hover-lift:active { transform: translateY(-1px); }

/* Slightly stronger lift for store-badge images (CTA section) — they
   benefit from a tiny shadow since they sit on a Ball background. */
.lev-hover-badge {
  transition: transform var(--lev-dur-lift) ease-out,
              filter    var(--lev-dur-lift) ease-out;
  will-change: transform, filter;
}
.lev-hover-badge:hover  { transform: translateY(-4px); filter: drop-shadow(0 8px 14px rgba(0,0,0,0.18)); }
.lev-hover-badge:active { transform: translateY(-1px); }

/* Pill / button scale (1.02). Native :hover only on coarse-pointer
   devices we drop to :active. */
.lev-hover-pill {
  transition: transform var(--lev-dur-pill) ease-out,
              background-color var(--lev-dur-pill) ease,
              color var(--lev-dur-pill) ease;
  will-change: transform;
}
.lev-hover-pill:hover  { transform: scale(1.02); }
.lev-hover-pill:active { transform: scale(0.98); }

/* ============================================================
   CONTINUOUS FLOAT — hero callout cards only.
   ±8px translateY, 6s ease-in-out infinite alternate.
   Children of an entrance-revealed wrapper compose cleanly.
   ============================================================ */

.lev-float-1 { animation: lev-float 6.0s ease-in-out infinite alternate; animation-delay: -0.0s; }
.lev-float-2 { animation: lev-float 6.4s ease-in-out infinite alternate; animation-delay: -1.6s; }
.lev-float-3 { animation: lev-float 5.8s ease-in-out infinite alternate; animation-delay: -3.0s; }
.lev-float-4 { animation: lev-float 6.6s ease-in-out infinite alternate; animation-delay: -4.4s; }

@keyframes lev-float {
  from { transform: translate3d(0, -8px, 0); }
  to   { transform: translate3d(0,  8px, 0); }
}

/* ============================================================
   GLOW BREATHE — behind phones.
   Carries its own transform (translate(-50%, -52%) etc) so each
   element variant declares its own keyframes inline-friendly with
   data-attrs. Keep keyframes simple: opacity + uniform scale.
   ============================================================ */

.lev-glow-breathe {
  animation: lev-glow-breathe 5s ease-in-out infinite;
  will-change: opacity, transform;
}
@keyframes lev-glow-breathe {
  0%, 100% { opacity: 0.55; }
  50%      { opacity: 0.92; }
}

/* For the hero halo which uses translate to center itself, we add a
   scale on top of the existing transform via the variant. */
.lev-glow-breathe-scale { animation: lev-glow-breathe-scale 5s ease-in-out infinite; }
@keyframes lev-glow-breathe-scale {
  0%, 100% { opacity: 0.78; transform: translate(-50%, -52%) scale(1.00); }
  50%      { opacity: 0.95; transform: translate(-50%, -52%) scale(1.05); }
}

/* Variant for the second hero halo (centered at top: 60%) */
.lev-glow-breathe-scale-2 { animation: lev-glow-breathe-scale-2 5.4s ease-in-out infinite; animation-delay: -1.2s; }
@keyframes lev-glow-breathe-scale-2 {
  0%, 100% { opacity: 0.55; transform: translate(-50%, -50%) scale(1.00); }
  50%      { opacity: 0.85; transform: translate(-50%, -50%) scale(1.06); }
}

/* Spotlight section halos — centered with translate(-50%,-50%) implicit
   because they're positioned via inset. Pure opacity+scale around center. */
.lev-glow-breathe-soft { animation: lev-glow-breathe-soft 5.6s ease-in-out infinite; }
@keyframes lev-glow-breathe-soft {
  0%, 100% { opacity: 0.50; transform: scale(1.00); }
  50%      { opacity: 0.85; transform: scale(1.05); }
}

/* ============================================================
   HERO ENTRANCE — auto-play on load. Same shape as reveal but the
   trigger is `animation-fill-mode: both` with `--d` delay set inline.
   No JS gate — text paints immediately then animates in.
   ============================================================ */

.lev-enter {
  opacity: 0;
  animation: lev-enter var(--lev-dur-reveal) var(--lev-ease-out) both;
  animation-delay: var(--d, 0ms);
  will-change: opacity, transform;
}
@keyframes lev-enter {
  from { opacity: 0; transform: translate3d(0, 24px, 0); }
  to   { opacity: 1; transform: none; }
}

.lev-enter-scale {
  opacity: 0;
  animation: lev-enter-scale 700ms var(--lev-ease-out) both;
  animation-delay: var(--d, 0ms);
  will-change: opacity, transform;
}
@keyframes lev-enter-scale {
  from { opacity: 0; transform: scale(0.94); }
  to   { opacity: 1; transform: none; }
}

/* ============================================================
   STOREFRONT TILE — rotation lives on the tile so reveal can own
   the translateY. Hover lift composes via `rotate(var(--rot)) translateY()`.
   ============================================================ */

.lev-storefront-tile {
  transition: transform var(--lev-dur-lift) ease-out;
  will-change: transform;
}
.lev-storefront-tile:hover {
  transform: rotate(var(--rot, 0deg)) translateY(-6px);
}
.lev-storefront-tile:active {
  transform: rotate(var(--rot, 0deg)) translateY(-1px);
}

/* ============================================================
   ACCORDION — grid-template-rows 0fr↔1fr.
   ============================================================ */

.lev-accordion {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition:
    grid-template-rows var(--lev-dur-accord) ease,
    opacity            var(--lev-dur-accord) ease;
}
.lev-accordion.is-open {
  grid-template-rows: 1fr;
  opacity: 1;
}
.lev-accordion > .lev-accordion-inner {
  overflow: hidden;
  min-height: 0;
}

/* ============================================================
   FAQ tab pill — sliding indicator (transform: translateX).
   Two states (.is-users / .is-brands) move a Ball-fill pill behind
   the active button. The component sets the data-active attribute.
   ============================================================ */

.lev-faq-pill {
  position: absolute;
  top: 4px;
  left: 4px;
  height: calc(100% - 8px);
  width: calc(50% - 4px);
  border-radius: 999px;
  background: var(--lev-ball);
  transition: transform 320ms var(--lev-ease-out);
  z-index: 0;
  pointer-events: none;
}
.lev-faq-tabs[data-active="brands"] .lev-faq-pill {
  transform: translateX(100%);
}

/* ============================================================
   ARROW DRAW — payment-flow connectors. Uses stroke-dashoffset to
   draw on first view. Triggered by `.is-in` from the IntersectionObserver.
   ============================================================ */

.lev-draw-arrow path {
  stroke-dasharray: var(--len, 60);
  stroke-dashoffset: var(--len, 60);
  transition: stroke-dashoffset 700ms var(--lev-ease-out);
  transition-delay: calc(var(--i, 0) * 200ms + 200ms);
}
.lev-draw-arrow.is-in path { stroke-dashoffset: 0; }

/* Long curving arrow on the partnerships annotation. */
.lev-draw-curve path {
  stroke-dasharray: 200;
  stroke-dashoffset: 200;
  transition: stroke-dashoffset 1100ms var(--lev-ease-out) 200ms;
}
.lev-draw-curve.is-in path { stroke-dashoffset: 0; }

/* ============================================================
   REDUCED MOTION — everything off, final state shown instantly.
   ============================================================ */

@media (prefers-reduced-motion: reduce) {
  .lev-reveal, .lev-pop, .lev-enter, .lev-enter-scale {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
    transition: none !important;
  }
  .lev-float-1, .lev-float-2, .lev-float-3, .lev-float-4,
  .lev-glow-breathe, .lev-glow-breathe-scale, .lev-glow-breathe-scale-2,
  .lev-glow-breathe-soft {
    animation: none !important;
  }
  .lev-accordion {
    transition: none !important;
  }
  .lev-draw-arrow path,
  .lev-draw-curve path {
    stroke-dasharray: 0 !important;
    stroke-dashoffset: 0 !important;
    transition: none !important;
  }
  .lev-hover-lift, .lev-hover-pill, .lev-hover-badge {
    transition: none !important;
  }
}

/* ============================================================
   MOBILE — keep reveals (handled by reduced-distance utility below),
   disable continuous loops + parallax intensity.
   ============================================================ */

@media (max-width: 768px) {
  .lev-float-1, .lev-float-2, .lev-float-3, .lev-float-4 {
    animation: none !important;
  }
  .lev-glow-breathe-scale, .lev-glow-breathe-scale-2, .lev-glow-breathe-soft {
    /* Hold a static mid-state instead of looping. */
    animation: none !important;
    opacity: 0.7;
  }
  /* Reveal distance halved on small screens — feels less twitchy. */
  .lev-reveal { transform: translate3d(0, 14px, 0); }
  .lev-reveal--right { transform: translate3d(20px, 0, 0); }
  .lev-reveal--left  { transform: translate3d(-20px, 0, 0); }
  .lev-reveal.is-in,
  .lev-reveal--right.is-in,
  .lev-reveal--left.is-in { transform: none; }

  /* Active-state feedback on touch (no hover). */
  .lev-hover-lift:active,
  .lev-hover-pill:active,
  .lev-hover-badge:active { transform: scale(0.97); }
}
