/* ============================================================
   footnote — PRELOADER DE IMÁGENES (compartido por las páginas de proyecto)

   Cada recuadro de foto trae, incrustada en su HTML, una miniatura de ~28 px de
   ESA misma foto (--lqip, la escribe herramientas/lqip.py). Mientras la imagen
   real viaja por la red se ve esa miniatura ampliada y desenfocada —el color y la
   composición de la foto, no un recuadro vacío—; al llegar la imagen se funde
   encima (assets/js/carga.js pone las clases).

     [data-lqip]   recuadro con miniatura (la pone la herramienta)
     .is-pending   la imagen real aún no llegó: se oculta y se ve solo la miniatura
     .is-loaded    llegó y ya está decodificada: se funde sobre la miniatura
     .is-done      terminó el fundido: se retira la miniatura (libera el desenfoque)

   Sin JS no hay .is-pending: la foto se pinta como siempre, con la miniatura
   debajo. Solo `opacity` en la foto y en la miniatura (sin layout). Con «reducir
   movimiento» el cambio es instantáneo. Los carruseles (.hcar) y los fundidos
   (.xfade) no usan esto: los gobierna su propio JS.
   ============================================================ */
.media-slot[data-lqip]::before {
  content: ''; position: absolute; inset: -8%; z-index: 0; pointer-events: none;
  background: var(--lqip) center / cover no-repeat;
  filter: blur(16px) saturate(1.12);
  transition: opacity 0.7s ease 0.1s;
}
.media-slot[data-lqip] > .media-slot__img,
.media-slot[data-lqip] > picture > .media-slot__img {
  transition: opacity 0.7s ease, transform 0.3s ease-out;
}
.media-slot[data-lqip].is-pending > .media-slot__img,
.media-slot[data-lqip].is-pending > picture > .media-slot__img { opacity: 0; }
.media-slot[data-lqip].is-loaded::before { opacity: 0; }
.media-slot[data-lqip].is-done::before { display: none; }

@media (prefers-reduced-motion: reduce) {
  .media-slot[data-lqip]::before,
  .media-slot[data-lqip] > .media-slot__img,
  .media-slot[data-lqip] > picture > .media-slot__img { transition: none; }
}
