/* Scroll motion for tyronzky.ninja.
 *
 * Inspired by motion.page's entrance feel: elements rise, fade AND unblur together,
 * rather than a flat fade. The blur is what makes it read as considered instead of
 * generic, and it costs nothing extra because it animates on the compositor.
 *
 * Two rules this file never breaks:
 *   1. Nothing is hidden unless JS is alive. The `motion-ready` class is set by
 *      motion.js, so a JS failure leaves the page fully readable rather than blank.
 *   2. Only transform / opacity / filter animate. No layout properties, so no CLS.
 */

/* Hidden state applies only once JS has confirmed it can reveal things again. */
html.motion-ready [data-motion]:not(.in) {
  opacity: 0;
  will-change: transform, opacity, filter;
}

html.motion-ready [data-motion="rise"]:not(.in)  { transform: translateY(26px); filter: blur(6px); }
html.motion-ready [data-motion="left"]:not(.in)  { transform: translateX(-28px); filter: blur(5px); }
html.motion-ready [data-motion="right"]:not(.in) { transform: translateX(28px);  filter: blur(5px); }
html.motion-ready [data-motion="scale"]:not(.in) { transform: scale(.965);       filter: blur(6px); }

html.motion-ready [data-motion] {
  transition:
    opacity .72s cubic-bezier(.22, .61, .36, 1),
    transform .72s cubic-bezier(.22, .61, .36, 1),
    filter .72s cubic-bezier(.22, .61, .36, 1);
}

html.motion-ready [data-motion].in {
  opacity: 1;
  transform: none;
  filter: none;
  will-change: auto;
}

/* Header condenses once you leave the hero. The site already has a fixed header;
   this only tightens it and adds a blur behind, so nothing reflows. */
header {
  transition: padding .3s ease, background-color .3s ease, backdrop-filter .3s ease,
              border-color .3s ease;
}
html.scrolled header {
  background: rgba(11, 13, 16, .82);
  backdrop-filter: saturate(140%) blur(12px);
  -webkit-backdrop-filter: saturate(140%) blur(12px);
  border-bottom: 1px solid rgba(255, 255, 255, .08);
}
html.scrolled header .nav,
html.scrolled header .wrap.nav { padding-top: 10px; padding-bottom: 10px; }

/* A thin progress bar for long reads. Only injected on article pages by motion.js. */
.read-bar {
  position: fixed; top: 0; left: 0; height: 2px; width: 0;
  background: linear-gradient(90deg, var(--cyan, #00D9FF), var(--red, #E53935));
  z-index: 9999; pointer-events: none;
  transition: width .1s linear;
}

@media (prefers-reduced-motion: reduce) {
  html.motion-ready [data-motion],
  html.motion-ready [data-motion]:not(.in) {
    opacity: 1 !important;
    transform: none !important;
    filter: none !important;
    transition: none !important;
  }
  header { transition: none !important; }
  .read-bar { display: none; }
}
