/* ---------------------------------------------------------------------------
   parallax.css — scroll-linked image depth.

   Ported from the motion study of mtechnikbmw.net (Squarespace 7.0 Momentum,
   `positionIndexImages()`, drift constant h = 0.8). That template pinned each
   image into a position:fixed 100vh box and counter-translated the image by
   -0.8 x the section offset, so the on-screen image moved at 20% of scroll
   speed while content moved at 100%.

   Our sections are in normal flow, not fixed, so the same 20% is produced a
   different way: the image is overscaled by `--px-travel` top and bottom, and
   JS translates it within +/- that slack. Because |translate| never exceeds the
   slack, an edge can never be exposed. See parallax.js for the derivation.

   Everything here is scoped under `html.px-on`, a class JS adds only when the
   effect is actually allowed to run. With JS off, with reduced motion, or on
   touch/narrow screens, none of these rules apply and the page renders exactly
   as it does today.

   CONTAINER GEOMETRY
     Absolutely positioning the image takes it out of flow, so each container
     must already have its own height or it would collapse to nothing. All
     three homepage containers do, in the public stylesheet, and nothing here
     touches those declarations:

       .luxury-home-hero          min-height: min(920px, 100svh)
       .luxury-brand-panel        min-height: 520px
       .luxury-landscape-feature  min-height: clamp(680px, 80vw, 880px)

     A future container without an intrinsic height needs one added there, not
     patched in here.
   --------------------------------------------------------------------------- */

html.px-on [data-parallax] {
  position: relative;
  overflow: hidden;
}

/* <picture> generates no box, so the <img> positions against [data-parallax]. */
html.px-on [data-parallax] picture {
  display: contents;
}

html.px-on [data-parallax] [data-parallax-image] {
  position: absolute;
  left: 0;
  right: auto;
  bottom: auto;
  margin: 0;
  width: 100%;
  top: calc(-1 * var(--px-travel, 10%));
  height: calc(100% + 2 * var(--px-travel, 10%));
  /* The overscale is taller than the container by construction, so an
     inherited cap would clip it and re-expose the edge the overscale exists to
     hide. `right`/`bottom`/`margin` above are here for the same reason: a site
     rule with `inset: 0` would otherwise stretch the image back to the box. */
  max-width: none;
  max-height: none;
  object-fit: cover;
  /* object-position is deliberately not set: the site stylesheet owns each
     image's crop, including the responsive variants on the team panel. */
  transform: translate3d(0, var(--px-y, 0px), 0);
  will-change: transform;
}

/* Belt and braces. JS already refuses to add .px-on under reduced motion; this
   makes the CSS side inert too, in case the class is ever set another way. */
@media (prefers-reduced-motion: reduce) {
  html.px-on [data-parallax] [data-parallax-image] {
    top: 0;
    height: 100%;
    transform: none;
    will-change: auto;
  }
}

/* --- The Stretch Guru -------------------------------------------------------
   Single container: the session photograph on the homepage "For real life and
   performance" band.

   CONTAINER GEOMETRY
     The site's own rule is `.sg-photo img { width:100%; aspect-ratio:3/4 }` --
     the FIGURE has no height of its own, it is sized by the image plus the
     caption below it. Taking the image out of flow would therefore collapse
     the figure to just its caption.

     So the mu-plugin wraps the image in `.sg-photo-frame` and that frame, not
     the figure, is the parallax container. The frame carries the 3/4 ratio
     unconditionally -- with JS, without JS, and under reduced motion -- so the
     card occupies exactly the same space it did before this module existed.
     The image still fills it (`width:100%`, `object-fit:cover`, same ratio),
     so the enhanced and static renderings are pixel-identical at rest.

     `.sg-photo` keeps `overflow:hidden` and `border-radius:16px`, so the
     drifting image stays clipped to the card's rounded corners.
   -------------------------------------------------------------------------- */
.sg-photo-grid,
.sg-photo-frame {
  width: 100%;
}

.sg-photo-frame {
  aspect-ratio: 3 / 4;
}

.sg-photo .sg-photo-frame > img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* The image is lazy-loaded and hosted off-site. Until it decodes there is
   nothing to see inside the frame, and a bare white rectangle reads as a
   broken card. This is the card's own border colour, so the placeholder looks
   deliberate rather than empty. */
.sg-photo-frame {
  background: #e8eefc;
}
