/* ============================================================================
   scroll-reveal-v1.css — pure-CSS scroll-driven reveal language.

   Cards and section headers gently fade-and-rise (opacity 0 -> 1,
   translateY 14px -> 0) as they enter the viewport, driven by
   `animation-timeline: view()` — no JS, no IntersectionObserver.

   Hard gates (both required, in order):
   1. @media screen + prefers-reduced-motion: no-preference — reduced-motion
      users and print output get the fully static page.
   2. @supports (animation-timeline: view()) — browsers without scroll-driven
      animations (Firefox without the flag) skip everything here and render
      fully static. No fallback class, no hidden content, zero degradation.

   Constraints:
   - Animates ONLY opacity + transform. Never height/margin (zero CLS).
   - Keyframes declare a `from` state only. The implicit `to` resolves to the
     element's underlying styles, so once the reveal completes the animation
     stops overriding the cascade — card :hover lifts (transform:
     translateY(-3px) on .hg-beta-blog-card, .blog-mag-lead-card, etc.)
     keep working. A filled `to { transform: none }` would beat them forever.
   - Reveal completes within the first ~55% of the element's own entry —
     small distance, quick travel, Aman-restraint not parallax circus.
   - Selectors are an explicit allowlist of card + header classes. Ad
     containers (.hgads*, injected by ad-injector-v5.js) and widget interiors
     (.no-ad-inject) are never matched — do not add broad selectors like
     `section > *` here.

   view() timeline gotcha for future editors: the timeline tracks the nearest
   ancestor SCROLL CONTAINER, and `overflow: hidden` creates one. If a target
   ever gains an overflow:hidden/auto ancestor (other than body, whose
   overflow-x propagates to the viewport), its reveal freezes at opacity 0.
   Every class below was checked against homepage-beta-v1.css,
   island-guide-compass-v1.css, blog-magazine-v1.css and inline styles —
   re-check before adding new targets.
   ============================================================================ */

@media screen and (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {

    /* The master stylesheet sets body { overflow-x: hidden } (a horizontal-
       scrollbar guard), which makes body compute overflow: hidden auto — a
       scroll container. view() resolves to the NEAREST scroll container, so
       every timeline below would attach to body, which never scrolls (the
       viewport does), freezing all reveals at opacity 0. Verified live in
       Chromium. `clip` clips horizontal overflow exactly the same (when
       propagated to the viewport, clip is interpreted as hidden) but does
       NOT create a scroll container, so timelines track the viewport.
       Scoped inside both gates: browsers without view() keep the original
       overflow-x: hidden untouched. */
    body {
      overflow-x: clip;
    }

    @keyframes hg-scroll-reveal-rise {
      from {
        opacity: 0;
        transform: translateY(14px);
      }
    }

    /* --- Section headers ---------------------------------------------------
       Homepage + /blog magazine + blog hub rails all share
       .hg-beta-section > .hg-beta-section-header. */
    .hg-beta-section > .hg-beta-section-header,

    /* --- Homepage card grids -----------------------------------------------
       .hg-beta-bookcard is deliberately ABSENT: homepage-beta-v1.css puts a
       lazyload shimmer (`animation: hgShimmer`) on the bookcard root itself
       via :has(img.lazyload) at higher specificity. A reveal animation on
       the same element would hand off mid-entry when the image finishes
       loading — a visible flicker. Book-the-Trip cards stay static. */
    .hg-beta-island-card,
    .hg-beta-toolcard,
    .hg-beta-blog-card,
    .hg-beta-country-card,

    /* --- Island homepage section bands (igc compass) ----------------------- */
    .igc-card,
    .igc-2026-step,

    /* --- /blog magazine layout cards ---------------------------------------
       (.hg-beta-blog-card above already covers the rail + see-all cards) */
    .blog-mag-lead-card,
    .blog-mag-desk-card,
    .blog-mag-island-card {
      animation: hg-scroll-reveal-rise ease-out both;
      animation-timeline: view();
      /* Start as the element's top crosses the viewport bottom; fully
         revealed once 55% of the element has entered. Short elements
         (headers) resolve to ~80-100px of scroll travel, cards to
         ~200-250px — a quick, quiet settle either way. */
      animation-range: entry 0% entry 55%;
    }
  }
}
