/* Interior page heroes: an atmospheric photograph washed behind the copy.
   The home page frames its image around a product window; these pages set the
   copy directly on top, so legibility cannot depend on the photograph being
   quiet. Two layers do that job instead — a per-theme opacity on the image and
   a background-coloured scrim under the text column — which lets a real, busy
   photograph sit here without being chosen for its emptiness.

   All four interior frames are shot the same way: low-key, subject in the right
   half, near-black wall or sky filling the left where the copy lands. The tone
   treatment below assumes that, and only the crop bias varies per page. */

.page-hero {
  position: relative;
  isolation: isolate; /* keeps the layers below off any stacking context above */
  overflow: hidden;   /* the image is full-bleed; nothing escapes the band */
}

.page-hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  /* The pale field is the hard one: a dark photograph washed over white has to
     be held back or it lands as a smudge. No brightness lift — the dark shapes
     are the signal here, and lifting them is what makes the frame disappear. */
  opacity: 0.4;
  filter: grayscale(0.45);
  /* Fade the top, bottom and right edges into the page. The left edge is left
     alone: the scrim already takes it down to flat background. */
  -webkit-mask-image: linear-gradient(to right, #000 0%, #000 82%, transparent 100%),
    linear-gradient(to bottom, transparent 0%, #000 18%, #000 82%, transparent 100%);
  mask-image: linear-gradient(to right, #000 0%, #000 82%, transparent 100%),
    linear-gradient(to bottom, transparent 0%, #000 18%, #000 82%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}

/* The dark field is where these frames are already at home, so they run near
   full strength with only a light desaturation: the near-black side of each one
   sits under the copy and the lit side reads as a photograph rather than a
   texture. */
.dark .page-hero__bg {
  opacity: 0.92;
  filter: grayscale(0.3);
}

.page-hero__bg img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

/* Crop bias, one rule per frame. Each source is cut close above its subject and
   far wider than it is tall, so cover has to trim: horizontally at narrow
   viewports, vertically once the band passes roughly 3.7:1. The horizontal
   number aims that trim at the empty left rather than at the subject; the
   vertical one keeps it on the floor rather than on faces and rooflines. */
.page-hero--consulting .page-hero__bg img {
  object-position: 70% 18%;
}

/* Strat-OS carries a third figure already clipped by the top of the source
   frame, so it takes no vertical bias at all: any trim off the top comes
   straight out of what is left of him, and the desk can be spared instead. */
.page-hero--stratos .page-hero__bg img {
  object-position: 68% top;
}

.page-hero--about .page-hero__bg img {
  object-position: 62% 18%;
}

.page-hero--contact .page-hero__bg img {
  object-position: 65% 18%;
}

/* The legibility layer. Copy is left-aligned in the left half, so the scrim is
   opaque there and clears entirely by the time it reaches the open right side
   where the photograph is meant to be seen. */
.page-hero__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    to right,
    var(--color-background) 0%,
    var(--color-background) 26%,
    color-mix(in oklab, var(--color-background) 72%, transparent) 52%,
    transparent 72%
  );
}

.page-hero__inner {
  position: relative;
  z-index: 2;
}

/* Below lg the copy runs the full width, so a horizontal scrim cannot protect
   it. Cover the whole band instead and let the photograph sit further back. */
@media (max-width: 1023px) {
  .page-hero__bg { opacity: 0.16; }
  .dark .page-hero__bg { opacity: 0.55; }
  .page-hero__scrim {
    background: linear-gradient(
      to right,
      var(--color-background) 0%,
      color-mix(in oklab, var(--color-background) 84%, transparent) 60%,
      color-mix(in oklab, var(--color-background) 62%, transparent) 100%
    );
  }
}
