/*
 * ParallaxImage styles — served as a plain static asset via
 * _content/DeepDrftShared.Client/css/parallax.css.
 *
 * Why global, not scoped (.razor.css):
 *   DeepDrftShared.Client is a WASM RCL referenced only by DeepDrftPublic.Client,
 *   not by the DeepDrftPublic server host. Blazor merges scoped-CSS bundles only
 *   from RCLs the *host* references, so this component's scoped bundle is absent
 *   from DeepDrftPublic.styles.css and never reaches the SSR first paint — it
 *   arrives only after WASM boots. Structural rules AND the scroll-driven
 *   animation must be present at first paint, so they live here as global CSS,
 *   delivered as a static web asset regardless of which project references the RCL.
 *
 * ParallaxImage is the sole producer of .parallax-window / .layer, so unscoped
 * class selectors are unambiguous.
 */

.parallax-window {
    position: relative;
    overflow: hidden;
    height: var(--window-height, 300px);
    width: 100%;
}

.parallax-window.full-width {
    width: 100vw;
    position: relative;
    left: 50%;
    right: 50%;
    margin-left: -50vw;
    margin-right: -50vw;
}

.layer {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-repeat: no-repeat;
    background-position-x: 50%;
    background-position-y: var(--parallax-from, 0%);
}

.layer-1 {
    opacity: 1;
}

.layer-2 {
    opacity: 0;
    transition: opacity 700ms ease;
}

.parallax-window:hover .layer-2 {
    opacity: 1;
}

/*
 * Scroll-driven parallax, present at SSR first paint (no JS, no custom-property
 * inheritance chain):
 *
 * Before WASM:
 *   The view() timeline animates background-position-y on each .layer directly,
 *   from --parallax-from to --parallax-to (both percentages set inline on
 *   .parallax-window by the component, encoding ParallaxSpeed/InvertDirection).
 *   The layer pans as the window scrolls through the viewport — correct from
 *   first paint.
 *
 * After WASM:
 *   JS sets data-parallax-active on .parallax-window, which cancels the CSS
 *   animation (animation: none). JS then drives background-position-y via the
 *   scroll listener. One writer at a time — the two never compete.
 *
 * prefers-reduced-motion:
 *   animation: none → static image at --parallax-from. JS also skips its
 *   scroll listener (see parallax.ts), so the image stays put.
 */
@supports (animation-timeline: view()) {
    @keyframes parallax-pan {
        from { background-position-y: var(--parallax-from, 0%); }
        to   { background-position-y: var(--parallax-to,   0%); }
    }

    /* Animate layers directly — no --parallax-pos inheritance chain.
       .parallax-window uses overflow: hidden, which establishes a block
       formatting context but NOT a scroll container (that needs overflow:
       scroll/auto), so view() correctly resolves to the root scroller. */
    .parallax-window > .layer {
        animation: parallax-pan linear both;
        animation-timeline: view();
    }

    /* JS takes over on register: cancel the CSS animation so the two writers
       to background-position-y never compete. */
    .parallax-window[data-parallax-active] > .layer {
        animation: none;
    }

    @media (prefers-reduced-motion: reduce) {
        .parallax-window > .layer {
            animation: none;
        }
    }
}

@media (prefers-reduced-motion: reduce) {
    .layer-2 {
        transition-duration: 0ms;
    }
}
