/* ============================================================================
   SFV · CAPA DE MOVIMIENTO (17-sep-2026) — «placas con iconos animados, botones con
   efectos, el menú, el login: sorpréndeme»

   El usuario pidió Remotion. Remotion renderiza VÍDEO con React; el CRM son páginas HTML
   estáticas y aquí el movimiento vive en CSS (y un poco de JS para contar cifras y el
   ripple de los botones): pesa cero, corre en el teléfono, y se apaga solo con «reducir
   movimiento» del sistema (regla global en sfv-components.css).

   Tres reglas, para que sea chic y no una feria:
     1. El movimiento INFORMA: una cifra que sube, un icono que responde al puntero, una
        sección que entra. Nada se mueve solo en bucle salvo dos guiños suaves (el logo del
        login y el anillo de WhatsApp cuando hay clientes esperando).
     2. Duraciones cortas y una sola curva (--sfv-dur-1/2/3, --sfv-ease).
     3. Todo tiene versión sin movimiento idéntica en información.
   ============================================================================ */

/* ---------- Curvas y duraciones (por si la página no carga crm.css primero) ---------- */
:root {
  --sfv-ease-out: cubic-bezier(.16, 1, .3, 1);      /* llega rápido, frena suave */
  --sfv-ease-back: cubic-bezier(.34, 1.56, .64, 1);  /* pasa de largo un pelo y vuelve */
}

/* ---------- ICONOS: UN SOLO GESTO, SOBRIO ----------
   La primera versión daba a cada icono su propio gesto (el trofeo saltaba, la mano
   saludaba, WhatsApp vibraba con un anillo…) y el usuario lo vio cargado: «trabaja a todos
   en un solo estilo, sobrio, elegante, corporativo». Así que TODOS los iconos del CRM hacen
   lo mismo: se elevan apenas y crecen un 6 %, y vuelven. Es el mismo gesto que llevan los
   vídeos Remotion de las placas (sfvIconosAnimar), para que en Safari o sin vídeo se vea
   igual. Sin rebotes, sin giros, sin anillos. */
@keyframes sfvIconoSobrio { 0% { transform: translateY(0) scale(1); } 38% { transform: translateY(-.05em) scale(1.06); } 100% { transform: translateY(0) scale(1); } }
.sfv-pico i, .sfv-kpi-icon i, .sfv-sec-head .sfv-pico i, .sfv-sidebar a[data-nav] i, .sfv-tbtn i, .sfv-btn > i.fa, .cfg-tab i, .sfv-empty-ico i {
  display: inline-block; transition: transform var(--sfv-dur-2, .22s) var(--sfv-ease-out);
}
/* El <i> de la calculadora ES la caja (display: grid; place-items: center en crm.css): no se
   le cambia el display, o el glifo se va arriba de su recuadro (captura del iPhone). */
.calc-mode > i { transition: transform var(--sfv-dur-2, .22s) var(--sfv-ease-out); }
.sfv-kpi:hover .sfv-pico i, .dash-kpi:hover .sfv-pico i, .sfv-kpi:hover .sfv-kpi-icon i,
.sfv-card:hover .sfv-sec-head .sfv-pico i, .sfv-mini-card:hover .sfv-sec-head .sfv-pico i, .calc-mode:hover > i,
.sfv-sidebar a[data-nav]:hover i, .sfv-tbtn:hover i, .sfv-btn:hover > i.fa, .cfg-tab:hover i {
  animation: sfvIconoSobrio 1.2s cubic-bezier(.45, 0, .2, 1);
}
/* Las placas responden como conjunto: la sombra crece y un brillo suave cruza la tarjeta.
   Nada se alza (el usuario lo quitó, 18-sep-2026). Es el único adorno, y es el mismo en todas. */
.sfv-kpi .sfv-pico, .dash-kpi .sfv-pico, .sfv-kpi .sfv-kpi-icon { transition: transform var(--sfv-dur-2, .22s) var(--sfv-ease-out), box-shadow var(--sfv-dur-2, .22s); }
.sfv-kpi:hover .sfv-pico, .dash-kpi:hover .sfv-pico, .sfv-kpi:hover .sfv-kpi-icon { box-shadow: 0 10px 20px rgba(16,32,26,.22); }   /* la placa no se alza: solo la sombra */
.sfv-kpi, .dash-kpi { position: relative; overflow: hidden; }
.sfv-kpi::after, .dash-kpi::after {
  content: ''; position: absolute; top: -40%; bottom: -40%; left: -60%; width: 45%;
  background: linear-gradient(105deg, rgba(255,255,255,0) 0%, rgba(255,255,255,.45) 50%, rgba(255,255,255,0) 100%);
  transform: skewX(-18deg) translateX(-120%); pointer-events: none; opacity: 0;
}
.sfv-kpi:hover::after, .dash-kpi:hover::after { animation: sfvBrillo .9s var(--sfv-ease-out) forwards; }
@keyframes sfvBrillo { 0% { transform: skewX(-18deg) translateX(-120%); opacity: 0; } 15% { opacity: 1; } 100% { transform: skewX(-18deg) translateX(420%); opacity: 0; } }
body.sfv-dark .sfv-kpi::after, body.sfv-dark .dash-kpi::after { background: linear-gradient(105deg, rgba(255,255,255,0) 0%, rgba(255,255,255,.14) 50%, rgba(255,255,255,0) 100%); }
/* La cifra sube desde cero al aparecer (sfvMotionContar en app.js) y late al cambiar. */
.sfv-kpi-value, .dash-kpi-val { font-variant-numeric: tabular-nums; }
.sfv-contando { color: var(--sfv-mint-dark, #0e8043); }

/* ---------- BOTONES ---------- */
.sfv-btn { position: relative; overflow: hidden; transition: transform var(--sfv-dur-2, .22s) var(--sfv-ease-out), box-shadow var(--sfv-dur-2, .22s), background var(--sfv-dur-2, .22s), border-color var(--sfv-dur-2, .22s), filter var(--sfv-dur-2, .22s); }
.sfv-btn:active { transform: translateY(0) scale(.97); }
/* Ripple al pulsar (lo crea sfvMotionRipple en app.js). */
.sfv-ripple { position: absolute; border-radius: 999px; transform: scale(0); pointer-events: none; background: rgba(255,255,255,.45); animation: sfvRipple .55s var(--sfv-ease-out) forwards; }
.sfv-btn.secondary .sfv-ripple, .sfv-btn.ghost .sfv-ripple, .sfv-btn.danger-ghost .sfv-ripple { background: rgba(31,176,88,.22); }
@keyframes sfvRipple { to { transform: scale(2.6); opacity: 0; } }
/* Brillo en el botón principal al pasar el puntero. */
.sfv-btn:not(.secondary):not(.ghost):not(.danger-ghost)::before {
  content: ''; position: absolute; top: -50%; bottom: -50%; left: -70%; width: 40%;
  background: linear-gradient(105deg, rgba(255,255,255,0), rgba(255,255,255,.35), rgba(255,255,255,0));
  transform: skewX(-20deg) translateX(-140%); pointer-events: none; opacity: 0;
}
.sfv-btn:not(.secondary):not(.ghost):not(.danger-ghost):hover::before { animation: sfvBrillo .8s var(--sfv-ease-out) forwards; }
/* ---------- MENÚ LATERAL ----------
   SIN entrada en cascada: cada pantalla es una página y el menú se vuelve a pintar en cada
   navegación; con la cascada, el usuario lo veía «temblar» y «reiniciarse» a cada clic
   (18-sep-2026). El menú aparece quieto; solo responde al puntero (sfv-web.css). */
.sfv-sidebar a[data-nav] { transition: background var(--sfv-dur-2, .22s), color var(--sfv-dur-2, .22s); }

/* ---------- LOGIN ---------- */
/* login.html ya trae su propia entrada de la tarjeta (sfvCardIn) y el hover del botón en su
   <style> en línea, que gana por venir después: acá solo se suma lo que le falta. */
@keyframes sfvFlota { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-4px); } }
.login-card > img, .login-card > .sfv-logo { animation: sfvFlota 5s ease-in-out 1s infinite; }
.login-card .login-field input { transition: border-color .15s, box-shadow .15s, background .15s, transform var(--sfv-dur-2, .22s); }
.login-card .login-field input:focus { transform: translateY(-1px); }
.login-btn { position: relative; overflow: hidden; }
.login-btn::before { content: ''; position: absolute; top: -50%; bottom: -50%; left: -70%; width: 40%; background: linear-gradient(105deg, rgba(255,255,255,0), rgba(255,255,255,.35), rgba(255,255,255,0)); transform: skewX(-20deg) translateX(-140%); pointer-events: none; opacity: 0; }
.login-btn:hover:not(:disabled)::before { animation: sfvBrillo .8s var(--sfv-ease-out) forwards; }

/* ---------- PANTALLAS: títulos, tarjetas, badges ---------- */
/* (El subrayado del título ya no se dibuja al cargar: junto con las demás entradas hacía
   «temblar» la pantalla en cada navegación, 18-sep-2026.) */
.sfv-card { transition: transform var(--sfv-dur-2, .22s) var(--sfv-ease-out), box-shadow var(--sfv-dur-2, .22s); }
/* (La insignia ya no crece al pasar por su fila: nada se alza ni se agranda al pasar el cursor.) */
/* (La fila de totales y el punto del semáforo ya no «entran»: nada se mueve al cargar.) */
/* Aurelion: el botón flotante respira al pasar el puntero. */
.sfv-fab:hover, .aur-fab:hover { transform: scale(1.06); }

/* ---------- ICONOS ANIMADOS CON REMOTION (sfvIconosAnimar en app.js) ----------
   El vídeo mide 2em × 2em (el glifo ocupa el em central, como el <i>) y se centra sobre la
   placa; aparece solo cuando cargó (.sfv-anim-lista) y entonces el <i> se apaga: en reposo
   son la misma imagen, así que el cambio no se ve. */
.sfv-kpi-icon, .calc-mode > i.fa { position: relative; }
video.sfv-ico-anim {
  position: absolute; left: 50%; top: 50%; width: 2em; height: 2em; transform: translate(-50%, -50%);
  pointer-events: none; opacity: 0; transition: opacity .25s; z-index: 1; background: transparent;
}
.sfv-anim-lista > video.sfv-ico-anim { opacity: 1; }
/* EL ICONO SE APAGA SOLO CUANDO HAY UN VÍDEO ENCIMA QUE DE VERDAD SE VE. `.sfv-anim-lista` la
   pone el propio vídeo al cargar; si no carga, el icono se queda donde estaba. En el menú ya
   no se ponen vídeos (ver SFV_ICONOS_ANIM_SEL en app.js): se repintaba en cada navegación y
   dejaba quince recuadros vacíos mientras tanto. */
.sfv-anim-lista > i.fa { opacity: 0; }                 /* la placa contiene al <i>: se apaga el <i> */
i.fa.sfv-anim-lista::before { visibility: hidden; }    /* el <i> ES la placa: se apaga solo su glifo */
/* Red de seguridad: en el menú, el glifo NO se apaga nunca, haya pasado lo que haya pasado. */
.sfv-nav a > i.fa, .sfv-mod > i.sfv-mod-ico { opacity: 1 !important; }
.sfv-nav a > i.fa::before, .sfv-mod > i.sfv-mod-ico::before { visibility: visible !important; }

/* ---------- REDUCIR MOVIMIENTO ----------
   La regla global (sfv-components.css) acorta toda animación a .001ms: para lo que entra
   una vez es como no animar, pero un bucle «infinite» a esa duración parpadea. Los dos
   bucles y los adornos puros se apagan del todo; la información no cambia. */
@media (prefers-reduced-motion: reduce) {
  .login-card > img, .login-card > .sfv-logo { animation: none !important; }
  .sfv-kpi::after, .dash-kpi::after, .sfv-btn::before, .login-btn::before, .sfv-ripple { display: none !important; }
}
