/* =====================================================================
   LESTATE REAL — site stylesheet
   Built on the brand kit tokens (css/brand.css).

   Performance contract for every scroll-linked effect in js/:
   only `transform` and `opacity` are written per frame. Nothing here
   animates a property that forces layout or a re-raster — no
   width/height/top/left/border-radius on scroll surfaces.
   ===================================================================== */

*,*::before,*::after{box-sizing:border-box}

html{
  -webkit-text-size-adjust:100%;
  background:var(--canvas);
  scroll-behavior:smooth;
  /* keeps in-page anchors clear of the floating nav */
  scroll-padding-top:104px;
}
body{
  margin:0;color:var(--ink-1);
  font-family:var(--font-sans);letter-spacing:.2px;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
  /* clip, not hidden: `hidden` turns body into a scroll container and
     makes position:sticky far more expensive on iOS. */
  overflow-x:clip;
}

/* The architectural grid lives on one fixed, composited layer.
   A scrolling background-image would repaint the whole viewport
   on every scroll tick; this never repaints at all. */
body::before{
  content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;
  background-image:
    linear-gradient(to right,var(--grid-line) 1px,transparent 1px),
    linear-gradient(to bottom,var(--grid-line) 1px,transparent 1px);
  background-size:var(--grid-size) var(--grid-size);
}

img{max-width:100%;display:block}
[hidden]{display:none !important}

/* =====================================================================
   BRAND MARKS
   The three wordmarks have different intrinsic ratios, and the Lestate
   Real lockup stacks two lines plus a tagline — at the same box height
   its letters come out half the size of the single line marks. So every
   mark is sized by height only (the width follows the real ratio, never
   a hand written one) and the lockup gets its own larger height.
   ===================================================================== */
.nav-logo img,.footer-logo,.op-mark,.p-mark{
  width:auto;max-width:none;object-fit:contain;object-position:left center;
}
a{color:inherit;text-decoration:none}
button{font-family:inherit}
::selection{background:var(--blue-accent-tint-2)}

:root{
  --nav-h:60px;
  --ease:cubic-bezier(.22,1,.36,1);
  --ease-io:cubic-bezier(.65,0,.35,1);
  --spring:cubic-bezier(.34,1.42,.5,1);
  --maxw:1160px;
  --pad:32px;
  /* One rhythm for the whole site. Every section pays the same padding
     top and bottom, so the gap between any two sections is identical
     and nothing has to be tuned by hand. */
  --sec-pad:72px;
  --hair:rgba(0,0,0,.07);
}

.wrap{max-width:var(--maxw);margin:0 auto;padding:0 var(--pad);width:100%}
.section,.stats,.orbit-sec,.contact{position:relative;padding:var(--sec-pad) 0}

/* skip link — keyboard + screen reader entry point */
.skip{
  position:absolute;left:-9999px;top:0;z-index:200;
  padding:12px 18px;border-radius:0 0 12px 0;background:var(--blue-accent);color:#fff;
  font-size:13px;font-weight:700;
}
.skip:focus{left:0}

:where(a,button,input,textarea,select,[tabindex]):focus-visible{
  outline:2px solid var(--blue-accent);outline-offset:3px;border-radius:6px;
}
/* A pill button must keep its own radius when it is focused. A 6px
   outline around a 999px button pushes four square corners past the
   edge of whatever contains it — which is how the Investor Login ring
   broke out of the nav. */
.btn:focus-visible{border-radius:inherit;outline-offset:2px}
.nav .btn:focus-visible{outline-offset:1px}

/* =====================================================================
   TYPE
   ===================================================================== */
.eyebrow{
  margin:0;font-size:12px;font-weight:700;color:var(--blue-accent);
  letter-spacing:1.5px;text-transform:uppercase;
}
h1,h2,h3,h4{margin:0;color:var(--ink-1)}
h2{
  font-size:clamp(28px,3.4vw,44px);font-weight:700;
  letter-spacing:-1.1px;line-height:1.1;
}
h3{font-size:20px;font-weight:700;letter-spacing:-.4px;line-height:1.25}
.h2-sm{font-size:clamp(24px,2.6vw,34px);letter-spacing:-.8px}
.lead{margin:0;font-size:16px;line-height:1.6;color:var(--ink-2);max-width:62ch}
.lead b{color:var(--blue-accent);font-weight:700;font-variant-numeric:tabular-nums}
.muted{color:var(--ink-2)}
.note{margin:0;font-size:12px;color:var(--ink-3);line-height:1.55}
.micro{
  margin:0;font-size:10.5px;font-weight:700;letter-spacing:1.5px;
  text-transform:uppercase;color:var(--ink-3);
}
.sec-head{display:flex;flex-direction:column;gap:16px;max-width:760px}

.list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:9px}
.list li{position:relative;padding-left:18px;font-size:13.5px;line-height:1.55;color:var(--ink-2)}
.list li::before{
  content:"";position:absolute;left:0;top:8px;width:6px;height:6px;border-radius:50%;
  background:var(--blue-accent);
}
.list-green li::before{background:var(--green)}
.list-ink li::before{background:var(--ink-4)}

/* =====================================================================
   BUTTONS
   ===================================================================== */
.btn{
  position:relative;display:inline-flex;align-items:center;justify-content:center;gap:8px;
  font-size:13px;font-weight:700;letter-spacing:.3px;
  padding:13px 26px;border-radius:14px;border:1px solid transparent;cursor:pointer;
  transition:transform .5s var(--ease),background .25s ease,box-shadow .35s ease,
             color .25s ease,border-color .25s ease;
  overflow:hidden;text-align:center;
}
.btn::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  background:radial-gradient(120px 60px at var(--mx,50%) var(--my,50%),rgba(255,255,255,.32),transparent 70%);
  opacity:0;transition:opacity .3s ease;
}
.btn:hover::after{opacity:1}
.btn-primary{color:#fff;background:var(--blue-accent);box-shadow:0 4px 18px rgba(49,115,246,.32)}
.btn-primary:hover{background:#2765e8;box-shadow:0 10px 30px rgba(49,115,246,.4)}
.btn-primary:active{background:#1f57cf}
.btn-ghost{color:var(--blue-accent);background:var(--blue-accent-tint);border-color:rgba(49,115,246,.16)}
.btn-ghost:hover{background:var(--blue-accent-tint-2)}
.btn-line{color:var(--ink-1);background:transparent;border-color:var(--ink-5)}
.btn-line:hover{border-color:var(--ink-3);background:rgba(0,0,0,.02)}
.btn-sm{padding:9px 18px;border-radius:999px;font-size:12px}
.btn-block{width:100%}

/* the quiet blue used for Investor Login — present, never loud */
.btn-quiet{
  color:var(--blue-accent);background:var(--blue-accent-tint);
  border-color:rgba(49,115,246,.2);box-shadow:none;
}
.btn-quiet:hover{background:var(--blue-accent-tint-2);border-color:rgba(49,115,246,.34)}

.link-arrow{
  display:inline-flex;align-items:center;gap:7px;
  font-size:13px;font-weight:700;color:var(--blue-accent);
}
.link-arrow svg{width:14px;height:14px;fill:none;stroke:currentColor;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round;transition:transform .4s var(--ease)}
.link-arrow:hover svg{transform:translateX(4px)}

/* =====================================================================
   GLASS SURFACE
   ===================================================================== */
.glass{
  background:rgba(255,255,255,.66);
  -webkit-backdrop-filter:blur(22px) saturate(180%);backdrop-filter:blur(22px) saturate(180%);
  border:1px solid rgba(255,255,255,.7);
  box-shadow:0 8px 32px rgba(0,0,0,.08),inset 0 1px 0 rgba(255,255,255,.7);
  border-radius:20px;
}
.card{
  background:rgba(255,255,255,.72);border:1px solid var(--hair);border-radius:20px;
  box-shadow:0 1px 2px rgba(0,0,0,.03);
}

/* =====================================================================
   SCROLL PROGRESS
   ===================================================================== */
.scroll-progress{position:fixed;top:0;left:0;right:0;height:2px;z-index:120;pointer-events:none}
.scroll-progress i{
  display:block;height:100%;width:100%;
  background:linear-gradient(90deg,#6ba3ff,var(--blue-accent));
  transform:scaleX(var(--p,0));transform-origin:left;
}

/* =====================================================================
   NAV
   ===================================================================== */
.nav{
  position:fixed;top:16px;left:50%;z-index:100;
  display:flex;align-items:center;gap:20px;padding:8px 10px 8px 20px;
  max-width:calc(100vw - 28px);
  background:rgba(255,255,255,.62);
  -webkit-backdrop-filter:blur(22px) saturate(180%);backdrop-filter:blur(22px) saturate(180%);
  border:1px solid rgba(0,0,0,.06);border-radius:999px;
  box-shadow:0 8px 32px rgba(0,0,0,.09),inset 0 1px 0 rgba(255,255,255,.65);
  transform:translate3d(-50%,var(--ty,0),0);
  transition:transform .55s var(--ease),background .4s ease,box-shadow .4s ease,border-color .4s ease;
}
.nav.hide{--ty:-160%}

/* dark treatment while the nav floats over the hero */
.nav.dark{
  background:rgba(18,18,21,.55);border-color:rgba(255,255,255,.12);
  box-shadow:0 8px 32px rgba(0,0,0,.38),inset 0 1px 0 rgba(255,255,255,.12);
}
.nav.dark .nav-logo img{filter:brightness(0) invert(1)}
.nav.dark .nav-links a{color:rgba(255,255,255,.74)}
.nav.dark .nav-links a:hover,.nav.dark .nav-links a.on{color:#fff}
.nav.dark .nav-pill{background:rgba(255,255,255,.13)}
.nav.dark .btn-quiet{
  color:#a9c8ff;background:rgba(49,115,246,.2);border-color:rgba(140,180,255,.28);
}
.nav.dark .btn-quiet:hover{background:rgba(49,115,246,.34);color:#fff}

.nav-logo{display:flex;align-items:center;flex:none}
.nav-logo img{height:30px;transition:filter .4s ease}

.nav-links{position:relative;display:flex;gap:2px;align-items:center}
.nav-links a{
  position:relative;z-index:1;font-size:12.5px;font-weight:700;letter-spacing:.2px;
  color:var(--ink-2);padding:7px 12px;border-radius:999px;transition:color .3s ease;
  white-space:nowrap;
}
.nav-links a:hover{color:var(--ink-1)}
.nav-links a.on{color:var(--blue-accent)}
/* The pill used to be a 1px box stretched with scaleX, which stretches
   its corner radii with it: a 999px radius resolved down to half a pixel
   and came back out of the scale as a flat-topped rectangle. It carries
   its real width instead, so it is the same pill as the Investor Login
   button beside it. Width is only written when the active link changes,
   never per frame. */
.nav-pill{
  position:absolute;top:0;left:0;height:100%;width:var(--w,0px);border-radius:999px;
  background:rgba(0,0,0,.055);opacity:0;
  transform:translate3d(var(--x,0),0,0);
  transition:transform .5s var(--ease),width .5s var(--ease),opacity .3s ease;
}
.nav-pill.show{opacity:1}
.nav-cta{flex:none}

/* ---------- mobile: the house button ---------- */
.nav-house{
  display:none;width:42px;height:42px;flex:none;padding:0;cursor:pointer;
  align-items:center;justify-content:center;
  border-radius:50%;border:1px solid rgba(0,0,0,.08);
  background:rgba(255,255,255,.72);
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  transition:background .3s ease,border-color .3s ease,transform .5s var(--spring);
}
.nav-house:active{transform:scale(.92)}
.nav.dark .nav-house{background:rgba(255,255,255,.13);border-color:rgba(255,255,255,.18)}

.nav-house svg{width:23px;height:23px;overflow:visible}
.nav-house svg *{
  fill:none;stroke:var(--ink-1);stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round;
  transition:transform .55s var(--spring),opacity .3s ease,stroke .3s ease;
}
.nav.dark .nav-house svg *{stroke:#fff}

/* closed → open: the roof lifts and tilts, the walls settle,
   the door swings open. The house literally unfolds the menu. */
.h-roof{transform-origin:16px 12px}
.h-door{transform-origin:12.5px 26px;opacity:1}
.h-walls{transform-origin:16px 22px}
.h-beam{opacity:0;transform-origin:16px 20px;transform:scaleX(0)}

.nav.open .nav-house{background:var(--blue-accent-tint);border-color:rgba(49,115,246,.3)}
.nav.open .nav-house svg *{stroke:var(--blue-accent)}
.nav.open .h-roof{transform:translateY(-6px) rotate(-4deg)}
.nav.open .h-door{transform:scaleX(.1);opacity:0}
.nav.open .h-walls{transform:translateY(2px) scaleX(1.06)}
.nav.open .h-beam{opacity:1;transform:scaleX(1);transition-delay:.12s}

/* ---------- mobile: the sheet that unfolds ---------- */
.nav-sheet{
  position:absolute;top:calc(100% + 12px);right:0;width:min(300px,calc(100vw - 32px));
  display:flex;flex-direction:column;padding:10px;gap:2px;
  background:rgba(255,255,255,.82);
  -webkit-backdrop-filter:blur(26px) saturate(180%);backdrop-filter:blur(26px) saturate(180%);
  border:1px solid rgba(0,0,0,.07);border-radius:22px;
  box-shadow:0 20px 60px rgba(0,0,0,.18);
  transform-origin:calc(100% - 21px) 0;
  opacity:0;transform:translate3d(0,-10px,0) scale(.94);pointer-events:none;
  transition:opacity .26s ease,transform .5s var(--spring);
}
.nav.open .nav-sheet{opacity:1;transform:none;pointer-events:auto}
.nav-sheet a{
  padding:13px 16px;border-radius:14px;font-size:15px;font-weight:700;color:var(--ink-1);
  display:flex;align-items:center;justify-content:space-between;
  opacity:0;transform:translateY(-6px);
  transition:opacity .3s ease,transform .45s var(--ease),background .2s ease;
}
.nav.open .nav-sheet a{opacity:1;transform:none;transition-delay:calc(60ms + var(--i,0) * 34ms)}
.nav-sheet a:active{background:rgba(0,0,0,.05)}
.nav-sheet a.on{color:var(--blue-accent)}
.nav-sheet .sheet-cta{
  margin-top:6px;justify-content:center;
  background:var(--blue-accent-tint);color:var(--blue-accent);
  border:1px solid rgba(49,115,246,.2);
}
.nav-sheet hr{border:none;border-top:1px solid var(--hair);margin:8px 6px}
.nav.dark .nav-sheet{background:rgba(22,22,25,.9);border-color:rgba(255,255,255,.12)}
.nav.dark .nav-sheet a{color:#fff}
.nav.dark .nav-sheet hr{border-top-color:rgba(255,255,255,.12)}

@media (min-width:961px){.nav-sheet{display:none}}

/* =====================================================================
   HERO
   ===================================================================== */
.hero{position:relative;height:340vh;background:#0b0b0d;color:#fff}
.hero-pin{
  position:sticky;top:0;height:100svh;overflow:hidden;
  display:flex;align-items:center;justify-content:center;
}

/* --- the stage: scaled, never re-laid-out ---
   Full bleed from the first frame. It used to open from a rounded 90%
   card, which put a dark margin around the drawing that only closed once
   you scrolled — the hero read as a screenshot of itself. The scroll
   still pushes in (1 → 1.06), it just never starts inset. */
.stage{
  position:absolute;inset:0;overflow:hidden;background:#0d1117;
  transform:scale(var(--s,1)) translateY(var(--sy,0px));
  will-change:transform;
}
.stage-video{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;transition:opacity .8s ease;
}
.stage.has-video .stage-video{opacity:1}
.stage.has-video .scene{opacity:0}

.stage-vignette{
  position:absolute;inset:0;pointer-events:none;
  background:
    linear-gradient(100deg,rgba(6,8,12,.9) 0%,rgba(6,8,12,.64) 32%,rgba(6,8,12,.12) 60%,transparent 78%),
    linear-gradient(180deg,rgba(0,0,0,.4) 0%,transparent 22%,transparent 62%,rgba(0,0,0,.6) 100%),
    radial-gradient(130% 100% at 55% 45%,transparent 45%,rgba(0,0,0,.38) 100%);
}
/* static grain — an animated, blended full screen overlay costs a
   full repaint every frame, so it stays still. */
.stage-grain{
  position:absolute;inset:0;pointer-events:none;opacity:.05;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* --- the wipe: two transforms, zero repaints --- */
.scene{position:absolute;inset:0;transition:opacity .6s ease}
.scene-layer{position:absolute;inset:0}
.scene-after{
  overflow:hidden;
  transform:scaleX(var(--wipe,0));transform-origin:0 50%;
  will-change:transform;
}
.scene-after .facade{transform:scaleX(var(--wipeInv,1));transform-origin:0 50%}
.scene-after.blank{visibility:hidden}
.scene-seam{
  position:absolute;top:0;bottom:0;left:0;width:2px;
  background:linear-gradient(180deg,transparent,rgba(140,190,255,.95),transparent);
  box-shadow:0 0 26px 5px rgba(49,115,246,.5);
  opacity:var(--seam,0);transform:translate3d(0,0,0);will-change:transform;
}

.facade{position:absolute;inset:0;overflow:hidden}
.facade .sky{position:absolute;inset:0}
.facade[data-facade="before"] .sky{
  background:
    radial-gradient(100% 70% at 62% 96%,rgba(160,175,195,.14),transparent 62%),
    linear-gradient(180deg,#0c0f14 0%,#141a22 55%,#1a222c 100%);
}
.facade[data-facade="after"] .sky{
  background:
    radial-gradient(70% 46% at 66% 92%,rgba(120,180,255,.22),transparent 62%),
    radial-gradient(110% 80% at 30% 8%,rgba(49,115,246,.22),transparent 60%),
    linear-gradient(180deg,#060b13 0%,#0b1725 52%,#122436 100%);
}
.facade .mesh{position:absolute;inset:0;opacity:.45}
.facade[data-facade="before"] .mesh{
  background-image:
    linear-gradient(to right,rgba(255,255,255,.05) 1px,transparent 1px),
    linear-gradient(to bottom,rgba(255,255,255,.05) 1px,transparent 1px);
  background-size:48px 48px;
}
.facade[data-facade="after"] .mesh{
  background-image:
    linear-gradient(to right,rgba(120,180,255,.08) 1px,transparent 1px),
    linear-gradient(to bottom,rgba(120,180,255,.08) 1px,transparent 1px);
  background-size:48px 48px;
}
.facade .horizon{
  position:absolute;left:0;right:0;bottom:14%;height:1px;opacity:0;
  background:linear-gradient(90deg,transparent,rgba(158,208,255,.5),transparent);
}
.facade[data-facade="after"] .horizon{opacity:1}

.facade svg{position:absolute;inset:0;width:100%;height:100%}

.dw{fill:none;stroke-linecap:round;stroke-linejoin:round;vector-effect:non-scaling-stroke}
.dw-far  {stroke:rgba(255,255,255,.12);stroke-width:1}
.dw-out  {stroke:rgba(255,255,255,.7);stroke-width:1.6}
.dw-line {stroke:rgba(255,255,255,.26);stroke-width:1}
.dw-win  {stroke:rgba(255,255,255,.36);stroke-width:1;fill:rgba(255,255,255,.04)}
.dw-dim  {stroke:rgba(255,255,255,.28);stroke-width:1;stroke-dasharray:3 4}
.dw-txt-v{fill:rgba(255,255,255,.86);font-size:13px;font-weight:700;letter-spacing:1.2px}

.facade[data-facade="after"] .dw-far  {stroke:rgba(120,180,255,.18)}
.facade[data-facade="after"] .dw-out  {stroke:rgba(158,208,255,.95)}
.facade[data-facade="after"] .dw-line {stroke:rgba(120,180,255,.36)}
.facade[data-facade="after"] .dw-win  {stroke:rgba(158,208,255,.5);fill:rgba(10,30,55,.45)}
.facade[data-facade="after"] .dw-dim  {stroke:rgba(120,180,255,.45)}
.facade[data-facade="after"] .dw-txt-v{fill:#fff}

/* The transformed asset is one drawing in one colour. Marking the added
   storey, the balconies and the retrofit envelope in a second hue turned
   the building into a legend with a key, and the eye read the colours
   instead of the architecture — so everything here is the same light
   blue and only the line weight changes. */
.dw-add  {stroke:rgba(158,208,255,.85);stroke-width:1.4;fill:none}
.dw-add-f{stroke:rgba(158,208,255,.55);stroke-width:1.2;fill:rgba(120,180,255,.06)}
.dw-bal  {stroke:rgba(178,218,255,.72);stroke-width:1.15;fill:none}
.dw-bal-f{stroke:rgba(178,218,255,.78);stroke-width:1;fill:rgba(150,200,255,.16)}
.dw-glass{stroke:rgba(178,218,255,.3);stroke-width:.8;fill:rgba(150,200,255,.09)}
.dw-pv   {stroke:rgba(158,208,255,.9);stroke-width:1.2;fill:rgba(49,115,246,.2)}
.dw-pv-c {stroke:rgba(158,208,255,.55);stroke-width:.7;fill:none}

/* glazing bars, frame rebates, door leaves: the finest line weight in
   the drawing, which is what turns a rectangle into a window */
.dw-glaz {stroke:rgba(255,255,255,.24);stroke-width:.8;fill:none}
.facade[data-facade="after"] .dw-glaz{stroke:rgba(158,208,255,.36)}

/* mullion and transom. Heavier than a glazing bar on purpose: at this
   scale the cross is the whole difference between a window and a hole. */
.dw-bar  {stroke:rgba(255,255,255,.44);stroke-width:1.1;fill:none}
.facade[data-facade="after"] .dw-bar{stroke:rgba(178,218,255,.62)}

/* the added storey fades in behind the crane rather than appearing
   fully built — the outline is there, the substance arrives */
.new-storey{opacity:var(--storey,1)}

/* site infrastructure: crane, scaffold, crew. Present during the
   transformation, gone once the asset is finished. */
.construct{opacity:var(--build,0)}
/* the load on the hook drifts — one tiny composited group, nothing else */
.hoist{animation:hoistDrift 7s ease-in-out infinite}
@keyframes hoistDrift{0%,100%{transform:translate(0,0)}50%{transform:translate(-5px,-7px)}}
.dw-rig  {stroke:rgba(255,255,255,.62);stroke-width:1.3;fill:none}
.dw-rig-f{stroke:rgba(255,255,255,.62);stroke-width:1.3;fill:rgba(255,255,255,.06)}
.dw-crew {stroke:rgba(178,218,255,.8);stroke-width:1.5;fill:none}
.dw-hook {stroke:rgba(255,255,255,.5);stroke-width:1;fill:none}

/* Occupancy, not yellow blocks. A warm fill made a handful of flats
   read as a different material to the rest of the facade, so a lit flat
   is simply a brighter pane of the same blue. */
.dw-win{transition:fill .7s ease,stroke .7s ease}
.facade[data-facade="after"] .dw-win.lit{
  fill:rgba(150,205,255,.17);stroke:rgba(196,228,255,.72);
}

/* --- hero copy --- */
.hero-inner{
  position:relative;z-index:3;width:100%;max-width:var(--maxw);
  padding:0 var(--pad);margin:0 auto;height:100%;
  display:flex;flex-direction:column;justify-content:center;
  pointer-events:none;
}
.hero-inner a,.hero-inner button{pointer-events:auto}
.hero-copy{
  max-width:680px;display:flex;flex-direction:column;gap:22px;
  opacity:var(--copyOpacity,1);
  transform:translate3d(0,calc(var(--copyY,0) * -1px),0) scale(var(--copyScale,1));
  will-change:transform,opacity;
}
.hero-copy .eyebrow{color:#6fa6ff;letter-spacing:1.8px}
.hero-h1{
  font-size:clamp(32px,4.6vw,60px);line-height:1.05;font-weight:700;
  letter-spacing:-2px;color:#fff;text-shadow:0 4px 40px rgba(0,0,0,.45);
}
.hero-h1 .line{display:block;overflow:hidden}
.hero-h1 .line>span{display:block;transform:translateY(110%);animation:lineUp 1.05s var(--ease) forwards}
.hero-h1 .line:nth-child(1)>span{animation-delay:.14s}
.hero-h1 .line:nth-child(2)>span{animation-delay:.26s}
.hero-h1 .line:nth-child(3)>span{animation-delay:.38s}
@keyframes lineUp{to{transform:translateY(0)}}
.hero-sub{margin:0;font-size:17px;line-height:1.6;color:rgba(255,255,255,.78);max-width:560px}
.hero-cta{display:flex;gap:12px;flex-wrap:wrap}
.hero-cta .btn-ghost{color:#fff;background:rgba(255,255,255,.14);border-color:rgba(255,255,255,.18)}
.hero-cta .btn-ghost:hover{background:rgba(255,255,255,.22)}

.hero-scroll{
  position:absolute;right:var(--pad);bottom:12vh;
  display:flex;align-items:center;gap:12px;
  font-size:11px;font-weight:700;letter-spacing:1.4px;text-transform:uppercase;
  color:rgba(255,255,255,.58);opacity:var(--scrollOpacity,1);
}
.hero-scroll-rail{display:block;width:70px;height:2px;background:rgba(255,255,255,.22);position:relative;overflow:hidden}
.hero-scroll-rail i{
  position:absolute;inset:0;background:#fff;transform:translateX(-100%);
  animation:railRun 2.2s var(--ease-io) infinite;
}
@keyframes railRun{0%{transform:translateX(-100%)}55%{transform:translateX(0)}100%{transform:translateX(100%)}}

/* =====================================================================
   MARKET STATS
   No rules, no dividers: the numbers carry the section on their own.
   Everything that moves here is a transform or an opacity.
   ===================================================================== */
/* the pinned section that follows brings its own vertical slack, so this
   one does not pay for the gap twice */
.stats{padding:44px 0 0}
.stats-h{max-width:22ch;font-size:clamp(26px,3vw,38px);letter-spacing:-.9px}
.stats-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:14px;margin-top:34px}
.stat{
  position:relative;display:flex;flex-direction:column;gap:12px;
  padding:18px 16px 18px 0;border-radius:18px;
  transition:transform .55s var(--ease);
}

/* the number rides up out of a mask while it counts */
.stat-val{display:block;overflow:hidden;padding-bottom:4px;margin-bottom:-4px}
.stat-v{
  display:block;font-size:clamp(34px,4vw,52px);font-weight:700;letter-spacing:-2px;
  color:var(--blue-accent);font-variant-numeric:tabular-nums;line-height:1.04;
  transform:translate3d(0,108%,0);
  transition:transform 1s var(--ease);
  transition-delay:calc(var(--d,0) * 1ms + 60ms);
}
.reveal.in .stat-v{transform:none}

.stat-l{
  font-size:13.5px;line-height:1.45;color:var(--ink-2);max-width:19ch;font-weight:700;
  opacity:0;transform:translate3d(0,10px,0);
  transition:opacity .7s var(--ease),transform .7s var(--ease);
  transition-delay:calc(var(--d,0) * 1ms + 320ms);
}
.reveal.in .stat-l{opacity:1;transform:none}

/* a bloom behind the figure as it lands, then it settles back to almost
   nothing — a single keyframe, so it never repaints again afterwards */
.stat-glow{
  position:absolute;left:-30px;top:-20px;width:200px;height:136px;pointer-events:none;
  background:radial-gradient(closest-side,var(--blue-accent-tint-2),transparent 72%);
  opacity:0;
}
.reveal.in .stat-glow{
  animation:statBloom 1.7s var(--ease) forwards;
  animation-delay:calc(var(--d,0) * 1ms + 140ms);
}
@keyframes statBloom{
  0%  {opacity:0;transform:scale(.68)}
  42% {opacity:1;transform:scale(1.04)}
  100%{opacity:.32;transform:scale(1)}
}

@media (hover:hover){
  .stat:hover{transform:translateY(-5px)}
  .stat:hover .stat-l{color:var(--ink-1)}
}

/* --- desktop: the figures sit beside the headline, not under it ---
   Five numbers at 52px across the full column outweighed everything else
   on the page — they were the first and loudest thing after the hero.
   Beside the headline they become what they are: the evidence for it.
   Each one is a row, so the figure can shrink without the labels
   crowding, and the column reads top to bottom like a fact sheet. */
@media (min-width:1081px){
  .stats .wrap{
    display:grid;grid-template-columns:minmax(0,1.08fr) minmax(0,.92fr);
    gap:60px;align-items:start;
  }
  .stats-h{max-width:none;font-size:clamp(26px,2.7vw,35px);letter-spacing:-.8px}

  .stats-grid{display:flex;flex-direction:column;gap:0;margin-top:5px}
  .stat{
    flex-direction:row;align-items:baseline;gap:20px;
    padding:15px 0;border-radius:0;border-top:1px solid var(--hair);
  }
  .stat:first-child{border-top:none;padding-top:0}
  .stat:last-child{padding-bottom:0}

  /* wide enough for `0.67 %`, the longest figure, and nothing more —
     any slack here opens a gap the label has to reach across */
  .stat-val{flex:none;width:96px}
  .stat-v{font-size:clamp(24px,2.2vw,30px);letter-spacing:-1.1px}
  .stat-l{max-width:none;font-size:13px}
  .stat-glow{left:-24px;top:-16px;width:140px;height:88px}
}
/* the lift belongs to a tile; in a row list the figure nudges instead */
@media (min-width:1081px) and (hover:hover){
  .stats-grid .stat:hover{transform:translateX(4px)}
}

/* =====================================================================
   DIMENSIONS — pinned horizontal track
   ===================================================================== */
/* --pull is measured in js/home.js: it takes back the empty space the
   sticky frame leaves above and below the composition, so this section
   sits in the same rhythm as every other one. */
.dims{height:330vh;position:relative;margin:calc(-1 * var(--pull,0px)) 0}
/* The pinned frame is a fixed 100svh, so whatever the content does not
   use turns into slack above and below it — which is what made the gap
   into this section twice the size of every other one. The card height
   is set so the composition fills the frame and the slack lands close to
   the site's normal section gap. */
.dims-pin{
  position:sticky;top:0;height:100svh;overflow:hidden;
  display:flex;flex-direction:column;justify-content:center;gap:32px;
}
.dims-top{display:flex;flex-direction:column;gap:24px}
.dims-head h2{max-width:22ch}
/* the label sits with the cards it describes, not underneath them */
.dims-meta{display:flex;align-items:center;gap:20px}
.dims-label{font-size:12px;font-weight:700;letter-spacing:.4px;color:var(--ink-2);white-space:nowrap}
.dims-bar{flex:1;height:2px;background:rgba(0,0,0,.09);position:relative;overflow:hidden}
.dims-bar i{position:absolute;inset:0;background:var(--blue-accent);transform:scaleX(var(--p,0));transform-origin:left}

.dims-rail{
  width:100%;
  /* the rail clips horizontally, so it needs vertical room for the
     hover lift — otherwise the top edge of a card gets shaved off */
  padding:26px 0;margin:-26px 0;overflow:hidden;
}
.dims-track{
  display:flex;gap:20px;
  padding:0 max(var(--pad),calc((100vw - var(--maxw))/2 + var(--pad)));
  transform:translate3d(var(--x,0px),0,0);will-change:transform;
}
.dim{
  position:relative;flex:none;width:min(26vw,320px);height:min(46vh,370px);
  border-radius:24px;padding:26px;overflow:hidden;
  background:linear-gradient(165deg,rgba(255,255,255,.9) 0%,rgba(244,244,247,.9) 100%);
  border:1px solid var(--hair);
  display:flex;flex-direction:column;justify-content:space-between;
  transition:transform .5s var(--ease),box-shadow .5s var(--ease),border-color .4s ease;
}
.dim-n{
  font-size:15px;font-weight:700;letter-spacing:2px;color:var(--ink-4);
  font-variant-numeric:tabular-nums;position:relative;z-index:1;
}
.dim-icon{
  position:absolute;right:-14px;top:34%;width:190px;height:190px;
  transform:translateY(-50%);opacity:.12;pointer-events:none;
  transition:opacity .5s var(--ease),transform .6s var(--ease);
}
.dim-icon svg{width:100%;height:100%;fill:none;stroke:var(--blue-accent);stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
.dim-body{position:relative;z-index:1;display:flex;flex-direction:column;gap:6px}
.dim h3{font-size:26px;letter-spacing:-.6px}
.dim p{margin:0;font-size:13.5px;color:var(--ink-3);line-height:1.5}
.dim-glow{
  position:absolute;inset:auto -30% -60% -30%;height:70%;pointer-events:none;
  background:radial-gradient(closest-side,rgba(49,115,246,.2),transparent);
  opacity:0;transition:opacity .5s ease;
}
@media (hover:hover){
  .dim:hover{transform:translateY(-6px);box-shadow:var(--shadow-lg);border-color:rgba(49,115,246,.35)}
  .dim:hover .dim-icon{opacity:.22;transform:translateY(-50%) scale(1.05)}
  .dim:hover .dim-glow{opacity:1}
}

/* the success checkmark draws itself with this */
@keyframes drawIn{to{stroke-dashoffset:0}}

/* =====================================================================
   THE SELECTOR — platform stages and transformation measures
   ---------------------------------------------------------------------
   This was a ring of buttons around a circle, with a blue arc sweeping
   round it on a loop, a green value arc growing on every turn, and a
   panel that replaced itself every few seconds. Three animations, one
   decision, and copy nobody could finish reading.

   What replaced it: a list you choose from, a pair of arrows for the
   same job, and a panel that changes only when asked. Same component
   twice, same markup, no timer.
   ===================================================================== */
.orbit-sec{padding:var(--sec-pad) 0}
.picker{display:grid;grid-template-columns:320px 1fr;gap:56px;align-items:start;margin-top:48px}
.picker-side{display:flex;flex-direction:column;gap:22px;position:sticky;top:108px}

.picker-list{display:flex;flex-direction:column}
.pick{
  position:relative;width:100%;cursor:pointer;text-align:left;
  display:grid;grid-template-columns:auto 1fr;gap:3px 13px;align-items:baseline;
  padding:17px 4px 17px 16px;background:none;border:none;
  border-top:1px solid var(--hair);
  transition:border-color .35s ease;
}
.pick:last-child{border-bottom:1px solid var(--hair)}
/* the marker that says which one you are reading */
.pick::before{
  content:"";position:absolute;left:0;top:50%;width:2px;height:0;
  background:var(--blue-accent);border-radius:2px;translate:0 -50%;
  transition:height .45s var(--ease);
}
.pick-n{
  font-size:11px;font-weight:700;letter-spacing:1.6px;color:var(--ink-4);
  font-variant-numeric:tabular-nums;transition:color .3s ease;
}
.pick-t{
  font-size:17px;font-weight:700;letter-spacing:-.3px;color:var(--ink-2);
  transition:color .3s ease;
}
.pick-s{
  grid-column:2;font-style:normal;font-size:12px;line-height:1.4;color:var(--ink-4);
  transition:color .3s ease;
}
.pick:hover .pick-t{color:var(--ink-1)}
.pick.on::before{height:calc(100% - 26px)}
.pick.on .pick-t{color:var(--ink-1)}
.pick.on .pick-n,.pick.on .pick-s{color:var(--blue-accent)}

.picker-nav{display:flex;align-items:center;gap:10px}
.pick-arrow{
  width:40px;height:40px;flex:none;display:grid;place-items:center;cursor:pointer;
  border-radius:999px;border:1px solid var(--hair);background:rgba(255,255,255,.7);
  transition:border-color .3s ease,background .3s ease,transform .5s var(--spring);
}
.pick-arrow svg{
  width:15px;height:15px;fill:none;stroke:var(--ink-2);stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round;transition:stroke .3s ease;
}
.pick-arrow:hover{border-color:rgba(49,115,246,.34);background:#fff}
.pick-arrow:hover svg{stroke:var(--blue-accent)}
.pick-arrow:active{transform:scale(.94)}
.pick-at{
  margin-left:6px;font-size:11px;font-weight:700;letter-spacing:1.4px;
  text-transform:uppercase;color:var(--ink-4);font-variant-numeric:tabular-nums;
}
.pick-at b{color:var(--ink-1)}

/* --- the panel --- */
.picker-panel{
  position:relative;padding:36px;border-radius:24px;overflow:hidden;
  min-height:400px;display:flex;flex-direction:column;gap:22px;
}
.op-head{display:flex;flex-direction:column;gap:12px}
.op-step{font-size:11px;font-weight:700;letter-spacing:1.6px;text-transform:uppercase;color:var(--ink-4)}
.op-mark{height:26px}
.op-mark[src*="lestate-real"]{height:46px}
.op-mark-txt{font-size:23px;font-weight:700;letter-spacing:-.6px}
.op-head h3{font-size:23px;letter-spacing:-.6px;line-height:1.3;max-width:30ch}
.op-tag{margin:0;font-size:16px;line-height:1.5;color:var(--ink-2);max-width:44ch}
/* description across the full width, facts underneath — side by side
   the fact tiles get so narrow that every label wraps three times */
.op-body{display:flex;flex-direction:column;gap:22px}
.op-desc{margin:0;font-size:14px;line-height:1.65;color:var(--ink-2);max-width:62ch}
.op-facts{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.op-fact{
  padding:14px 16px;border-radius:14px;background:rgba(255,255,255,.7);
  border:1px solid var(--hair);display:flex;flex-direction:column;gap:3px;
}
.op-fact span{font-size:9.5px;font-weight:700;letter-spacing:1.3px;text-transform:uppercase;color:var(--ink-4)}
.op-fact b{font-size:13.5px;font-weight:700;letter-spacing:-.1px;color:var(--ink-1);line-height:1.3}
.op-layer{
  margin-top:auto;font-size:11px;font-weight:700;letter-spacing:1.5px;
  text-transform:uppercase;color:var(--ink-4);
}
/* a short settle on the new content, not a transition anybody waits out */
.picker-panel.is-in>*{animation:panelIn .3s var(--ease) both}
@keyframes panelIn{from{opacity:0}to{opacity:1}}

#measures .op-head h3{font-size:27px;max-width:24ch}

/* =====================================================================
   CONTACT
   ===================================================================== */
.contact{padding:var(--sec-pad) 0;position:relative;overflow:hidden}
.contact::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(60% 55% at 12% 0%,rgba(49,115,246,.09),transparent 62%),
    radial-gradient(46% 46% at 92% 100%,rgba(52,199,89,.08),transparent 62%);
}
.contact-grid{position:relative;display:grid;grid-template-columns:1fr 1fr;gap:60px;align-items:start}
.contact-copy{display:flex;flex-direction:column;gap:18px}
.contact-reach{display:flex;flex-direction:column;gap:8px;margin-top:8px}
.contact-reach a{font-size:14px;font-weight:700;color:var(--blue-accent)}

.form-card{padding:32px;border-radius:24px}
.form-card form{display:flex;flex-direction:column;gap:16px}
.field{display:flex;flex-direction:column;gap:7px}
.field label,.field-label{font-size:13px;font-weight:700;color:var(--ink-1)}
.field input,.field textarea{
  font-family:inherit;font-size:14px;padding:13px 15px;border-radius:12px;
  border:1px solid var(--grey-300);background:#fff;outline:none;letter-spacing:.2px;
  color:var(--ink-1);width:100%;
  transition:border-color .25s ease,box-shadow .25s ease;
}
.field textarea{resize:vertical;min-height:104px;line-height:1.5}
.field input::placeholder,.field textarea::placeholder{color:var(--ink-4)}
.field input:focus,.field textarea:focus{border-color:var(--blue-accent);box-shadow:0 0 0 3px rgba(49,115,246,.16)}
.field input.err,.field textarea.err{border-color:var(--red);box-shadow:0 0 0 3px rgba(255,59,48,.14)}

.chips{display:flex;gap:8px;flex-wrap:wrap}
.chips button{
  font-size:12.5px;font-weight:700;padding:10px 15px;border-radius:12px;cursor:pointer;
  border:1px solid var(--grey-300);background:#fff;color:var(--ink-2);letter-spacing:.2px;
  transition:border-color .25s ease,background .25s ease,color .25s ease,transform .4s var(--spring);
}
.chips button:hover{border-color:var(--ink-4)}
.chips button:active{transform:scale(.96)}
.chips button.on{border-color:var(--blue-accent);background:var(--blue-accent-tint);color:var(--blue-accent)}
.form-error{margin:0;font-size:12.5px;color:var(--red);font-weight:700}
.form-done{display:flex;flex-direction:column;align-items:center;text-align:center;gap:10px;padding:52px 0}
.form-done h3{font-size:19px}
.form-done p{margin:0;font-size:13.5px;color:var(--ink-2);max-width:38ch}
.form-done .note a{color:var(--blue-accent);font-weight:700}
.check{width:52px;height:52px;border-radius:50%;background:var(--green-tint);display:grid;place-items:center}
.check svg{width:26px;height:26px;fill:none;stroke:var(--green);stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round}
.check svg path{stroke-dasharray:26;stroke-dashoffset:26;animation:drawIn .6s var(--ease) .15s forwards}

/* =====================================================================
   FOOTER
   ===================================================================== */
/* the bottom bar (copyright + brand marks) is gone, so the columns are the
   last thing in the footer and need their own closing space */
.footer{position:relative;border-top:1px solid var(--hair);padding:64px 0 64px;margin-top:0}
.footer-top{display:grid;grid-template-columns:1.6fr 1fr 1fr;gap:40px}
.footer-brand{display:flex;flex-direction:column;gap:16px;max-width:280px;align-items:flex-start}
.footer-logo{height:34px}
.footer-brand p{margin:0;font-size:13px;line-height:1.6;color:var(--ink-3)}
.footer-mail{font-size:13.5px;font-weight:700;color:var(--blue-accent);transition:opacity .25s ease}
.footer-mail:hover{opacity:.72}
.footer-col{display:flex;flex-direction:column;gap:12px}
.footer-col h4{font-size:10.5px;font-weight:700;letter-spacing:1.5px;text-transform:uppercase;color:var(--ink-4)}
.footer-col a{font-size:13.5px;color:var(--ink-2);transition:color .25s ease;width:fit-content}
.footer-col a:hover{color:var(--blue-accent)}

/* =====================================================================
   SUBPAGES
   ===================================================================== */
.page-hero{padding:180px 0 72px;position:relative}
.page-hero .eyebrow{margin-bottom:16px}
.page-hero h1{font-size:clamp(34px,5vw,62px);font-weight:700;letter-spacing:-2px;line-height:1.05}
.page-hero .lead{margin-top:20px;font-size:17px}
.page-hero-inner{max-width:820px;display:flex;flex-direction:column}

/* --- legal pages --- */
.legal{padding:0 0 120px}
.legal-inner{max-width:760px}
.legal h2{font-size:22px;letter-spacing:-.5px;margin:44px 0 14px}
.legal h3{font-size:16px;margin:26px 0 10px}
.legal p,.legal li{font-size:14.5px;line-height:1.7;color:var(--ink-2)}
.legal p{margin:0 0 14px}
.legal ul{margin:0 0 14px;padding-left:20px;display:flex;flex-direction:column;gap:6px}
.legal a{color:var(--blue-accent);font-weight:700}

/* --- investor login ---
   One column at every width. Side by side, the sign-in card competed
   with the capital story for the same first look and neither won; in
   sequence the page states the proposition, offers the door, and then
   explains the mechanics to whoever wants them. */
/* 820px, the same reading column the page hero above it uses */
.login-grid{
  display:flex;flex-direction:column;gap:64px;
  max-width:820px;padding-bottom:110px;
}
.login-card{
  padding:36px;border-radius:24px;display:flex;flex-direction:column;gap:20px;
  width:100%;max-width:520px;
}
.login-card h2{font-size:22px;letter-spacing:-.5px}
.login-card form{display:flex;flex-direction:column;gap:16px}
.login-meta{display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap}
.login-meta a{font-size:12.5px;font-weight:700;color:var(--blue-accent)}

/* the capital loop, now living on the investor page */
.loop{position:relative;width:340px;height:340px;margin:0 auto}
.loop-ring{position:absolute;inset:0}
.loop-svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible;transform:rotate(-90deg)}
.loop-track{fill:none;stroke:rgba(0,0,0,.08);stroke-width:1.5}
.loop-fill{
  fill:none;stroke:var(--blue-accent);stroke-width:3;stroke-linecap:round;
  stroke-dasharray:741;stroke-dashoffset:calc(741 - 741 * var(--p,0));
}
.loop-dot{fill:#fff;stroke:var(--blue-accent);stroke-width:3}
.loop-steps{position:absolute;inset:0}
.loop-steps span{
  position:absolute;left:50%;top:50%;
  transform:rotate(var(--a)) translate(166px) rotate(calc(-1 * var(--a))) translate(-50%,-50%);
  display:flex;flex-direction:column;gap:1px;white-space:nowrap;
  font-size:12px;font-weight:700;letter-spacing:.2px;color:var(--ink-4);
  transition:color .35s ease;
}
.loop-steps span em{font-style:normal;font-size:10px;font-weight:400;color:var(--ink-4)}
.loop-steps span.on{color:var(--ink-1)}
.loop-steps span.on em{color:var(--blue-accent)}
.loop-core{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  display:flex;flex-direction:column;align-items:center;gap:2px;text-align:center;
}
.loop-core span{font-size:21px;font-weight:700;letter-spacing:-.4px;color:var(--blue-accent)}
.loop-core em{font-style:normal;font-size:10.5px;letter-spacing:1.4px;text-transform:uppercase;color:var(--ink-4)}

/* --- 404 --- */
.nf{min-height:70svh;display:flex;flex-direction:column;justify-content:center;gap:20px;align-items:flex-start;padding:160px 0 100px}
.nf-code{font-size:clamp(64px,12vw,140px);font-weight:700;letter-spacing:-5px;line-height:1;color:var(--blue-accent)}

/* =====================================================================
   REVEAL
   ===================================================================== */
.reveal{
  opacity:0;transform:translate3d(0,24px,0);
  transition:opacity .8s var(--ease),transform .8s var(--ease);
  transition-delay:calc(var(--d,0) * 1ms);
}
.reveal.in{opacity:1;transform:none}

/* =====================================================================
   RESPONSIVE
   ===================================================================== */
@media (max-width:1180px){
  .nav-links a{padding:7px 10px;font-size:12px}
  .nav{gap:14px}
}
@media (max-width:1080px){
  :root{--sec-pad:64px}
  .stats-grid{grid-template-columns:repeat(3,1fr);gap:26px 14px}
  .picker{grid-template-columns:1fr;gap:34px}
  .picker-side{position:static}
  .contact-grid{grid-template-columns:1fr;gap:44px}
  .login-grid{gap:48px}
  .footer-top{grid-template-columns:1fr 1fr;gap:36px}
  .footer-brand{grid-column:1 / -1;max-width:none}
}
@media (max-width:960px){
  :root{--pad:20px;--sec-pad:56px}
  .nav{
    left:14px;right:14px;width:auto;gap:12px;padding:8px 8px 8px 16px;
    transform:translate3d(0,var(--ty,0),0);
  }
  .nav-links{display:none}
  .nav-cta{display:none}
  .nav-house{display:flex;margin-left:auto}

  .stats{padding-top:32px}
  .stats-grid{grid-template-columns:1fr 1fr;gap:24px 14px}
  .stat{padding:14px 12px 14px 0}
  .stat-glow{left:-22px;width:150px;height:110px}


  .stats{padding-top:32px}
  .dims{height:280vh}
  .dim{width:74vw;height:auto;min-height:300px}
  .dims-top{gap:18px}
  .dims-pin{gap:26px}

  .hero{height:300vh}

  /* On a phone the scene is the whole screen, not a band inside a column.
     The band framed itself from its own box: at 390px wide that box was
     roughly 350×280, which fitScene reads as a landscape frame and answers
     with ~940 units across, so the building drew at 36% of the width and
     its hairlines had no pixels left to sit on. Full bleed hands it a
     portrait frame (~530 units) and the same vectors draw at close to
     twice the size in both axes. The copy sits over the scene the way it
     does on desktop. */

  /* no transform runs here (see js/home.js), so the promotion hint comes
     off with it — an un-animated composited layer only costs the drawing
     a rasterisation it has no use for. */
  .stage{transform:none;will-change:auto}

  /* The top padding is measured from the nav, not guessed: the bar sits at
     top:16px and is 58px tall (42px house button + 2 × 8px padding), so it
     ends at 74px. 84px left barely 10px under it while the eyebrow had 14px
     plus the headline's leading below it — the label read as stuck to the
     bar. 96px gives it the same air above as below. */
  .hero-inner{
    max-width:none;justify-content:flex-start;
    padding:96px var(--pad) calc(20px + env(safe-area-inset-bottom,0px));
  }
  .hero-copy{max-width:none;gap:16px}

  .hero-h1{font-size:clamp(30px,7.8vw,44px);letter-spacing:-1.2px}
  /* The three fixed lines are a desktop composition. On a phone they
     orphan single words, so the headline flows and reveals as one.
     `backwards` rather than `both`: a filling animation would outrank
     the opacity above and the headline could never fade out again. */
  .hero-h1 .line{display:inline;overflow:visible}
  .hero-h1 .line>span{display:inline;transform:none;animation:none}
  .hero-h1{animation:heroIn 1s var(--ease) .1s backwards}
  @keyframes heroIn{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
  .hero-sub{font-size:15px}
  /* side by side at their own width: stretched to the full column they
     read as two slabs and outweighed the headline above them. */
  .hero-cta{flex-direction:row;align-items:center;gap:10px}
  .hero-cta .btn{width:auto;padding:12px 20px}

  .hero-scroll{display:none}
  /* the copy is back over the drawing, so the wash is too: weighted to
     the head for the headline and open through the middle where the
     building stands. */
  .stage-vignette{
    background:
      linear-gradient(180deg,rgba(6,8,12,.92) 0%,rgba(6,8,12,.7) 24%,rgba(6,8,12,.16) 50%,transparent 66%),
      linear-gradient(0deg,rgba(6,8,12,.86) 0%,rgba(6,8,12,.3) 14%,transparent 30%),
      radial-gradient(130% 92% at 50% 48%,transparent 54%,rgba(0,0,0,.42) 100%);
  }

  .pick{padding:15px 4px 15px 14px}
  .pick-t{font-size:16px}
  .pick-arrow:active{transform:scale(.94)}
  .picker-panel{padding:26px;min-height:0}
  .op-body{grid-template-columns:1fr;gap:20px}
  .op-head h3{font-size:20px}
  #measures .op-head h3{font-size:21px}

  .page-hero{padding:130px 0 56px}

  /* the capital loop gets the same treatment as the wheels: the ring
     keeps filling, the stages become a readable row beneath it */
  .loop{
    width:100%;height:auto;
    display:flex;flex-direction:column;align-items:center;gap:22px;
  }
  .loop-ring{position:relative;width:min(240px,62vw);height:min(240px,62vw);flex:none}
  .loop-steps{position:static;display:flex;flex-wrap:wrap;justify-content:center;gap:8px}
  .loop-steps span{
    position:static;left:auto;top:auto;transform:none;
    flex-direction:row;align-items:baseline;gap:6px;
    padding:9px 13px;border-radius:12px;font-size:12px;
    background:rgba(255,255,255,.72);border:1px solid var(--hair);
  }
  .loop-steps span.on{border-color:rgba(49,115,246,.34);background:#fff}
  .form-card,.login-card{padding:24px}
}
@media (max-width:640px){
  :root{--sec-pad:48px}
  .stats-grid{grid-template-columns:1fr 1fr;gap:22px 12px}
  .stats-grid .stat:last-child{grid-column:1 / -1}
  .footer-top{grid-template-columns:1fr}
  .dim{width:82vw}
  .op-facts{grid-template-columns:1fr}
}

/* The hero column is the one composition on the site with a hard height
   budget: everything in it has to fit 100svh, and whatever the copy does
   not use is what the animation gets. On a short phone the headline eats
   the band, so the type tightens rather than the scene disappearing. */
@media (max-width:960px) and (max-height:740px){
  /* same clearance under the nav, tightened to the smaller inner gap */
  .hero-inner{padding:90px var(--pad) calc(18px + env(safe-area-inset-bottom,0px))}
  .hero-copy{gap:13px}
  .hero-h1{font-size:clamp(26px,6.6vw,34px)}
  .hero-sub{font-size:14px}
}

/* A phone held sideways keeps the same composition on barely a third of
   the height. Everything tightens one more step instead of anything
   being dropped. */
@media (max-width:960px) and (max-height:460px){
  .hero-inner{padding:80px var(--pad) calc(14px + env(safe-area-inset-bottom,0px))}
  .hero-copy{gap:8px}
  .hero-h1{font-size:clamp(20px,4.4vw,26px);letter-spacing:-.8px}
  .hero-sub{font-size:13px}
  .hero-cta .btn{padding:10px 16px;font-size:12px}
}

/* On touch devices the blur budget is tight — soften every glass
   surface so scrolling stays at frame rate. */
@media (hover:none){
  .glass,.nav,.nav-sheet,.nav-house{
    -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  }
  .glass{background:rgba(255,255,255,.86)}
}

/* =====================================================================
   REDUCED MOTION
   ===================================================================== */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:.01ms !important;animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
  }
  .reveal{opacity:1;transform:none}
  .hero-h1 .line>span{transform:none}
  .hero{height:100svh}
  .dims{height:auto}
  .dims-pin{position:static;height:auto;padding:80px 0}
  .dims-rail{overflow-x:auto;-webkit-overflow-scrolling:touch}
  .dims-track{transform:none}
  /* static end states for everything that normally arrives on scroll */
  .stat-v{transform:none}
  .stat-l{opacity:1;transform:none}
  .stat-glow{opacity:.32}
}
