/* ==========================================================================
   LK Risk — Animations
   Subtle, composed motion. Elements are only hidden when JS is available
   (html.js), so content is never lost if scripts fail.
   ========================================================================== */

/* --- Scroll reveal: fade + gentle rise ----------------------------------- */
.js .reveal {
  opacity: 0;
  transform: translateY(24px);
  transition:
    opacity var(--duration-slow) var(--ease-out),
    transform var(--duration-slow) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}

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

/* --- Image reveal: a slow curtain lift -----------------------------------
   The clip sits on the <img>, never on the observed wrapper: Chromium's
   IntersectionObserver treats a fully clipped target as not intersecting,
   so clipping the wrapper itself means it would never be revealed. */
.js .reveal-image > img {
  clip-path: inset(100% 0 0 0);
  transition: clip-path 1.2s var(--ease-in-out);
  transition-delay: var(--reveal-delay, 0ms);
}

.js .reveal-image.is-visible > img {
  clip-path: inset(0 0 0 0);
}

/* Stagger helpers */
.delay-1 { --reveal-delay: 120ms; }
.delay-2 { --reveal-delay: 240ms; }
.delay-3 { --reveal-delay: 360ms; }
.delay-4 { --reveal-delay: 480ms; }

/* --- Hero entrance ------------------------------------------------------- */
@keyframes rise-in {
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

@keyframes settle {
  from { transform: scale(1.08); }
  to   { transform: scale(1); }
}

.hero-enter {
  opacity: 0;
  animation: rise-in 1.1s var(--ease-out) forwards;
  animation-delay: var(--enter-delay, 0ms);
}

@media (prefers-reduced-motion: reduce) {
  .js .reveal,
  .js .reveal-image > img,
  .hero-enter {
    opacity: 1;
    transform: none;
    clip-path: none;
  }
}
