/* Progressive background blur behind the hero copy — Figma 1:1276.

   The headline scrolls over the pinned clip, and until the Hero-Overlay has
   faded to full strength (272px from y=420) she reads straight through the
   text. This blurs the part of the image that sits under the copy, and lays a
   light wash over it, so the text has something to sit on.

   CSS has no progressive blur, so it is a stack of `backdrop-filter` layers
   with doubling radii, each masked to a band that begins where the one above
   has reached full opacity. The blur ramps from nothing at the top edge to
   heavy at the bottom, with no step in between.

   THE TRAP, and it cost several rounds: `backdrop-filter` samples what is
   painted behind the element, but a `mask` (or `filter`, or `opacity` below 1)
   on ANY ancestor makes that ancestor a backdrop root, and descendants can
   then only sample inside it. The first version put the edge fades on the
   container, which paints nothing — so every layer dutifully blurred an empty
   backdrop and the result was invisible. Nothing here may carry a mask except
   the layers themselves. Each one therefore composites its own edge fades.

   `backdrop-filter` is acceptable here even though LOG.md rules it out for the
   veil: the objection was Chromium dropping bands out of a 4600px-tall layer,
   and these are one panel tall. */

/* ── The veil over the pinned clip ──────────────────────────────────────────
   Figma's blur on this node is PROGRESSIVE. Dev mode cannot express that, so
   it prints a flat `backdrop-filter: blur(50px)` — which, taken literally,
   switches from sharp to fully blurred at one line and draws a hard edge
   across her. Building it literally is what put that edge on the page.

   The construction is lifted from the reference Flora sent
   (numerical-slider-495510.framer.app), whose hero does exactly this:

     backdrop-filter: blur(20px);
     mask: linear-gradient(180deg, rgba(0,0,0,0) 5%, rgba(0,0,0,0.47) 50%, rgba(0,0,0,1) 100%)

   One layer, constant radius, and a three-stop mask that ramps how much of it
   lands. A constant blur fading in reads as a blur growing, so there is no
   band to see, and it costs one filter pass rather than a stack of them.

   The layer is one clip tall, so the ramp travels with the pinned clip instead
   of sitting at a fixed page position. It needs no bottom fade: below the clip
   the backdrop is flat page grey, and a blur of flat grey is flat grey. */

.veil-onset,
.hero-overlay span,
.page-veil span {
  -webkit-backdrop-filter: blur(64px);
  backdrop-filter: blur(64px);
}

/* The onset. Static, sitting at the top of the range, so its ramp is measured
   in PAGE coordinates — which is the only place it can be. It gives the smooth
   entry at y=420 that stops the filter drawing a line where it begins. */
.veil-onset {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 300px;
  -webkit-mask-image: linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,1) 100%);
  mask-image: linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,1) 100%);
}

/* The pinned layer. It begins where the onset ends, so it never has to fade in
   at its own top edge — which is what left the top of her head sharp: a ramp
   measured down a pinned layer is measured down the VIEWPORT, so the softest
   part of it sits at the top of the screen forever, however far you scroll. */
.hero-overlay span,
.page-veil span {
  position: absolute;
  inset: 0;
  display: block;
}

/* ── The blur behind the hero copy ────────────────────────────────────────── */

.progressive-blur {
  position: absolute;
  /* Bleed past the panel. The sideways overshoot clears the 640 column, so no
     vertical edge is drawn down the middle of the clip. */
  top: -40px;
  bottom: -56px;
  left: -72px;
  right: -72px;
  z-index: -1;
  pointer-events: none;
  /* No mask, no filter, no opacity on this element. See above. */
}

.progressive-blur span {
  position: absolute;
  inset: 0;
  display: block;
  /* Every layer carries the same two edge fades, intersected with whatever
     band it is responsible for: down the page so the stack dissolves into the
     veil, and across so it ends before its own box does. */
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
}

/* Doubling radii. The second gradient in each pair is the shared side fade;
   the bottom fade is folded into the first, since both run down the page. */
.progressive-blur span:nth-child(1) {
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  -webkit-mask-image:
    linear-gradient(to bottom, rgba(0,0,0,0) 0%, #000 14%, #000 82%, rgba(0,0,0,0) 100%),
    linear-gradient(to right, rgba(0,0,0,0) 0, #000 14%, #000 86%, rgba(0,0,0,0) 100%);
  mask-image:
    linear-gradient(to bottom, rgba(0,0,0,0) 0%, #000 14%, #000 82%, rgba(0,0,0,0) 100%),
    linear-gradient(to right, rgba(0,0,0,0) 0, #000 14%, #000 86%, rgba(0,0,0,0) 100%);
}

.progressive-blur span:nth-child(2) {
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  -webkit-mask-image:
    linear-gradient(to bottom, rgba(0,0,0,0) 14%, #000 29%, #000 82%, rgba(0,0,0,0) 100%),
    linear-gradient(to right, rgba(0,0,0,0) 0, #000 14%, #000 86%, rgba(0,0,0,0) 100%);
  mask-image:
    linear-gradient(to bottom, rgba(0,0,0,0) 14%, #000 29%, #000 82%, rgba(0,0,0,0) 100%),
    linear-gradient(to right, rgba(0,0,0,0) 0, #000 14%, #000 86%, rgba(0,0,0,0) 100%);
}

.progressive-blur span:nth-child(3) {
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  -webkit-mask-image:
    linear-gradient(to bottom, rgba(0,0,0,0) 29%, #000 43%, #000 82%, rgba(0,0,0,0) 100%),
    linear-gradient(to right, rgba(0,0,0,0) 0, #000 14%, #000 86%, rgba(0,0,0,0) 100%);
  mask-image:
    linear-gradient(to bottom, rgba(0,0,0,0) 29%, #000 43%, #000 82%, rgba(0,0,0,0) 100%),
    linear-gradient(to right, rgba(0,0,0,0) 0, #000 14%, #000 86%, rgba(0,0,0,0) 100%);
}

.progressive-blur span:nth-child(4) {
  -webkit-backdrop-filter: blur(16px);
  backdrop-filter: blur(16px);
  -webkit-mask-image:
    linear-gradient(to bottom, rgba(0,0,0,0) 43%, #000 57%, #000 82%, rgba(0,0,0,0) 100%),
    linear-gradient(to right, rgba(0,0,0,0) 0, #000 14%, #000 86%, rgba(0,0,0,0) 100%);
  mask-image:
    linear-gradient(to bottom, rgba(0,0,0,0) 43%, #000 57%, #000 82%, rgba(0,0,0,0) 100%),
    linear-gradient(to right, rgba(0,0,0,0) 0, #000 14%, #000 86%, rgba(0,0,0,0) 100%);
}

.progressive-blur span:nth-child(5) {
  -webkit-backdrop-filter: blur(32px);
  backdrop-filter: blur(32px);
  -webkit-mask-image:
    linear-gradient(to bottom, rgba(0,0,0,0) 57%, #000 71%, #000 82%, rgba(0,0,0,0) 100%),
    linear-gradient(to right, rgba(0,0,0,0) 0, #000 14%, #000 86%, rgba(0,0,0,0) 100%);
  mask-image:
    linear-gradient(to bottom, rgba(0,0,0,0) 57%, #000 71%, #000 82%, rgba(0,0,0,0) 100%),
    linear-gradient(to right, rgba(0,0,0,0) 0, #000 14%, #000 86%, rgba(0,0,0,0) 100%);
}

/* The wash. No blur of its own — it sits on top of the five blurred layers and
   lifts the whole area a little toward the page grey, which is what actually
   makes the copy readable. Deliberately light: at 0.28 the silhouette is still
   clearly there behind the words. */
.progressive-blur span:nth-child(6) {
  background: var(--grey-background-100);
  opacity: 0.28;
  -webkit-mask-image:
    linear-gradient(to bottom, rgba(0,0,0,0) 0%, #000 18%, #000 82%, rgba(0,0,0,0) 100%),
    linear-gradient(to right, rgba(0,0,0,0) 0, #000 14%, #000 86%, rgba(0,0,0,0) 100%);
  mask-image:
    linear-gradient(to bottom, rgba(0,0,0,0) 0%, #000 18%, #000 82%, rgba(0,0,0,0) 100%),
    linear-gradient(to right, rgba(0,0,0,0) 0, #000 14%, #000 86%, rgba(0,0,0,0) 100%);
}

@media (max-width: 700px) {
  /* The column is the full screen here, so the sideways bleed has nowhere to
     go — `overflow-x: clip` on .scroll would cut it. Keep it inside. */
  .progressive-blur {
    left: -16px;
    right: -16px;
    top: -32px;
    bottom: -40px;
  }
}
