/* ==========================================================================
   motion.css — the cold open: title flash → shatter → terminal reveal.
   All heavy motion is gated behind (prefers-reduced-motion: no-preference)
   plus a body[data-reduce] fallback toggled in JS.
   ========================================================================== */

/* ---- cold open scaffold ---- */
.coldopen {
  position: fixed; inset: 0;
  display: grid; place-items: center;
  background: #000;
  z-index: 40;
  overflow: hidden;
}

/* act 1: the circle — one stroke, drawn closed at an even pace */
.co-ring {
  width: min(38vmin, 240px);
  height: auto;
  overflow: visible;
}
.co-line {
  fill: none;
  stroke: #f4f2ec;
  stroke-width: 1.6;
}

/* act 3: the title card — resolves into the circle's center point, then holds.
   no sheen, no idle motion. the mask doesn't perform. */
.co-title {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  text-align: center;
  color: #f4f2ec;
  opacity: 0;
}
.co-title .t-welcome {
  font-family: var(--font-mono);
  letter-spacing: 0.34em;
  text-indent: 0.34em;
  font-size: clamp(18px, 5.4vw, 40px);
  text-transform: uppercase;
}

/* shard layer: pieces of the mask that crack and fall away */
.co-shards { position: absolute; inset: 0; pointer-events: none; }
.co-shard {
  position: absolute; inset: 0;
  background: #000;
  will-change: transform, opacity;
}

/* the terminal that is revealed beneath the shattered gloss */
.co-reveal {
  position: absolute; inset: 0;
  background: var(--paper);
  opacity: 0;
}

/* ---------------- keyframes ---------------- */
@keyframes co-glitch {         /* the gloss degrading right before the crack */
  0%,100% { transform: translate(0,0); filter: none; }
  20% { transform: translate(-2px, 1px); filter: hue-rotate(8deg) contrast(1.3); }
  40% { transform: translate(3px, -1px); }
  60% { transform: translate(-1px, 2px); filter: contrast(1.5) saturate(0); }
  80% { transform: translate(2px, 0); }
}
@keyframes co-reveal-in {
  0% { opacity: 0; }
  100% { opacity: 1; }
}

/* JS toggles data-beat on the coldopen root to sequence acts */
.coldopen[data-beat="title"] .co-title {
  opacity: 1;
  animation: co-resolve 900ms ease forwards;
}
.coldopen[data-beat="glitch"] .co-title { opacity: 1; animation: co-glitch 360ms steps(2) 2; }
.coldopen[data-beat="reveal"] .co-reveal { animation: co-reveal-in 500ms ease forwards; }
.coldopen[data-beat="reveal"] .co-title { opacity: 0; transition: opacity 200ms; }

/* the resolve: letters sharpen into place — replacement, not arrival */
@keyframes co-resolve {
  0%   { opacity: 0; filter: blur(8px); }
  100% { opacity: 1; filter: blur(0); }
}

/* reduced-motion / reduce fallback: no shards, quick cross-fade */
.coldopen[data-reduce] .co-shard { display: none; }
.coldopen[data-reduce] .co-title { transition: opacity 200ms ease; animation: none; }

/* generic fade utility used across stages */
.fade-in { animation: fade-in 420ms ease forwards; }
.fade-out { animation: fade-out 360ms ease forwards; }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes fade-out { from { opacity: 1; } to { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .co-title { animation: none !important; }
  .fade-in, .fade-out { animation-duration: 1ms; }
}

/* ---- finale: the six-into-one ---- */
.fin-overlay {
  position: fixed; inset: 0;
  display: grid; place-items: center;
  z-index: 70;
  background: color-mix(in srgb, var(--paper) 88%, transparent);
  backdrop-filter: blur(2px);
  opacity: 0;
  transition: opacity 600ms ease;
  pointer-events: none;
}
.fin-overlay.show { opacity: 1; }
.fin-svg { width: min(72vmin, 460px); height: auto; overflow: visible; }
.fin-node {
  fill: none;
  stroke: var(--lit, var(--ink));
  stroke-width: 1.6;
  opacity: 0;
  transition: opacity 500ms ease;
}
.fin-node.on { opacity: 1; }
.fin-one {
  fill: none;
  stroke: var(--lit, var(--ink));
  stroke-width: 2;
  opacity: 0;
  transition: opacity 900ms ease;
}
.fin-one.on { opacity: 1; }
.fin-skip { margin-top: 4px; opacity: 0.6; }
.fin-skip:hover { opacity: 1; }
