/*
 * Liquid Motion — shared animation primitives for vendor storefront themes.
 * Vanilla CSS/JS, no build step, CSP-safe (loaded as a same-origin file,
 * never inline). Pair with static/js/liquid-motion.js.
 *
 * Usage:
 *   <div class="lm-stagger">              <!-- children get auto-staggered delay -->
 *     <div class="lm-reveal">...</div>
 *     <div class="lm-reveal">...</div>
 *   </div>
 *   <a class="lm-magnet">...</a>          <!-- pointer-follow on 1-2 focal elements only -->
 *   <div class="lm-blob"></div>           <!-- organic morphing accent shape -->
 *   <span class="lm-shimmer">Sale</span>  <!-- animated gradient sheen -->
 */

:root {
  --lm-ease-liquid: cubic-bezier(.22,1,.36,1);
  --lm-ease-elastic: cubic-bezier(.34,1.56,.64,1);
  --lm-ease-out: cubic-bezier(.16,1,.3,1);
  --lm-dur-fast: .3s;
  --lm-dur: .6s;
  --lm-dur-slow: .9s;
  --lm-stagger-step: 70ms;
}

@media (prefers-reduced-motion: reduce) {
  :root { --lm-dur-fast: 1ms; --lm-dur: 1ms; --lm-dur-slow: 1ms; --lm-stagger-step: 0ms; }
}

/* Scroll reveal — opacity/transform only, stays on the compositor thread */
.lm-reveal {
  opacity: 0;
  transform: translateY(26px) scale(.97);
  transition: opacity var(--lm-dur) var(--lm-ease-liquid), transform var(--lm-dur) var(--lm-ease-liquid);
  transition-delay: calc(var(--lm-i, 0) * var(--lm-stagger-step));
  will-change: opacity, transform;
}
.lm-reveal.lm-visible {
  opacity: 1;
  transform: none;
}
/* Once revealed, drop will-change so idle sections don't hold a compositor layer */
.lm-reveal.lm-visible:not(.lm-magnet) { will-change: auto; }

/* Softer variant for large hero copy — smaller travel distance */
.lm-reveal-soft { transform: translateY(14px); }

/* Magnetic pointer-follow — JS sets transform directly on move; this transition
   only fires on release (the elastic "settle"). Reserve for 1-2 focal elements. */
.lm-magnet {
  transition: transform var(--lm-dur-slow) var(--lm-ease-elastic);
  will-change: transform;
}
.lm-magnet.lm-magnet-tracking { transition: none; }

/* Organic blob accent — animated border-radius morph, GPU-friendly (no filter) */
.lm-blob {
  position: absolute;
  border-radius: 42% 58% 65% 35% / 45% 40% 60% 55%;
  animation: lm-blob-morph 16s var(--lm-ease-liquid) infinite alternate;
  pointer-events: none;
}
@keyframes lm-blob-morph {
  0%   { border-radius: 42% 58% 65% 35% / 45% 40% 60% 55%; transform: rotate(0deg) scale(1); }
  33%  { border-radius: 60% 40% 30% 70% / 50% 60% 40% 50%; transform: rotate(8deg) scale(1.04); }
  66%  { border-radius: 35% 65% 55% 45% / 65% 35% 65% 35%; transform: rotate(-6deg) scale(.98); }
  100% { border-radius: 55% 45% 40% 60% / 40% 55% 45% 60%; transform: rotate(4deg) scale(1.02); }
}
@media (prefers-reduced-motion: reduce) { .lm-blob { animation: none; } }

/* Shimmer sheen — for badges, price tags, luxury underlines */
.lm-shimmer {
  background: linear-gradient(100deg, transparent 30%, rgba(255,255,255,.55) 48%, rgba(255,255,255,.55) 52%, transparent 70%);
  background-size: 220% 100%;
  animation: lm-shimmer-sweep 3.2s ease-in-out infinite;
}
@keyframes lm-shimmer-sweep {
  0% { background-position: 140% 0; }
  60%, 100% { background-position: -40% 0; }
}
@media (prefers-reduced-motion: reduce) { .lm-shimmer { animation: none; } }

/* Seamless marquee loop — pair two identical .lm-marquee-track children inside .lm-marquee */
.lm-marquee { overflow: hidden; display: flex; }
.lm-marquee-track {
  display: flex;
  flex-shrink: 0;
  gap: var(--lm-marquee-gap, 48px);
  padding-right: var(--lm-marquee-gap, 48px);
  animation: lm-marquee-scroll var(--lm-marquee-dur, 28s) linear infinite;
}
.lm-marquee:hover .lm-marquee-track { animation-play-state: paused; }
@keyframes lm-marquee-scroll {
  from { transform: translateX(0); }
  to { transform: translateX(-100%); }
}
@media (prefers-reduced-motion: reduce) {
  .lm-marquee-track { animation-duration: 90s; }
}

/* Press feedback for cards/buttons — subtle, layout-safe */
.lm-press { transition: transform var(--lm-dur-fast) var(--lm-ease-out); }
.lm-press:active { transform: scale(.97); }

/* 3D tilt — pointer-driven perspective rotation. JS sets --lm-rx/--lm-ry/--lm-tz. */
.lm-tilt {
  transform: perspective(900px) rotateX(var(--lm-rx, 0deg)) rotateY(var(--lm-ry, 0deg)) translateZ(var(--lm-tz, 0px));
  transition: transform var(--lm-dur) var(--lm-ease-liquid);
  transform-style: preserve-3d;
  will-change: transform;
}
.lm-tilt.lm-tilt-tracking { transition: transform .08s linear; }
.lm-tilt-shine {
  position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
  background: radial-gradient(circle at var(--lm-mx,50%) var(--lm-my,50%), rgba(255,255,255,.35), transparent 55%);
  opacity: 0; transition: opacity var(--lm-dur-fast) var(--lm-ease-out);
}
.lm-tilt.lm-tilt-tracking .lm-tilt-shine { opacity: 1; }

/* Cursor parallax — JS shifts children by their data-lm-depth (px range) */
.lm-parallax { position: relative; }
.lm-parallax-layer { transition: transform .2s var(--lm-ease-out); will-change: transform; }

/* Count-up target — JS animates textContent; this just guards layout width */
.lm-count { font-variant-numeric: tabular-nums; }

/* Mesh gradient backdrop — richer than a flat blob wash */
.lm-mesh {
  position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background:
    radial-gradient(circle at 15% 20%, var(--lm-mesh-a, rgba(124,58,237,.35)) 0%, transparent 45%),
    radial-gradient(circle at 85% 15%, var(--lm-mesh-b, rgba(37,99,235,.3)) 0%, transparent 50%),
    radial-gradient(circle at 50% 85%, var(--lm-mesh-c, rgba(16,185,129,.22)) 0%, transparent 55%);
  animation: lm-mesh-drift 20s ease-in-out infinite alternate;
}
@keyframes lm-mesh-drift {
  0% { transform: scale(1) translate(0,0); }
  100% { transform: scale(1.08) translate(-1.5%, 1.5%); }
}
@media (prefers-reduced-motion: reduce) { .lm-mesh { animation: none; } }

@media (prefers-reduced-motion: reduce) {
  .lm-tilt { transform: none !important; }
}
