/* webfx — movimiento común de los sitios (/srv/lib/webfx).
   Todo va en :where() (especificidad 0): lo que cada sitio ya define, gana.
   Solo opacity/transform/scale; nada se anima con «reducir movimiento». */

:root { --fx-accent: #3b82f6; --fx-ease: cubic-bezier(.2, .7, .2, 1); }

@media (prefers-reduced-motion: no-preference) {

  /* Cambio de página dentro del mismo sitio: fundido corto en vez de parpadeo. */
  @view-transition { navigation: auto; }
  ::view-transition-old(root), ::view-transition-new(root) { animation-duration: .16s; }

  /* Pulsar: `scale` (no `transform`) para no pisar transforms del sitio. */
  :where(button, .btn, [role="button"], input[type="submit"], input[type="button"]) { transition: scale .12s var(--fx-ease); }
  :where(button, .btn, [role="button"], input[type="submit"], input[type="button"]):where(:not(:disabled)):active { scale: .96; }

  /* Entrada de filas/tarjetas (--i = posición, la pone fx.js). */
  :where(.fx-in) { animation: fx-in .3s var(--fx-ease) backwards; animation-delay: calc(var(--i, 0) * 26ms); }
  @keyframes fx-in { from { opacity: 0; transform: translateY(9px); } }

  /* Fila que acaba de llegar sola (sondeo): entra y destella. */
  :where(.fx-new) { animation: fx-in .35s var(--fx-ease) backwards, fx-glow 1.6s ease-out; }
  @keyframes fx-glow { from { box-shadow: inset 3px 0 0 var(--fx-accent), inset 0 0 0 999px color-mix(in srgb, var(--fx-accent) 16%, transparent); } }

  :where(.fx-pop) { animation: fx-pop .22s var(--fx-ease) backwards; }
  @keyframes fx-pop { from { opacity: 0; transform: translateY(10px) scale(.97); } }
  :where(.fx-fade) { animation: fx-fade .25s ease-out backwards; }
  @keyframes fx-fade { from { opacity: 0; } }

  :where(dialog[open]) { animation: fx-pop .22s var(--fx-ease); }
  :where(dialog[open])::backdrop { animation: fx-fade .2s ease-out; }

  /* Número que cambia. */
  :where(.fx-bump) { animation: fx-bump .4s var(--fx-ease); }
  @keyframes fx-bump { 35% { scale: 1.18; } }

  /* Error. */
  :where(.fx-shake) { animation: fx-shake .36s ease-in-out; }
  @keyframes fx-shake { 20%, 60% { translate: -5px 0; } 40%, 80% { translate: 5px 0; } }

  /* «Cargando…» escrito a mano: late en vez de quedarse quieto. */
  :where(.fx-wait) { animation: fx-wait 1.1s ease-in-out infinite alternate; }
  @keyframes fx-wait { from { opacity: .4; } to { opacity: 1; } }

  /* Esqueleto. */
  :where(.fx-skel)::after { animation: fx-skel 1.25s linear infinite; }
  @keyframes fx-skel { to { transform: translateX(100%); } }

  /* Imagen que aparece al terminar de cargar. */
  :where(img.fx-img) { opacity: 0; transition: opacity .35s ease-out; }
  :where(img.fx-img.fx-ok) { opacity: 1; }

  /* Palomita que se dibuja. */
  :where(.fx-check) circle { stroke-dasharray: 151; stroke-dashoffset: 151; animation: fx-draw .45s ease-out forwards; }
  :where(.fx-check) path { stroke-dasharray: 40; stroke-dashoffset: 40; animation: fx-draw .3s .35s ease-out forwards; }
  @keyframes fx-draw { to { stroke-dashoffset: 0; } }
}

:where(.fx-skel) { position: relative; overflow: hidden; display: block; height: 14px; margin: 10px 0; border-radius: 6px;
  background: color-mix(in srgb, currentColor 10%, transparent); }
:where(.fx-skel)::after { content: ""; position: absolute; inset: 0; transform: translateX(-100%);
  background: linear-gradient(90deg, transparent, color-mix(in srgb, currentColor 12%, transparent), transparent); }
:where(.fx-skel.w40) { width: 40%; } :where(.fx-skel.w60) { width: 60%; } :where(.fx-skel.w80) { width: 80%; }
:where(.fx-check) { width: 56px; height: 56px; fill: none; stroke: currentColor; stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
:where(.fx-confetti) { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; z-index: 2147483000; }
