/* ==============================================================
   VIVO MOTION v1 · Kit de webs para negocios
   Animaciones 3D y de scroll, nivel agencia. Vanilla, cero
   dependencias. Motor híbrido: CSS nativo de scroll donde el
   navegador lo soporta (corre en el compositor = fluido siempre)
   + respaldo JS automático (vivo.js) donde no.

   Colores del negocio como variables:
   :root { --vv-primario:#...; --vv-secundario:#...;
           --vv-fondo:#...; --vv-texto:#...; }

   Componentes:
   .vv-intro      apertura iris con el logo
   .vv-escena     escena 3D: las capas vuelan hacia la cámara al scrollear
   .vv-rev        aparición al entrar en pantalla (data-vv-fx)
   .vv-titulo     titular que se arma palabra por palabra en 3D
   .vv-tilt       tarjeta 3D que sigue el puntero, con brillo
   .vv-iman       botón magnético
   .vv-contador   número que cuenta hasta su valor (data-vv-hasta)
   .vv-cinta      cinta infinita (zonas, marcas, servicios)
   .vv-riel       riel lateral de navegación por escenas
   .vv-flotante   botón flotante de WhatsApp con pulso
   ============================================================== */

@property --vv-p { syntax: "<number>"; inherits: true; initial-value: 0; }

/* --- INTRO: iris circular con el logo ------------------------- */
/* HTML: <div class="vv-intro"><img src="logo" alt=""></div> (primer hijo del body) */
.vv-intro { position: fixed; inset: 0; z-index: 9999; display: grid; place-items: center;
  background: var(--vv-fondo, #0d0d0f); animation: vvIris .9s cubic-bezier(.7,0,.3,1) 1.9s forwards; }
.vv-intro img { max-width: min(44vw, 250px); max-height: 28vh; opacity: 0;
  animation: vvLogo 1.2s cubic-bezier(.2,.9,.3,1.1) .2s forwards; }
@keyframes vvLogo { from { opacity: 0; transform: perspective(700px) rotateX(38deg) scale(.8); }
  60% { opacity: 1; } to { opacity: 1; transform: none; } }
@keyframes vvIris { to { clip-path: circle(0% at 50% 42%); visibility: hidden; } }
/* Modo quieto: vivo.js agrega html.vv-quieto cuando el sistema pide reducir
   movimiento (salvo que el body lleve data-vv-animar="siempre") */
html.vv-quieto .vv-intro { display: none; }

/* --- ESCENA 3D: viaje en profundidad --------------------------
   La cámara avanza con el scroll y cada capa llega a foco, se
   atraviesa y aparece la siguiente. El JS solo escribe --vv-p
   (0 a 1) por escena; toda la matemática vive acá.

   HTML:
   <section class="vv-escena" data-vv-nombre="Historia" style="--vv-n:4">
     <div class="vv-lienzo"><div class="vv-mundo">
       <div class="vv-capa" style="--zi:0"> ... </div>
       <div class="vv-capa" style="--zi:1"> ... </div>
       ...
     </div></div>
   </section>
   --vv-n = cantidad de capas. --zi = índice de cada una (0,1,2…) */
.vv-escena { position: relative; height: calc(var(--vv-n, 3) * 95vh); }
.vv-lienzo { position: sticky; top: 0; height: 100vh; height: 100dvh; overflow: clip;
  perspective: 1100px; display: grid; }
.vv-mundo { position: relative; transform-style: preserve-3d; display: grid; }
.vv-capa { position: absolute; inset: 0; display: grid; place-items: center;
  text-align: center; padding: clamp(16px, 5vw, 64px); isolation: isolate;
  /* distancia de esta capa al punto de foco actual */
  --vv-d: calc(var(--vv-p, 0) * (var(--vv-n, 3) - 1) - var(--zi, 0));
  --vv-abs: max(var(--vv-d), calc(-1 * var(--vv-d)));
  transform: translateZ(calc(var(--vv-d) * 340px)) scale(calc(1 + var(--vv-d) * 0.04));
  opacity: clamp(0, calc(1.2 - var(--vv-abs) * 1.15), 1); }
.vv-capa > *:not(.vv-fondo) { max-width: 900px; }
/* foto a sangre completa como fondo de una capa */
.vv-capa .vv-fondo { position: absolute; inset: 0; z-index: -1; }
.vv-capa .vv-fondo img { width: 100%; height: 100%; object-fit: cover; }
.vv-capa .vv-fondo::after { content: ""; position: absolute; inset: 0;
  background: color-mix(in srgb, var(--vv-fondo, #000) 45%, transparent); }
/* volumen interno: sub-capas a distinta profundidad dentro de una capa */
.vv-hondo { transform: translateZ(var(--vv-z, 60px)); }
/* Modo quieto: las capas se vuelven secciones completas, legibles y elegantes */
html.vv-quieto .vv-escena { height: auto; }
html.vv-quieto .vv-lienzo { position: static; height: auto; perspective: none; overflow: visible; }
html.vv-quieto .vv-capa { position: relative; inset: auto; transform: none !important;
  opacity: 1 !important; min-height: 92vh; }
html.vv-quieto .vv-capa .vv-fondo { z-index: 0; }
html.vv-quieto .vv-capa > *:not(.vv-fondo) { position: relative; z-index: 1; }
html.vv-quieto .vv-hondo { transform: none; }

/* --- APARICIONES (.vv-rev) -------------------------------------
   Nativo con animation-timeline si existe; si no, vivo.js agrega
   .vv-visible con IntersectionObserver. data-vv-fx: subir (defecto),
   zoom, izquierda, derecha, girar. */
.vv-rev { opacity: 0; }
.vv-rev.vv-visible { opacity: 1; transition: opacity .7s ease, transform .8s cubic-bezier(.2,.9,.3,1); transform: none !important; }
.vv-rev[data-vv-fx="subir"], .vv-rev:not([data-vv-fx]) { transform: translateY(34px); }
.vv-rev[data-vv-fx="zoom"] { transform: scale(.88); }
.vv-rev[data-vv-fx="izquierda"] { transform: translateX(-44px); }
.vv-rev[data-vv-fx="derecha"] { transform: translateX(44px); }
.vv-rev[data-vv-fx="girar"] { transform: perspective(700px) rotateX(24deg) translateY(20px); }
@supports (animation-timeline: view()) {
  .vv-rev { animation: vvRevela both cubic-bezier(.2,.9,.3,1);
    animation-timeline: view(); animation-range: entry 5% cover 32%; }
  @keyframes vvRevela { to { opacity: 1; transform: none; } }
}
html.vv-quieto .vv-rev { opacity: 1 !important; transform: none !important; animation: none !important; }

/* --- TITULAR palabra a palabra en 3D --------------------------- */
/* HTML: <h1 class="vv-titulo">Tu titular</h1> (vivo.js lo trocea) */
.vv-titulo .vv-pal { display: inline-block; overflow: hidden; vertical-align: bottom; }
.vv-titulo .vv-pal > span { display: inline-block;
  transform: translateY(105%) rotateX(-55deg); opacity: 0; }
.vv-titulo.vv-visible .vv-pal > span { animation: vvPalabra .7s cubic-bezier(.2,.9,.3,1) forwards;
  animation-delay: calc(var(--vv-i) * .06s); }
@keyframes vvPalabra { to { transform: none; opacity: 1; } }
html.vv-quieto .vv-titulo .vv-pal > span { transform: none; opacity: 1; animation: none; }

/* --- TARJETA 3D que sigue el puntero (.vv-tilt) ----------------
   vivo.js escribe --rx/--ry/--mx/--my. En táctil queda estática. */
.vv-tilt { position: relative; transform-style: preserve-3d; transition: transform .18s ease-out;
  transform: perspective(800px) rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)); overflow: hidden; }
.vv-tilt::after { content: ""; position: absolute; inset: 0; pointer-events: none; opacity: 0;
  background: radial-gradient(340px circle at var(--mx, 50%) var(--my, 50%),
    color-mix(in srgb, #ffffff 18%, transparent), transparent 65%); transition: opacity .25s; }
.vv-tilt:hover::after { opacity: 1; }
.vv-tilt > .vv-hondo { transform: translateZ(34px); }

/* --- BOTÓN MAGNÉTICO (.vv-iman) — vivo.js escribe --ix/--iy ---- */
.vv-iman { display: inline-block; transform: translate(var(--ix, 0px), var(--iy, 0px));
  transition: transform .22s cubic-bezier(.2,.9,.3,1.4); will-change: transform; }

/* --- CONTADOR (.vv-contador data-vv-hasta="45") ---------------- */
.vv-contador { font-variant-numeric: tabular-nums; }

/* --- CINTA INFINITA (.vv-cinta > .vv-cinta-tira) --------------- */
.vv-cinta { overflow: hidden; white-space: nowrap; mask-image: linear-gradient(90deg,
  transparent, #000 8%, #000 92%, transparent); }
.vv-cinta-tira { display: inline-flex; gap: 2.2em; padding-right: 2.2em;
  animation: vvCinta var(--vv-vel, 26s) linear infinite; }
@keyframes vvCinta { to { transform: translateX(-50%); } }
html.vv-quieto .vv-cinta-tira { animation: none; }

/* --- RIEL lateral de escenas (vivo.js lo construye) ------------ */
.vv-riel { position: fixed; right: 14px; top: 50%; transform: translateY(-50%);
  z-index: 900; display: grid; gap: 10px; }
.vv-riel a { width: 9px; height: 9px; border-radius: 50%; display: block;
  background: color-mix(in srgb, var(--vv-texto, #fff) 30%, transparent);
  transition: transform .25s, background .25s; }
.vv-riel a.vv-activo { background: var(--vv-primario, #fff); transform: scale(1.5); }
@media (max-width: 720px) { .vv-riel { right: 7px; } }

/* --- FLOTANTE de WhatsApp con pulso ---------------------------- */
.vv-flotante { position: fixed; right: 18px; bottom: 18px; z-index: 950;
  width: 58px; height: 58px; border-radius: 50%; display: grid; place-items: center;
  background: #25d366; color: #fff; box-shadow: 0 8px 24px rgba(0,0,0,.25); }
.vv-flotante::before { content: ""; position: absolute; inset: 0; border-radius: 50%;
  background: inherit; z-index: -1; animation: vvPulso 2.2s ease-out infinite; }
@keyframes vvPulso { from { transform: scale(1); opacity: .55; } to { transform: scale(1.85); opacity: 0; } }
html.vv-quieto .vv-flotante::before { animation: none; }

/* --- PARALLAX suave para fotos sueltas (nativo si existe) ------ */
@supports (animation-timeline: view()) {
  .vv-parallax { animation: vvPar linear both; animation-timeline: view();
    animation-range: cover 0% cover 100%; }
  @keyframes vvPar { from { transform: translateY(6%); } to { transform: translateY(-6%); } }
}

/* --- Higiene de rendimiento ------------------------------------ */
.vv-capa, .vv-mundo { will-change: transform, opacity; }
html.vv-quieto .vv-capa, html.vv-quieto .vv-mundo { will-change: auto; }
