/* ============================================================
   zzz-article-header-entrance.css — article header load-in
   ------------------------------------------------------------
   Everything below the fold already fades up as it scrolls into
   view (micro-interactions.js → .reveal-block / card reveal), but
   the article header itself — breadcrumbs, title, description,
   meta and the hairline rule — sat above the fold and simply
   appeared on load. This gives that first screen a gentle, once-
   only entrance so opening an article feels like it "arrives"
   rather than blinking into place. Desktop + mobile.

   Progressive enhancement only:
   - Gated behind html.motion-reveal, which is added to <html> in
     <head> BEFORE first paint, and ONLY when the visitor has not
     requested reduced motion (see partials/extend_head.html). So
     no-JS / reduced-motion visitors never get the hidden start
     state — there is no flash and no layout shift.
   - animation-fill-mode: both means the "from" (hidden) state is
     applied pre-paint and the "to" (natural) state sticks after,
     so if the motion-reveal failsafe ever drops the class the
     header is already at its normal, fully-visible resting state.
   - The cover image is intentionally NOT animated here: it has its
     own pointer-parallax / tilt motion (cover-parallax.js,
     zzz-cover-motion.css) and layering a transform on top would
     fight that. Header text only.

   Loads late (zzz- prefix → concatenated after custom.css) so the
   overrides win cleanly.
   ============================================================ */

@keyframes article-header-rise {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}

html.motion-reveal .post-single .article-marginalia-mobile,
html.motion-reveal .post-single .post-header .breadcrumbs,
html.motion-reveal .post-single .post-header .post-title,
html.motion-reveal .post-single .post-header .post-description,
html.motion-reveal .post-single .post-header .post-meta,
html.motion-reveal .post-single .post-header .post-header-rule {
  animation: article-header-rise 0.6s cubic-bezier(0.22, 0.61, 0.36, 1) both;
  /* will-change is dropped automatically once the one-shot finishes;
     these are few elements so the brief hint is cheap. */
  will-change: opacity, transform;
}

/* Staggered cascade — each line follows the one above so the header
   unfolds top-to-bottom. Delays are short so the whole sequence is
   well under half a second and never feels like a wait. */
html.motion-reveal .post-single .article-marginalia-mobile {
  animation-delay: 0s;
}
html.motion-reveal .post-single .post-header .breadcrumbs {
  animation-delay: 0.04s;
}
html.motion-reveal .post-single .post-header .post-title {
  animation-delay: 0.1s;
}
html.motion-reveal .post-single .post-header .post-description {
  animation-delay: 0.18s;
}
html.motion-reveal .post-single .post-header .post-meta {
  animation-delay: 0.26s;
}
html.motion-reveal .post-single .post-header .post-header-rule {
  animation-delay: 0.32s;
}

/* ------------------------------------------------------------
   Reduced motion: hard stop. (motion-reveal is already absent for
   these visitors, so this is belt-and-braces — never animate, never
   leave anything hidden.)
   ------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  html.motion-reveal .post-single .article-marginalia-mobile,
  html.motion-reveal .post-single .post-header .breadcrumbs,
  html.motion-reveal .post-single .post-header .post-title,
  html.motion-reveal .post-single .post-header .post-description,
  html.motion-reveal .post-single .post-header .post-meta,
  html.motion-reveal .post-single .post-header .post-header-rule {
    animation: none !important;
    opacity: 1 !important;
    transform: none !important;
    will-change: auto !important;
  }
}
