/* ==========================================================================
   Motion — restrained, expensive-feeling, and fully optional.
   Hidden states apply only when <html class="js"> is set, so content is
   always readable if JavaScript is unavailable.
   ========================================================================== */

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

@keyframes scroll-cue {
  0% {
    transform: translateY(-100%);
  }
  60%,
  100% {
    transform: translateY(260%);
  }
}

@keyframes hero-zoom {
  from {
    transform: scale(1.12);
  }
  to {
    transform: scale(1);
  }
}

@keyframes fade-in {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

/* ---- Hero entrance ------------------------------------------------------ */
.hero__media img,
.page-hero__media img {
  animation: hero-zoom 2.6s var(--ease-expo) both;
}

.hero .hero__pattern-wrap,
.page-hero .pattern {
  animation: fade-in 2s var(--ease) 0.4s both;
}

/* Line-by-line heading reveal: <span class="line"><span>…</span></span> */
.line {
  display: block;
  overflow: hidden;
  padding-block: 0.06em;
  margin-block: -0.06em;
}

:root[dir="rtl"] .line {
  padding-block: 0.12em;
  margin-block: -0.12em;
}

.line > span {
  display: block;
}

.js .reveal-lines .line > span {
  transform: translateY(108%);
  transition: transform 1.2s var(--ease-expo);
  transition-delay: calc(0.15s + var(--l, 0) * 0.09s);
}

.js .reveal-lines.is-visible .line > span {
  transform: none;
}

/* ---- Generic reveal: fade + rise ---------------------------------------- */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(2rem);
  transition:
    opacity 0.9s var(--ease),
    transform 1.1s var(--ease-expo);
  transition-delay: calc(var(--d, 0) * 0.08s);
}

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

/* Fade only (no movement) */
.js [data-reveal="fade"] {
  transform: none;
}

/* ---- Masked image reveal: clip + settle from 1.08 to 1 ------------------ */
.js [data-reveal="mask"] {
  opacity: 1;
  transform: none;
  clip-path: inset(0 0 100% 0);
  transition: clip-path 1.4s var(--ease-expo);
  transition-delay: calc(var(--d, 0) * 0.08s);
}

.js [data-reveal="mask"] img {
  transform: scale(1.08);
  transition: transform 1.8s var(--ease-expo);
  transition-delay: calc(var(--d, 0) * 0.08s);
}

.js [data-reveal="mask"].is-visible {
  clip-path: inset(0 0 0 0);
}

.js [data-reveal="mask"].is-visible img {
  transform: none;
}

/* Directional mask — opens from the inline-start side */
.js [data-reveal="mask-side"] {
  opacity: 1;
  transform: none;
  clip-path: inset(0 100% 0 0);
  transition: clip-path 1.5s var(--ease-expo);
}

:root[dir="rtl"].js [data-reveal="mask-side"] {
  clip-path: inset(0 0 0 100%);
}

.js [data-reveal="mask-side"] img {
  transform: scale(1.08);
  transition: transform 1.9s var(--ease-expo);
}

.js [data-reveal="mask-side"].is-visible,
:root[dir="rtl"].js [data-reveal="mask-side"].is-visible {
  clip-path: inset(0 0 0 0);
}

.js [data-reveal="mask-side"].is-visible img {
  transform: none;
}

/* ---- Hairline expansion ------------------------------------------------- */
.js [data-reveal="line"] {
  opacity: 1;
  transform: none;
}

.js [data-reveal="line"]::before {
  transform: scaleX(0);
  transition: transform 1.4s var(--ease-expo);
  transition-delay: calc(var(--d, 0) * 0.08s);
}

.js [data-reveal="line"].is-visible::before {
  transform: scaleX(1);
}

.js [data-reveal="line"] > * {
  opacity: 0;
  transform: translateY(1.25rem);
  transition: opacity 0.8s var(--ease), transform 1s var(--ease-expo);
  transition-delay: calc(0.2s + var(--d, 0) * 0.08s);
}

.js [data-reveal="line"].is-visible > * {
  opacity: 1;
  transform: none;
}

/* ---- Numeral rise ------------------------------------------------------- */
.js [data-reveal="num"] {
  opacity: 1;
  transform: none;
  overflow: hidden;
}

.js [data-reveal="num"] > span {
  display: inline-block;
  transform: translateY(100%);
  transition: transform 1.2s var(--ease-expo);
  transition-delay: calc(var(--d, 0) * 0.08s);
}

.js [data-reveal="num"].is-visible > span {
  transform: none;
}

/* Staggered children */
.js [data-stagger] > * {
  opacity: 0;
  transform: translateY(1.5rem);
  transition: opacity 0.8s var(--ease), transform 1s var(--ease-expo);
}

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

.js [data-stagger].is-visible > *:nth-child(2) { transition-delay: 0.07s; }
.js [data-stagger].is-visible > *:nth-child(3) { transition-delay: 0.14s; }
.js [data-stagger].is-visible > *:nth-child(4) { transition-delay: 0.21s; }
.js [data-stagger].is-visible > *:nth-child(5) { transition-delay: 0.28s; }
.js [data-stagger].is-visible > *:nth-child(6) { transition-delay: 0.35s; }
.js [data-stagger].is-visible > *:nth-child(7) { transition-delay: 0.42s; }

/* ==========================================================================
   Reduced motion — everything visible, nothing moves
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    transition-delay: 0s !important;
  }

  .js [data-reveal],
  .js [data-reveal] > *,
  .js [data-stagger] > *,
  .js .reveal-lines .line > span,
  .js [data-reveal="num"] > span,
  .js [data-reveal] img {
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
  }

  .js [data-reveal="line"]::before {
    transform: none !important;
  }

  .hero__pattern,
  .gate__pattern,
  .scroll-cue__line::after {
    animation: none !important;
  }
}

/* Delay helpers (classes rather than inline styles) */
.d-1 { --d: 1; }
.d-2 { --d: 2; }
.d-3 { --d: 3; }
.d-4 { --d: 4; }
.d-5 { --d: 5; }
.d-6 { --d: 6; }

/* Line-reveal stagger */
.reveal-lines .line:nth-child(2) { --l: 1; }
.reveal-lines .line:nth-child(3) { --l: 2; }
.reveal-lines .line:nth-child(4) { --l: 3; }
