/* ---------------------------------------------------------------
   motion.css — reveals, split-text, page transitions
   Everything here only activates once <html> has the .js class,
   added by an inline script in <head>. Without JS, none of this
   applies and content is fully visible.
--------------------------------------------------------------- */

/* ---- Generic reveal system ---- */
html.js [data-reveal] {
  opacity: 0;
  transition: opacity var(--dur-med) var(--ease), transform var(--dur-med) var(--ease);
}

html.js [data-reveal='up'] {
  transform: translateY(28px);
}

html.js [data-reveal='fade'] {
  transform: none;
}

html.js [data-reveal='scale'] {
  transform: scale(0.94);
}

html.js [data-reveal='wipe'] {
  transform: none;
  clip-path: inset(0 100% 0 0);
  opacity: 1;
  transition: clip-path var(--dur-med) var(--ease);
}

html.js [data-reveal].is-visible {
  opacity: 1;
  transform: none;
  clip-path: inset(0 0% 0 0);
}

/* stagger via data-delay (steps of ~80ms) */
html.js [data-delay='1'] { transition-delay: 0.08s; }
html.js [data-delay='2'] { transition-delay: 0.16s; }
html.js [data-delay='3'] { transition-delay: 0.24s; }
html.js [data-delay='4'] { transition-delay: 0.32s; }
html.js [data-delay='5'] { transition-delay: 0.4s; }
html.js [data-delay='6'] { transition-delay: 0.48s; }

/* ---- Split-text hero reveal ---- */
html.js .hero__word {
  transform: translateY(110%);
  transition: transform 0.9s var(--ease);
}

html.js .hero__name.is-visible .hero__word {
  transform: translateY(0);
}

html.js .hero__name.is-visible .hero__line:nth-child(2) .hero__word {
  transition-delay: 0.08s;
}

/* ---- Hero scroll indicator ---- */
.hero__scroll-line {
  transform: scaleY(0.4);
  animation: scrollPulse 2.2s var(--ease) infinite;
}

@keyframes scrollPulse {
  0%, 100% { transform: scaleY(0.4); opacity: 0.5; }
  50% { transform: scaleY(1); opacity: 1; }
}

/* ---- Status dot pulse ---- */
.status-dot {
  animation: statusPulse 2.4s ease-in-out infinite;
}

@keyframes statusPulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--color-accent) 45%, transparent); }
  50% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--color-accent) 0%, transparent); }
}

/* ---- Hairline draw-in ---- */
html.js hr.hairline[data-reveal] {
  transform: scaleX(0);
  transform-origin: left;
  opacity: 1;
  transition: transform var(--dur-med) var(--ease);
}

html.js hr.hairline[data-reveal].is-visible {
  transform: scaleX(1);
}

/* ---- Timeline node pop ---- */
.timeline__node {
  /* base state defined in components.css; transition already present */
}

/* ---- Page transition wipe ---- */
.page-transition {
  position: fixed;
  inset: 0;
  background: var(--color-accent);
  z-index: 2000;
  transform: translateY(100%);
  pointer-events: none;
}

html.js .page-transition.is-covering {
  animation: wipeIn 0.5s var(--ease) forwards;
}

html.js .page-transition.is-revealing {
  animation: wipeOut 0.5s var(--ease) forwards;
}

@keyframes wipeIn {
  from { transform: translateY(100%); }
  to { transform: translateY(0%); }
}

@keyframes wipeOut {
  from { transform: translateY(0%); }
  to { transform: translateY(-100%); }
}

/* ---- Magnetic elements ---- */
.magnetic {
  transition: transform 0.2s var(--ease);
}

/* ---- Language swap cross-fade ---- */
html.js [data-i18n] {
  transition: opacity 0.2s ease;
}

.i18n-swapping [data-i18n] {
  opacity: 0;
}

/* ---- Reduced motion: neutralize everything, show content immediately ---- */
@media (prefers-reduced-motion: reduce) {
  html.js [data-reveal],
  html.js .hero__word,
  html.js hr.hairline[data-reveal] {
    transition: none !important;
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
    clip-path: none !important;
  }

  .hero__scroll-line,
  .status-dot,
  .marquee__track {
    animation: none !important;
  }

  .page-transition {
    display: none !important;
  }
}
