/* Source: custom — Exvisios (scroll-reveal module)
   Restrained editorial reveal: short distance, quick, NO per-item stagger
   cascade (that reads as template/AI). Elements enter together per section.

   Progressive enhancement: the hidden state is gated behind `html.js`
   (set by /js/head.js before first paint). If JS is disabled or errors,
   content stays fully visible — the page never renders blank.
   Honors prefers-reduced-motion. No `will-change` (kept off the compositor). */

.js [data-reveal] {
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity 0.55s var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1)),
    transform 0.55s var(--ease-out, cubic-bezier(0.16, 1, 0.3, 1));
}

.js [data-reveal="left"]  { transform: translateX(-18px); }
.js [data-reveal="right"] { transform: translateX(18px); }
.js [data-reveal="scale"] { transform: scale(0.98); }

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

/* Photographs do not animate in (2026-10-03, Aleksandar): no 45° unveil, no
   lazy-image fade. Images are static and load with the page; only text and
   UI blocks use the reveal above. */

@media (prefers-reduced-motion: reduce) {
  .js [data-reveal],
  .js [data-reveal="left"],
  .js [data-reveal="right"],
  .js [data-reveal="scale"] {
    opacity: 1 !important;
    transform: none !important;
    transition: none !important;
  }
}
