/*
 * Kate Angelo — Blog single-post scroll reveal (initial-hidden state)
 * ---------------------------------------------------------------------------
 * Companion stylesheet for assets/blog-scroll-reveal.js. This file owns ONLY
 * the "hidden until JS proves it can animate" state — the actual fade/slide-in
 * and image parallax transforms are driven by GSAP inline styles at runtime.
 *
 * FAILSAFE PRINCIPLE (mirrors kate-book-manager's `.kbm-js .kbm-anim { opacity:0 }`
 * guard used on book pages):
 *   - blog-scroll-reveal.js adds the class `kbm-blog-js` to <html> as the very
 *     first line it executes, before touching GSAP or the DOM in any other way.
 *   - Every hiding rule below is scoped under `.kbm-blog-js`, so if the script
 *     never loads, throws, or is blocked (ad blocker, CDN outage, JS disabled),
 *     `.kbm-blog-js` is never added and NONE of these opacity:0 rules ever
 *     match. Content is visible by default — the unhidden state requires no
 *     JS at all. This is a hard requirement, not a nice-to-have.
 *   - The hiding is done STRUCTURALLY (by selector, matching the exact
 *     "direct child of the post-content container" convention the JS also
 *     uses) rather than by waiting for JS to walk the DOM and tag each
 *     section with a class first. That removes any race between first paint
 *     and JS discovery — the moment `.kbm-blog-js` lands on <html>, the CSS
 *     engine (not a later JS pass) is what hides the sections.
 *
 * CONTENT CONVENTION this selector list encodes (see blog-scroll-reveal.js
 * header comment for the full writeup):
 *   - Native/Astra template output: every direct child of `.entry-content`
 *     is a "section".
 *   - Elementor Theme Builder "Post Content" dynamic widget: every direct
 *     child of the `.elementor-widget-container` INSIDE
 *     `.elementor-widget-theme-post-content` is a "section". (Deliberately
 *     NOT the bare `.elementor-widget-container` selector — that class is
 *     used by every Elementor widget site-wide, including header/footer/
 *     sidebar widgets, and hiding its children generically would break
 *     unrelated page chrome.)
 */

.kbm-blog-js .entry-content > *,
.kbm-blog-js .elementor-widget-theme-post-content .elementor-widget-container > * {
  opacity: 0;
}

/* Opt-out escape hatch — an author or a future template can mark any
   top-level element with this class to exempt it from the reveal (e.g. a
   hero/intro block that should already be visible on load). Not required
   for the convention to work; purely a manual override when needed. */
.kbm-blog-js .kbm-blog-no-reveal {
  opacity: 1 !important;
  transform: none !important;
}

/* Parallax clip frame — applied by JS (kbm-blog-parallax-frame) to the
   nearest block ancestor of any <img> found inside a section (a Gutenberg
   <figure>, the img's own parent, or the img itself if unwrapped). The image
   inside is deliberately scaled up (via GSAP, see the JS) so a vertical
   parallax drift never exposes empty edges — this element is what clips
   that overscan. */
.kbm-blog-parallax-frame {
  overflow: hidden;
  position: relative;
}

.kbm-blog-parallax-img {
  /* No forced width/height/object-fit here on purpose: WP content images
     keep their normal natural-aspect-ratio box. The JS scales the <img> up
     ~12% via a GSAP transform (paint-only, doesn't change layout size), and
     the overflow:hidden frame above clips that overscan as it drifts — no
     dependency on the frame having an explicit height. */
  display: block;
}

/* Belt-and-suspenders: even though blog-scroll-reveal.js checks
   prefers-reduced-motion before running ANY GSAP code (and skips straight to
   "reveal everything, no animation" if it's set), this media query
   guarantees visibility from CSS alone in case a future edit to the JS ever
   regresses that check. */
@media (prefers-reduced-motion: reduce) {
  .kbm-blog-js .entry-content > *,
  .kbm-blog-js .elementor-widget-theme-post-content .elementor-widget-container > * {
    opacity: 1 !important;
    transform: none !important;
  }
  .kbm-blog-parallax-img {
    transform: none !important;
  }
}
