/* Entrance choreography, the CSS half. Paired with dist/entrance.js.
 *
 * One keyframe, a ladder of delays — the pattern the reference study measured, where the author wrote
 * a single `topIn` / `sideInLeft` and ordered the whole page with `animation-delay` alone.
 *
 * The hiding state is keyed on `[data-entrance="on"]`, which ONLY the script sets. That is deliberate:
 * if the script never runs, nothing here applies and every element renders at its natural state. The
 * site's standing guarantee is that no content is ever hidden by an animation, and gating on a
 * script-set attribute is what keeps that guarantee true.
 *
 * `both` fill is used rather than `forwards`: the animation needs the `from` state applied during the
 * delay, or an element that has not started yet would sit visible and then jump.
 */

:root {
  /* The ladder's rung. The study measured 60-90ms between elements; 80ms sits in that band and is
     overridable per element by the script through --entrance-delay. */
  --entrance-step: 80ms;
  --entrance-duration: 520ms;
  --entrance-ease: cubic-bezier(.22, .68, .24, 1);
  --entrance-y: 16px;
  --entrance-delay: 0ms;
}

@keyframes entrance-in {
  from {
    opacity: 0;
    transform: translate3d(0, var(--entrance-y, 16px), 0);
  }
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0);
  }
}

/* Only transform and opacity animate, so the whole ladder stays on the compositor. */
[data-entrance="on"] {
  animation: entrance-in var(--entrance-duration) var(--entrance-ease) var(--entrance-delay) both;
  will-change: transform, opacity;
}

/* Once landed, drop the compositor hint: a permanent `will-change` on dozens of elements is a
   standing cost for an animation that already finished. */
[data-entrance="done"] {
  will-change: auto;
}

/* Reduced motion keeps the content and drops the travel. The script also flushes on this query; this
   rule is the belt to that braces, so the outcome does not depend on JS timing. */
@media (prefers-reduced-motion: reduce) {
  [data-entrance="on"] {
    animation: none;
    opacity: 1;
    transform: none;
  }
}

/* Quiet mode is the site's own "calm everything" switch and already kills animations globally in
   quiet-magic.css / upgrade.css; this keeps the entrance from being the one exception. */
html[data-motion="quiet"] [data-entrance="on"] {
  animation: none;
  opacity: 1;
  transform: none;
}

@media print {
  [data-entrance="on"] {
    animation: none;
    opacity: 1;
    transform: none;
  }
}
