/* Movimiento de la vista General (transitions.dev): menús que crecen desde su botón, ventanas que suben con escala
   suave, cifras que se cruzan difuminadas al actualizarse y filas con hover suave. Nada de esto mueve el tablero:
   sólo anima lo que se abre o lo que cambió. Todo se apaga con «reducir movimiento». */
:root {
  --dropdown-open-dur: 250ms;
  --dropdown-close-dur: 150ms;
  --dropdown-pre-scale: 0.97;
  --dropdown-closing-scale: 0.99;
  --dropdown-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --modal-open-dur: 250ms;
  --modal-close-dur: 150ms;
  --modal-scale: 0.96;
  --modal-scale-close: 0.96;
  --modal-ease: cubic-bezier(0.22, 1, 0.36, 1);
  --text-soft-dur: 200ms;
  --text-soft-blur: 2px;
  --text-soft-ease: ease-in-out;
  --text-soft-resize-dur: 240ms;
  --text-soft-resize-ease: cubic-bezier(0.22, 1, 0.36, 1);
}

/* Menu dropdown (05). */
.t-dropdown {
  transform-origin: top left;
  transform: scale(var(--dropdown-pre-scale));
  opacity: 0;
  pointer-events: none;
  transition:
    transform var(--dropdown-open-dur) var(--dropdown-ease),
    opacity   var(--dropdown-open-dur) var(--dropdown-ease);
  will-change: transform, opacity;
}
.t-dropdown[data-origin="top-right"]     { transform-origin: top right; }
.t-dropdown[data-origin="top-center"]    { transform-origin: top center; }
.t-dropdown[data-origin="bottom-left"]   { transform-origin: bottom left; }
.t-dropdown[data-origin="bottom-center"] { transform-origin: bottom center; }
.t-dropdown[data-origin="bottom-right"]  { transform-origin: bottom right; }

.t-dropdown.is-open {
  transform: scale(1);
  opacity: 1;
  pointer-events: auto;
}
.t-dropdown.is-closing {
  transform: scale(var(--dropdown-closing-scale));
  opacity: 0;
  pointer-events: none;
  transition:
    transform var(--dropdown-close-dur) var(--dropdown-ease),
    opacity   var(--dropdown-close-dur) var(--dropdown-ease);
}

@media (prefers-reduced-motion: reduce) {
  .t-dropdown { transition: none !important; }
}

/* Modal open / close (06). */
.t-modal {
  transform-origin: center;
  transform: scale(var(--modal-scale));
  opacity: 0;
  pointer-events: none;
  transition:
    transform var(--modal-open-dur) var(--modal-ease),
    opacity   var(--modal-open-dur) var(--modal-ease);
  will-change: transform, opacity;
}
.t-modal.is-open {
  transform: scale(1);
  opacity: 1;
  pointer-events: auto;
}
.t-modal.is-closing {
  transform: scale(var(--modal-scale-close));
  opacity: 0;
  pointer-events: none;
  transition:
    transform var(--modal-close-dur) var(--modal-ease),
    opacity   var(--modal-close-dur) var(--modal-ease);
}

@media (prefers-reduced-motion: reduce) {
  .t-modal { transition: none !important; }
}

/* Text swap soft (34). */
.t-text-soft {
  display: inline-grid;
  justify-items: var(--text-soft-align, start);
  transition: width var(--text-soft-resize-dur) var(--text-soft-resize-ease);
}
.t-text-soft > span {
  grid-area: 1 / 1;
  white-space: pre;
  transition:
    filter  var(--text-soft-dur) var(--text-soft-ease),
    opacity var(--text-soft-dur) var(--text-soft-ease);
}
.t-text-soft-new {
  opacity: 0;
  filter: blur(var(--text-soft-blur));
}
.t-text-soft.is-swapping .t-text-soft-old {
  opacity: 0;
  filter: blur(var(--text-soft-blur));
}
.t-text-soft.is-swapping .t-text-soft-new {
  opacity: 1;
  filter: blur(0);
}

@media (prefers-reduced-motion: reduce) {
  .t-text-soft,
  .t-text-soft > span { transition: none !important; }
}

/* Adaptación al tablero. Las ventanas ya no usan su entrada anterior (gen-modal-entra): ahora entran con .t-modal,
   y el fondo oscuro aparece y se va con la misma duración. */
body.modo-general .gen-det-ventana.t-modal, body.modo-general .gen-modal.t-modal { animation:none !important; }
body.modo-general .gen-det-capa, body.modo-general .gen-modal-fondo { transition:opacity var(--modal-open-dur) var(--modal-ease); }
body.modo-general .gen-det-capa.sp-entrando, body.modo-general .gen-modal-fondo.sp-entrando,
body.modo-general .gen-det-capa.sp-saliendo { opacity:0; }
body.modo-general .gen-det-capa.sp-saliendo { transition-duration:var(--modal-close-dur); }
/* El panel de periodo es un menú anclado a su botón: crece desde la esquina de arriba a la izquierda. */
body.modo-general .gen-modal-fondo.sp-pop .gen-modal.t-dropdown { animation:none !important; }
/* El menú se abre aunque tenga el atributo hidden mientras termina de cerrarse. */
body.modo-general #app-shell .t-dropdown.is-closing[hidden] { display:block !important; }

/* Hover de filas y botones: el fondo entra suave en lugar de saltar. */
body.modo-general #app-shell :is(.gen-top2 li > button, .gen-cat-tabla tr.gen-fila td, .gen-filas li > button, .gen-canal, .seg-filtros .chip, .sp-campo-btn, .sp-orden-btn, .gen-periodo-btn, .sp-campo-menu button, .sp-orden-menu button) {
  transition:background-color var(--duration-quick, 150ms) ease-out, color var(--duration-quick, 150ms) ease-out, box-shadow var(--duration-quick, 150ms) ease-out;
}
@media (prefers-reduced-motion: reduce) {
  body.modo-general .gen-det-capa, body.modo-general .gen-modal-fondo,
  body.modo-general #app-shell :is(.gen-top2 li > button, .gen-cat-tabla tr.gen-fila td, .gen-filas li > button, .gen-canal, .seg-filtros .chip, .sp-campo-btn, .sp-orden-btn, .gen-periodo-btn, .sp-campo-menu button, .sp-orden-menu button) { transition:none !important; }
}
/* La ventana del portal (producto o periodo) se queda invisible hasta que recibe su transición, para que no se vea
   un instante completa y luego vuelva a entrar. */
body.modo-general #gen-modal > .gen-modal:not(.t-dropdown):not(.t-modal) { opacity:0; }

/* Revisión del difuminado (impeccable + Taste, 2026-11-01). Se queda sólo donde explica algo: el cambio de una cifra
   que se actualiza (text swap soft, 2 px) y el vidrio del login. Se quita donde sólo decoraba o estorbaba:
   - Al cambiar de página, todo el contenido entraba desde un desenfoque de 10 px (y salía con 6 px): ahora es un
     fundido corto. Mismo nombre de animación, sin filtro.
   - Cada cifra aparecía desde un desenfoque de 14 px durante casi un segundo: el dato tardaba en leerse. Ahora se
     ve de inmediato, con un fundido de 0.2 s.
   - Al pasar el mouse por una tarjeta de cifras, las demás se desenfocaban y se apagaban: escondía datos. Ya no. */
@keyframes vt-entra { from { opacity:0; } }
@keyframes vt-sale { to { opacity:0; } }
@keyframes num-revela { from { opacity:0; } }
@keyframes tarjeta-revela { from { opacity:0; transform:translateY(4px); } }
#content.contenido-entra { animation-duration:.2s !important; }
.num-revela { animation-duration:.2s !important; animation-delay:0s !important; }
.tarjeta-revela { animation-duration:.25s !important; }
#content:has(.tarjeta-cifras:hover) .tarjeta-cifras:not(:hover):not(:has(:hover)) { filter:none !important; opacity:1 !important; }
