/* ============================================================
   JW EN VIVO — SISTEMA DE MOVIMIENTO (revisión senior 2026-07-19)
   Capa de movimiento premium. Aditiva y opt-in: nada se mueve sin
   body.jv / body.jv-login, y TODO el movimiento vive dentro de
   @media (prefers-reduced-motion: no-preference).
   Reglas de oro: solo se anima transform y opacity; sin propiedades
   que provoquen reflow; sin librerías; sin layout shift; el contenido
   es visible aunque el CSS/JS falle (los estados ocultos iniciales de
   revelado se activan solo cuando motion.js añade body.jv-motion).
   Fuente de verdad: docs/diseno/08-sistema-movimiento.md.
   ============================================================ */

/* ============================================================
   1) LOGIN — entrada escalonada + fondo tecnológico sutil
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {

  /* Cascada breve dentro del panel ya asentado (login-premium.css anima .login-box).
     Los hijos entran con retardo creciente: icono → título → campos → botón. */
  body.jv-login .page-icon,
  body.jv-login .form h2,
  body.jv-login .form .inputBox,
  body.jv-login .form .botones_login,
  body.jv-login .admin-login-error {
    animation: jv-rise-in var(--jv-motion-dur-3) var(--jv-motion-ease-entrance) backwards;
  }
  body.jv-login .page-icon { animation-delay: 90ms; }
  body.jv-login .form h2 { animation-delay: 150ms; }
  body.jv-login .form .inputBox { animation-delay: 210ms; }
  body.jv-login .form .inputBox + .inputBox { animation-delay: 260ms; }
  body.jv-login .form .botones_login { animation-delay: 320ms; }

  /* Fondo: respiración muy tenue del halo tras el panel (no intensa, baja amplitud). */
  body.jv-login .box::before {
    animation: jv-halo-breathe 9s ease-in-out infinite alternate;
    will-change: opacity, transform;
  }
  @keyframes jv-halo-breathe {
    from { opacity: 0.82; transform: scale(0.98); }
    to   { opacity: 1;    transform: scale(1.02); }
  }
}

/* ============================================================
   2) INTERIOR — entrada única de barra y encabezado (CSS, sin JS)
   Solo superficies grandes de una-por-página. Nunca filas de tabla.
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  body.jv .navbar,
  body.jv .navbar-fixed-top,
  body.jv-pub .menu {
    animation: jv-fade-down var(--jv-motion-dur-3) var(--jv-motion-ease-entrance) backwards;
  }
  body.jv .subnavbar { animation: jv-fade-down var(--jv-motion-dur-3) var(--jv-motion-ease-entrance) 40ms backwards; }
  body.jv h1 { animation: jv-rise-in var(--jv-motion-dur-3) var(--jv-motion-ease-entrance) 80ms backwards; }
}

/* ============================================================
   3) REVELADO AL HACER SCROLL (impulsado por motion.js + IntersectionObserver)
   Los estados ocultos solo aplican cuando motion.js confirma soporte y
   añade body.jv-motion: si el JS no corre, el contenido queda visible.
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  body.jv.jv-motion [data-jv-reveal] {
    opacity: 0;
    transform: translateY(var(--jv-motion-rise));
    transition: opacity var(--jv-motion-dur-3) var(--jv-motion-ease-entrance),
                transform var(--jv-motion-dur-3) var(--jv-motion-ease-entrance);
    transition-delay: calc(var(--jv-i, 0) * var(--jv-motion-stagger));
    will-change: opacity, transform;
  }
  body.jv.jv-motion [data-jv-reveal].is-in {
    opacity: 1;
    transform: none;
  }
}

/* ============================================================
   4) MICROINTERACCIONES — botones, tarjetas, iconos (hover/active/focus)
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  /* Pulsación de botones: respuesta física breve. */
  body.jv .btn,
  body.jv-pub .btn,
  body.jv button {
    transition: transform var(--jv-motion-dur-1) var(--jv-motion-ease-standard),
                box-shadow var(--jv-motion-dur-2) var(--jv-motion-ease-standard),
                background-color var(--jv-motion-dur-2) var(--jv-motion-ease-standard),
                border-color var(--jv-motion-dur-2) var(--jv-motion-ease-standard);
  }
  body.jv .btn:active,
  body.jv button:active { transform: scale(var(--jv-motion-press)); }

  /* Elevación al pasar por tarjetas/paneles operativos (opt-in .jv-lift + superficies conocidas). */
  body.jv .jv-lift,
  body.jv-admin .number-card,
  body.jv-admin .note-card,
  body.jv-admin .companies-card,
  body.jv-pub .panel,
  body.jv-pub .card {
    transition: transform var(--jv-motion-dur-2) var(--jv-motion-ease-standard),
                box-shadow var(--jv-motion-dur-2) var(--jv-motion-ease-standard);
  }
  body.jv .jv-lift:hover,
  body.jv-admin .number-card:hover,
  body.jv-admin .note-card:hover,
  body.jv-admin .companies-card:hover,
  body.jv-pub .panel:hover,
  body.jv-pub .card:hover {
    transform: translateY(-2px);
  }

  /* Microinteracción de iconos dentro de acciones. */
  body.jv .btn i,
  body.jv-pub .menu ul li a i {
    transition: transform var(--jv-motion-dur-2) var(--jv-motion-ease-spring);
  }
  body.jv .btn:hover i { transform: scale(1.08); }
}

/* ============================================================
   5) MODALES — apertura/cierre refinados (Bootstrap 3 .modal)
   Los diálogos de SweetAlert conservan su propia animación.
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  body.jv .modal.fade .modal-dialog {
    transform: translateY(8px) scale(0.985);
    opacity: 0;
    transition: transform var(--jv-motion-dur-4) var(--jv-motion-ease-entrance),
                opacity var(--jv-motion-dur-4) var(--jv-motion-ease-entrance);
    will-change: transform, opacity;
  }
  body.jv .modal.fade.in .modal-dialog {
    transform: none;
    opacity: 1;
  }
}

/* ============================================================
   6) ESTADOS AJAX / CARGA — pulso y giro discretos (utilidades)
   ============================================================ */
@media (prefers-reduced-motion: no-preference) {
  body.jv .jv-busy { animation: jv-pulse 1.1s ease-in-out infinite; }
  @keyframes jv-pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.55; } }

  body.jv .jv-spin { animation: jv-spin 0.8s linear infinite; transform-origin: center; }
  @keyframes jv-spin { to { transform: rotate(360deg); } }

  /* Aparición breve de bloques inyectados por AJAX (opt-in). */
  body.jv .jv-appear { animation: jv-rise-in var(--jv-motion-dur-3) var(--jv-motion-ease-entrance) backwards; }
}

/* ============================================================
   Keyframes compartidos
   ============================================================ */
@keyframes jv-rise-in {
  from { opacity: 0; transform: translateY(var(--jv-motion-rise)); }
  to   { opacity: 1; transform: none; }
}
@keyframes jv-fade-down {
  from { opacity: 0; transform: translateY(calc(-1 * var(--jv-motion-rise))); }
  to   { opacity: 1; transform: none; }
}

/* ============================================================
   7) MOVIMIENTO REDUCIDO — anulación defensiva total
   (además de que casi todo vive bajo no-preference)
   ============================================================ */
@media (prefers-reduced-motion: reduce) {
  body.jv [data-jv-reveal],
  body.jv.jv-motion [data-jv-reveal] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
  body.jv *, body.jv *::before, body.jv *::after,
  body.jv-login *, body.jv-login *::before, body.jv-login *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
