/* ==========================================================================
   UTILITIES — animación de aparición, helpers de layout, accesibilidad.
   ========================================================================== */

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.text-center { text-align: center; }
.mx-auto { margin-inline: auto; }

.stack { display: flex; flex-direction: column; }
.cluster { display: flex; flex-wrap: wrap; align-items: center; }
.gap-xs { gap: var(--space-xs); }
.gap-sm { gap: var(--space-sm); }
.gap-md { gap: var(--space-md); }
.gap-lg { gap: var(--space-lg); }

.mt-lg { margin-top: var(--space-lg); }
.mt-xl { margin-top: var(--space-xl); }
.mb-xl { margin-bottom: var(--space-xl); }

/* Reveal / fade-up controlados por animations.js (IntersectionObserver) */
[data-reveal] {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity var(--dur-slow) var(--ease-organic), transform var(--dur-slow) var(--ease-organic);
}

[data-reveal].is-visible {
  opacity: 1;
  transform: translateY(0);
}

[data-reveal="fade"] {
  transform: none;
}

/* Retardo escalonado para grupos de tarjetas */
[data-reveal-group] > * { transition-delay: calc(var(--reveal-index, 0) * 90ms); }

@media (prefers-reduced-motion: reduce) {
  [data-reveal] {
    opacity: 1;
    transform: none;
    transition: none;
  }
}

/* Capa de parallax (fondo líquido en hero y transiciones) */
.parallax-layer {
  position: absolute;
  inset: 0;
  will-change: transform;
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .parallax-layer {
    transform: none !important;
  }
}
