/* CLEO Website Core — motion.
   Accessibility-first: content is fully visible and static by default.
   The hidden-then-reveal states below only activate when the visitor's
   browser reports no reduced-motion preference AND JS has confirmed it
   can run (via the .motion-ready class on <html>). If JS never runs, or
   the visitor prefers reduced motion, nothing here ever hides anything. */

@media (prefers-reduced-motion: no-preference) {
    html.motion-ready [data-reveal] {
        opacity: 0;
        transform: translateY(var(--cleo-motion-distance, 16px));
        transition: opacity var(--cleo-motion-duration, 500ms) var(--cleo-motion-easing, ease),
                    transform var(--cleo-motion-duration, 500ms) var(--cleo-motion-easing, ease);
    }

    html.motion-ready [data-reveal].is-visible {
        opacity: 1;
        transform: none;
    }

    html.motion-ready [data-reveal-group] > * {
        transition-delay: calc(var(--cleo-motion-stagger, 80ms) * var(--reveal-index, 0));
    }

    /* Clarity Engine motion language (2026-08-18): a distinct sibling of
       [data-reveal] reserved for headline-weight moments — "resolves into
       focus" (blur -> sharp) rather than "rises into place" (translateY).
       Deliberately NOT applied to every [data-reveal] element site-wide;
       see core/helpers.php's cleo_reveal_focus_attrs() doc comment and
       docs/DESIGN-SYSTEM.md for where this is and isn't used.

       Blur radius and duration are deliberately larger/slower than the
       standard [data-reveal] fade (20px over ~1.6x the base duration, vs a
       16px translateY over 1x) — visual-review feedback on the first pass
       (10px/1x) was that it read as indistinguishable from a plain fade at
       normal scrolling speed. This is a one-time-per-pageload entrance
       (unobserved after it fires, same as [data-reveal]) — a fresh page
       load, not just scrolling back up, is needed to see it again. */
    html.motion-ready [data-reveal-focus] {
        opacity: 0;
        filter: blur(20px);
        transition: opacity calc(var(--cleo-motion-duration, 500ms) * 1.6) var(--cleo-motion-easing, ease),
                    filter calc(var(--cleo-motion-duration, 500ms) * 1.6) var(--cleo-motion-easing, ease);
    }

    html.motion-ready [data-reveal-focus].is-visible {
        opacity: 1;
        filter: blur(0);
    }

    /* Depth-to-clarity PROTOTYPE (2026-08-18) — not yet a documented
       docs/DESIGN-SYSTEM.md catalog primitive, scoped to the homepage hero
       and "Everything We Cover" only while under review
       (core/helpers.php's cleo_reveal_depth_attrs() doc comment has the
       full rationale). Three focal planes instead of one uniform blur:
       - back  (background media): filter only, no opacity — media should
         never disappear, only soften/clear. Shallow blur, resolves first.
       - mid   (the dominant subject, e.g. a headline): deepest blur,
         longest duration, a distinct decelerate curve instead of the
         site's standard easing, and a short lag before it starts — focus
         visibly "pulls toward" this element rather than everything
         resolving in lockstep.
       - front (supporting copy/CTA): shallowest blur, starts latest but
         resolves quickest, like detail that was barely out of focus.
       All three are one-time-per-pageload/per-scroll-into-view transitions
       (never continuous, never tied to a scroll listener), so this adds no
       new scroll cost — it rides the exact same shared IntersectionObserver
       every other [data-reveal*] attribute already uses. */
    html.motion-ready [data-reveal-depth] {
        opacity: 0;
    }
    html.motion-ready [data-reveal-depth="back"] {
        opacity: 1;
        filter: blur(10px);
        transition: filter calc(var(--cleo-motion-duration, 500ms) * 1) var(--cleo-motion-easing, ease) 0ms;
    }
    html.motion-ready [data-reveal-depth="mid"] {
        filter: blur(28px);
        transition: opacity calc(var(--cleo-motion-duration, 500ms) * 1.5) cubic-bezier(.22, 1, .36, 1) 150ms,
                    filter calc(var(--cleo-motion-duration, 500ms) * 1.5) cubic-bezier(.22, 1, .36, 1) 150ms;
    }
    html.motion-ready [data-reveal-depth="front"] {
        filter: blur(8px);
        transition: opacity calc(var(--cleo-motion-duration, 500ms) * .9) var(--cleo-motion-easing, ease) 380ms,
                    filter calc(var(--cleo-motion-duration, 500ms) * .9) var(--cleo-motion-easing, ease) 380ms;
    }
    html.motion-ready [data-reveal-depth].is-visible {
        opacity: 1;
        filter: blur(0);
    }

    html.motion-ready .cleo-hero[data-hero-motion="fade"] .hero-motion-target {
        animation: cleo-hero-fade var(--cleo-motion-duration, 500ms) var(--cleo-motion-easing, ease) both;
    }

    html.motion-ready .cleo-hero[data-hero-motion="fade-rise"] .hero-motion-target {
        animation: cleo-hero-fade-rise calc(var(--cleo-motion-duration, 500ms) * 1.3) var(--cleo-motion-easing, ease) both;
    }

    html.motion-ready .cleo-hero[data-hero-motion="scale-in"] .hero-motion-target {
        animation: cleo-hero-scale-in var(--cleo-motion-duration, 500ms) var(--cleo-motion-easing, ease) both;
    }

    /* Clarity Engine hero entrance: the hero-level equivalent of
       [data-reveal-focus] above, using the hero's own load-time animation
       mechanism (see components/hero.php's doc comment on why hero entrance
       can't use the scroll-triggered IntersectionObserver system). Strength/
       duration bumped alongside [data-reveal-focus] above for the same
       legibility reason — this plays once, in the first instant of page
       load, so it needs to read clearly on the very first look, not just
       on close inspection of a screenshot. */
    html.motion-ready .cleo-hero[data-hero-motion="focus-pull"] .hero-motion-target {
        animation: cleo-hero-focus-pull calc(var(--cleo-motion-duration, 500ms) * 1.7) var(--cleo-motion-easing, ease) both;
    }

    /* Depth-to-clarity PROTOTYPE, hero entrance (2026-08-18) — the hero-level
       equivalent of [data-reveal-depth] above, using the hero's own
       load-time animation mechanism since hero content is always in the
       initial viewport (see components/hero.php's doc comment). Requires
       hero_motion: "depth-pull" in the Manifest AND the immersive variant's
       hero-depth-mid/hero-depth-front markup (components/hero.php) — an
       inert combination for every other hero_motion value, so this can't
       regress fade/fade-rise/scale-in/focus-pull. */
    html.motion-ready .cleo-hero[data-hero-motion="depth-pull"] .hero-immersive-media {
        animation: cleo-depth-back calc(var(--cleo-motion-duration, 500ms) * 1) var(--cleo-motion-easing, ease) both;
    }
    html.motion-ready .cleo-hero[data-hero-motion="depth-pull"] .hero-depth-mid {
        animation: cleo-depth-mid calc(var(--cleo-motion-duration, 500ms) * 1.5) cubic-bezier(.22, 1, .36, 1) 150ms both;
    }
    html.motion-ready .cleo-hero[data-hero-motion="depth-pull"] .hero-depth-front {
        animation: cleo-depth-front calc(var(--cleo-motion-duration, 500ms) * .9) var(--cleo-motion-easing, ease) 380ms both;
    }

    /* CLEO chatbot launcher (assets/css/chatbot.css): a brief "iris settling
       into focus" pulse on the gold ring when the panel opens
       (assets/js/chatbot.js toggles .is-open) — Level 3 "interactive"
       motion (docs/DESIGN-SYSTEM.md's motion hierarchy), gated the same as
       everything else here. Without motion, the panel simply opens with no
       pulse — a fully correct, unbroken static state. */
    html.motion-ready .cleo-chatbot-launcher.is-open::before {
        animation: cleo-chatbot-focus-pull var(--cleo-motion-duration, 500ms) var(--cleo-motion-easing, ease) both;
    }

    html.motion-ready [data-hover-micro] {
        transition: transform .25s ease, box-shadow .25s ease;
    }

    html.motion-ready [data-hover-micro]:hover {
        transform: translateY(-3px);
    }

    html.motion-ready .button[data-hover-micro]:hover {
        transform: translateY(-2px) scale(1.02);
    }

    /* Movement as default texture, not just an entrance flourish (see
       docs/DESIGN-SYSTEM.md's "Cinematic & immersive" section): a slow,
       continuous Ken-Burns drift on non-video hero media, and a slow drift
       on the zero-asset cinematic gradient fallback. Both no-ops when
       motion is disabled/reduced — the hero media then simply holds still,
       which is a fully correct, intentional static state, not a bug.

       `.trust-proof-media` is deliberately EXCLUDED here (2026-08-17
       scroll-performance pass): it sits directly behind `.trust-proof-panel`'s
       `backdrop-filter` blur, which must re-sample its backdrop continuously
       while anything behind it is transforming — a drift that's barely
       perceptible through frosted glass was nonetheless one of the more
       expensive things on the homepage. `hotspot-map`'s panel has no media
       drifting behind it, so it isn't affected by this same issue. */
    .hero-immersive-media.cleo-media,
    .hero-immersive-media.hero-immersive-cinematic-fallback,
    .editorial-band-media.cleo-media,
    .editorial-band-media.hero-immersive-cinematic-fallback,
    .media-sequence-media.cleo-media,
    .media-sequence-media.hero-immersive-cinematic-fallback {
        animation: cleo-hero-kenburns 26s ease-in-out infinite alternate;
    }
    .hero-immersive-media.hero-immersive-cinematic-fallback,
    .editorial-band-media.hero-immersive-cinematic-fallback,
    .media-sequence-media.hero-immersive-cinematic-fallback {
        animation-name: cleo-hero-gradient-drift;
        animation-duration: 22s;
    }
}

@keyframes cleo-hero-kenburns {
    from { transform: scale(1); }
    to { transform: scale(1.06); }
}

@keyframes cleo-hero-gradient-drift {
    from { background-position: 0% 0%, 0% 0%; }
    to { background-position: 30% 25%, 0% 0%; }
}

@keyframes cleo-hero-fade {
    from { opacity: 0; }
    to { opacity: 1; }
}

@keyframes cleo-hero-fade-rise {
    from { opacity: 0; transform: translateY(18px); }
    to { opacity: 1; transform: none; }
}

@keyframes cleo-hero-scale-in {
    from { opacity: 0; transform: scale(.96); }
    to { opacity: 1; transform: none; }
}

@keyframes cleo-hero-focus-pull {
    from { opacity: 0; filter: blur(24px); }
    to { opacity: 1; filter: blur(0); }
}

@keyframes cleo-depth-back {
    from { filter: blur(10px); }
    to { filter: blur(0); }
}

@keyframes cleo-depth-mid {
    from { opacity: 0; filter: blur(28px); }
    to { opacity: 1; filter: blur(0); }
}

@keyframes cleo-depth-front {
    from { opacity: 0; filter: blur(8px); }
    to { opacity: 1; filter: blur(0); }
}

@keyframes cleo-chatbot-focus-pull {
    0% { transform: scale(.85); opacity: .6; }
    60% { transform: scale(1.08); opacity: 1; }
    100% { transform: scale(1); opacity: 1; }
}
