/* ============================================================
   MOTION KIT v2 · Cazador de Webs
   Patrones de animación nivel agencia premium. Vanilla, sin
   dependencias. Colores del cliente como variables:
   :root { --mk-primario:#...; --mk-secundario:#...; --mk-fondo:#...; --mk-texto:#...; }
   ============================================================ */

/* --- INTRO: cortina con el logo del cliente ------------------ */
/* HTML: <div class="mk-intro"><img src="logo" alt=""></div> (primer hijo del body) */
.mk-intro { position: fixed; inset: 0; z-index: 9999; display: grid; place-items: center; background: var(--mk-fondo); animation: mkCurtain 1s cubic-bezier(.76,0,.24,1) 1.6s forwards; }
.mk-intro img { max-width: min(42vw, 260px); max-height: 30vh; opacity: 0; animation: mkLogoIn 1.1s cubic-bezier(.22,1,.36,1) .15s forwards; }
@keyframes mkLogoIn { from { opacity: 0; transform: scale(.86); filter: blur(8px); } to { opacity: 1; transform: scale(1); filter: none; } }
@keyframes mkCurtain { to { transform: translateY(-100%); } }

/* --- BARRA DE PROGRESO de scroll (motion.js la crea) --------- */
.mk-progress { position: fixed; top: 0; left: 0; height: 3px; width: 100%; z-index: 9998; background: var(--mk-primario); transform-origin: 0 50%; transform: scaleX(0); }

/* --- HERO: entrada escalonada -------------------------------- */
.mk-hero > * { opacity: 0; animation: mkRise .9s cubic-bezier(.22,1,.36,1) forwards; }
.mk-hero > *:nth-child(1) { animation-delay: 2.1s; }
.mk-hero > *:nth-child(2) { animation-delay: 2.25s; }
.mk-hero > *:nth-child(3) { animation-delay: 2.4s; }
.mk-hero > *:nth-child(4) { animation-delay: 2.55s; }
@keyframes mkRise { from { opacity: 0; transform: translateY(28px); } to { opacity: 1; transform: none; } }
/* Si no hay .mk-intro en la página, usa .mk-hero--solo (sin espera) */
.mk-hero--solo > *:nth-child(1) { animation-delay: .1s; } .mk-hero--solo > *:nth-child(2) { animation-delay: .25s; }
.mk-hero--solo > *:nth-child(3) { animation-delay: .4s; } .mk-hero--solo > *:nth-child(4) { animation-delay: .55s; }

/* --- SPLIT-TEXT: titular palabra a palabra (motion.js trocea) - */
/* HTML: <h1 class="mk-split">Tu titular aquí</h1> */
.mk-split .mk-w { display: inline-block; overflow: hidden; vertical-align: top; }
.mk-split .mk-w > span { display: inline-block; transform: translateY(110%); animation: mkWord .8s cubic-bezier(.22,1,.36,1) forwards; animation-delay: calc(var(--mk-i) * .07s + var(--mk-split-base, 2.1s)); }
@keyframes mkWord { to { transform: none; } }

/* --- GLOW de fondo con el color primario --------------------- */
.mk-glow { position: relative; overflow: hidden; }
.mk-glow::before { content: ""; position: absolute; inset: -20%; z-index: 0; pointer-events: none;
  background: radial-gradient(ellipse 60% 45% at 50% 0%, color-mix(in srgb, var(--mk-primario) 26%, transparent), transparent 70%);
  animation: mkGlow 9s ease-in-out infinite alternate; }
.mk-glow > * { position: relative; z-index: 1; }
@keyframes mkGlow { from { transform: translateX(-4%) scale(1); opacity: .8; } to { transform: translateX(4%) scale(1.08); opacity: 1; } }

/* --- KEN BURNS: fotos reales del cliente con zoom lento ------ */
/* HTML: <figure class="mk-kenburns"><img src="foto-real.jpg"></figure> */
.mk-kenburns { overflow: hidden; }
.mk-kenburns img { width: 100%; height: 100%; object-fit: cover; animation: mkKen 14s ease-in-out infinite alternate; }
@keyframes mkKen { from { transform: scale(1) translate(0,0); } to { transform: scale(1.12) translate(-1.5%, 1.5%); } }

/* --- REVELADO DE IMAGEN con cortinilla (clip-path) ----------- */
.mk-unveil { clip-path: inset(0 100% 0 0); transition: clip-path 1.1s cubic-bezier(.76,0,.24,1); }
.mk-unveil.mk-in { clip-path: inset(0 0 0 0); }

/* --- REVEAL al scroll ---------------------------------------- */
.mk-reveal { opacity: 0; transform: translateY(34px); transition: opacity .8s cubic-bezier(.22,1,.36,1), transform .8s cubic-bezier(.22,1,.36,1); }
.mk-reveal.mk-in { opacity: 1; transform: none; }
.mk-reveal:nth-child(2) { transition-delay: .1s; } .mk-reveal:nth-child(3) { transition-delay: .2s; } .mk-reveal:nth-child(4) { transition-delay: .3s; }

/* --- PARALLAX a sangre completa (motion.js mueve el fondo) --- */
/* HTML: <section class="mk-parallax" style="background-image:url(foto-real.jpg)">…</section> */
.mk-parallax { background-size: cover; background-position: center 0px; background-attachment: fixed; }
@supports (-webkit-touch-callout: none) { .mk-parallax { background-attachment: scroll; } }

/* --- CARDS con tilt 3D (motion.js) --------------------------- */
.mk-card { transition: transform .45s cubic-bezier(.22,1,.36,1), box-shadow .45s; will-change: transform; transform-style: preserve-3d; }
.mk-card:hover { box-shadow: 0 24px 60px color-mix(in srgb, var(--mk-primario) 22%, rgba(0,0,0,.25)); }

/* --- MARQUEE (reseñas / platos / marcas) --------------------- */
.mk-marquee { overflow: hidden; white-space: nowrap; mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
.mk-marquee-track { display: inline-flex; gap: 3rem; padding-right: 3rem; animation: mkMarquee 26s linear infinite; }
.mk-marquee:hover .mk-marquee-track { animation-play-state: paused; }
@keyframes mkMarquee { to { transform: translateX(-50%); } }

/* --- CTA con pulso ------------------------------------------- */
.mk-pulse { position: relative; }
.mk-pulse::after { content: ""; position: absolute; inset: -4px; border-radius: inherit; border: 2px solid var(--mk-primario); animation: mkPulse 2.2s ease-out infinite; pointer-events: none; }
@keyframes mkPulse { 0% { opacity: .9; transform: scale(1); } 100% { opacity: 0; transform: scale(1.12); } }
/* Mientras hay scroll el pulso se pausa: si late sobre el túnel obliga a recomponer
   toda la escena en cada fotograma (medido: 13 tirones → 0). Vuelve al parar. */
.mk-pulse::after { will-change: transform, opacity; }
.mk-scroll .mk-pulse::after { animation-play-state: paused; opacity: 0; }

/* ============================================================
   SCROLLYTELLING 3D — patrones conducidos por --mk-p (0→1),
   que escribe motion.js en cada [data-mk-scrolly].
   Uso típico del hero:
   <section class="mk-pin" data-mk-scrolly>
     <div class="mk-pin-stage mk-scene3d">
       <div class="mk-layer" style="--mk-depth:-220px"><img class="mk-zoomout" src="ambiente.jpg"></div>
       <div class="mk-layer" style="--mk-depth:-80px"><img src="plato.jpg"></div>
       <div class="mk-layer mk-seq" style="--mk-depth:40px"> logo + titular + claims </div>
     </div>
   </section>
   ============================================================ */

/* --- PIN: la escena se clava y el scroll "avanza la película" - */
.mk-pin { position: relative; height: 250vh; }
.mk-pin-stage { position: sticky; top: 0; height: 100vh; overflow: hidden; display: grid; place-items: center; }

/* --- Escenario 3D y capas con profundidad -------------------- */
.mk-scene3d { perspective: 1200px; transform-style: preserve-3d; }
.mk-layer {
  position: absolute; inset: 0; display: grid; place-items: center;
  will-change: transform;
  /* cada capa se acerca desde su profundidad hasta el plano según avanza el scroll */
  transform: translateZ(calc(var(--mk-depth, 0px) * (1 - var(--mk-p, 0))))
             translateY(calc(var(--mk-depth, 0px) * (1 - var(--mk-p, 0)) * -0.25));
}

/* --- ZOOM-OUT del fondo: entra cerca, asienta lejos ----------- */
.mk-zoomout {
  width: 100%; height: 100%; object-fit: cover;
  transform: scale(calc(1.25 - 0.25 * var(--mk-p, 0)));
  filter: brightness(calc(0.55 + 0.25 * var(--mk-p, 0)));
}

/* --- TILT por scroll: el producto rota en 3D ------------------ */
.mk-tilt-scroll {
  will-change: transform;
  transform: rotateX(calc((1 - var(--mk-p, 0)) * 24deg))
             rotateY(calc((var(--mk-p, 0) - 0.5) * 14deg))
             scale(calc(0.9 + 0.1 * var(--mk-p, 0)));
}

/* --- SECUENCIA: los hijos aparecen por umbrales de scroll ----- */
.mk-seq > * { opacity: calc((var(--mk-p, 0) - var(--mk-at, 0.2)) / 0.15); transform: translateY(calc(max(0, 1 - (var(--mk-p, 0) - var(--mk-at, 0.2)) / 0.15) * 26px)); }
.mk-seq > *:nth-child(1) { --mk-at: 0.15; }
.mk-seq > *:nth-child(2) { --mk-at: 0.35; }
.mk-seq > *:nth-child(3) { --mk-at: 0.55; }
.mk-seq > *:nth-child(4) { --mk-at: 0.75; }

/* --- STATEMENT: frase gigante que vive en el centro del scroll -
   Sección normal con data-mk-scrolly; el texto aparece al llegar
   al centro del viewport y se desvanece al pasarlo (pico en p=0.5). */
.mk-statement {
  opacity: calc(1 - max(calc(var(--mk-p, 0) - 0.5), calc(0.5 - var(--mk-p, 0))) * 2.6);
  transform: scale(calc(0.92 + 0.08 * (1 - max(calc(var(--mk-p, 0) - 0.5), calc(0.5 - var(--mk-p, 0))) * 2)));
  will-change: transform, opacity;
}

/* --- GALERÍA HORIZONTAL conducida por scroll vertical ---------
   <section class="mk-pin" data-mk-scrolly>
     <div class="mk-pin-stage mk-hscroll">
       <div class="mk-hscroll-track" style="--mk-shift:-60%"> fotos… </div>
     </div>
   </section>  (ajusta --mk-shift al ancho del track) */
.mk-hscroll { display: flex; align-items: center; }
.mk-hscroll-track {
  display: flex; gap: 3vw; padding: 0 8vw; will-change: transform;
  transform: translateX(calc(var(--mk-p, 0) * var(--mk-shift, -60%)));
}
.mk-hscroll-track > * { flex-shrink: 0; }

/* --- WIPE: la siguiente imagen se abre en círculo con el scroll */
.mk-wipe {
  clip-path: circle(calc(var(--mk-p, 0) * 120%) at 50% 50%);
  will-change: clip-path;
}

/* --- COLORMORPH: el fondo de la sección muta con el progreso -- */
.mk-colormorph {
  background: color-mix(in srgb,
    var(--mk-fondo) calc(100% - var(--mk-p, 0) * 22%),
    var(--mk-primario) calc(var(--mk-p, 0) * 22%));
}

/* ============================================================
   ⚠️ REGLA CRÍTICA — LÉELA ANTES DE USAR CUALQUIER PATRÓN DE ESTE ARCHIVO
   (v3/v4/v5 de sticky, Y TAMBIÉN v6 de scroll-timeline nativo, más abajo):

   NUNCA pongas `overflow` (ni siquiera solo `overflow-x: hidden`) en
   `html` Y `body` A LA VEZ. Verificado con Playwright, dos bugs distintos:

   1. En v3/v4/v5 (basados en position:sticky): rompe el sticky en
      silencio — el "stage" deja de quedarse fijo, sale de pantalla a los
      ~100vh de scroll, y todo lo que viene después queda en blanco.
   2. En v6 (basado en animation-timeline:view()): NO deja la página en
      blanco, pero CONGELA la animación — cada escena se queda fija en
      el valor de opacidad/transform de su primer render y deja de
      responder al scroll, aunque el contenido siga siendo visible (bug
      mucho más difícil de notar a simple vista: la web "se ve bien" en
      una sola captura, pero no se mueve nada al hacer scroll de verdad).

   Poner overflow-x:hidden en SOLO `html` o SOLO `body` (no ambos) no
   causa ninguno de los dos problemas — pero para no tener que recordar
   la distinción, la regla simple y segura es: nunca lo pongas en ninguno
   de los dos. Si necesitas evitar scroll horizontal, aplícalo a un
   contenedor que no sea `html`/`body`.

   → Por defecto usa v5 (el túnel, más abajo): es el que de verdad se siente
   como "volar a través" del negocio — verificado con Playwright que el
   movimiento de profundidad es real y reversible. v6 (`.mk-scene`, al final
   del archivo) es una alternativa más simple y más difícil de romper, pero
   el efecto es notablemente más sutil/plano. Úsalo solo si el usuario pide
   explícitamente algo más discreto.
   ============================================================ */

/* ============================================================
   LA PELÍCULA (v4) — experiencia de UN SOLO LIENZO.
   Sin secciones: un contenedor .mk-film da la duración del scroll
   y un lienzo sticky .mk-film-stage lo muestra todo. Cada bloque
   de información es un "shot" con su ventana temporal --in/--out
   dentro del timeline global --mk-p (0→1).

   <div class="mk-film" data-mk-scrolly style="--mk-shots:10">
     <div class="mk-film-stage">
       <div class="mk-shot mk-fx-zoom" style="--in:0; --out:.14">  …fondo/logo… </div>
       <div class="mk-shot mk-fx-rise" style="--in:.10; --out:.26"> …titular…  </div>
       …
     </div>
   </div>
   <footer> …cierre estático (CTA/contacto), fuera de la película… </footer>

   Solapa las ventanas (~4%) para que el lienzo nunca quede vacío.
   ============================================================ */
.mk-film { position: relative; height: calc(var(--mk-shots, 8) * 150vh); }
.mk-film-stage { position: sticky; top: 0; height: 100vh; overflow: hidden; }

.mk-shot {
  /* progreso local del shot dentro de su ventana */
  --lp: clamp(0, calc((var(--mk-p, 0) - var(--in, 0)) / max(0.001, calc(var(--out, 1) - var(--in, 0)))), 1);
  /* rampas de entrada (primer 15% de la ventana) y salida (último 15%) */
  --ramp-in: clamp(0, calc(var(--lp) / 0.15), 1);
  --ramp-out: clamp(0, calc((1 - var(--lp)) / 0.15), 1);
  --alive: min(var(--ramp-in), var(--ramp-out));
  position: absolute; inset: 0; display: grid; place-items: center;
  opacity: var(--alive);
  pointer-events: none;
  will-change: transform, opacity;
}
/* el shot sólo es interactivo mientras está en escena */
.mk-shot[data-live], .mk-shot:hover { pointer-events: auto; }

/* --- Efectos de shot (combinables) --------------------------- */
/* Sube al entrar y se eleva al despedirse */
.mk-fx-rise { transform: translateY(calc((1 - var(--ramp-in)) * 60px - (1 - var(--ramp-out)) * 60px)); }
/* Se acerca desde el fondo y sigue creciendo al salir (atraviesa la cámara) */
.mk-fx-zoom { transform: scale(calc(0.82 + var(--lp) * 0.28)); }
/* Entra desde un lateral y sale por el contrario */
.mk-fx-drift-l { transform: translateX(calc((1 - var(--ramp-in)) * -12vw + (1 - var(--ramp-out)) * 12vw)); }
.mk-fx-drift-r { transform: translateX(calc((1 - var(--ramp-in)) * 12vw + (1 - var(--ramp-out)) * -12vw)); }
/* Rota en 3D mientras vive */
.mk-fx-tilt { transform: perspective(1100px) rotateX(calc((1 - var(--lp)) * 18deg)) rotateY(calc((var(--lp) - 0.5) * 10deg)); }
/* Foto de fondo viva: zoom continuo durante toda su ventana */
.mk-fx-kenburns-live img, img.mk-fx-kenburns-live { width: 100%; height: 100%; object-fit: cover; transform: scale(calc(1.06 + var(--lp) * 0.14)); }
/* Capas internas con profundidad (dentro de un shot) */
.mk-fx-parallax > * { transform: translateY(calc((1 - var(--lp)) * var(--mk-depth, 0px))); will-change: transform; }

/* ============================================================
   EL TÚNEL 3D (v5) — la cámara VUELA A TRAVÉS de los contenidos.
   Cada shot vive a una profundidad del túnel (--zi = su índice) y
   el scroll avanza la cámara: los shots emergen del fondo, llegan
   a foco, y PASAN POR ENCIMA de la cámara (nos metemos dentro).

   <div class="mk-film" data-mk-scrolly data-mk-shots="16" style="--mk-nshots:16">
     <div class="mk-film-stage mk-tunnel">
       <div class="mk-zshot" style="--zi:0">  …logo…            </div>
       <div class="mk-zshot" style="--zi:1">  …titular + foto…  </div>
       …
       <div class="mk-zshot" style="--zi:15"> …CTA…             </div>
     </div>
   </div>
   (--mk-nshots = número de shots; el mismo valor que data-mk-shots)
   ============================================================ */
.mk-tunnel {
  perspective: 1100px; perspective-origin: 50% 46%;
  /* El "aire" del túnel: un resplandor del color de la marca en el fondo.
     Las escenas nacen de aquí, no de un rectángulo negro. */
  background: radial-gradient(ellipse 70% 60% at 50% 46%,
    color-mix(in srgb, var(--mk-secundario, #555) 30%, var(--mk-fondo, #000)) 0%,
    var(--mk-fondo, #000) 75%);
}
.mk-zshot {
  /* f = distancia de la cámara a este shot, en "unidades de shot".
     f<0: aún lejos, al fondo · f=0: en foco · f>0: lo estamos atravesando */
  --f: calc(var(--mk-p, 0) * (var(--mk-nshots, 10) - 1) - var(--zi, 0));
  position: absolute; inset: 0; display: grid; place-items: center;
  transform: translateZ(calc(var(--f) * 760px));
  /* Ventana de visibilidad ajustada para dar tiempo real de lectura:
     nace en f=-0.8, alcanza opacidad plena en f=-0.45, se mantiene
     plana (plateau de lectura, sin apenas solape con la vecina) hasta
     f=0.45, y termina de desvanecerse en f=0.8. Ajustado a partir de
     feedback real de usuario — antes el plateau era más corto y hasta
     3 shots se solapaban a la vez, dando sensación de "pasa muy rápido".
     Si necesitas ajustar el ritmo: sube los "0.35" para transiciones
     más largas/suaves, o el "150vh" de .mk-film (más arriba) para más
     tiempo de scroll por escena sin tocar estas proporciones. */
  opacity: min(
    clamp(0, calc((var(--f) + 0.8) / 0.35), 1),
    clamp(0, calc((0.8 - var(--f)) / 0.35), 1)
  );
  pointer-events: none;
  /* NITIDEZ: sin will-change a propósito. Con will-change el navegador pinta la
     escena UNA vez, cuando aún está lejos y pequeña, y luego estira ese dibujo al
     acercarse: fotos y textos se ven borrosos. Sin él, la repinta a su tamaño real
     (medido: +39 % de nitidez en foco). No lo vuelvas a poner. */
}
.mk-zshot[data-live] { pointer-events: auto; }
/* Solo MIENTRAS hay scroll (motion.js pone .mk-moviendo): movimiento fluido sin redibujar.
   Al parar se quita y la escena se redibuja nítida. */
.mk-moviendo .mk-zshot { will-change: transform, opacity; }
/* Las escenas lejanas (opacidad 0) no se dibujan: motion.js marca con data-vis las
   que están en su ventana. Sin JS o con movimiento reducido, todas se ven. */
.mk-film.mk-vis-activo .mk-zshot:not([data-vis]) { visibility: hidden; }

/* Dentro de un zshot: capas a distinta profundidad → paralaje al atravesar.
   El zshot tiene su propia perspectiva (si no, la opacidad aplanaría las capas)
   y la separación entre capas crece al acercarnos: unas pasan antes que otras. */
.mk-zshot { perspective: 1100px; }
.mk-zdepth { transform: translateZ(calc(var(--z, 0px) * (1 + var(--f, 0) * 0.9))); }

/* FRAGMENTO FLOTANTE: foto suelta dentro del túnel, sin marco, sin sombra, sin
   esquinas: sus bordes se funden con el aire. Úsala en vez de miniaturas o tarjetas.
   <img class="mk-zfloat mk-zdepth" style="--z:-200px; left:8%; top:12%; width:34vw" src="assets/foto.jpg" alt="">  */
.mk-zfloat {
  position: absolute; display: block; aspect-ratio: 4 / 5; height: auto; object-fit: cover;
  /* Fundido escalonado (no lineal): un fundido lineal se percibe como un óvalo con canto. */
  -webkit-mask-image: radial-gradient(ellipse 50% 50% at 50% 50%, #000 0%, rgba(0,0,0,.92) 28%, rgba(0,0,0,.6) 52%, rgba(0,0,0,.28) 72%, rgba(0,0,0,.08) 88%, transparent 100%);
          mask-image: radial-gradient(ellipse 50% 50% at 50% 50%, #000 0%, rgba(0,0,0,.92) 28%, rgba(0,0,0,.6) 52%, rgba(0,0,0,.28) 72%, rgba(0,0,0,.08) 88%, transparent 100%);
}

/* FONDO DE ESCENA SIN MARCO (usa SIEMPRE esto para las fotos de fondo):
   <div class="mk-zbg"><img class="mk-fx-dive" src="assets/foto.jpg" alt=""></div>
   - Es más grande que la pantalla y sus bordes se funden en el aire del túnel:
     la foto surge de la oscuridad, nunca se ve su rectángulo.
   - Lleva su propio velo para que el texto se lea (mk-zbg--suave = velo ligero).
   - La niebla (lo lejano más oscuro) va incluida: no hace falta mk-zfog. */
.mk-zbg {
  position: absolute; inset: 0; z-index: -1; pointer-events: none;
  display: grid; place-items: center;
  /* niebla: lo lejano se funde con el aire del túnel (opacidad, nunca filtros sobre la escena) */
  opacity: clamp(0, calc(1 + min(0, var(--f, 0)) * 1.1), 1);
}
/* La foto se ve ENTERA, a un tamaño que cabe en pantalla (sin zoom que la recorte o la
   ablande) y con los bordes fundidos. */
.mk-zbg > img {
  position: relative; z-index: 1; display: block;
  width: auto; height: auto; max-width: 96vw; max-height: 94vh; object-fit: contain;
  /* La foto se ve COMPLETA. Su borde (≈16 %, en curva suave) se disuelve en el ambiente difuminado
     de detrás, que es la misma foto: así no se nota marco y no se pierde contenido. */
  -webkit-mask-image: linear-gradient(to right, transparent 0, rgba(0,0,0,.35) 5%, rgba(0,0,0,.85) 11%, #000 16%, #000 84%, rgba(0,0,0,.85) 89%, rgba(0,0,0,.35) 95%, transparent 100%),
                      linear-gradient(to bottom, transparent 0, rgba(0,0,0,.35) 5%, rgba(0,0,0,.85) 11%, #000 16%, #000 84%, rgba(0,0,0,.85) 89%, rgba(0,0,0,.35) 95%, transparent 100%);
  -webkit-mask-composite: source-in;
          mask-image: linear-gradient(to right, transparent 0, rgba(0,0,0,.35) 5%, rgba(0,0,0,.85) 11%, #000 16%, #000 84%, rgba(0,0,0,.85) 89%, rgba(0,0,0,.35) 95%, transparent 100%),
                      linear-gradient(to bottom, transparent 0, rgba(0,0,0,.35) 5%, rgba(0,0,0,.85) 11%, #000 16%, #000 84%, rgba(0,0,0,.85) 89%, rgba(0,0,0,.35) 95%, transparent 100%);
          mask-composite: intersect;
}
.mk-zbg::before, .mk-zbg::after { content: ""; position: absolute; pointer-events: none; }
/* Ambiente: la misma foto, difuminada y tenue, llena la pantalla alrededor (motion.js
   copia su dirección en --mk-zbg-src). Así los bordes "se continúan" sin verse el marco. */
.mk-zbg::before {
  inset: -6%; z-index: 0;
  background: var(--mk-zbg-src, none) center / cover no-repeat;
  /* bordes del ambiente también fundidos: cuando la escena aún está lejos (más pequeña que
     la pantalla) su rectángulo se notaba como un panel marrón (visto en un móvil real) */
  -webkit-mask-image: radial-gradient(ellipse 50% 50% at 50% 50%, #000 0%, #000 55%, rgba(0,0,0,.5) 78%, transparent 100%);
          mask-image: radial-gradient(ellipse 50% 50% at 50% 50%, #000 0%, #000 55%, rgba(0,0,0,.5) 78%, transparent 100%);
  /* SIN filter: blur() (provocaba tirones). motion.js pone aquí una copia de 40 px de
     la foto, que al estirarse ya se ve difuminada. */
  opacity: 1;
}
/* velo de lectura sobre la foto */
.mk-zbg::after {
  inset: 0; z-index: 2;
  /* velo de lectura: amplio detrás del texto + una capa uniforme muy ligera.
     Su fuerza la decide la luz de la foto (--mk-velo, lo calcula motion.js). */
  background:
    radial-gradient(ellipse 58% 50% at 50% 50%,
      color-mix(in srgb, var(--mk-fondo, #000) 85%, transparent) 0%,
      color-mix(in srgb, var(--mk-fondo, #000) 50%, transparent) 65%,
      transparent 100%),
    color-mix(in srgb, var(--mk-fondo, #000) 22%, transparent);
  /* motion.js mide la luz de cada foto: clara → velo fuerte, oscura → casi nada */
  opacity: var(--mk-velo, .6);
}
.mk-zbg--suave::after { opacity: calc(var(--mk-velo, .6) * .6); }
.mk-zbg--sin-copia::before { opacity: .3; }

/* TEXTO DE LAS ESCENAS: entra más tarde y sale antes que la foto. Su ventana
   (f de -0.45 a 0.3) no coincide nunca con la de la escena vecina (que empieza en
   f = 0.55), así que dos textos jamás se montan, aunque estén a la misma altura.
   No hace falta alternar arriba/abajo. */
.mk-zshot > :not(.mk-zbg):not(.mk-zfloat):not(.mk-zdepth) {
  opacity: min(clamp(0, calc((var(--f, 0) + 0.45) / 0.15), 1),
               clamp(0, calc((0.3 - var(--f, 0)) / 0.15), 1));
}

/* DIVE: foto por la que ENTRAMOS — crece hasta tragarse la cámara. */
.mk-fx-dive { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Niebla de profundidad para escenas sin foto (o webs antiguas):
   un velo del color de fondo, sin filtro, para no perder nitidez. */
.mk-zfog::after {
  content: ""; position: absolute; inset: -16%; z-index: 5; pointer-events: none;
  background: var(--mk-fondo, #000);
  opacity: clamp(0, calc(var(--f, 0) * -0.6), .7);
}

/* Polvo en suspensión: lo crea motion.js dentro de cada .mk-tunnel.
   Las motas pasan junto a la cámara al avanzar y dan la sensación de viaje. */
.mk-dust { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 0; }

/* Raíl de progreso de la película (lado derecho) — lo crea motion.js.
   Es un SCRUBBER: se puede pinchar y arrastrar para moverse por la película. */
.mk-rail {
  position: fixed; right: 12px; top: 50%; transform: translateY(-50%);
  width: 5px; height: 60vh; border-radius: 5px;
  background: rgba(255,255,255,0.22); z-index: 9997;
  pointer-events: auto; cursor: grab; touch-action: none;
}
/* zona de agarre generosa (invisible) alrededor del raíl */
.mk-rail::before { content: ""; position: absolute; inset: -10px -16px; }
.mk-rail.mk-dragging { cursor: grabbing; }
.mk-rail-thumb {
  position: absolute; left: 0; width: 100%; height: 10%; border-radius: 5px;
  background: var(--mk-primario, #fff);
  top: calc(var(--mk-p, 0) * 90%);
  box-shadow: 0 0 12px color-mix(in srgb, var(--mk-primario, #fff) 60%, transparent);
  transition: transform .2s;
}
.mk-rail:hover .mk-rail-thumb, .mk-rail.mk-dragging .mk-rail-thumb { transform: scaleX(2.2); }

/* ============================================================
   ESCENAS 3D (v6) — PATRÓN ALTERNATIVO, más simple. Inmersión 3D real, sin
   position:sticky y sin cálculo de scroll en JS: el propio navegador
   gobierna la animación con `animation-timeline: view()`, atada a la
   posición de scroll de cada escena dentro del viewport. Por eso es
   NATIVAMENTE reversible — subir el scroll deshace la animación
   exactamente igual que al bajar — y no puede sufrir el bug de
   `position:sticky` de los patrones v3/v4/v5 de arriba.

   Cada escena es una <section> normal (documento normal, un poco más
   alta que el viewport para dar tiempo de lectura): gira suavemente en
   3D y se acerca con blur al entrar, se mantiene plana mientras se lee,
   y hace el gesto simétrico inverso al salir. Nota: el efecto se percibe
   notablemente más sutil que el del túnel (v5) — cada escena es
   independiente, no hay sensación de cámara continua volando a través del
   contenido. Prioriza v5 salvo que el usuario pida algo más discreto.

   IMPORTANTE: es UNA SOLA animación por elemento (no dos combinadas de
   entrada+salida) — verificado con Playwright que combinar dos
   animaciones sobre la MISMA propiedad (opacity) en el mismo view()
   timeline hace que la segunda de la lista pise a la primera durante
   toda su fase "before" (antes de que empiece su propio rango), dejando
   el elemento invisible u opaco de más el resto del tiempo. Con una sola
   animación de 4 keyframes (entra → se asienta → se asienta → sale) no
   hay ninguna propiedad en conflicto.

   <section class="mk-scene">
     <div class="mk-scene-bg bg-a"></div>          (opcional, fondo con paralaje)
     <div class="mk-scene-in">  …contenido…  </div>
   </section>

   Requiere Chrome/Edge 115+. Sin soporte → fallback seguro: todo
   visible, sin animar (nunca en blanco). Comprueba tú mismo el
   resultado con Playwright antes de entregar (ver Fase 3 del SKILL.md).
   ============================================================ */
.mk-scene{
  position: relative; min-height: 130vh; display: flex; align-items: center;
  justify-content: center; perspective: 1400px; overflow: clip;
}
.mk-scene-in{
  position: relative; z-index: 1; opacity: 1; /* fallback: siempre visible */
}
.mk-scene-bg{ position: absolute; inset: -8% -8%; z-index: 0; }

@supports (animation-timeline: view()) {
  .mk-scene-in{
    animation: mk-scene-pass linear both;
    animation-timeline: view();
    animation-range: cover 0% cover 100%;
  }
  /* Alterna el giro escena a escena para que no se sienta repetitivo.
     Puedes sobreescribir --mk-rot/--mk-rotx por escena con style="" inline. */
  .mk-scene:nth-of-type(odd)  .mk-scene-in{ --mk-rot: 16deg;  --mk-rotx: 14deg; }
  .mk-scene:nth-of-type(even) .mk-scene-in{ --mk-rot: -16deg; --mk-rotx: -14deg; }

  .mk-scene-bg{
    animation: mk-bg-parallax linear both;
    animation-timeline: view();
    animation-range: cover 0% cover 100%;
  }
}
/* Una sola animación, 4 tramos: entra (0→28%) · asentada (28→72%) · sale (72→100%) */
@keyframes mk-scene-pass{
  0%   { opacity: 0; filter: blur(10px);
         transform: perspective(1400px) translateZ(-420px) translateY(90px)
                    rotateX(var(--mk-rotx, 14deg)) rotateY(var(--mk-rot, 16deg)) scale(.78); }
  28%  { opacity: 1; filter: blur(0);
         transform: perspective(1400px) translateZ(0) translateY(0) rotateX(0) rotateY(0) scale(1); }
  72%  { opacity: 1; filter: blur(0);
         transform: perspective(1400px) translateZ(0) translateY(0) rotateX(0) rotateY(0) scale(1); }
  100% { opacity: 0; filter: blur(10px);
         transform: perspective(1400px) translateZ(-420px) translateY(-90px)
                    rotateX(calc(var(--mk-rotx, 14deg) * -1)) rotateY(calc(var(--mk-rot, 16deg) * -1)) scale(.78); }
}
@keyframes mk-bg-parallax{
  0%   { transform: scale(1.22) translateY(-6%); }
  100% { transform: scale(1.22) translateY(6%); }
}
/* Móvil en vertical: una foto apaisada "entera" quedaba diminuta en medio de una niebla.
   Aquí llena casi toda la altura (se recortan los lados, con los bordes igual de fundidos). */
@media (orientation: portrait) and (max-width: 760px) {
  .mk-zbg > img { width: 100vw; height: 74vh; max-width: none; max-height: none; object-fit: cover; }
}
@media (prefers-reduced-motion: reduce){
  .mk-scene-in, .mk-scene-bg{ animation: none !important; opacity: 1 !important; transform: none !important; filter: none !important; }
}

/* --- Accesibilidad (patrones v3/v4/v5) ------------------------ */
@media (prefers-reduced-motion: reduce) {
  .mk-intro { display: none; }
  .mk-hero > *, .mk-split .mk-w > span, .mk-reveal, .mk-unveil, .mk-marquee-track, .mk-pulse::after, .mk-glow::before, .mk-kenburns img { animation: none !important; transition: none !important; opacity: 1 !important; transform: none !important; clip-path: none !important; }
  .mk-pin { height: auto; }
  .mk-pin-stage { position: relative; height: auto; min-height: 100vh; }
  .mk-layer { position: relative; transform: none !important; }
  .mk-zoomout, .mk-tilt-scroll, .mk-seq > *, .mk-statement, .mk-hscroll-track { transform: none !important; opacity: 1 !important; filter: none !important; }
  .mk-wipe { clip-path: none !important; }
  .mk-hscroll { overflow-x: auto; }
  /* La película se despliega como documento normal: shots apilados, todo visible */
  .mk-rail { display: none; }
  .mk-film { height: auto; }
  .mk-film-stage { position: relative; height: auto; overflow: visible; }
  .mk-shot, .mk-zshot { position: relative; inset: auto; min-height: 60vh; opacity: 1 !important; transform: none !important; pointer-events: auto; }
  .mk-zfog::after, .mk-zbg::before, .mk-dust { display: none !important; }
  .mk-zbg { opacity: 1 !important; }
}
