/* motion.css: state styles for the hooks js/motion.js drives.
   Layout, type, colour tokens and section structure live in styles.css. */

/* Fade-up: [data-reveal] gets .is-in once; --d is the per-element delay. */
[data-reveal] {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 1s var(--ease), transform 1s var(--ease);
  transition-delay: var(--d, 0s);
}
[data-reveal].is-in { opacity: 1; transform: none; }

/* Line mask (hero): each .ln clips its inner span, which rises into place. */
.ln {
  display: block;
  overflow: hidden;
  padding-bottom: .08em;
  margin-bottom: -.08em;
}
.ln > span {
  display: block;
  transform: translateY(105%);
  transition: transform 1s var(--ease);
}
.ln:nth-child(2) > span { transition-delay: .08s; }
.ln:nth-child(3) > span { transition-delay: .16s; }
[data-lines].is-in .ln > span { transform: none; }

/* Word blur-in: motion.js wraps each word as .w > span[--i]. */
[data-split] .w {
  display: inline-block;
  overflow: hidden;
  vertical-align: bottom;
  padding-bottom: .1em;
  margin-bottom: -.1em;
}
[data-split] em .w { padding-right: .06em; margin-right: -.06em; } /* italic overhang */
[data-split] .w > span {
  display: inline-block;
  opacity: 0;
  transform: translateY(.5em);
  filter: blur(8px);
  transition: opacity .7s var(--ease), transform .7s var(--ease), filter .7s var(--ease);
  transition-delay: calc(var(--i, 0) * 45ms);
}
[data-split].is-in .w > span { opacity: 1; transform: none; filter: none; }

/* Scroll-lit statements: words go ghost -> ink; the em clause lights in accent. */
[data-statement] .sw { color: var(--ghost); transition: color .25s linear; }
[data-statement] .sw.lit { color: var(--text); }
[data-statement] em .sw.lit { color: var(--accent-2); }
.paper [data-statement] .sw { color: var(--paper-line); }
.paper [data-statement] .sw.lit,
.paper [data-statement] em .sw.lit { color: var(--paper-ink); }

/* Pinned stage: one active step; segments fill by --p. */
.step {
  opacity: 0;
  transform: translateY(30px);
  transition: opacity .6s var(--ease), transform .6s var(--ease);
  pointer-events: none;
}
.step.is-active { opacity: 1; transform: none; pointer-events: auto; }
.seg { position: relative; }
.seg::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--accent);
  transform-origin: left;
  transform: scaleX(var(--p, 0));
}

/* Ghost word drift and marquee (both written per frame by motion.js). */
.ghost { transform: translateX(var(--gx, 0px)); will-change: transform; }
.marquee-track { will-change: transform; }
[data-marquee].is-live .marquee-track { animation: none; } /* JS owns the motion once live */

/* Nav: transparent -> solid after 20px of scroll. */
.nav {
  transition: background .3s var(--ease), border-color .3s var(--ease), backdrop-filter .3s;
}
.nav.is-solid {
  background: rgba(5, 9, 18, .9);
  -webkit-backdrop-filter: blur(16px) saturate(140%);
  backdrop-filter: blur(16px) saturate(140%);
  border-bottom: 1px solid var(--line);
}

/* Mobile menu: links rise in, 70ms apart. */
#menu.is-open { display: flex; }
#menu nav a {
  opacity: 0;
  transform: translateY(40px);
  transition: opacity .7s var(--ease), transform .7s var(--ease);
}
#menu.is-open nav a { opacity: 1; transform: none; }
#menu.is-open nav a:nth-child(2) { transition-delay: .07s; }
#menu.is-open nav a:nth-child(3) { transition-delay: .14s; }
#menu.is-open nav a:nth-child(4) { transition-delay: .21s; }
#menu.is-open nav a:nth-child(5) { transition-delay: .28s; }
#menu.is-open nav a:nth-child(6) { transition-delay: .35s; }
body.menu-open { overflow: hidden; }

/* Section rail: dots, active dot, label on hover/focus. */
.rail a { position: relative; }
.rail a i { background: rgba(214, 228, 250, .42); transition: background .3s, transform .3s; } /* ≥3:1 on the dark page */ /* geometry + label live in styles.css */
.rail a.is-active i { background: var(--accent); transform: scale(1.5); }

/* Cursor: difference-blend ring that lerps to the pointer; fills on links. */
#cursor {
  top: 0;
  left: 0;
  width: 34px;
  height: 34px;
  border: 1.5px solid #fff;
  border-radius: 50%;
  mix-blend-mode: difference;
  transform: translate(-50%, -50%);
  opacity: 0;
  transition: width .3s var(--ease), height .3s var(--ease), background .3s, opacity .3s;
}
#cursor.is-on { opacity: 1; }
#cursor.is-link { width: 76px; height: 76px; background: rgba(255, 255, 255, .22); } /* translucent so card copy stays legible under it */
@media (hover: none), (max-width: 859px) {
  #cursor { display: none; }
}

/* Card spotlight: radial accent that follows --mx/--my. */
[data-spot] { position: relative; }
[data-spot]::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  transition: opacity .4s var(--ease);
  background: radial-gradient(320px circle at var(--mx, 50%) var(--my, 50%), rgba(var(--accent-rgb), .16), transparent 60%);
}
[data-spot]:hover::after { opacity: 1; }

/* Reduced motion: every state snaps to its end; the pinned stage still swaps, without transitions. */
@media (prefers-reduced-motion: reduce) {
  [data-reveal],
  .ln > span,
  [data-split] .w > span,
  [data-statement] .sw,
  .step,
  .nav,
  #menu nav a,
  .rail a i,
  .rail a::before,
  #cursor,
  [data-spot]::after { transition: none; }
  [data-reveal],
  .ln > span,
  [data-split] .w > span { opacity: 1; transform: none; filter: none; }
  #menu nav a { opacity: 1; transform: none; }
  .ghost { transform: none; }
  #cursor { display: none; }
}
