/* ===========================================================================
   less2own — the house-build sequence, INSIDE the descent hero's own pin.

   It began as its own <section> below the hero and Tony asked for it to be
   part of the hero instead: "id like it if it was a part of the original hero,
   not just on the page below it." That is not a styling change, it is a
   structural one — two sticky sections means the first unpins and the second
   pins, and no amount of matching the frames hides that seam. One pin means
   the camera never lets go.

   So the hero section runs 1240vh now (640 descent + 600 build), this layer is
   absolutely positioned over `.gvmap-wrap` inside `.hero-pin`, and the two
   hand over inside a wash rather than a cross-dissolve.
   =========================================================================== */

/* ---- the layer that carries the build ----------------------------------
   Z-INDEX 20, NOT 6, AND THE NUMBER IS NOT ARBITRARY. `.gvmap-wrap` sets no
   stacking context of its own, so the hero's overlays inside it compete
   directly with this layer: `.map-legend` and `.scroll-hint` are 6,
   `.hero-end` — Ronnie's card and the CTAs — and `.rates-tile` are 7, and
   `.sl-toast` is 8. At 6 this layer would have had the loan officer's plate
   painted on top of the framing. 20 clears all of them and still sits under
   the lead modal (1000/2000) and the /build overlay (1400). */
.bs-layer{position:absolute;inset:0;z-index:20;opacity:0;pointer-events:none;
  background:#0a0e16}
/* NOT `display:none` WHEN IDLE, AND THAT IS THE POINT OF A SEPARATE CLASS.
   `bs-off` is the state on a box where the sequence has not rendered — the
   layer must never paint at all, or it would sit as a black sheet over a
   perfectly good hero. Once frame 1 loads the script removes it and opacity
   alone takes over, because opacity can be driven per-frame and display
   cannot. */
.bs-layer.bs-off{display:none}
.bs-layer.lit{pointer-events:auto}

.bs-stage{position:absolute;inset:0}
.bs-stage img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  display:block;opacity:0;transition:opacity .18s linear}
.bs-stage img.on{opacity:1}

/* ---- THE WASH THAT HIDES THE CUT ---------------------------------------
   A satellite view at 6,500 ft and a path-traced frame at 520 m do not line
   up, and dissolving one into the other shows you precisely that. This closes
   over the handoff and opens again on the parcel — the descent already flies
   through cloud, so it reads as one more layer rather than as an effect. */
.bs-wipe{position:absolute;inset:0;z-index:21;opacity:0;pointer-events:none;
  background:radial-gradient(120% 90% at 50% 46%,
    rgba(255,252,246,.99) 0%,rgba(244,236,222,.97) 42%,rgba(226,214,196,.95) 100%)}

/* ---- the vignette, so overlay text always has ground to sit on ---------- */
.bs-vig{position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(6,9,15,.60) 0%,rgba(6,9,15,0) 24%,
    rgba(6,9,15,0) 50%,rgba(6,9,15,.80) 100%)}

/* ---- the loader ---------------------------------------------------------
   Only ever seen inside the build's own stretch of scroll, because the layer
   it lives in is transparent until then. */
.bs-load{position:absolute;inset:0;display:grid;place-items:center;
  background:linear-gradient(160deg,#0d1320,#070b12);z-index:2;
  transition:opacity .5s var(--ease)}
.bs-load.gone{opacity:0;pointer-events:none}
.bs-load .in{text-align:center}
.bs-load .bar{width:180px;height:2px;background:rgba(197,151,62,.2);margin:14px auto 0}
.bs-load .bar i{display:block;height:100%;width:0;background:var(--acc);
  transition:width .3s linear}
.bs-load p{font:600 11px/1 var(--m);letter-spacing:.18em;text-transform:uppercase;
  color:var(--acc)}

/* ---- the caption that names the stage ---------------------------------- */
.bs-cap{position:absolute;left:0;right:0;bottom:0;padding:0 22px 44px;
  pointer-events:none;z-index:3}
.bs-cap .in{max-width:1320px;margin:0 auto}
.bs-cap .step{font:600 11px/1 var(--m);letter-spacing:.2em;text-transform:uppercase;
  color:var(--acc);margin-bottom:12px}
.bs-cap h2{font:800 clamp(24px,4.6vw,46px)/1.04 var(--h);letter-spacing:-.02em;
  max-width:14ch;margin-bottom:10px;color:var(--txt)}
.bs-cap p{font:400 clamp(13.5px,1.5vw,16px)/1.5 var(--b);color:#c3ccdd;
  max-width:46ch}
.bs-cap .swap{display:block;transition:opacity .3s var(--ease),
  transform .3s var(--ease)}
.bs-cap .swap.out{opacity:0;transform:translateY(9px)}

/* ---- the progress rail up the side ------------------------------------- */
.bs-rail{position:absolute;right:20px;top:50%;transform:translateY(-50%);
  display:flex;flex-direction:column;gap:9px;pointer-events:none;z-index:3}
.bs-rail b{display:block;width:2px;height:20px;background:rgba(255,255,255,.16);
  border-radius:2px;transition:background .3s var(--ease),height .3s var(--ease)}
.bs-rail b.on{background:var(--acc);height:30px}
@media(max-width:700px){.bs-rail{display:none}}

/* ---- the card that opens the build ------------------------------------- */
.bs-intro{position:absolute;left:0;right:0;top:0;padding:96px 22px 0;
  pointer-events:none;z-index:3;transition:opacity .5s var(--ease)}
.bs-intro .in{max-width:1320px;margin:0 auto}
.bs-intro .micro{font:600 11px/1 var(--m);letter-spacing:.2em;
  text-transform:uppercase;color:var(--acc);margin-bottom:14px}
.bs-intro h2{font:800 clamp(26px,5vw,52px)/1.02 var(--h);letter-spacing:-.025em;
  max-width:16ch;color:var(--txt)}
.bs-intro.gone{opacity:0}

/* ---- the CTA that lands on the finished house -------------------------- */
.bs-end{position:absolute;left:0;right:0;bottom:0;padding:0 22px 40px;z-index:4;
  opacity:0;pointer-events:none;transition:opacity .5s var(--ease)}
.bs-end.on{opacity:1;pointer-events:auto}
.bs-end .in{max-width:1320px;margin:0 auto;display:flex;gap:12px;flex-wrap:wrap}

/* Where the caption and the CTA would collide on the last frames, the caption
   goes — the finished house's job is the button, not another paragraph.
   Driven off a class on the LAYER rather than a sibling combinator off
   `.bs-end`: that element comes after `.bs-cap` in the DOM, so `~` could only
   ever have selected forwards and the rule would have been dead. */
.bs-layer.at-end .bs-cap{opacity:0;transition:opacity .4s var(--ease)}

/* ---- NO WEBGL, NO SEQUENCE ---------------------------------------------
   `.hero-static` is what the hero sets on itself when WebGL is unavailable:
   the pin becomes a plain block and the map becomes a still. The build layer
   cannot scrub against a section that no longer pins, so it turns into one
   more still underneath it rather than an empty black box. */
.hero-static .bs-layer{position:relative;opacity:1;height:min(70vh,640px)}
.hero-static .bs-layer .bs-load,.hero-static .bs-layer .bs-rail,
.hero-static .bs-wipe{display:none}
.hero-static .bs-end{opacity:1;pointer-events:auto}
