/* ==========================================================================
   Animations — keyframes, scroll-reveal states, engrave-on-scroll.
   Every effect degrades to "instantly visible" under prefers-reduced-motion.
   Only transform/opacity are animated (no layout thrash).
   ========================================================================== */

/* --------------------------------------------------------------------------
   Keyframes
   -------------------------------------------------------------------------- */

@keyframes hero-line-in {
  from { transform: translateY(105%); }
  to   { transform: translateY(0); }
}

@keyframes fade-up {
  from { opacity: 0; transform: translateY(26px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes nav-item-in {
  from { opacity: 0; transform: translateY(16px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes draw-stroke {
  to { stroke-dashoffset: 0; }
}

@keyframes pulse-dot {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: 0.45; transform: scale(0.82); }
}

@keyframes scroll-trace {
  0%   { top: -50%; }
  100% { top: 100%; }
}

@keyframes pin-pulse {
  0%, 100% { box-shadow: 0 0 0 0 rgba(221, 20, 10, 0.34); }
  70%      { box-shadow: 0 0 0 16px rgba(221, 20, 10, 0); }
}

@keyframes float-drift {
  0%   { transform: translate(0, 0); }
  25%  { transform: translate(9px, -14px); }
  50%  { transform: translate(-6px, -24px); }
  75%  { transform: translate(-12px, -11px); }
  100% { transform: translate(0, 0); }
}

@keyframes shimmer-sweep {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

@keyframes spin-slow {
  to { transform: rotate(360deg); }
}

/* --------------------------------------------------------------------------
   Scroll-triggered reveals — IntersectionObserver adds .is-visible
   -------------------------------------------------------------------------- */

[data-reveal] {
  opacity: 0;
  transform: translateY(30px);
  transition:
    opacity var(--dur-page) var(--ease-out),
    transform var(--dur-page) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
  will-change: opacity, transform;
}

/* Horizontal reveals use a small offset and are clipped by .section so an
   un-revealed element can never widen the page. */
[data-reveal="left"]  { transform: translateX(-38px); }
[data-reveal="right"] { transform: translateX(38px); }

/* Below the mobile breakpoint, slide vertically instead — a sideways offset
   on a full-width column is what creates phantom horizontal scroll. */
@media (max-width: 1024px) {
  [data-reveal="left"],
  [data-reveal="right"] { transform: translateY(30px); }
}
[data-reveal="scale"] { transform: scale(0.94); }
[data-reveal="fade"]  { transform: none; }

[data-reveal].is-visible {
  opacity: 1;
  transform: translate(0, 0) scale(1);
  will-change: auto;
}

/* Staggered children — index set inline as --i. */
[data-stagger] > * {
  opacity: 0;
  transform: translateY(26px);
  transition:
    opacity var(--dur-page) var(--ease-out),
    transform var(--dur-page) var(--ease-out);
  transition-delay: calc(var(--i, 0) * 85ms);
}

[data-stagger].is-visible > * {
  opacity: 1;
  transform: translateY(0);
}

/* --------------------------------------------------------------------------
   Engrave-on-scroll — headings are "cut" into the page.
   The SVG overlay draws its stroke as the heading enters the viewport.
   -------------------------------------------------------------------------- */

.engrave { position: relative; display: inline-block; }

.engrave__line {
  display: block;
  width: 100%;
  height: 2px;
  margin-top: var(--sp-4);
  overflow: visible;
}

.engrave__line path {
  stroke: var(--accent-deep);
  stroke-width: 1.5;
  fill: none;
  stroke-dasharray: 300;
  stroke-dashoffset: 300;
  transition: stroke-dashoffset 1.15s var(--ease-out);
}

.engrave.is-visible .engrave__line path { stroke-dashoffset: 0; }

/* --------------------------------------------------------------------------
   Hero entrance cascade
   -------------------------------------------------------------------------- */

.hero__title .line > span {
  animation: hero-line-in 0.95s var(--ease-out) forwards;
  animation-delay: calc(var(--i, 0) * 105ms + 180ms);
}

.hero__lead,
.hero__actions,
.trust-row,
.hero__visual {
  opacity: 0;
  animation: fade-up 0.85s var(--ease-out) forwards;
}

.hero__lead    { animation-delay: 520ms; }
.hero__actions { animation-delay: 640ms; }
.trust-row     { animation-delay: 760ms; }
.hero__visual  { animation-delay: 400ms; }

/* Slowly rotating guilloché rings behind the medallion. */
.hero__rings svg { animation: spin-slow 130s linear infinite; }

/* Floating motes drift continuously. */
.mote { animation: float-drift var(--drift, 15s) var(--ease-in-out) infinite; }

/* Foil headings catch a slow travelling highlight. */
.foil--animate {
  animation: shimmer-sweep 7s linear infinite;
}

/* --------------------------------------------------------------------------
   Reduced motion — disable everything, show final state.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }

  [data-reveal],
  [data-stagger] > * {
    opacity: 1 !important;
    transform: none !important;
  }

  .hero__title .line > span,
  .hero__lead,
  .hero__actions,
  .trust-row,
  .hero__visual,
  .mobile-nav__link {
    opacity: 1 !important;
    transform: none !important;
    animation: none !important;
  }

  .engrave__line path { stroke-dashoffset: 0 !important; }

  .preloader { display: none !important; }

  .medallion { transform: none !important; }

  .card--tilt { transform: none !important; }
}
