/* ==========================================================================
   HASH/DS - Motion module
   Load after hash-ds.css. Everything here degrades gracefully:
   no JS, reveal-fallback and prefers-reduced-motion all render final state.
   ========================================================================== */

/* ---- Deeper default reveal (more travel, more presence) ---- */
html.hds-js [data-hds-reveal] { opacity: 0; transform: translateY(26px); }
html.hds-js [data-hds-reveal].in {
  opacity: 1; transform: none;
  transition: opacity 700ms var(--hds-ease), transform 700ms var(--hds-ease);
  transition-delay: var(--d, 0ms);
}

/* ---- Kicker print-wipe: § labels print in from the left ---- */
html.hds-js .hds-kicker[data-hds-reveal] {
  opacity: 1; transform: none;
  clip-path: inset(0 100% 0 0);
}
html.hds-js .hds-kicker[data-hds-reveal].in {
  clip-path: inset(0 -5% 0 0);
  transition: clip-path 800ms var(--hds-ease);
  transition-delay: var(--d, 0ms);
}

/* ---- Section header hairline draws left to right ---- */
.hds-section-hd { border-bottom: 0; position: relative; }
.hds-section-hd::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: var(--hds-line);
}
html.hds-js .hds-section-hd[data-hds-reveal]::after {
  transform: scaleX(0); transform-origin: 0 50%;
}
html.hds-js .hds-section-hd[data-hds-reveal].in::after {
  transform: scaleX(1);
  transition: transform 1100ms var(--hds-ease) 120ms;
}

/* ---- Display headings rise word by word (hash-ds.js splits into .w spans) ---- */
html.hds-js .hds-display.words[data-hds-reveal] { opacity: 1; transform: none; }
html.hds-js .hds-display.words .w {
  display: inline-block;
  opacity: 0; transform: translateY(0.55em);
}
html.hds-js .hds-display.words.in .w {
  opacity: 1; transform: none;
  transition: opacity 650ms var(--hds-ease), transform 650ms var(--hds-ease);
  transition-delay: calc(var(--wi, 0) * 60ms + var(--d, 0ms));
}

/* ---- Staggered lists: children cascade (set --i per child) ---- */
html.hds-js .hds-reveal-list > * { opacity: 0; }
html.hds-js .hds-reveal-list.in > * {
  animation: hds-item-in 550ms var(--hds-ease) forwards;
  animation-delay: calc(var(--i, 0) * 90ms);
}
@keyframes hds-item-in {
  from { opacity: 0; transform: translateY(16px); }
  to { opacity: 1; transform: none; }
}

/* ---- Scroll progress bar (2px accent, very top) ---- */
.hds-progress {
  position: fixed; top: 0; left: 0; z-index: 1200;
  height: 2px; width: 0;
  background: var(--hds-accent);
  pointer-events: none;
}

/* ---- Fallbacks: everything visible, always ---- */
html.hds-fallback [data-hds-reveal],
html.hds-fallback .hds-display.words .w,
html.hds-fallback .hds-reveal-list > * { opacity: 1 !important; transform: none !important; clip-path: none !important; }
html.hds-fallback .hds-section-hd::after { transform: scaleX(1) !important; }

@media (prefers-reduced-motion: reduce) {
  html.hds-js [data-hds-reveal],
  html.hds-js .hds-display.words .w,
  html.hds-js .hds-reveal-list > * { opacity: 1 !important; transform: none !important; transition: none !important; animation: none !important; clip-path: none !important; }
  html.hds-js .hds-section-hd[data-hds-reveal]::after { transform: scaleX(1); transition: none; }
  .hds-progress { display: none; }
}

/* ==========================================================================
   Scroll-scrubbed section choreography
   Base decor (ghost numbers, rail) works everywhere; the scrubbing itself is
   progressive enhancement via CSS scroll-driven animations (Chromium).
   ========================================================================== */

/* Ghost section numeral: huge outlined serif digit behind each band */
.hds-band { position: relative; }
.hds-band > .hds-container { position: relative; z-index: 1; }
.hds-band[data-num] { overflow: clip; }
.hds-band[data-num]::before {
  content: attr(data-num);
  position: absolute; top: 3.5rem; right: max(1rem, 3vw); z-index: 0;
  font-family: var(--hds-font-serif); font-style: italic; font-weight: 400;
  font-size: clamp(7rem, 11vw, 11.5rem); line-height: 1;
  color: transparent;
  -webkit-text-stroke: 1px var(--hds-line-2);
  pointer-events: none;
  opacity: 0.9;
}

/* Side rail: fixed section index, current one lights up (js toggles .on) */
.hds-rail {
  position: fixed; right: 1.25rem; top: 50%; transform: translateY(-50%);
  z-index: 90;
  display: flex; flex-direction: column; gap: 0.875rem;
}
.hds-rail a {
  display: flex; align-items: center; gap: 0.5rem;
  font-family: var(--hds-font-mono); font-size: 0.625rem; letter-spacing: 0.08em;
  color: var(--hds-ink-4);
  transition: color var(--hds-fast) var(--hds-ease);
}
.hds-rail a::before { content: ''; width: 10px; height: 1px; background: currentColor; }
.hds-rail a:hover { color: var(--hds-ink-2); }
.hds-rail a.on { color: var(--hds-accent); }
@media (max-width: 1240px) { .hds-rail { display: none; } }

/* The scrubbing (Chromium): bands drift into focus and dim on the way out */
@supports (animation-timeline: view()) {
  .hds-band { view-timeline: --hds-band block; }

  .hds-band > .hds-container {
    animation: hds-band-in linear both, hds-band-out linear both;
    animation-timeline: --hds-band, --hds-band;
    animation-range: entry 0% entry 100%, exit 10% exit 100%;
  }

  .hds-band[data-num]::before {
    animation: hds-ghost-drift linear both;
    animation-timeline: --hds-band;
    animation-range: cover 0% cover 100%;
  }
}

@keyframes hds-band-in {
  from { opacity: 0.3; transform: translateY(46px); }
  to { opacity: 1; transform: none; }
}
@keyframes hds-band-out {
  from { opacity: 1; transform: none; }
  to { opacity: 0.4; transform: translateY(-30px); }
}
@keyframes hds-ghost-drift {
  from { transform: translateY(90px); }
  to { transform: translateY(-90px); }
}

@media (prefers-reduced-motion: reduce) {
  .hds-band > .hds-container, .hds-band[data-num]::before { animation: none !important; }
  .hds-rail { display: none; }
}
