/* ---------------------------------------------------------------------
   Aparición al hacer scroll — Power Switch Solutions

   Las secciones entran con un desplazamiento corto hacia arriba y un fundido.
   Deliberadamente sobrio: el sitio vende ingeniería, no efectos. Movimientos
   cortos (18 px), curva de salida suave y nada que rebote.

   Regla de oro: el contenido NUNCA queda oculto por culpa de este efecto.
   Todo parte visible, y solo cuando el JS confirma que puede animar añade la
   clase .reveal-activo al <html>. Si el JavaScript falla, si el navegador no
   soporta IntersectionObserver o si la persona pidió menos movimiento, la
   página se ve completa y quieta. Ocultar primero con CSS y revelar después
   con JS es el error clásico de estos efectos: cuando el script no corre, la
   página queda en blanco.
   --------------------------------------------------------------------- */

.reveal-activo [data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition:
    opacity .62s cubic-bezier(.22, .61, .36, 1),
    transform .62s cubic-bezier(.22, .61, .36, 1);
  will-change: opacity, transform;
}

.reveal-activo [data-reveal].reveal-visible {
  opacity: 1;
  transform: none;
}

/* Una vez terminada la entrada se suelta will-change: mantenerlo activo en
   decenas de elementos obliga al navegador a conservar una capa por cada uno. */
.reveal-activo [data-reveal].reveal-listo {
  will-change: auto;
  transition: none;
}

/* Variantes para elementos que entran desde un costado, útiles en las filas
   de dos columnas donde el texto y la imagen se alternan. */
.reveal-activo [data-reveal="izquierda"] { transform: translateX(-22px); }
.reveal-activo [data-reveal="derecha"]   { transform: translateX(22px); }
.reveal-activo [data-reveal="escala"]    { transform: scale(.975); }

.reveal-activo [data-reveal="izquierda"].reveal-visible,
.reveal-activo [data-reveal="derecha"].reveal-visible,
.reveal-activo [data-reveal="escala"].reveal-visible { transform: none; }

/* Escalonado dentro de un grupo: cada hijo entra un poco después que el
   anterior, lo que hace que una grilla de tarjetas se lea como una secuencia
   y no como un bloque que aparece de golpe. El tope de 8 evita que la última
   tarjeta de una lista larga tarde un segundo entero en aparecer. */
.reveal-activo [data-reveal-grupo] > * { transition-delay: 0ms; }
.reveal-activo [data-reveal-grupo] > *:nth-child(2) { transition-delay: 70ms; }
.reveal-activo [data-reveal-grupo] > *:nth-child(3) { transition-delay: 140ms; }
.reveal-activo [data-reveal-grupo] > *:nth-child(4) { transition-delay: 210ms; }
.reveal-activo [data-reveal-grupo] > *:nth-child(5) { transition-delay: 280ms; }
.reveal-activo [data-reveal-grupo] > *:nth-child(6) { transition-delay: 350ms; }
.reveal-activo [data-reveal-grupo] > *:nth-child(7) { transition-delay: 420ms; }
.reveal-activo [data-reveal-grupo] > *:nth-child(n+8) { transition-delay: 490ms; }

/* Quien pidió menos movimiento en su sistema no recibe ninguno: el contenido
   aparece sin desplazamiento ni fundido. */
@media (prefers-reduced-motion: reduce) {
  .reveal-activo [data-reveal],
  .reveal-activo [data-reveal].reveal-visible {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* Al imprimir tampoco: una sección a medio aparecer saldría desvanecida. */
@media print {
  .reveal-activo [data-reveal] {
    opacity: 1 !important;
    transform: none !important;
  }
}
