/* TIC2026 transitions — RUTA 2.0 ronda t4 — 2026-07-14
 * CAMBIO t3: el motor PRINCIPAL que ve el usuario son ahora las transiciones JS
 * GARANTIZADAS de la Seccion 5 (body.tdc-exit / html.tdc-enter), disparadas por
 * motion.js en TODOS los navegadores. La VT nativa cross-document de abajo queda como
 * MEJORA PROGRESIVA (sobre todo el morph): se comprobo empiricamente que se crea pero es
 * imperceptible/skipped en el sitio real, y que el no-store NO la desactiva. Historico:
 * View Transitions CROSS-DOCUMENT con lenguaje "RODADA", coreografia INCONFUNDIBLE
 * al estilo del mockup (mockup-4-ruta2.html): estiron de salida (arrancada) + barrido
 * diagonal de entrada con BORDE-ACENTO visible + asentamiento con leve overshoot, mientras
 * la CABECERA permanece fija (continuidad espacial). Ademas: MORPH de la imagen de la card
 * a la portada de la ficha (la "joya" del mockup) via view-transition-name compartido
 * (tic-pimg, asignado por JS). Y un FALLBACK universal (clases .tdc-leg-*) para navegadores
 * SIN cross-document VT (Firefox / Chrome viejos), activado solo por JS.
 *
 * DIAGNOSTICO r3->r4: la transicion r3 SI disparaba (pagereveal.viewTransition=1, navType
 * push, confirmado en vivo) y la pagina renderiza rapido (FCP ~700ms << 4s, sin skip). El
 * usuario no la percibia porque la coreografia era demasiado sutil: saliente -6% + blur6 +
 * fade a .35, entrante en 460ms sobre paginas de fondo casi identico => un "flash" diagonal
 * imperceptible. r4 sube la amplitud y duracion (460/540ms), oscurece/aleja mas el saliente,
 * y anade un borde-acento que barre => evento visual claro.
 *
 * REALCE PROGRESIVO / seguridad:
 *   - Navegadores sin soporte ignoran @view-transition y ::view-transition-* => cero efecto.
 *   - Solo transform / opacity / filter / clip-path (compositor).
 *   - reduced-motion NEUTRALIZADO por decision explicita del usuario (gate min-width:99999px:
 *     la regla nunca aplica; los efectos deben verse siempre). NO restaurar.
 *   - Las navegaciones AJAX (buscadorkits, PS) no son navegaciones de documento => no disparan.
 */

/* ============================================================
   1. Activacion cross-document — DESACTIVADA en t3 (navigation:none).
      MOTIVO (empirico): en el sitio real la VT nativa cross-document SE CREA pero se
      DESCARTA en la pagina entrante (imperceptible: ni barrido ni morph), y ese descarte
      emite "Uncaught (in promise)" en consola en CADA navegacion por click (el ready de la
      VT auto rechaza sin handler fiable — pagereveal no siempre dispara). No aporta nada
      visible y solo mete ruido/errores. Las transiciones que VE el usuario son las JS de
      la Seccion 5 (body.tdc-exit / html.tdc-enter). Toda la maquinaria de morph/wipe de
      abajo (Secc. 2-4) se conserva INERTE y re-activable: si algun dia se corrige el skip
      (p.ej. nombre view-transition-name duplicado), basta volver a poner navigation:auto.
   ============================================================ */
@view-transition { navigation: none; }

/* ============================================================
   2. Continuidad de cabecera (ley 4): la cabecera es su propio snapshot
      => sale del root => NO parpadea; como su caja es identica entre paginas,
      el grupo apenas se mueve => cabecera "clavada" mientras el cuerpo barre.
   ============================================================ */
@supports (view-transition-name: none) {
  header#header { view-transition-name: tic-header; }
  ::view-transition-group(tic-header) {
    animation-duration: var(--d-base, 320ms);
    animation-timing-function: var(--e-out, cubic-bezier(0.16, 1, 0.3, 1));
    z-index: 30; /* siempre por encima del barrido del cuerpo y de la imagen que viaja */
  }
}

/* ============================================================
   3. RODADA — direccion "hacia adelante" (rodar) por defecto.
      SALIENTE: carga peso y ARRANCA: se aleja a la izquierda, reduce, se
                desenfoca y se oscurece (deja sitio; nunca "blanco").
      ENTRANTE: BARRIDO diagonal desde la derecha con borde-acento + un leve
                empuje que ASIENTA con micro-overshoot (llega y se acomoda).
   ============================================================ */

/* -- saliente adelante: estiron + alejamiento + desenfoque + oscurecido -- */
@keyframes tdc-old-fwd {
  0%   { transform: translateX(0)     scale(1);    filter: blur(0)    brightness(1);   opacity: 1; }
  100% { transform: translateX(-22%)  scale(0.90); filter: blur(8px)  brightness(0.72); opacity: .28; }
}
/* -- entrante adelante: barrido diagonal (clip) + deslizamiento con asentamiento -- */
@keyframes tdc-new-clip-fwd {
  0%   { clip-path: polygon(100% 0, 132% 0, 132% 100%, 58% 100%); }
  100% { clip-path: polygon(-45% 0, 132% 0, 132% 100%, -45% 100%); }
}
@keyframes tdc-new-slide-fwd {
  0%   { transform: translateX(9%)  scale(1.03); filter: blur(5px) drop-shadow(-18px 0 14px var(--accent, #e40046)); }
  62%  {                                          filter: blur(0)   drop-shadow(-6px 0 8px color-mix(in srgb, var(--accent, #e40046) 45%, transparent)); }
  100% { transform: translateX(0)   scale(1);    filter: blur(0)   drop-shadow(0 0 0 transparent); }
}

/* -- direccion "hacia atras" (traverse): espejo en X -- */
@keyframes tdc-old-back {
  0%   { transform: translateX(0)    scale(1);    filter: blur(0)   brightness(1);    opacity: 1; }
  100% { transform: translateX(22%)  scale(0.90); filter: blur(8px) brightness(0.72); opacity: .28; }
}
@keyframes tdc-new-clip-back {
  0%   { clip-path: polygon(-32% 0, 0 0, 42% 100%, -32% 100%); }
  100% { clip-path: polygon(-32% 0, 145% 0, 145% 100%, -32% 100%); }
}
@keyframes tdc-new-slide-back {
  0%   { transform: translateX(-9%) scale(1.03); filter: blur(5px) drop-shadow(18px 0 14px var(--accent, #e40046)); }
  62%  {                                          filter: blur(0)   drop-shadow(6px 0 8px color-mix(in srgb, var(--accent, #e40046) 45%, transparent)); }
  100% { transform: translateX(0)   scale(1);    filter: blur(0)   drop-shadow(0 0 0 transparent); }
}

/* --- aplicacion por defecto (adelante) --- */
::view-transition-old(root) {
  animation: tdc-old-fwd 460ms var(--e-travel, cubic-bezier(0.83, 0, 0.17, 1)) both;
  transform-origin: 50% 50%;
  z-index: 1;
}
::view-transition-new(root) {
  animation: tdc-new-clip-fwd 500ms var(--e-out, cubic-bezier(0.16, 1, 0.3, 1)) both,
             tdc-new-slide-fwd 560ms var(--e-settle, cubic-bezier(0.22, 1.2, 0.36, 1)) both;
  transform-origin: 50% 50%;
  z-index: 2; /* el entrante barre POR ENCIMA del saliente que se aleja */
}

/* --- override direccional (atras) cuando motion.js marca la navegacion --- */
:root[data-tdc-nav="back"]::view-transition-old(root) {
  animation: tdc-old-back 460ms var(--e-travel, cubic-bezier(0.83, 0, 0.17, 1)) both;
}
:root[data-tdc-nav="back"]::view-transition-new(root) {
  animation: tdc-new-clip-back 500ms var(--e-out, cubic-bezier(0.16, 1, 0.3, 1)) both,
             tdc-new-slide-back 560ms var(--e-settle, cubic-bezier(0.22, 1.2, 0.36, 1)) both;
}

/* ============================================================
   4. MORPH de imagen card -> ficha (la joya). El nombre tic-pimg lo asigna
      motion.js: en el documento SALIENTE a la imagen de LA card pulsada, y en
      el ENTRANTE (ficha) a la portada de la galeria. El navegador interpola la
      caja (pequena -> grande) con curva de viaje + leve banking. La imagen viaja
      POR DEBAJO de la cabecera (z-index 30) pero POR ENCIMA del barrido del cuerpo.
   ============================================================ */
@supports (view-transition-name: none) {
  ::view-transition-group(tic-pimg) {
    animation-duration: 560ms;
    animation-timing-function: var(--e-travel, cubic-bezier(0.83, 0, 0.17, 1));
    z-index: 20;
  }
  /* las dos imagenes son la MISMA foto: sin cross-fade que ensucie el morph */
  ::view-transition-image-pair(tic-pimg) {
    animation-duration: 560ms;
    animation-timing-function: var(--e-travel, cubic-bezier(0.83, 0, 0.17, 1));
  }
  ::view-transition-old(tic-pimg) { animation: none; opacity: 1; }
  ::view-transition-new(tic-pimg) { animation: none; opacity: 1; }
}

/* ============================================================
   5. TRANSICIONES GARANTIZADAS POR JS (universales, TODOS los navegadores) — t3.
      Este es el motor REAL que percibe el usuario. HALLAZGO t3 (empirico en Chrome):
      la VT nativa cross-document SI se crea en el sitio real (pageswap.viewTransition
      = objeto) pero es IMPERCEPTIBLE / se descarta en la pagina entrante; y el no-store
      NO la desactiva (test aislado .html sin no-store vs .php con no-store: ambas
      corrieron la VT). Por eso NO dependemos de la VT nativa: motion.js dispara estas
      dos animaciones SIEMPRE (la VT nativa queda como mejora progresiva del morph).
        - SALIDA (body.tdc-exit, 620ms decelerante SOSTENIDA — t4): al pulsar un enlace
          interno motion.js navega YA (1-2 frames) y la pagina se retira al fondo DURANTE
          la espera de red, quedando recedida (fill forwards) hasta el mismo frame del
          swap. Sin hueco muerto ni pop-back. motion.js excluye #, flujos AJAX de
          buscadorkits, add-to-cart, descargas y destinos _blank.
        - ENTRADA (html.tdc-enter, ~330ms "rodada"): el contenido entra con
          desplazamiento + desenfoque que se ASIENTA con micro-overshoot. motion.js la
          aplica antes del primer paint. Estado por defecto (sin clase) = TODO VISIBLE
          (jamas opacity:0 permanente); salvaguarda JS la retira pase lo que pase a los
          800ms. Overflow-safe: solo transform/opacity/filter, scale<=1, sin desbordes.
   ============================================================ */
/* t4 (feedback usuario con video): la salida NO es un evento previo a la navegacion sino
   el estado en que la pagina vieja ESPERA el swap. motion.js navega INMEDIATAMENTE (~1-2
   frames tras el click) y esta animacion corre DURANTE la espera de red: curva decelerante
   larga hacia un estado final SOSTENIDO (fill-mode forwards — JAMAS se retira la clase antes
   del unload; solo pageshow la limpia). Si la red tarda mas que la animacion, la pagina
   descansa recedida hasta el swap; si es rapida, el swap cae a mitad del fundido. El estado
   recedido "se retira al fondo" (oscurecido brightness .85, opacity .55, blur 2.5px, scale
   .985) — nunca lavado a blanco ni borrado. */
@keyframes tdc-exit-kf {
  0%   { opacity: 1;   transform: translate3d(0,0,0)    scale(1);     filter: blur(0)      brightness(1); }
  100% { opacity: .55; transform: translate3d(0,-6px,0) scale(0.985); filter: blur(2.5px)  brightness(0.85); }
}
@keyframes tdc-enter-kf {
  0%   { opacity: 0;   transform: translate3d(0,16px,0)  scale(0.992); filter: blur(9px); }
  58%  { opacity: 1;                                                    filter: blur(0); }
  82%  {               transform: translate3d(0,-2px,0)  scale(1); }
  100% { opacity: 1;   transform: translate3d(0,0,0)     scale(1);     filter: blur(0); }
}
body.tdc-exit {
  animation: tdc-exit-kf 620ms var(--e-out, cubic-bezier(0.16, 1, 0.3, 1)) forwards;
  pointer-events: none; /* la pagina esta de salida: sin hovers/clicks fantasma */
  will-change: transform, opacity, filter;
}
html.tdc-enter {
  animation: tdc-enter-kf 330ms var(--e-settle, cubic-bezier(0.22, 1.2, 0.36, 1)) both;
  will-change: transform, opacity, filter;
}

/* ============================================================
   6. Slow-mo de QA (opt-in): motion.js pone html[data-tdc-vtslow] si existe la
      flag sessionStorage.__tdcVtSlow. Ralentiza TODAS las animaciones VT para
      poder capturar fotogramas. Inerte en produccion (atributo ausente).
   ============================================================ */
html[data-tdc-vtslow]::view-transition-old(root),
html[data-tdc-vtslow]::view-transition-new(root),
html[data-tdc-vtslow]::view-transition-group(tic-header),
html[data-tdc-vtslow]::view-transition-group(tic-pimg),
html[data-tdc-vtslow]::view-transition-image-pair(tic-pimg) {
  animation-duration: 3400ms !important;
}
/* mismo slow-mo para las transiciones JS garantizadas (solo alarga la DURACION de las
   animaciones para capturar fotogramas; la navegacion es inmediata igual — t4). */
html[data-tdc-vtslow].tdc-enter { animation-duration: 2400ms !important; }
html[data-tdc-vtslow] body.tdc-exit { animation-duration: 3000ms !important; }

/* ============================================================
   7. reduced-motion: fundido corto. NEUTRALIZADO (gate min-width:99999px:
      no aplica jamas). Decision explicita del usuario. NO restaurar el gate.
   ============================================================ */
@keyframes tdc-ro-out { to   { opacity: 0; } }
@keyframes tdc-ro-in  { from { opacity: 0; } }

@media (prefers-reduced-motion: reduce) and (min-width: 99999px) {
  ::view-transition-old(root),
  :root[data-tdc-nav]::view-transition-old(root) {
    animation: tdc-ro-out 110ms linear both;
    filter: none; transform: none; clip-path: none;
  }
  ::view-transition-new(root),
  :root[data-tdc-nav]::view-transition-new(root) {
    animation: tdc-ro-in 110ms linear both;
    filter: none; transform: none; clip-path: none;
  }
  ::view-transition-group(tic-header) { animation-duration: 1ms; }
}
