/* =========================================================================
   SIGNUM NIVA — Luxury 4 BHK Boutique Residences, Alipore, South Kolkata
   Mobile-first stylesheet. Base = mobile (375–430px), then 768px, 1024px.
   ========================================================================= */

/* ---------------------------- 0. HEADING FONT ----------------------------
   Absans drives every heading (via --font-display). */
@font-face{
  font-family:'Absans';
  src:url('assets/fonts/Absans-Regular.woff2') format('woff2'),
      url('assets/fonts/Absans-Regular.woff')  format('woff'),
      url('assets/fonts/Absans-Regular.otf')   format('opentype');
  font-weight:400;
  font-style:normal;
  font-display:swap;
}

/* ------------------------------ 1. TOKENS ------------------------------ */
:root{
  /* Colour */
  --color-bg-dark:#0B1214;
  --color-bg-charcoal:#1C1F22;
  --color-bg-light:#F1EFEA;
  --color-teal-deep:#0E7490;
  --color-teal-mid:#17A2A8;
  --color-teal-light:#6FD6C9;
  --color-gradient:linear-gradient(160deg,#6FD6C9 0%,#17A2A8 45%,#0E7490 100%);
  /* Same three-stop teal→blue ramp as above, lifted in luminance so filled buttons
     read bright and alive against the dark ground instead of dull. Buttons only —
     rules, motifs and gradient text keep the calmer original. */
  --color-gradient-btn:linear-gradient(160deg,#93F0E2 0%,#22C8CE 45%,#1596C4 100%);
  /* Brochure teal→blue panel gradient (Rooftop Swimming Pool spread) */
  --grad-pool:linear-gradient(135deg,#7CD8C8 0%,#33A7B4 42%,#2C6BA6 100%);
  /* Amenity band panels — sampled off the brochure amenity spreads:
     mint-teal #6FC6AC at the leading edge → marine #05769A at the trailing one.
     Three sweeps so consecutive panels catch the light differently. */
  --grad-band:linear-gradient(100deg,#6FC6AC 0%,#3FB4BE 34%,#12A2CB 62%,#0090BE 80%,#05769A 100%);
  --grad-band-rev:linear-gradient(260deg,#6FC6AC 0%,#3FB4BE 34%,#12A2CB 62%,#0090BE 80%,#05769A 100%);
  --grad-band-vert:linear-gradient(168deg,#6FC6AC 0%,#2FAEC4 40%,#0B96C4 70%,#05769A 100%);
  --color-gold-accent:#17A2A8;   /* brand cyan/blue accent (was gold #C9A24B) */
  --color-text-on-dark:#F5F4F0;
  --color-text-on-light:#1C1F22;
  --color-text-muted:rgba(245,244,240,.65);
  --color-text-muted-dark:rgba(28,31,34,.68);
  --color-hairline:rgba(245,244,240,.14);
  --color-hairline-dark:rgba(28,31,34,.16);

  /* Type */
  --font-display:'Absans','Fragment Serif','Zodiak',Georgia,'Times New Roman',serif;
  --font-body:'Satoshi',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;

  /* Spacing scale (4/8 rhythm) */
  --sp-1:4px;  --sp-2:8px;  --sp-3:12px; --sp-4:16px; --sp-5:24px;
  --sp-6:32px; --sp-7:48px; --sp-8:64px; --sp-9:96px; --sp-10:140px;

  /* Vertical rhythm. Three steps only, and every section uses them — no bespoke
     per-section clamps, so the page reads as one consistent cadence:
       --section-y  outer breathing room above/below a section
       --head-gap   section header → the content it introduces
       --block-gap  block → block inside a section */
  --section-y:56px;
  --head-gap:28px;
  --block-gap:24px;
  --gutter:24px;
  --maxw:1280px;
  --radius:4px;

  /* Motion */
  --ease-out:cubic-bezier(.22,1,.36,1);
  --dur-fast:180ms;
  --dur-mid:300ms;
  --dur-slow:800ms;
  /* Scroll reveals get their own pair. --ease-out is an expo curve: it spends
     its last 300ms crawling the final few pixels, which reads as lag on a
     heading. --ease-reveal settles cleanly, so 560ms lands crisper than 800
     did — and every reveal on the page shares one duration, so nothing
     arrives out of step with its neighbours. */
  --dur-reveal:560ms;
  --ease-reveal:cubic-bezier(.22,.82,.28,1);

  /* Layering */
  /* Nav sits ABOVE the menu overlay so the close (X) affordance stays reachable. */
  --z-base:0; --z-raise:10; --z-sticky:40; --z-overlay:900; --z-nav:950; --z-modal:1000;

  /* Nav bar row height — the logo and links size themselves to this. */
  --nav-h:56px;
}

/* ------------------------------ 2. RESET ------------------------------ */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{
  margin:0;
  background:var(--color-bg-dark);
  color:var(--color-text-on-dark);
  font-family:var(--font-body);
  font-size:1rem;
  line-height:1.7;
  font-weight:400;
  overflow-x:clip;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}
img,picture,svg,video{display:block;max-width:100%}
img{height:auto}
button,input,select,textarea{font:inherit;color:inherit}
button{background:none;border:0;cursor:pointer}
a{color:inherit;text-decoration:none}
h1,h2,h3,p,figure,blockquote,dl,dd,ol,ul{margin:0}
ol,ul{padding:0;list-style:none}
table{border-collapse:collapse;width:100%}
address{font-style:normal}
.svg-sprite{position:absolute;width:0;height:0;overflow:hidden}
.visually-hidden{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

:where(a,button,input,select,[tabindex]):focus-visible{
  outline:2px solid var(--color-teal-light);
  outline-offset:3px;
  border-radius:2px;
}

.skip-link{
  position:absolute;left:50%;top:-100px;transform:translateX(-50%);
  z-index:var(--z-modal);background:var(--color-teal-mid);color:#06171A;
  padding:12px 20px;font-weight:700;border-radius:0 0 var(--radius) var(--radius);
  transition:top var(--dur-fast) var(--ease-out);
}
.skip-link:focus{top:0}

/* ------------------------------ 3. LAYOUT ------------------------------ */
/* The side gutter is a MARGIN, not padding — content sits exactly --gutter from the
   viewport edge (120px on desktop) with zero inline padding. The max() keeps that
   gutter until the --maxw cap engages on very wide screens, where it becomes the
   centring margin instead. */
.container{max-width:var(--maxw);margin-inline:max(var(--gutter),(100% - var(--maxw))/2);padding-inline:0}
.container--narrow{max-width:820px;margin-inline:max(var(--gutter),(100% - 820px)/2)}
.center{text-align:center}

.section{position:relative;padding-block:var(--section-y);overflow:clip}
/* Two sections of the same tone read as one continuous field, so the pair would
   otherwise stack two full --section-y pads with no edge between them to justify
   it. The trailing pad of the first carries the whole gap. */
.section--light + .section--light,
.section--dark  + .section--dark,
.section--charcoal + .section--charcoal{padding-block-start:0}
/* …except the invitation. It draws its own sealing hairline and light wash, so it
   is a separate leaf of paper rather than a continuation of the section above —
   which means it needs the full site pad, tone match or not. */
.section--light + .section--light.echelons{padding-block-start:var(--section-y)}
.section--dark{background:var(--color-bg-dark)}
.section--charcoal{background:var(--color-bg-charcoal)}
.section--light{background:var(--color-bg-light);color:var(--color-text-on-light)}

/* ---------------------------- 4. TYPOGRAPHY ---------------------------- */
.h1,.h2,.h3,h1,h2,h3{
  font-family:var(--font-display);
  font-weight:400;
  letter-spacing:-.01em;
}
.h1{font-size:clamp(2.4rem,10.5vw,3.4rem);line-height:1.05;margin:0 0 var(--sp-5)}
.h2{font-size:clamp(1.8rem,7.2vw,2.4rem);line-height:1.12;margin:0 0 var(--sp-5)}
.h3{font-size:1.25rem;line-height:1.25;letter-spacing:0;margin:0 0 var(--sp-3)}
.h3__sub{display:block;font-family:var(--font-body);font-size:.95rem;line-height:1.5;
  letter-spacing:0;color:var(--color-text-muted);margin-top:var(--sp-2)}

.eyebrow{
  font-size:.8rem;letter-spacing:.14em;text-transform:uppercase;font-weight:500;
  color:var(--color-teal-light);margin:0 0 var(--sp-4);line-height:1.5;
}
.eyebrow i{font-style:normal;color:var(--color-gold-accent);padding-inline:2px}
.eyebrow--dark{color:var(--color-teal-deep)}
.eyebrow--dark i{color:var(--color-gold-accent)}

/* Hero eyebrow: a hairline lead-in, a gold lozenge separator and a two-tone read,
   so the address sits as a caption under the mark rather than a flat label. */
.eyebrow--hero{
  display:flex;align-items:center;flex-wrap:wrap;
  gap:.5em .6em;font-size:.75rem;letter-spacing:.2em;
  margin-bottom:var(--sp-5);
}
.eyebrow__rule{
  flex:none;width:clamp(24px,5vw,44px);height:1px;
  background:linear-gradient(90deg,rgba(111,214,201,0),var(--color-teal-light));
  transform:scaleX(0);transform-origin:left center;
  transition:transform .9s cubic-bezier(.22,.61,.36,1) .15s;
}
.reveal.is-in .eyebrow__rule,.eyebrow--hero.is-in .eyebrow__rule{transform:scaleX(1)}
/* The address is the plate's only label — set in the brand cyan, where it used to
   be the near-white second half of a two-tone pair with the group line. */
.eyebrow--hero .eyebrow__place{color:var(--color-teal-light)}

.lead{font-size:1rem;line-height:1.75;color:var(--color-text-muted);max-width:62ch}
.section--light .lead{color:var(--color-text-muted-dark)}

.prose p{margin:0 0 var(--sp-5);max-width:65ch;color:var(--color-text-muted-dark)}
.section--dark .prose p,.section--charcoal .prose p{color:var(--color-text-muted)}
.prose p:last-child{margin-bottom:0}
.prose--wide{max-width:76ch;margin-inline:auto}

/* Residences editorial intro — an oversized display-serif lead statement anchors
   the composition; the narrative sits in a measured column beside it, so the
   negative space reads as intentional rather than empty. */
.res__prose{margin-top:var(--head-gap)}
.prose__kicker{
  margin:0;font-size:.72rem;font-weight:500;letter-spacing:.2em;
  text-transform:uppercase;color:var(--color-teal-deep);
}
.prose__rule{
  display:block;width:56px;height:2px;border-radius:2px;
  margin:var(--sp-4) 0 var(--sp-5);background:var(--color-gradient);
}
.res__prose .prose__lead{
  margin:0;max-width:22ch;
  font-family:var(--font-display);font-weight:400;
  font-size:clamp(1.7rem,3.2vw,2.4rem);line-height:1.28;letter-spacing:-.012em;
  color:var(--color-text-on-light);
}
.res__prose .prose__lead em{font-style:italic;color:var(--color-teal-deep)}
.res__prose .prose__body{margin-top:var(--sp-6)}
.res__prose .prose__body p{max-width:60ch}
.res__prose .prose__body p+p{margin-top:var(--sp-5)}
@media (min-width:1024px){
  .res__prose{
    display:grid;align-items:start;margin-top:var(--head-gap);
    grid-template-columns:minmax(0,0.92fr) minmax(0,1.08fr);
    column-gap:clamp(56px,6vw,112px);
  }
  .prose__aside{grid-column:1}
  .res__prose .prose__body{grid-column:2;margin-top:.35em}
}

.prose .pull{
  font-family:var(--font-display);font-size:1.5rem;line-height:1.3;
  color:var(--color-teal-deep);letter-spacing:-.01em;
}

.note{font-size:.85rem;letter-spacing:.02em;color:var(--color-text-muted-dark);margin-top:var(--sp-4)}
.section--dark .note,.section--charcoal .note{color:var(--color-text-muted)}

/* --------------------------- 5. BRAND WORDMARK --------------------------- */
.brand{display:flex;align-items:center;flex:none;height:100%;line-height:1}
/* Cap by height AND width so a wide wordmark can never push the nav row taller
   or crowd the links; max-height keeps it inside the 80px bar with breathing room. */
.brand__logo{
  display:block;width:auto;height:auto;
  max-height:calc(var(--nav-h) - 20px);max-width:190px;object-fit:contain;
}
/* Over the hero the bar is transparent and the wordmark can land on bright foliage.
   A drop-shadow keeps its thin strokes readable; once the bar goes solid it is
   redundant and would only muddy the mark. */
.brand__logo{filter:drop-shadow(0 2px 12px rgba(3,9,11,.75))}
.nav.is-solid .brand__logo{filter:none}
.brand__logo--footer{max-height:none;max-width:260px;width:100%;filter:none}

/* ------------------------------ 6. BUTTONS ------------------------------ */
.btn{
  position:relative;display:inline-flex;align-items:center;justify-content:center;
  min-height:48px;padding:14px 28px;border-radius:999px;overflow:hidden;
  font-family:var(--font-body);font-weight:600;font-size:.82rem;
  letter-spacing:.08em;text-transform:uppercase;text-align:center;
  transition:transform var(--dur-mid) var(--ease-out),box-shadow var(--dur-mid) var(--ease-out),
             background-color var(--dur-mid) var(--ease-out),color var(--dur-mid) var(--ease-out);
  -webkit-tap-highlight-color:transparent;touch-action:manipulation;
}
.btn--primary{background-image:var(--color-gradient-btn);color:#06171A;box-shadow:0 6px 26px -10px rgba(34,200,206,.95)}
.btn--ghost{border:1px solid rgba(147,240,226,.62);color:var(--color-text-on-dark);background-image:var(--color-gradient-btn);
  background-size:100% 0;background-repeat:no-repeat;background-position:bottom}
.btn--block{display:flex;width:100%}
.btn:active{transform:scale(.985)}
/* Leading glyph (download, arrow…) — sized to the cap height of the label so the
   pair reads as one lockup rather than icon-plus-text. */
.btn--icon{gap:.62em}
.btn__ico{flex:none;width:17px;height:17px;color:currentColor}

@media (hover:hover){
  .btn--primary:hover{transform:scale(1.03);box-shadow:0 14px 38px -12px rgba(34,200,206,.9)}
  .btn--ghost:hover{background-size:100% 100%;color:#06171A;border-color:transparent}
}

/* Ripple (mobile tap feedback) */
.ripple{
  position:absolute;border-radius:50%;transform:scale(0);pointer-events:none;
  background:rgba(255,255,255,.45);animation:ripple 600ms var(--ease-out) forwards;
}
@keyframes ripple{to{transform:scale(2.6);opacity:0}}

/* ---------------------------- 7. NAVIGATION ---------------------------- */
.nav{
  position:fixed;inset:0 0 auto;z-index:var(--z-nav);
  padding-top:env(safe-area-inset-top);
  background:transparent;
  transition:transform 350ms var(--ease-out),background-color var(--dur-mid) linear,
             backdrop-filter var(--dur-mid) linear,border-color var(--dur-mid) linear;
  border-bottom:1px solid transparent;
}
.nav__inner{
  display:flex;align-items:center;justify-content:space-between;gap:var(--sp-5);
  width:auto;max-width:var(--maxw);height:var(--nav-h);
  margin-inline:max(var(--gutter),(100% - var(--maxw))/2);padding-inline:0;
}
.nav.is-solid{
  background:rgba(11,18,20,.82);
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  border-bottom-color:var(--color-hairline);
}
/* Over the hero the bar is transparent — this soft top-down scrim gives it presence
   as a prominent bar and melts into the image just below it. It lifts away the moment
   the bar goes solid on scroll, so the two treatments never stack. */
.nav::after{
  content:"";position:absolute;inset:0 0 auto;z-index:-1;pointer-events:none;
  height:calc(100% + 64px);
  background:linear-gradient(180deg,
    rgba(5,11,13,.72) 0%,rgba(5,11,13,.5) 32%,rgba(5,11,13,.24) 62%,transparent 100%);
  transition:opacity var(--dur-mid) linear;
}
.nav.is-solid::after{opacity:0}
.nav.is-hidden{transform:translateY(-115%)}
.nav__links{display:none}
.nav__cta{display:none}

.burger{
  display:flex;flex-direction:column;justify-content:center;gap:5px;
  width:48px;height:48px;margin-right:-10px;align-items:flex-end;
  -webkit-tap-highlight-color:transparent;touch-action:manipulation;
}
.burger span{
  display:block;height:1.5px;background:var(--color-text-on-dark);border-radius:2px;
  transition:transform 260ms var(--ease-out),opacity 160ms linear,width 260ms var(--ease-out);
}
.burger span:nth-child(1){width:26px}
.burger span:nth-child(2){width:20px}
.burger span:nth-child(3){width:26px}
.burger[aria-expanded="true"] span:nth-child(1){width:26px;transform:translateY(6.5px) rotate(45deg)}
.burger[aria-expanded="true"] span:nth-child(2){opacity:0}
.burger[aria-expanded="true"] span:nth-child(3){width:26px;transform:translateY(-6.5px) rotate(-45deg)}

/* Full-screen mobile menu */
.menu{
  position:fixed;inset:0;z-index:var(--z-overlay);
  display:flex;flex-direction:column;justify-content:space-between;
  padding:calc(84px + env(safe-area-inset-top)) var(--gutter) calc(28px + env(safe-area-inset-bottom));
  background:var(--color-bg-dark);
  opacity:0;transition:opacity 320ms var(--ease-out);
  overflow-y:auto;overscroll-behavior:contain;
}
.menu[hidden]{display:none}
.menu.is-open{opacity:1}
.menu__links{display:flex;flex-direction:column}
.menu__links a{
  display:flex;align-items:baseline;gap:var(--sp-4);
  padding:var(--sp-4) 0;min-height:56px;
  font-family:var(--font-display);font-size:2rem;line-height:1.1;
  border-bottom:1px solid var(--color-hairline);
  opacity:0;transform:translateY(22px);
}
.menu.is-open .menu__links a{animation:menuIn 520ms var(--ease-out) forwards}
.menu.is-open .menu__links a:nth-child(1){animation-delay:80ms}
.menu.is-open .menu__links a:nth-child(2){animation-delay:140ms}
.menu.is-open .menu__links a:nth-child(3){animation-delay:200ms}
.menu.is-open .menu__links a:nth-child(4){animation-delay:260ms}
.menu.is-open .menu__links a:nth-child(5){animation-delay:320ms}
.menu.is-open .menu__links a:nth-child(6){animation-delay:380ms}
@keyframes menuIn{to{opacity:1;transform:none}}
.menu__links span{
  font-family:var(--font-body);font-size:.68rem;font-weight:500;letter-spacing:.16em;
  color:var(--color-teal-light);
}
.menu__foot{padding-top:var(--sp-7)}
.menu__tag{margin-top:var(--sp-5);font-size:.62rem;letter-spacing:.2em;text-transform:uppercase;color:var(--color-teal-light)}
.menu__addr{font-size:.82rem;color:var(--color-text-muted);margin-top:var(--sp-2)}

body.is-locked{overflow:hidden}

/* ------------------------------- 8. HERO ------------------------------- */
/* The copy sits in the optical centre of the frame: the nav clears the top, the
   scroll cue clears the base, and the body centres in what is left. */
.hero{
  position:relative;min-height:100svh;min-height:100dvh;
  display:flex;flex-direction:column;justify-content:center;
  padding-block:calc(var(--nav-h) + var(--sp-5)) calc(96px + env(safe-area-inset-bottom));
  overflow:clip;isolation:isolate;
}
.hero__media,.cta__media{position:absolute;inset:-8% 0;z-index:-2;will-change:transform}
/* <picture> is inline by default — it must fill the frame or img height:100% collapses */
.hero__media picture,.cta__media picture,.day__media picture{display:block;width:100%;height:100%}
.hero__media img,.cta__media img{width:100%;height:100%;object-fit:cover;object-position:center 42%}
.hero__scrim,.cta__scrim{
  position:absolute;inset:0;z-index:-1;
  background:
    linear-gradient(180deg,rgba(11,18,20,.68) 0%,rgba(11,18,20,.12) 26%,rgba(11,18,20,.55) 62%,rgba(11,18,20,.94) 88%,#0B1214 100%),
    radial-gradient(120% 60% at 50% 112%,rgba(14,116,144,.38),transparent 70%);
}
/* The render is a flat, hazy blue by default. Grade it so the tower carries real
   depth AND stays clearly lit — a gentle brightness lift plus richer colour so the
   pool, canopy and lit windows read at a glance rather than sinking into the haze.
   A very slow ken-burns drift (child <img>, so it never fights the parent parallax)
   keeps the frame quietly alive. */
.hero__media img{
  filter:saturate(1.16) contrast(1.07) brightness(1.05);
  transform-origin:62% 46%;
  animation:heroKen 32s ease-in-out infinite alternate;
}
@keyframes heroKen{from{transform:scale(1.005)}to{transform:scale(1.075)}}

/* Three stacked layers, each with one job: nav backing plus the bottom hand-off to
   the section below; a vignette to stop the eye wandering out of frame; and a teal
   ground-glow picking up the brand gradient. Mobile stays vertical — the horizontal
   copy-plate arrives at 768px, where type and tower finally sit side by side. */
.hero__scrim{
  background:
    /* Copy pool — a soft, centred well of shade the type can sit inside without
       the whole frame going flat. This is what carries the centred composition. */
    radial-gradient(120% 78% at 26% 52%,rgba(3,9,11,.66),rgba(3,9,11,.28) 52%,transparent 78%),
    linear-gradient(180deg,
      rgba(6,13,15,.24) 0%,rgba(6,13,15,.06) 12%,transparent 24%,
      rgba(6,13,15,.24) 50%,rgba(11,18,20,.66) 78%,rgba(11,18,20,.9) 92%,#0B1214 100%),
    radial-gradient(145% 100% at 60% 42%,transparent 40%,rgba(3,9,11,.52) 100%),
    radial-gradient(96% 52% at 42% 110%,rgba(23,162,168,.36),transparent 72%);
}

/* A high, cool moonlight bloom over the towers — the one warm-cold contrast in the
   frame, and what keeps the render from reading as a flat night photograph. */
.hero__glow{
  position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:radial-gradient(46% 34% at 74% 12%,rgba(140,205,220,.16),transparent 68%);
  mix-blend-mode:screen;
}

/* Inset hairline frame with brighter corner brackets — the couture device: it
   states "this is a composed image" without adding a single opaque pixel. */
.hero__frame{
  position:absolute;inset:14px;z-index:0;pointer-events:none;
  border:1px solid rgba(245,244,240,.09);border-radius:3px;
}
.hero__frame::before,.hero__frame::after{
  content:"";position:absolute;width:38px;height:38px;
  border:1px solid rgba(111,214,201,.55);
}
.hero__frame::before{top:-1px;left:-1px;border-right:0;border-bottom:0}
.hero__frame::after{right:-1px;bottom:-1px;border-left:0;border-top:0}

/* Fine film grain — stops a large flat gradient banding on wide screens and gives
   the photograph a printed, editorial surface rather than a digital one. */
.hero::after{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  opacity:.05;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* Text sits directly on photography, so lift it off the image with a tight shadow
   for edge definition plus a wide one for separation — rather than darkening the
   whole scrim and losing the render. */
.hero__body{
  position:relative;z-index:1;
  text-shadow:0 1px 3px rgba(3,9,11,.62),0 3px 40px rgba(3,9,11,.72);
}
.hero__body .eyebrow{color:var(--color-teal-light)}

/* The copy is left-aligned against the frame's own left margin — eyebrow,
   headline, flourish, sub-copy and button all share that one edge. */
.hero__copy{margin-inline:0;text-align:left}

/* The eyebrow becomes a glass caption plate — blurred, hairlined, self-contained.
   Small, but it is the first thing read and sets the register for everything under it. */
.hero .eyebrow--hero{
  display:inline-flex;width:auto;
  padding:9px 18px 9px 14px;border-radius:999px;
  border:1px solid rgba(245,244,240,.14);
  background:linear-gradient(120deg,rgba(245,244,240,.09),rgba(245,244,240,.03));
  -webkit-backdrop-filter:blur(10px) saturate(1.2);backdrop-filter:blur(10px) saturate(1.2);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.09),0 10px 30px -20px rgba(0,0,0,.9);
  text-shadow:none;font-size:.68rem;
}
/* Hero heading tops out at 64px on desktop, scales down on small screens so
   each line still fits. Higher specificity than the responsive .h1 rules,
   so it wins across every breakpoint. */
.hero .h1{letter-spacing:-.022em;font-size:clamp(2.5rem,6.6vw,68px);margin-bottom:var(--sp-4)}
/* The payoff line is the only gradient-filled type on the page. Clipped fills can
   carry no text-shadow, so its lift comes from a drop-shadow filter instead. */
.hero .h1 em{
  font-style:normal;
  /* The inherited body shadow would be painted straight through a transparent
     glyph fill and grey the letters out — the drop-shadow filter replaces it. */
  text-shadow:none;
  background:linear-gradient(94deg,#FFFFFF 0%,#FBFFFE 30%,#C8F2E9 66%,var(--color-teal-light) 100%);
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;color:transparent;
  filter:drop-shadow(0 2px 26px rgba(3,9,11,.85));
}

/* Hairline flourish between headline and sub-copy, with a lozenge at its head —
   the same lozenge as the eyebrow, so the block reads as one set. It starts on
   the copy's left edge and fades right, following the left-aligned axis. */
.hero__flourish{
  display:block;position:relative;width:104px;height:1px;
  margin:0 0 var(--sp-5);
  background:linear-gradient(90deg,var(--color-teal-light),rgba(111,214,201,0));
}
.hero__flourish::after{
  content:"";position:absolute;left:0;top:50%;
  width:5px;height:5px;margin-top:-2.5px;
  background:var(--color-teal-light);transform:rotate(45deg);
  box-shadow:0 0 12px rgba(111,214,201,.9);
}
.hero__sub{
  font-size:1.05rem;line-height:1.62;color:rgba(245,244,240,.88);
  letter-spacing:.004em;margin:0 0 var(--sp-6);max-width:36ch;
}
/* Left-aligned on both axes: the stacked column stretches (so the mobile button
   spans the copy), the row that arrives at 768px starts at the copy's left edge. */
.hero__cta{
  display:flex;flex-direction:column;gap:var(--sp-3);
  align-items:stretch;justify-content:flex-start;
}
/* Reset the hero body's inherited text-shadow — the button label sits on a
   solid fill and needs no shadow. */
.hero__cta .btn{width:100%;text-shadow:none}
/* Hero CTA is enlarged (~1.4x) with tighter tracking so the label reads big
   and confident rather than spaced-out. */
.hero__cta .btn--primary{
  min-height:66px;padding:20px 48px;
  font-size:1rem;letter-spacing:.02em;
  box-shadow:0 12px 40px -12px rgba(34,200,206,1),0 2px 10px rgba(3,9,11,.45),
             inset 0 1px 0 rgba(255,255,255,.42);
}
/* A slow light sweep across the primary — the one moving highlight in the frame,
   long-cycled so it reads as sheen on a surface, not as an animation. */
.hero__cta .btn--primary::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(100deg,transparent 34%,rgba(255,255,255,.5) 50%,transparent 66%);
  transform:translateX(-120%);
  animation:heroSheen 6.5s cubic-bezier(.35,0,.2,1) 1.6s infinite;
}
@keyframes heroSheen{0%{transform:translateX(-120%)}38%,100%{transform:translateX(120%)}}

.scrollcue{
  position:absolute;left:50%;bottom:calc(28px + env(safe-area-inset-bottom));
  transform:translateX(-50%);
  display:flex;flex-direction:column;align-items:center;gap:var(--sp-2);
  min-height:44px;min-width:44px;justify-content:flex-end;
}
.scrollcue__line{
  display:block;width:1px;height:46px;
  background:linear-gradient(180deg,transparent,var(--color-teal-light));
  animation:cue 2200ms ease-in-out infinite;transform-origin:top;
}
.scrollcue__txt{
  font-size:.58rem;letter-spacing:.34em;text-transform:uppercase;text-indent:.34em;
  color:rgba(245,244,240,.62);text-shadow:0 1px 12px rgba(3,9,11,.7);
}
@keyframes cue{0%,100%{transform:scaleY(.35);opacity:.4}50%{transform:scaleY(1);opacity:1}}

/* ---------------------------- 9. MOTIF ART ---------------------------- */
.motif{
  position:absolute;pointer-events:none;
  width:min(78vw,420px);aspect-ratio:1;
  opacity:.12;z-index:0;
}
.motif--sun{top:-10%;right:-24%}
.motif--tr{top:auto;bottom:-8%;right:-28%;opacity:.09}
.motif--bl{top:auto;bottom:-12%;left:-30%;right:auto;opacity:.09}
.motif--rings{top:6%;left:-26%;opacity:.16}
.motif--spin{animation:spin 60s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
/* Doubled class so the 768px/1024px `.motif` width bump can't inflate the
   inline divider mark — it must stay a small typographic ornament. */
.motif.motif--inline{
  position:static;width:56px;opacity:.85;margin:0 auto var(--sp-4);
}

/* ------------------------- 10. MEANING / CREED -------------------------
   A single held statement over a glass plate. The section runs tighter than the
   page default — the whole point is one breath of text, so vertical air past
   what the type needs reads as a gap rather than as composure. */
.meaning{position:relative;isolation:isolate;padding-block:var(--section-y)}
/* Wider than the page measure on purpose: the statement is three long lines and
   each must hold on a single line at full type size. The cap is deliberately
   generous so the type — sized below — always has room to spare. */
.meaning .container--narrow{
  max-width:min(1240px,92vw);
  margin-inline:auto;
}

/* A very low teal wash pooled behind the statement, so the plate has something
   to sit against instead of flat black. */
.meaning__wash{
  position:absolute;inset:0;pointer-events:none;z-index:0;
  background:
    radial-gradient(72% 52% at 50% 16%,rgba(23,162,168,.11),transparent 68%),
    radial-gradient(52% 40% at 50% 104%,rgba(14,116,144,.10),transparent 70%);
}
.meaning__rings{width:min(64vw,340px);opacity:.07}

.meaning .h2{
  font-size:clamp(1.5rem,6.4vw,2.5rem);line-height:1.24;letter-spacing:-.012em;
  position:relative;z-index:1;margin-bottom:0;
  color:#FBFAF7;
  text-shadow:0 1px 40px rgba(111,214,201,.14);
}

/* ---- Creed plate ---- */
.creed{
  position:relative;z-index:1;isolation:isolate;overflow:hidden;
  /* A grid of ruled cells rather than a stack of padded lines — the rules are
     what hold the four statements together as one plate. */
  display:grid;gap:0;width:100%;max-width:100%;
  margin-top:clamp(18px,2.4vw,28px);
  padding:clamp(16px,2.2vw,22px) clamp(10px,1.4vw,16px) clamp(10px,1.4vw,16px);
  border-radius:16px;
  background:
    linear-gradient(180deg,rgba(255,255,255,.075) 0%,rgba(255,255,255,.018) 34%,rgba(255,255,255,0) 66%),
    linear-gradient(180deg,rgba(20,32,35,.44),rgba(9,15,17,.56));
  -webkit-backdrop-filter:blur(18px) saturate(150%);backdrop-filter:blur(18px) saturate(150%);
  box-shadow:
    0 40px 90px -52px rgba(0,0,0,.9),
    inset 0 1px 0 rgba(255,255,255,.14),
    inset 0 -40px 70px -56px rgba(23,162,168,.4);
}
/* Gradient frame stroke — a 1px ring of the brand cyan→blue, drawn as a masked
   border so the corners stay perfectly round and the fill stays untouched. */
.creed::before{
  content:"";position:absolute;inset:0;border-radius:inherit;padding:1px;
  background:linear-gradient(150deg,#93F0E2 0%,#22C8CE 34%,#1596C4 68%,rgba(21,150,196,.25) 100%);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);
  mask-composite:exclude;
  opacity:.62;pointer-events:none;
}
/* Slow specular sweep across the glass — same gesture as the brochure button,
   stretched long enough to read as light moving rather than a loop.
   The travelling band lives on a pseudo inside this wrapper rather than on the
   plate itself: backdrop-filter promotes .creed to its own layer, where its
   overflow:hidden can stop clipping descendants, so the clip is done here on a
   plain element that is guaranteed to hold it. */
.creed__sheen{
  position:absolute;inset:0;z-index:-1;
  overflow:hidden;border-radius:inherit;pointer-events:none;
}
.creed__sheen::after{
  content:"";position:absolute;inset:0;
  background:linear-gradient(108deg,transparent 38%,rgba(255,255,255,.10) 50%,transparent 62%);
  transform:translateX(-125%);
}
.creed.is-in .creed__sheen::after{animation:creed-sheen 9s cubic-bezier(.4,0,.2,1) 1.2s infinite}
@keyframes creed-sheen{0%{transform:translateX(-125%)}34%,100%{transform:translateX(125%)}}

/* The plate's only ornament: a hairline with a lit gradient lozenge at its
   centre. The brand sun-rays motif was drawn at 200px and its 1px strokes all
   but vanished at ornament size — this reads crisply at any scale. */
.creed__mark{
  position:relative;justify-self:center;
  width:min(200px,52%);height:1px;margin-bottom:clamp(14px,1.6vw,20px);
  background:linear-gradient(90deg,rgba(111,214,201,0),rgba(111,214,201,.45),rgba(111,214,201,0));
}
.creed__mark::after{
  content:"";position:absolute;left:50%;top:50%;
  width:6px;height:6px;transform:translate(-50%,-50%) rotate(45deg);
  background:var(--color-gradient-btn);
  box-shadow:0 0 14px rgba(34,200,206,.8);
}

/* Each line is a cell in a ruled grid. The rules are drawn on the cells so they
   span the full row height and always meet — the previous border-right on odd
   lines was only as tall as its own text, so with rows of unequal height it read
   as two stray, misaligned ticks. */
.creed p{
  position:relative;margin:0;text-align:left;
  padding:clamp(13px,1.5vw,18px) clamp(16px,1.8vw,24px) clamp(13px,1.5vw,18px) calc(clamp(16px,1.8vw,24px) + 1.05em);
  font-family:var(--font-display);font-style:italic;
  font-size:.98rem;line-height:1.45;letter-spacing:.012em;
  color:var(--color-teal-light);
  /* Revealed by the plate, staggered in CSS — see the note in the markup. */
  opacity:0;transform:translateY(10px);
  transition:opacity 700ms var(--ease-out),transform 700ms var(--ease-out);
}
/* A small cyan lozenge sets each line off without shouting like a bullet — the
   same diamond as the plate's ornament, so the marks read as one family. */
.creed p::before{
  content:"";position:absolute;left:clamp(16px,1.8vw,24px);top:1.5em;
  width:5px;height:5px;transform:rotate(45deg);
  background:var(--color-teal-light);opacity:.8;
  box-shadow:0 0 10px rgba(111,214,201,.7);
}
/* Stacked on mobile: a rule between consecutive lines. */
.creed p + p{border-top:1px solid rgba(111,214,201,.13)}
.creed.is-in p{opacity:1;transform:none}
.creed.is-in p:nth-of-type(1){transition-delay:120ms}
.creed.is-in p:nth-of-type(2){transition-delay:220ms}
.creed.is-in p:nth-of-type(3){transition-delay:320ms}
.creed.is-in p:nth-of-type(4){transition-delay:420ms}
@media (prefers-reduced-motion:reduce){
  .creed p{opacity:1;transform:none;transition:none}
}

/* ---------------------- 11. SPLIT (echelons / story) ---------------------- */
.split{display:grid;gap:var(--head-gap)}
.split__media{overflow:hidden;border-radius:var(--radius)}
.split__media img{width:100%;aspect-ratio:4/3;object-fit:cover;object-position:72% center}
@media (min-width:1024px){.split__media img{aspect-ratio:5/4}}

/* ===== Echelons — elevated editorial treatment of "The Invitation" ===== */
.echelons{position:relative;isolation:isolate}
.echelons .container{position:relative;z-index:1}
.echelons .split__copy{position:relative;z-index:1}

/* Reverse-spinning companion to .motif--spin */
.motif--spin-rev{animation:spin-rev 120s linear infinite}
@keyframes spin-rev{to{transform:rotate(-360deg)}}

/* Ambient light wash — the flat paper lifted by two faint teal glows, plus a
   hairline that seals the top edge so the section reads as its own leaf of paper. */
.echelons__wash{
  position:absolute;inset:0;z-index:0;pointer-events:none;
  background:
    radial-gradient(58% 55% at 84% 10%, rgba(23,162,168,.11), transparent 70%),
    radial-gradient(55% 62% at 6% 94%, rgba(14,116,144,.09), transparent 72%),
    radial-gradient(120% 60% at 50% 0%, rgba(255,255,255,.66), transparent 62%),
    linear-gradient(180deg, rgba(255,255,255,.55), transparent 26%);
}
.echelons__wash::after{
  content:"";position:absolute;left:0;right:0;top:0;height:1px;
  background:linear-gradient(90deg,transparent,rgba(14,116,144,.28) 22%,rgba(14,116,144,.28) 78%,transparent);
}

/* Vast, faint rotating Niva sun sitting behind the copy */
.echelons__sun{
  --sz:clamp(360px,58vw,700px);
  position:absolute;z-index:0;pointer-events:none;
  width:var(--sz);height:var(--sz);
  left:-17%;top:50%;margin-top:calc(var(--sz) / -2);
  opacity:.06;
}

/* Eyebrow with an animated lead-in rule */
.eyebrow--marked{display:inline-flex;align-items:center;gap:.75em}
.eyebrow--marked .eyebrow__rule{
  width:clamp(26px,4vw,44px);height:1px;
  background:linear-gradient(90deg,rgba(14,116,144,0),var(--color-teal-deep));
}

/* Heading — tighter tracking than the global .h2 so the two long lines hold
   together as one editorial block, and a measured column so the ragged right
   edge stays even instead of running the full grid cell. */
.echelons .h2{
  letter-spacing:-.02em;max-width:20ch;
  margin-bottom:var(--sp-6);
}

/* Copy column — one measure for the whole column so every paragraph shares a rag. */
.echelons .prose--lux{max-width:56ch}
.echelons .prose--lux p{max-width:none}

/* Lead paragraph — a touch larger, set on a gradient accent bar that glows
   faintly so it reads as brand light rather than a plain border. */
.prose--lux > p:first-child{
  position:relative;padding-left:var(--sp-5);
  font-size:1.06rem;line-height:1.72;color:var(--color-text-on-light);
  letter-spacing:.002em;
}
.prose--lux > p:first-child::before{
  content:"";position:absolute;left:0;top:.35em;bottom:.35em;width:2px;
  border-radius:2px;background:var(--color-gradient);
  box-shadow:0 0 14px -2px rgba(23,162,168,.55);
}

/* Elevated pull line — "Welcome to the high life." */
.echelons__pull{
  display:flex;align-items:center;gap:.9em;flex-wrap:wrap;
  margin-top:var(--sp-7);margin-bottom:0;
  font-family:var(--font-display);font-weight:400;letter-spacing:-.012em;
  font-size:clamp(1.55rem,4.4vw,2.05rem);line-height:1.2;
  color:var(--color-teal-deep);
}
.echelons__pull-rule{
  flex:none;width:clamp(30px,5vw,54px);height:2px;border-radius:2px;
  background:var(--color-gradient);
  transform:scaleX(0);transform-origin:left center;
  transition:transform .9s cubic-bezier(.22,.61,.36,1) .2s;
}
.reveal.is-in .echelons__pull-rule{transform:scaleX(1)}

/* Brochure CTA — the gradient pill plus a quiet line of reassurance beside it.
   Aligned to the copy's left edge (not the pull line's rule) so the whole
   column shares one optical margin. */
.echelons__cta{
  display:flex;align-items:center;gap:var(--sp-5);flex-wrap:wrap;
  margin-top:var(--sp-6);
}
.echelons__brochure{
  padding-inline:30px;letter-spacing:.1em;
  box-shadow:0 10px 30px -12px rgba(34,200,206,.85),0 2px 8px -4px rgba(11,18,20,.3);
}
/* A slow specular sweep — the only motion on the button at rest, so it catches
   the eye without competing with the rotating motifs. */
.echelons__brochure::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(105deg,transparent 36%,rgba(255,255,255,.62) 50%,transparent 64%);
  transform:translateX(-120%);
  animation:brochure-sheen 5.4s cubic-bezier(.4,0,.2,1) 1.6s infinite;
}
@keyframes brochure-sheen{0%{transform:translateX(-120%)}26%,100%{transform:translateX(120%)}}
.echelons__brochure .btn__ico{transition:transform var(--dur-mid) var(--ease-out)}
@media (hover:hover){
  .echelons__brochure:hover .btn__ico{transform:translateY(2px)}
}

/* Signature lockup */
/* Flex, not grid: the mark is now taller than the two text lines together, and a
   row-spanning grid item would stretch the rows apart to fill its height. */
.echelons__sign{
  display:flex;align-items:center;gap:var(--sp-5);max-width:32rem;
  margin-top:var(--sp-7);padding-top:var(--sp-5);
  border-top:1px solid var(--color-hairline-dark);
}
.echelons__sign-txt{display:flex;flex-direction:column;gap:3px;min-width:0}
/* Doubled from clamp(30–40px): at its old size the ring read as a bullet beside
   the wordmark rather than as the brand mark. Width and height carry the same
   clamp, so the ring stays circular at every step. */
.echelons__sign-mark{
  flex:none;
  width:clamp(60px,10vw,80px);height:clamp(60px,10vw,80px);
  opacity:.92;
}
.echelons__sign-name{
  font-family:var(--font-display);font-size:1.2rem;line-height:1.1;
  color:var(--color-text-on-light);letter-spacing:.01em;
}
.echelons__sign-tag{
  font-size:.62rem;font-weight:600;letter-spacing:.2em;
  text-transform:uppercase;color:var(--color-teal-deep);
}

/* Image — matted frame, floating spiral jewel, meaning caption.
   Geometry: --mat is the offset between the plate and its outline. */
.echelons__media{
  --mat:16px;
  position:relative;overflow:visible;border-radius:0;
}
/* The mat is measured against the plate alone, never the figure — otherwise the
   outline stretches down past the caption and cuts through the type. */
.echelons__plate{position:relative}
.echelons__media-inner{
  position:relative;z-index:1;overflow:hidden;border-radius:var(--radius);
  box-shadow:
    0 34px 66px -34px rgba(14,116,144,.4),
    0 12px 34px -20px rgba(11,18,20,.28),
    inset 0 0 0 1px rgba(255,255,255,.22);
  transition:transform var(--dur-slow) var(--ease-out),box-shadow var(--dur-slow) var(--ease-out);
}
/* The plate sits on paper, so it needs a warm inner edge rather than a hard cut. */
.echelons__media-inner::after{
  content:"";position:absolute;inset:0;z-index:2;pointer-events:none;
  border-radius:inherit;
  box-shadow:inset 0 0 42px -18px rgba(11,18,20,.45);
}
/* Specular sweep on hover — travels once, left to right, then parks off-plate. */
.echelons__sheen{
  position:absolute;inset:0;z-index:3;pointer-events:none;
  background:linear-gradient(104deg,transparent 38%,rgba(255,255,255,.3) 50%,transparent 62%);
  transform:translateX(-110%);
  transition:transform 1.1s cubic-bezier(.3,0,.2,1);
}
/* The mat is offset up and to the right: its top and right edges read as a fine
   outline around the plate, while its bottom and left edges hide behind it —
   leaving the space under the plate clear for the caption. */
.echelons__frame{
  position:absolute;z-index:0;pointer-events:none;
  top:calc(var(--mat) * -1);right:calc(var(--mat) * -1);left:var(--mat);bottom:var(--mat);
  border:1px solid rgba(14,116,144,.4);border-radius:var(--radius);
  transition:opacity var(--dur-slow) var(--ease-out),transform var(--dur-slow) var(--ease-out);
}
/* Corner tick — a jeweller's registration mark on the mat's one outer corner.
   The other three sit behind the plate, so a mark there would never be seen. */
.echelons__frame::after{
  content:"";position:absolute;right:-1px;top:-1px;width:18px;height:18px;
  border:0 solid var(--color-teal-mid);opacity:.85;
  border-right-width:2px;border-top-width:2px;
}
.echelons__spiral{
  position:absolute;z-index:2;pointer-events:none;
  width:clamp(76px,13vw,140px);height:clamp(76px,13vw,140px);
  top:-6%;left:-6%;
  filter:drop-shadow(0 6px 14px rgba(11,18,20,.18));
}
@media (hover:hover){
  .echelons__media:hover .echelons__media-inner{
    transform:translateY(-4px);
    box-shadow:
      0 46px 80px -36px rgba(14,116,144,.5),
      0 16px 40px -22px rgba(11,18,20,.32),
      inset 0 0 0 1px rgba(255,255,255,.3);
  }
  .echelons__media:hover .echelons__sheen{transform:translateX(110%)}
  .echelons__media:hover .echelons__frame{transform:translate(3px,3px)}
}
/* Caption — the signature lockup sits here, on the plate's own left edge, so mark
   and wordmark share one optical margin with the image above. */
.echelons__cap{
  display:block;padding-left:0;
}
/* The lockup carries its own rule and spacing (see .echelons__sign); inside the
   caption it only needs the gap from the plate. */
.echelons__cap .echelons__sign{
  margin-top:var(--sp-5);max-width:none;
}

/* Mobile only (<=767px): this column is set at desktop leading (1.7) with
   24px paragraph gaps and a 48px lead-in to the pull line — proportions that
   read as air on a wide measure but as dead scroll on a 345px one, where the
   same copy runs to roughly three screens. Tighten leading to 1.6 and halve
   the structural gaps. The rhythm is kept intact: paragraph gaps stay clearly
   larger than the line gap, so the copy still reads as separate thoughts
   rather than one congested slab. Desktop proportions are untouched. */
@media (max-width:767px){
  .echelons .h2{margin-bottom:var(--sp-4)}

  .echelons .prose--lux p{line-height:1.6;margin-bottom:var(--sp-4)}
  .echelons .prose--lux > p:first-child{
    font-size:1rem;line-height:1.62;padding-left:var(--sp-4);
  }

  /* 48px -> 24px: the pull line already earns separation from its own scale
     and its gradient rule, so it doesn't need the extra runway. */
  .echelons__pull{margin-top:var(--sp-5)}
  .echelons__cta{margin-top:var(--sp-5)}
}

@media (min-width:768px){
  .echelons__cta{gap:var(--sp-6)}
}

@media (min-width:1024px){
  .echelons .h2{font-size:clamp(2.3rem,3.4vw,3.15rem)}
  .echelons__pull{margin-top:var(--block-gap)}
  /* The mat overhangs up and right; the inset pulls the plate back so the
     outline — not the photo — sits flush with the grid column. */
  .echelons__media{--mat:24px;margin-right:var(--mat)}
  /* A near-square plate stands taller against the long copy column, so the two
     halves finish closer together instead of stranding air under the picture. */
  .echelons__media-inner img{aspect-ratio:1/1}
}

@media (prefers-reduced-motion:reduce){
  .echelons__brochure::after{animation:none;display:none}
  .echelons__sheen{display:none}
}
html.perf-lite .echelons__brochure::after,
html.perf-lite .echelons__sheen{display:none}

/* --------------------- 12. WEEK IN THE HIGH LIFE --------------------- */
/* A horizontal carousel of elevated, rounded image cards. Base = a native
   swipe/scroll-snap strip; desktop upgrades to a pinned scroll where vertical
   scroll drives the rail right→left, releasing to normal scroll after the last
   card (see the 1024 block and the JS week logic). */
/* The one light leaf in the dark run: a near-white ground with a very subtle grey
   gradient so the field still has depth rather than reading as flat paper. Text and
   frame ornament flip to their on-light values below. */
.week{
  position:relative;
  background:linear-gradient(170deg,#FBFBFC 0%,#F4F5F6 46%,#EDEEF0 100%);
  color:var(--color-text-on-light);
}
.week .eyebrow{color:var(--color-teal-deep)}
.week .eyebrow i{color:var(--color-gold-accent)}
.week .h2{color:var(--color-text-on-light)}
/* Same header→content step as every other section: the section pad carries the
   gap, so the heading's own bottom margin is dropped rather than added to it. */
.week__intro{padding-block:var(--section-y) var(--head-gap)}
.week__intro .h2{margin-bottom:0}
.week__stage{display:block}

.week__rail{
  display:flex;gap:clamp(16px,4vw,40px);
  overflow-x:auto;overflow-y:hidden;
  scroll-snap-type:x mandatory;-webkit-overflow-scrolling:touch;
  scrollbar-width:none;
  padding:var(--sp-2) clamp(16px,6vw,48px) var(--sp-6);
}
.week__rail::-webkit-scrollbar{display:none}

.day{
  flex:0 0 auto;width:min(88vw,560px);scroll-snap-align:center;
  display:flex;flex-direction:column;gap:var(--sp-4);
}
.day__media{
  position:relative;overflow:hidden;border-radius:18px;
  aspect-ratio:3/2;background:var(--color-bg-charcoal);
  box-shadow:0 30px 56px -30px rgba(28,31,34,.34),0 2px 8px rgba(28,31,34,.12);
}
/* Inset hairline ring seals the frame's edge against the near-white field. */
.day__media::after{
  content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;
  box-shadow:inset 0 0 0 1px rgba(28,31,34,.10);
}
.day__media img{
  width:100%;height:100%;object-fit:cover;object-position:center;
  transition:transform 900ms var(--ease-out);
}
@media (hover:hover){.day:hover .day__media img{transform:scale(1.045)}}
/* Phone: the landscape frame reads thin in a vertical scroll, so the card is
   deepened to a semi-portrait 4/5 — between square and a full portrait. */
@media (max-width:767px){
  .day__media{aspect-ratio:4/5}
}

/* Editorial caption: the descriptive line on its own, replacing the bare day
   name. (The small index numeral that used to lead it has been dropped.) */
.day__cap{
  display:flex;align-items:baseline;
  margin:0;padding-inline:var(--sp-1);
}
.day__txt{
  font-family:var(--font-display);font-weight:400;
  font-size:clamp(1.02rem,1.35vw,1.22rem);line-height:1.32;letter-spacing:-.005em;
  color:var(--color-text-on-light);
}

/* --------------------------- 13. ADDRESS --------------------------- */
/* Left rail: a centred header with the five neighbourhood cards beneath it.
   Right rail: the full portrait map, held to the top of the grid. Two revolving
   brand motifs drift behind, so the panel sits above them (z-index:1). */
.address{position:relative}
.address__grid{position:relative;z-index:1;display:grid;gap:var(--head-gap)}
.address__head{position:relative}
/* Mobile: the rail dissolves so map, cards and quote are direct grid items and
   `order` can put the closing statement last, after the cards it summarises. */
.address__rail{display:contents}
.address__head{order:1}
.map{order:2}
.amencards{order:3}
.address .quote{order:4}
.address .lead{margin-top:var(--sp-5)}

/* Left-ranged header — the measure is capped so the rag stays controlled, but it
   hangs off the left edge rather than centring in the column. */
.address__head--start{text-align:left}
.address__head--start .lead{max-width:62ch;margin-inline:0}
.address__head--start .vertical-note{margin-inline:0}
/* The eyebrow's flanking rules were built for a centred label; ranged left, only
   the leading rule earns its place — the trailing one would float mid-column. */
.address__head--start .eyebrow--centred{justify-content:flex-start}
.address__head--start .eyebrow__rule--rev{display:none}
/* Symmetric hairlines flanking the eyebrow, drawn only when it is centred. */
.eyebrow--centred{
  display:flex;align-items:center;justify-content:center;gap:.85em;
  flex-wrap:wrap;
}
/* Hidden on narrow screens, where the label wraps and the rules would strand on
   opposite ends of two different lines. */
.eyebrow--centred .eyebrow__rule{display:none}
@media (min-width:768px){
  .eyebrow--centred .eyebrow__rule{
    display:block;flex:none;width:clamp(20px,3.5vw,40px);height:1px;
    background:linear-gradient(90deg,rgba(111,214,201,0),var(--color-teal-light));
  }
}
.eyebrow--centred .eyebrow__rule--rev{transform:scaleX(-1)}

.vertical-note{
  position:relative;margin-top:var(--sp-6);padding-bottom:var(--sp-6);
  font-family:var(--font-display);font-style:italic;
  font-size:1.2rem;color:var(--color-teal-light);
}
/* Closing flourish under the note — the same gradient rule the removed
   "Amenities" title carried, now doing duty as the header's foot. Ranged left so
   it starts on the same axis as the type above it. */
.address__head--start .vertical-note::after{
  content:"";position:absolute;left:0;bottom:0;
  width:72px;height:2px;border-radius:2px;
  background:var(--color-gradient);opacity:.9;
}

/* Neighbourhood map — framed panel. The frame background matches the map's own
   dark ground (#121417), so the full portrait image is always shown end-to-end and
   any breathing room around it reads as part of the map, never a crop. */
.map{
  position:relative;margin:var(--sp-6) 0 0;overflow:hidden;isolation:isolate;
  background:#121417;border:1px solid var(--color-hairline);border-radius:16px;
  box-shadow:0 34px 80px -46px rgba(0,0,0,.92),inset 0 1px 0 rgba(245,244,240,.05);
}
/* A teal rim-light along the panel's top edge, so the map reads as a lit object
   on the charcoal ground rather than a hole cut into it. */
.map::before{
  content:"";position:absolute;z-index:2;left:12%;right:12%;top:0;height:1px;
  pointer-events:none;
  background:linear-gradient(90deg,rgba(111,214,201,0),rgba(111,214,201,.55),rgba(111,214,201,0));
}
.map__img{
  display:block;width:100%;height:auto;
  opacity:0;transform:translateY(10px);
  transition:opacity 700ms var(--ease-out),transform 700ms var(--ease-out);
}
.map.is-in .map__img{opacity:1;transform:none}
.map__cap{
  margin:0;padding:var(--sp-3) var(--sp-4);
  font-size:.72rem;line-height:1.5;color:var(--color-text-muted);text-align:center;
  border-top:1px solid var(--color-hairline);
}

/* Neighbourhood cards — glass tiles in the left rail beneath the centred header.
   Base is a single column; 768px+ pairs them with the fifth running full width so
   the set closes on a deliberate line rather than a stranded orphan. */
.amencards{margin-top:var(--block-gap)}
.cards{display:grid;gap:var(--sp-4);margin-top:0}
.card{
  display:grid;grid-template-columns:auto 1fr;align-items:start;
  /* Rows hold their content height instead of stretching to fill a tile that the
     grid has equalised — otherwise the shorter card's copy drifts down. */
  align-content:start;
  column-gap:var(--sp-4);row-gap:var(--sp-2);
  padding:var(--sp-5);
  border:1px solid rgba(245,244,240,.1);border-radius:18px;
  background:
    linear-gradient(180deg,rgba(245,244,240,.06),rgba(245,244,240,0) 44%),
    rgba(11,17,19,.55);
  box-shadow:0 24px 50px -36px rgba(0,0,0,.92),inset 0 1px 0 rgba(245,244,240,.06);
  position:relative;overflow:hidden;isolation:isolate;
  transition:transform var(--dur-mid) var(--ease-out),border-color var(--dur-mid) var(--ease-out),
             box-shadow var(--dur-mid) var(--ease-out);
}
/* Soft teal glow pooled in the top-right corner of each tile */
.card::after{
  content:"";position:absolute;z-index:-1;pointer-events:none;
  top:-38%;right:-30%;width:72%;height:80%;
  background:radial-gradient(closest-side,rgba(23,162,168,.16),rgba(23,162,168,0) 70%);
}
/* Index numeral — set in the far corner as a watermark, keeping the five in
   sequence without a heading to number them. */
.card__idx{
  position:absolute;top:var(--sp-4);right:var(--sp-5);
  font-family:var(--font-display);font-size:1.35rem;line-height:1;
  font-variant-numeric:tabular-nums;letter-spacing:.02em;
  color:rgba(111,214,201,.26);
  transition:color var(--dur-mid) var(--ease-out);
}
.card__ico{
  grid-row:1 / 3;grid-column:1;
  width:48px;height:48px;padding:12px;box-sizing:border-box;
  border-radius:14px;color:var(--color-teal-light);
  background:linear-gradient(140deg,rgba(111,214,201,.22),rgba(14,116,144,.14));
  border:1px solid rgba(111,214,201,.3);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.16),0 10px 22px -14px rgba(23,162,168,.7);
  transition:transform var(--dur-mid) var(--ease-out),box-shadow var(--dur-mid) var(--ease-out);
}
.card h3{
  grid-column:2;align-self:center;
  font-size:1.08rem;margin:0;letter-spacing:.005em;
  padding-right:2.6em; /* clears the index numeral */
}
/* Wrapper exists only so the mobile accordion has a single collapsible box to
   animate. Everywhere else it dissolves, so the copy sits on the card grid
   exactly as it did when the <p> was a direct child. */
.card__body{display:contents}
.card p{grid-column:2;font-size:.86rem;line-height:1.6;color:var(--color-text-muted);margin:0}
/* Chevron button — injected by JS, so it only exists where it can work. Hidden
   outside the mobile accordion. */
.card__toggle{display:none}
@media (hover:hover){
  .card:hover{
    transform:translateY(-4px);border-color:rgba(111,214,201,.42);
    box-shadow:0 40px 66px -34px rgba(0,0,0,.95),0 0 0 1px rgba(111,214,201,.14),
               inset 0 1px 0 rgba(245,244,240,.09);
  }
  .card:hover .card__idx{color:rgba(111,214,201,.5)}
  .card:hover .card__ico{
    transform:scale(1.06);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.22),0 14px 28px -12px rgba(23,162,168,.85);
  }
}
/* ---------------------- Mobile: cards become an accordion ----------------------
   Five full cards ran the section past three screens on a 393px viewport. Below
   768px each collapses to a single row — icon, heading, chevron — and reveals its
   copy on tap. Gated on .cards--acc, which JS adds, so without JS the copy stays
   open rather than becoming unreachable.

   The five rows share ONE vaulted panel rather than carrying five separate card
   frames: at this width the repeated borders, radii and drop shadows read as
   clutter, so the chrome is promoted to the container and the rows are parted by
   faded hairlines instead. */
@media (max-width:767px){
  .cards--acc{
    gap:0;
    border:1px solid rgba(245,244,240,.1);border-radius:16px;
    background:
      linear-gradient(180deg,rgba(245,244,240,.06),rgba(245,244,240,0) 22%),
      rgba(11,17,19,.55);
    box-shadow:0 24px 50px -36px rgba(0,0,0,.92),inset 0 1px 0 rgba(245,244,240,.06);
    position:relative;overflow:hidden;isolation:isolate;
  }
  /* One teal pool for the whole panel, replacing the five per-card glows. */
  .cards--acc::after{
    content:"";position:absolute;z-index:-1;pointer-events:none;
    top:-14%;right:-22%;width:64%;height:44%;
    background:radial-gradient(closest-side,rgba(23,162,168,.16),rgba(23,162,168,0) 70%);
  }
  .cards--acc .card{
    grid-template-columns:auto 1fr auto;
    align-items:center;column-gap:var(--sp-3);row-gap:0;
    padding:var(--sp-3) var(--sp-4);
    /* Chrome now belongs to the panel — strip it from the rows. */
    border:0;border-radius:0;background:none;box-shadow:none;
    transition:background-color var(--dur-mid) var(--ease-out);
  }
  .cards--acc .card::after{display:none}
  /* Faded hairline divider: inset from the panel edge and dissolving at both
     ends, so the rows are parted without drawing five hard rules. */
  .cards--acc .card + .card::before{
    content:"";position:absolute;z-index:1;pointer-events:none;
    top:0;left:var(--sp-4);right:var(--sp-4);height:1px;
    background:linear-gradient(90deg,
      rgba(245,244,240,0),rgba(245,244,240,.14) 14%,
      rgba(245,244,240,.14) 86%,rgba(245,244,240,0));
  }
  /* The numeral shared the top-right corner with the chevron; the chevron wins. */
  .cards--acc .card__idx{display:none}
  .cards--acc .card__ico{grid-row:1;grid-column:1;width:40px;height:40px;padding:9px;border-radius:11px}
  .cards--acc .card h3{grid-column:2;font-size:1rem;padding-right:0}
  .cards--acc .card__toggle{
    display:flex;align-items:center;justify-content:center;
    grid-column:3;grid-row:1;
    width:40px;height:40px;margin-right:calc(var(--sp-2) * -1);
    padding:0;border:0;border-radius:999px;background:none;
    color:var(--color-teal-light);cursor:pointer;-webkit-tap-highlight-color:transparent;
  }
  .cards--acc .card__toggle svg{
    width:21px;height:21px;fill:none;stroke:currentColor;stroke-width:1.6;
    stroke-linecap:round;stroke-linejoin:round;
    transition:transform var(--dur-mid) var(--ease-out);
  }
  .cards--acc .card.is-open .card__toggle svg{transform:rotate(180deg)}
  /* 0fr → 1fr gives the panel a real animated height without measuring it. */
  .cards--acc .card__body{
    display:grid;grid-template-rows:0fr;
    grid-column:1 / -1;grid-row:2;
    transition:grid-template-rows var(--dur-mid) var(--ease-out);
  }
  .cards--acc .card.is-open .card__body{grid-template-rows:1fr}
  .cards--acc .card__body > p{grid-column:1;min-height:0;overflow:hidden;padding-top:var(--sp-3)}
  /* With no per-row border left to tint, the open row is marked by a faint wash
     instead — enough to anchor the expanded copy to its heading. */
  .cards--acc .card.is-open{background-color:rgba(111,214,201,.05)}
  /* Rows sliding in one by one inside a frame that is already drawn reads as a
     glitch, so the panel arrives as a single object; .amencards still reveals. */
  .cards--acc .card.reveal{opacity:1;transform:none;transition:none}
}
@media (max-width:767px) and (prefers-reduced-motion:reduce){
  .cards--acc .card__body,.cards--acc .card__toggle svg{transition:none}
}

@media (min-width:768px){
  .cards{grid-template-columns:repeat(2,minmax(0,1fr))}
  .card--wide{grid-column:1 / -1}
  /* Run the wide card's copy beside its heading so it stays the same height as
     the pairs above instead of stretching the rail. */
  .card--wide{grid-template-columns:auto minmax(0,14rem) minmax(0,1fr);align-items:center}
  /* One row only here — the icon must not span into a second, empty row. */
  .card--wide .card__ico{grid-row:1}
  .card--wide h3{grid-column:2;padding-right:var(--sp-5)}
  .card--wide p{grid-column:3;grid-row:1;padding-right:2.6em}
}

.quote{position:relative;z-index:1;margin:var(--sp-8) 0 0;padding-left:var(--sp-5);border-left:2px solid;border-image:var(--color-gradient) 1}
.quote p{
  font-family:var(--font-display);font-style:italic;
  font-size:clamp(1.2rem,4.8vw,1.5rem);line-height:1.45;color:var(--color-text-on-dark);
  max-width:52ch;margin:0;
}

/* -------------------------- 14. RESIDENCES -------------------------- */
.res__head{margin-bottom:var(--head-gap)}
.stats{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--sp-5) var(--sp-4);margin:0 0 var(--sp-8)}
.stat dt{
  font-family:var(--font-display);font-size:clamp(2.2rem,10vw,2.8rem);line-height:1;
  letter-spacing:-.02em;
  background:var(--color-gradient);-webkit-background-clip:text;background-clip:text;color:transparent;
  font-variant-numeric:tabular-nums;
}
.stat dd{margin:var(--sp-2) 0 0;font-size:.78rem;letter-spacing:.1em;text-transform:uppercase;
  color:var(--color-text-muted-dark);line-height:1.45}
.stats--dev .stat dd{color:var(--color-text-muted)}

/* -------- Trust / credentials row (Residences) --------
   Each stat rises in on its own beat (staggered via data-delay), a gradient
   tick grows above the figure, and a light sheen sweeps across the numeral as
   it counts up — reading as four separate, verifiable proof points. */
.stats--trust{gap:var(--sp-6) var(--sp-5);margin:var(--block-gap) 0}
.stats--trust .stat{position:relative;padding-top:var(--sp-4)}
.stats--trust .stat::before{
  content:"";position:absolute;top:0;left:0;height:3px;width:0;border-radius:3px;
  background:var(--color-gradient);
  transition:width .6s var(--ease-out);
}
.stats--trust .stat.is-in::before{width:44px}

/* Bigger numerals + a sheen that sweeps left as the stat enters. */
.stats--trust .stat dt{
  font-size:clamp(3rem,13vw,4.4rem);line-height:.95;margin-bottom:2px;
  background-size:220% 100%;background-position:100% 0;
  transition:background-position 1.1s var(--ease-out);
}
.stats--trust .stat.is-in dt{background-position:0 0}
.stats--trust .stat dd{margin-top:var(--sp-3);font-weight:500}

@media (hover:hover){
  .stats--trust .stat::before{transition:width .35s var(--ease-out)}
  .stats--trust .stat:hover::before{width:72px}
}

/* Mobile only (<=767px): the four proof points free-float at desktop sizes,
   so on a 393px screen the numerals crowd the gutter, "4 BHK" runs to the
   edge and the three-word labels rag out with no structure holding them.
   Bind them into one compact 2x2 hairline plate: equal cells, quiet paper
   surface, smaller numerals that always fit on one line. Desktop untouched. */
@media (max-width:767px){
  .stats--trust{
    grid-template-columns:repeat(2,1fr);
    gap:0;
    margin:var(--sp-6) 0 var(--sp-7);
    border:1px solid var(--color-hairline-dark);
    border-radius:var(--radius);
    background:rgba(255,255,255,.45);
    overflow:hidden;
  }
  .stats--trust .stat{
    display:flex;flex-direction:column;
    min-height:126px;
    padding:var(--sp-4);
    border-top:1px solid var(--color-hairline-dark);
    border-left:1px solid var(--color-hairline-dark);
  }
  .stats--trust .stat:nth-child(-n+2){border-top:0}
  .stats--trust .stat:nth-child(odd){border-left:0}

  /* Tick moves inside the cell padding so it aligns with the numeral. */
  .stats--trust .stat::before{top:var(--sp-4);left:var(--sp-4);height:2px}
  .stats--trust .stat.is-in::before{width:26px}

  .stats--trust .stat dt{
    font-size:2.2rem;line-height:1;letter-spacing:-.03em;
    margin:var(--sp-4) 0 0;
    white-space:nowrap;
  }
  .stats--trust .stat dd{
    margin-top:var(--sp-2);
    font-size:.6rem;letter-spacing:.12em;line-height:1.5;
    text-wrap:balance;
  }
}

/* Mobile only (<=767px): elevate the proof block from a plain hairline grid to a
   quiet piece of stationery — a gradient-capped paper plate, lighter interior
   rules, numerals set on a shared baseline and labels flush to the cell floor,
   so the 2x2 reads as one composed object rather than four boxes. The header
   above it gets an editorial two-tone: the claim in ink, the resolution in a
   softer grey. Desktop untouched. */
@media (max-width:767px){
  #residences .res__head{margin-bottom:var(--sp-5)}

  /* Eyebrow gains a gradient lead-in rule and finer tracking. */
  #residences .eyebrow{
    display:inline-flex;align-items:center;gap:.85em;
    font-size:.6rem;letter-spacing:.3em;
  }
  #residences .eyebrow::before{
    content:"";flex:0 0 auto;width:20px;height:1px;
    background:var(--color-gradient);opacity:.9;
  }

  #residences .res__head .h2{
    font-size:1.85rem;line-height:1.16;letter-spacing:-.024em;
    margin:var(--sp-3) 0 0;
  }
  /* The closing clause recedes — statement, then resolution. */
  #residences .res__head .h2 .line:last-child span{color:rgba(28,31,34,.46)}

  /* Section shell: 56px of outer air top and bottom is a desktop measure. */
  #residences.section{padding-block:var(--sp-7)}

  /* ---- The plate ---- */
  #residences .stats--trust{
    position:relative;
    /* Adjacent block margins collapse, so this top value — not the header's
       24px — is the whole header-to-plate gap. 48px -> 32px. */
    margin:var(--sp-6) 0 var(--sp-6);
    border:0;
    border-radius:3px;
    background:linear-gradient(180deg,rgba(255,255,255,.92) 0%,rgba(255,255,255,.5) 100%);
    box-shadow:
      inset 0 0 0 1px rgba(28,31,34,.09),
      0 1px 0 rgba(255,255,255,.85),
      0 22px 44px -30px rgba(28,31,34,.5);
  }
  /* Gradient cap across the top edge — the only saturated line on the plate. */
  #residences .stats--trust::before{
    content:"";position:absolute;z-index:1;inset:0 0 auto;height:1px;
    background:var(--color-gradient);opacity:.75;
  }

  #residences .stats--trust .stat{
    min-height:92px;
    padding:var(--sp-3) var(--sp-4);
    border-top:1px solid rgba(28,31,34,.08);
    border-left:1px solid rgba(28,31,34,.08);
  }

  /* Tick: finer and shorter, aligned to the numeral's left edge. */
  #residences .stats--trust .stat::before{
    top:var(--sp-3);left:var(--sp-4);height:1.5px;border-radius:2px;
  }
  #residences .stats--trust .stat.is-in::before{width:20px}

  /* Numerals come down a full step so the figure sits inside its cell instead
     of filling it, and "4 BHK" stops out-shouting the single digits.
     Absans ships Regular only, so font-weight:500 alone would be a no-op here
     (and 600+ would trigger a smeared synthetic bold). The extra weight is cut
     into the glyph itself with a hairline stroke in the gradient's mid teal —
     same typeface, same gradient fill, just a heavier stem. */
  #residences .stats--trust .stat dt{
    font-size:1.9rem;line-height:1;letter-spacing:-.03em;
    margin:var(--sp-2) 0 0;
    font-weight:500;
    -webkit-text-stroke:.4px rgba(23,162,168,.92);
  }
  /* Labels sit on a common floor across all four cells. */
  #residences .stats--trust .stat dd{
    margin:0;margin-top:auto;padding-top:var(--sp-2);
    font-size:.58rem;letter-spacing:.14em;line-height:1.5;font-weight:500;
    color:rgba(28,31,34,.56);
  }
}

.moodstrip{display:grid;gap:var(--sp-4);margin:var(--sp-6) 0}
.mood{position:relative;overflow:hidden;border-radius:var(--radius)}
.mood img{width:100%;aspect-ratio:4/3;object-fit:cover;transition:transform 600ms var(--ease-out)}
.mood figcaption{
  position:absolute;left:var(--sp-4);bottom:var(--sp-3);
  font-size:.68rem;letter-spacing:.2em;text-transform:uppercase;color:#fff;
  text-shadow:0 1px 12px rgba(0,0,0,.7);
}
@media (hover:hover){.mood:hover img{transform:scale(1.05)}}

/* ------------------------ 14b. FLOOR PLANS (tabbed) ------------------------
   Split view: landscape floor-plan drawing on the left; on the right, a toggle
   sits directly above the spec table. Tabs switch both the drawing and table. */
.plans{margin-top:var(--head-gap)}
/* Standalone floor-plans section supplies its own vertical rhythm, tighter than
   the page default — the plan and its schedule are a reference panel, not a
   full-height editorial band. */
#floor-plans{padding-block:var(--section-y)}
#floor-plans .plans{margin-top:0}
.plans__head{margin-bottom:var(--head-gap)}
.plans__title{font-size:51px;line-height:1.15;margin:var(--sp-2) 0 0}
/* Phone: the section title drops to a size that clears the viewport in two lines. */
@media (max-width:767px){
  .plans__title{font-size:28.8px}
}

.plans__layout{display:grid;gap:var(--block-gap)}
@keyframes planIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

/* ---- Left: floor-plan drawing in a dark blueprint frame ---- */
.plans__figs{min-width:0}
.plans__fig[hidden]{display:none}
.plans__fig{
  position:relative;margin:0;display:flex;flex-direction:column;
  border-radius:16px;overflow:hidden;
  background:var(--color-bg-dark);border:1px solid var(--color-hairline-dark);
  box-shadow:0 34px 80px -50px rgba(0,0,0,.6);
  animation:planIn var(--dur-mid) var(--ease-out);
}
.plans__zoom{
  display:block;position:relative;width:100%;padding:0;border:0;cursor:zoom-in;background:none;
}
.plans__zoom img{display:block;width:100%;height:auto}
.plans__zoomhint{
  position:absolute;right:var(--sp-3);bottom:var(--sp-3);
  display:inline-flex;align-items:center;min-height:32px;padding:6px 14px;border-radius:999px;
  background:rgba(11,18,20,.72);color:var(--color-teal-light);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  font-size:.64rem;letter-spacing:.14em;text-transform:uppercase;
  opacity:0;transition:opacity var(--dur-mid) var(--ease-out);
}
@media (hover:hover){.plans__zoom:hover .plans__zoomhint{opacity:1}}
.plans__zoom:focus-visible .plans__zoomhint{opacity:1}
.plans__fig figcaption{
  padding:var(--sp-3) var(--sp-4);text-align:center;background:var(--color-bg-charcoal);
  font-size:.7rem;letter-spacing:.16em;text-transform:uppercase;color:var(--color-teal-light);
  border-top:1px solid var(--color-hairline);
}

/* ---- Right: toggle directly above the spec table ---- */
.plans__right{display:flex;flex-direction:column;gap:var(--sp-5);min-width:0}

/* Segmented toggle — spans the column, sits above the table */
.plans__tabs{
  display:flex;gap:6px;padding:5px;
  background:linear-gradient(180deg,rgba(28,31,34,.02),rgba(28,31,34,.065));
  border:1px solid var(--color-hairline-dark);border-radius:999px;
  box-shadow:inset 0 1px 2px rgba(28,31,34,.06);
}
.plans__tab{
  flex:1 1 0;appearance:none;border:0;cursor:pointer;background:transparent;
  min-height:42px;padding:9px 16px;border-radius:999px;
  font-family:var(--font-body);font-size:.76rem;font-weight:600;letter-spacing:.1em;
  text-transform:uppercase;color:var(--color-text-muted-dark);white-space:nowrap;text-align:center;
  transition:color var(--dur-fast) linear,background-color var(--dur-mid) var(--ease-out),
             box-shadow var(--dur-mid) var(--ease-out),transform var(--dur-fast) var(--ease-out);
}
@media (hover:hover){.plans__tab:hover{color:var(--color-text-on-light)}}
.plans__tab:active{transform:translateY(.5px)}
.plans__tab.is-active{
  color:#fff;background-image:var(--color-gradient);
  box-shadow:0 10px 24px -10px rgba(14,116,144,.78),inset 0 1px 0 rgba(255,255,255,.3);
}

/* Spec table card */
.plans__tblpanel[hidden]{display:none}
.plans__tblpanel{
  position:relative;display:flex;flex-direction:column;justify-content:center;
  /* Paper, not panel: a warm ivory body with a cool light falling in from the
     top-right corner, so the card has a direction of light like the renders do. */
  background:
    radial-gradient(120% 82% at 92% -6%,rgba(23,162,168,.08),transparent 56%),
    linear-gradient(168deg,#FFFFFF 0%,#FDFBF8 54%,#F7F4EE 100%);
  border:1px solid rgba(28,31,34,.085);border-radius:22px;
  padding:clamp(16px,1.6vw,22px);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.95),
    0 1px 2px rgba(28,31,34,.05),
    0 28px 56px -44px rgba(14,116,144,.55),
    0 64px 110px -74px rgba(28,31,34,.55);
  animation:planIn var(--dur-mid) var(--ease-out);
}
/* Hairline accent along the top edge — tapered at both ends so it reads as a
   filament of light on the card rather than a printed bar. */
.plans__tblpanel::before{
  content:"";position:absolute;top:0;left:clamp(16px,1.6vw,22px);right:clamp(16px,1.6vw,22px);
  height:1.5px;border-radius:999px;
  background-image:linear-gradient(90deg,
    transparent 0%,rgba(111,214,201,.75) 16%,var(--color-teal-mid) 46%,
    var(--color-teal-deep) 74%,transparent 100%);
}
.plan-tbl-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
.plan-tbl{border-collapse:separate;border-spacing:0;width:100%;font-variant-numeric:tabular-nums lining-nums}
.plan-tbl thead th{
  padding:0 var(--sp-3) var(--sp-2);text-align:right;vertical-align:bottom;
  font-family:var(--font-body);font-weight:700;font-size:.6rem;letter-spacing:.2em;text-transform:uppercase;
  color:var(--color-teal-deep);border-bottom:1px solid rgba(28,31,34,.11);
}
.plan-tbl thead th:first-child{text-align:left;vertical-align:bottom;padding-left:var(--sp-2)}
/* Scoped to the first column: the unit monograms are spans in this row too, and a
   bare `thead th span` would outrank .plan-tbl__unit and strip them. */
.plan-tbl thead th:first-child span{
  display:block;margin-top:5px;
  color:rgba(28,31,34,.44);font-weight:500;font-size:.58rem;letter-spacing:.14em;
}
/* A hairline "UNIT" caption over each monogram, set in CSS so the column header's
   accessible name stays the bare letter. */
.plan-tbl thead th:not(:first-child)::before{
  content:"Unit";display:block;margin-bottom:4px;
  font-size:.48rem;font-weight:600;letter-spacing:.26em;color:rgba(28,31,34,.38);
}
/* Unit monograms — an engraved ring, not a floating button: hairline rim, a wash
   of tint inside it, and the letter in the display face. */
.plan-tbl__unit{
  display:inline-grid;place-items:center;width:34px;height:34px;border-radius:50%;
  background:
    linear-gradient(152deg,rgba(255,255,255,.95),rgba(255,255,255,0) 58%),
    linear-gradient(152deg,rgba(23,162,168,.16),rgba(14,116,144,.07));
  border:1px solid rgba(23,162,168,.38);
  color:var(--color-teal-deep);
  font-family:var(--font-display);font-weight:400;font-size:1.05rem;line-height:1;
  letter-spacing:0;text-transform:none;
  box-shadow:
    inset 0 1px 1px rgba(255,255,255,.9),
    inset 0 -6px 12px -8px rgba(14,116,144,.4),
    0 8px 18px -14px rgba(14,116,144,.9);
}
.plan-tbl th[scope="row"]{
  padding:7px var(--sp-4) 7px var(--sp-2);text-align:left;
  font-family:var(--font-body);font-weight:500;font-size:.9rem;letter-spacing:.005em;
  color:rgba(28,31,34,.74);
  border-bottom:1px solid rgba(28,31,34,.07);
  transition:color var(--dur-fast) linear;
}
/* Figures are set in the display face with lining tabular figures — the columns
   stay on a strict vertical rhythm and read as a schedule, not a spreadsheet. */
.plan-tbl td{
  padding:7px var(--sp-3);text-align:right;
  font-family:var(--font-display);font-weight:400;font-size:1.06rem;letter-spacing:.005em;
  color:var(--color-text-on-light);
  border-bottom:1px solid rgba(28,31,34,.07);
}
.plan-tbl tbody tr:last-child th,.plan-tbl tbody tr:last-child td{border-bottom:0}
@media (hover:hover){
  .plan-tbl tbody tr:not(.is-key):hover th[scope="row"]{color:var(--color-text-on-light)}
  .plan-tbl tbody tr:not(.is-key):hover th[scope="row"],
  .plan-tbl tbody tr:not(.is-key):hover td{background:rgba(23,162,168,.05)}
}
/* Headline rows (Carpet + Built-up). A FLAT tint, not a gradient: each cell paints
   its own background, so a horizontal gradient restarts at every column boundary
   and seams the band. The emphasis comes from the teal edge and the figure size. */
.plan-tbl tr.is-key th,.plan-tbl tr.is-key td{
  background:rgba(23,162,168,.068);
  padding-block:10px;border-bottom-color:transparent;
}
.plan-tbl tr.is-key th:first-child{
  border-radius:10px 0 0 10px;
  box-shadow:inset 3px 0 0 var(--color-teal-mid);
  padding-left:var(--sp-5);
}
.plan-tbl tr.is-key td:last-child{border-radius:0 10px 10px 0}
.plan-tbl tr.is-key th{color:var(--color-text-on-light);font-weight:700}
.plan-tbl tr.is-key td{font-size:1.3rem;letter-spacing:-.012em;color:var(--color-teal-deep)}
/* Figures step up only once the spec column has room — below this the same sizes
   would force the schedule into a horizontal scroll. */
@media (min-width:1200px){
  .plan-tbl th[scope="row"]{white-space:nowrap}
  .plan-tbl td{font-size:1.16rem}
  .plan-tbl tr.is-key td{font-size:1.55rem}
}
.plan-tbl i{font-style:normal;color:var(--color-teal-mid);font-weight:700}
/* The typical floor carries four units in the same column width — step the whole
   schedule down a size so it sits inside the card instead of scrolling. */
.plans__tblpanel[data-plan="typical"] .plan-tbl th[scope="row"]{
  font-size:.82rem;padding-right:var(--sp-2);white-space:normal;
}
.plans__tblpanel[data-plan="typical"] .plan-tbl td{font-size:1.02rem;padding-inline:var(--sp-2)}
.plans__tblpanel[data-plan="typical"] .plan-tbl tr.is-key td{font-size:1.28rem}
.plans__tblpanel[data-plan="typical"] .plan-tbl tr.is-key th:first-child{padding-left:var(--sp-4)}
.plans__tblpanel[data-plan="typical"] .plan-tbl__unit{width:32px;height:32px;font-size:.98rem}
.plans__tblpanel[data-plan="typical"] .plan-tbl thead th:not(:first-child){padding-inline:var(--sp-2)}
.plans__tblpanel[data-plan="typical"] .plan-tbl thead th::before{letter-spacing:.18em}
/* Narrowest desktop column — one more step down, or the four units scroll. */
@media (min-width:1024px) and (max-width:1199px){
  .plans__tblpanel[data-plan="typical"] .plan-tbl th[scope="row"]{font-size:.76rem;padding-right:4px}
  .plans__tblpanel[data-plan="typical"] .plan-tbl td{font-size:.9rem;padding-inline:2px}
  .plans__tblpanel[data-plan="typical"] .plan-tbl tr.is-key th:first-child{padding-left:var(--sp-3)}
  .plans__tblpanel[data-plan="typical"] .plan-tbl tr.is-key td{font-size:1.18rem}
  .plans__tblpanel[data-plan="typical"] .plan-tbl__unit{width:34px;height:34px;font-size:.98rem}
  .plans__tblpanel[data-plan="typical"] .plan-tbl thead th:not(:first-child){padding-inline:4px}
  .plans__tblpanel[data-plan="typical"] .plan-tbl thead th:not(:first-child)::before{display:none}
}

/* Four units on a phone: the tightest the schedule ever gets. */
@media (max-width:767px){
  .plans__tblpanel[data-plan="typical"] .plan-tbl td{font-size:.88rem;padding-inline:4px}
  .plans__tblpanel[data-plan="typical"] .plan-tbl tr.is-key td{font-size:1.14rem}
  .plans__tblpanel[data-plan="typical"] .plan-tbl th[scope="row"]{font-size:.78rem}
  .plans__tblpanel[data-plan="typical"] .plan-tbl__unit{width:32px;height:32px;font-size:.94rem}
  .plans__tblpanel[data-plan="typical"] .plan-tbl thead th:not(:first-child){padding-inline:4px}
  .plans__tblpanel[data-plan="typical"] .plan-tbl thead th:not(:first-child)::before{display:none}
}
/* Footnote sits under its own hairline, in the register of a printed key. */
.plan-tbl__foot{
  margin:var(--sp-5) 0 0;padding-top:var(--sp-4);
  border-top:1px solid rgba(28,31,34,.08);
  font-size:.7rem;line-height:1.5;letter-spacing:.01em;color:rgba(28,31,34,.55);
}
.plan-tbl__foot i{font-style:normal;color:var(--color-teal-deep);font-weight:700}
.plans__note{margin-top:var(--block-gap)}

/* -------------------------- 15. AMENITIES -------------------------- */
.amen__head{margin-bottom:var(--head-gap);position:relative;z-index:1}
.amen__head .lead{margin-inline:auto}
/* The head carries its own bottom margin, so the first band's full band-to-band
   rhythm on top would double the gap. Collapse it — the intro copy should read
   as the lead-in to the first panel, not as a separate stanza. */
.amen__head + .band,
.amen__head + .amen__rail > .band:first-of-type{margin-top:0}
/* The rail only exists to be a scroll container below 768px. Everywhere else it
   generates no box at all, so the bands stay direct children of the section as
   far as layout is concerned. */
.amen__rail{display:contents}

/* ---- Amenity bands -------------------------------------------------------
   The brochure's signature spread: a teal→blue gradient panel that carries the
   copy, with the photograph riding ~70% inside the panel and ~30% breaking out
   of it. A 12-column grid does the overlap — panel and photograph share grid
   rows, so no magic offsets and the text row sizes itself.

   Mobile keeps the same idea at one column: the photograph bleeds a little past
   the panel edge instead of a third of its width. */
.band{position:relative;margin-block:var(--block-gap);isolation:isolate}
.band__grid{
  display:grid;grid-template-columns:1fr;
  grid-template-rows:clamp(18px,3vw,36px) auto auto clamp(22px,3.2vw,40px);
  align-items:start;
}

/* The gradient panel. Sampled straight off the brochure spread: mint-teal at the
   leading edge falling to a deep marine blue. --alt mirrors the sweep and --vert
   tips it vertical so four consecutive panels never light the same way. */
.band__panel{
  /* align-self overrides the grid's start alignment — the panel is an empty
     element, so it must stretch across every row it spans to have height. */
  grid-column:1;grid-row:1/5;align-self:stretch;position:relative;z-index:0;
  border-radius:2px;overflow:hidden;will-change:transform;
  background:var(--grad-band);
  box-shadow:0 46px 90px -56px rgba(4,58,84,.85);
}
.band--alt .band__panel{background:var(--grad-band-rev)}
.band__panel--vert{background:var(--grad-band-vert)}

/* A soft top-left light so the flat gradient reads as a lit surface, plus a
   barely-there darkening at the foot to seat the panel on the page. */
.band__sheen{
  position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(120% 85% at 8% -10%,rgba(255,255,255,.26),transparent 58%),
    linear-gradient(180deg,transparent 62%,rgba(4,52,78,.22) 100%);
}
/* Brand motif watermark inside the panel — large, faint, slowly turning. */
.band__ring{
  position:absolute;top:-6%;right:-8%;width:min(46%,320px);aspect-ratio:1;
  color:rgba(255,255,255,.34);opacity:.5;pointer-events:none;
}
.band__ring--sm{width:min(34%,240px);top:auto;bottom:-6%;right:-6%;opacity:.42}

/* Photograph frame. The image inside is deliberately over-tall (130%) and
   absolutely placed, so the parallax has real travel without ever exposing an
   edge; JS measures that overflow and clamps the shift to it. */
.band__media{
  grid-column:1;grid-row:2;position:relative;z-index:2;margin:0;
  border-radius:2px;overflow:clip;will-change:transform;
  box-shadow:0 34px 68px -34px rgba(4,32,46,.62),0 2px 0 rgba(255,255,255,.10) inset;
}
.band__media picture{display:block;position:absolute;inset:0}
.band__media img{
  position:absolute;left:0;top:-15%;width:100%;height:130%;
  object-fit:cover;will-change:transform;
}
.band__media--wide{aspect-ratio:2/1}
.band__media--tall{aspect-ratio:4/3}
.band__media--cine{aspect-ratio:16/9;border-radius:0}

/* Copy sits inside the panel, always over the gradient. */
.band__copy{
  grid-column:1;grid-row:3;position:relative;z-index:2;
  padding:clamp(18px,3vw,28px) clamp(20px,4vw,40px) 0;
  color:#fff;
}
.band__idx{
  display:flex;align-items:center;gap:.7em;margin:0 0 var(--sp-3);
  font-size:.66rem;letter-spacing:.24em;text-transform:uppercase;
  color:rgba(255,255,255,.86);
}
.band__num{font-family:var(--font-display);font-size:1.05rem;letter-spacing:.08em;color:#fff}
.band__rule{width:clamp(24px,4vw,46px);height:1px;background:rgba(255,255,255,.55)}
.band__title{
  font-family:var(--font-display);font-weight:400;
  font-size:clamp(1.6rem,5vw,2.2rem);line-height:1.1;margin:0;
  letter-spacing:.012em;color:#fff;
  text-shadow:0 2px 18px rgba(4,52,78,.28);
}
.band__text{
  margin:var(--sp-4) 0 0;max-width:52ch;
  font-size:.95rem;line-height:1.66;color:rgba(255,255,255,.92);
}
/* Feature chips — glass pills, the one place each band names its rooms. */
.band__tags{
  display:flex;flex-wrap:wrap;gap:var(--sp-2) var(--sp-2);
  margin:var(--sp-4) 0 0;
}
.band__tags li{
  display:inline-flex;align-items:center;gap:.55em;
  padding:6px 13px;border-radius:999px;
  font-size:.68rem;letter-spacing:.1em;text-transform:uppercase;
  color:#fff;background:rgba(255,255,255,.14);
  border:1px solid rgba(255,255,255,.34);
  -webkit-backdrop-filter:blur(4px);backdrop-filter:blur(4px);
}
.band__tagico{width:15px;height:15px;flex:none;color:rgba(255,255,255,.92)}

/* Band 03 — full-bleed gradient, no container edge. It runs the full width of the
   page, so it takes a fixed 100px of air above it rather than the shared block
   rhythm — enough of a break that the edge-to-edge band reads as its own panel. */
.band--bleed{margin-block:100px var(--block-gap)}
.band__panel--bleed{
  width:100vw;margin-inline:calc(50% - 50vw);border-radius:0;
  padding-block:clamp(48px,6vw,104px);
}
.band__sun{
  position:absolute;top:50%;right:-10%;translate:0 -50%;
  width:min(58vw,620px);aspect-ratio:1;color:rgba(255,255,255,.28);opacity:.4;pointer-events:none;
}
.band__split{position:relative;z-index:2;display:grid;gap:clamp(26px,4vw,44px)}
/* The split lays its own children out — drop the explicit rows/columns the
   grid-overlay bands set on .band__media and .band__copy. */
.band__split > *{grid-column:auto;grid-row:auto}
.band__copy--split{padding:0}

/* The brochure's cut-out figure. It uses a real transparent PNG/WebP cut-out
   (dancer-leap-cutout.*) rather than the white-ground JPEG under multiply — the
   blend tinted the diver blue against the gradient. With true alpha he keeps his
   own colour, and the tight crop means the frame is all figure and no padding.
   The matte is re-keyed from dancer-leap-serenity.jpg and decontaminated: the old
   cut-out kept white backdrop in its semi-transparent edge pixels, which lit up
   as a broken outline against the teal panel. Master is 2x so he stays clean at
   this size on retina — the figure is only ~664px in the source, so the upscale
   is done once with Lanczos rather than by the browser on every paint. */
.band__figure{
  grid-column:1;grid-row:3;justify-self:end;align-self:start;margin:-9% 0 0 0;
  width:min(38%,205px);position:relative;z-index:1;pointer-events:none;
  transform:translateX(calc(18% - 30px));   /* hangs past the panel's right edge */
}
.band__figure img{width:100%;height:auto;will-change:transform}

/* Mobile keeps the break-out gesture by running the photograph past the panel
   to the screen edge — the side alternates with the band. */
.band--right .band__media{margin-left:calc(var(--gutter) * -1)}
.band--left  .band__media{margin-right:calc(var(--gutter) * -1)}
.band--bleed .band__media--cine{margin-left:calc(var(--gutter) * -1)}

/* Band 04 — a second, smaller photograph clipped to the panel's lower edge. */
.band__inset{
  /* Mobile: the paired photograph sits in the frame's bottom corner and breaks
     out of it on the outward side — capped at the gutter, since that is all the
     room the page has before the section clips. Kept clear of the copy below. */
  --inset-out:min(30%,var(--gutter));
  grid-column:1;grid-row:2;justify-self:end;align-self:end;
  margin:0 calc(var(--inset-out) * -1) 10px 0;
  width:min(40%,190px);aspect-ratio:4/3;position:relative;z-index:3;
  border-radius:2px;overflow:hidden;
  /* No white keyline — the photograph meets the gradient directly. A deeper,
     tighter shadow does the separating work the border used to do. */
  box-shadow:0 26px 48px -20px rgba(4,32,46,.78),0 2px 10px -4px rgba(4,32,46,.5);
  will-change:transform;
}
.band__inset picture{display:block;height:100%}
.band__inset img{width:100%;height:100%;object-fit:cover}
.band__inset--left{justify-self:start;margin:0 0 10px calc(var(--inset-out) * -1)}
/* Band 04's plate is a wide render. The frame is a little tighter than the
   source's own 2:1, so object-fit:cover trims the outer edges left and right and
   the play area reads closer, without the upright crop squaring it off. */
.band__inset--land{aspect-ratio:16/9}

.ico{width:28px;height:28px;flex:none}

/* Lightbox */
.lightbox{
  position:fixed;inset:0;z-index:var(--z-modal);
  display:flex;align-items:center;justify-content:center;padding:var(--sp-4);
  background:rgba(11,18,20,.94);
  -webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);
  overflow:auto;
}
.lightbox[hidden]{display:none}
.lightbox img{max-width:100%;height:auto;background:#fff;border-radius:var(--radius)}
.lightbox__close{
  position:fixed;top:calc(12px + env(safe-area-inset-top));right:12px;
  width:48px;height:48px;font-size:2rem;line-height:1;color:var(--color-text-on-dark);
  border-radius:50%;background:rgba(28,31,34,.9);
}

/* --------------------------- 17. DEVELOPER ---------------------------
   Compact, editorial credibility block: on desktop the brand + heading pair
   beside the narrative, closed by a premium credentials band. */
.developer{padding-block:var(--section-y)}

.dev__head{position:relative;z-index:1;text-align:center;margin-bottom:var(--head-gap)}
.devmark{margin:0 0 var(--sp-4)}
.devmark__name{
  display:block;font-family:var(--font-display);font-size:1.55rem;letter-spacing:.2em;line-height:1;
  background:var(--color-gradient);-webkit-background-clip:text;background-clip:text;color:transparent;
}
.devmark__tag{
  display:block;margin-top:var(--sp-2);font-size:.64rem;letter-spacing:.24em;
  text-transform:uppercase;color:var(--color-gold-accent);
}
.developer .h2{font-size:clamp(1.9rem,5.2vw,2.4rem);margin:0}

/* Narrative — tighter rhythm, a touch smaller for density */
.developer .prose p{margin:0 0 var(--sp-4);font-size:.98rem;line-height:1.72}
.developer .prose p:last-child{margin-bottom:0}

/* Read more / Read less (phones only — see the ≤767px block below). Off the
   desktop layout entirely: the panel is display:contents, so its paragraphs
   stay direct flow children of .prose exactly as they were, and the toggle
   is not rendered at all. */
.prose__more,.prose__more-in{display:contents}
.prose__toggle{display:none}
@media (max-width:767px){
  /* 0fr → 1fr animates a real height without measuring it (same trick as the
     neighbourhood accordion); the inner block is the single grid row. */
  .developer .prose--fold .prose__more{
    display:grid;grid-template-rows:0fr;
    transition:grid-template-rows var(--dur-mid) var(--ease-out);
  }
  .developer .prose--fold.is-open .prose__more{grid-template-rows:1fr}
  .developer .prose--fold .prose__more-in{display:block;min-height:0;overflow:hidden}
  /* Clipped while closed, so this bottom margin only ever spaces the open
     panel off the toggle — keeping the gap identical in both states. */
  .developer .prose--fold .prose__more-in > p:last-child{margin-bottom:var(--sp-4)}

  .developer .prose--fold .prose__toggle{
    display:inline-flex;align-items:center;gap:var(--sp-3);
    margin:0;padding:0;border:0;background:none;
    font-family:inherit;font-size:.72rem;font-weight:600;letter-spacing:.2em;
    text-transform:uppercase;color:var(--color-teal-light);
    cursor:pointer;-webkit-tap-highlight-color:transparent;
  }
  /* The chevron carries the affordance, so it gets a tinted disc of its own. */
  .developer .prose--fold .prose__toggle svg{
    width:26px;height:26px;padding:5px;flex:none;
    border-radius:999px;border:1px solid rgba(111,214,201,.34);
    background-color:rgba(111,214,201,.08);
    fill:none;stroke:currentColor;stroke-width:2.2;
    stroke-linecap:round;stroke-linejoin:round;
    transition:transform var(--dur-mid) var(--ease-out);
  }
  .developer .prose--fold.is-open .prose__toggle svg{transform:rotate(180deg)}
}
@media (max-width:767px) and (prefers-reduced-motion:reduce){
  .developer .prose--fold .prose__more,
  .developer .prose--fold .prose__toggle svg{transition:none}
}

/* Premium credentials band — bordered panel, brand-gradient top hairline,
   soft inner light and hairline dividers between the figures. */
.stats--dev{
  grid-template-columns:repeat(2,1fr);gap:0;
  margin:var(--sp-7) 0 0;text-align:center;
  position:relative;overflow:hidden;border-radius:16px;
  border:1px solid var(--color-hairline);
  background:
    linear-gradient(180deg,rgba(245,244,240,.05),rgba(245,244,240,0) 58%),
    rgba(11,18,20,.36);
  box-shadow:0 34px 66px -48px rgba(0,0,0,.92),inset 0 1px 0 rgba(245,244,240,.05);
}
.stats--dev::before{content:"";position:absolute;inset:0 0 auto;height:1px;background:var(--color-gradient);opacity:.55}
.stats--dev .stat{
  margin:0;padding:clamp(22px,5vw,32px) var(--sp-4);
  border-top:1px solid var(--color-hairline);border-left:1px solid var(--color-hairline);
  transition:background-color var(--dur-mid) var(--ease-out);
}
.stats--dev .stat:nth-child(-n+2){border-top:0}
.stats--dev .stat:nth-child(odd){border-left:0}
.stats--dev .stat dt{font-size:clamp(1.9rem,8vw,2.5rem)}
.stats--dev .stat dd{margin-top:var(--sp-3);font-size:.66rem;letter-spacing:.16em;color:var(--color-text-muted)}
@media (hover:hover){.stats--dev .stat:hover{background-color:rgba(245,244,240,.03)}}

/* Awards ticker — a compact credential band: one calm, continuous river of slim
   medal chips with a centred lead-in label and a soft edge fade. No per-card hover
   motion, so the scroll stays quiet and premium. */
.awards{margin-top:var(--head-gap);padding-block:var(--sp-4) var(--sp-5)}
.awards__head{text-align:center;margin-bottom:var(--sp-5)}
.awards__label{
  display:inline-flex;align-items:center;gap:clamp(12px,3vw,20px);
  margin:0;font-family:var(--font-body);font-weight:500;
  font-size:.7rem;letter-spacing:.28em;text-transform:uppercase;
  color:var(--color-teal-light);white-space:nowrap;
}
.awards__rule{
  width:clamp(28px,8vw,72px);height:1px;
  background:linear-gradient(90deg,rgba(111,214,201,0),rgba(111,214,201,.85));
}
.awards__rule--r{background:linear-gradient(90deg,rgba(111,214,201,.85),rgba(111,214,201,0))}

.marquee{
  overflow:hidden;padding-block:var(--sp-1);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 7%,#000 93%,transparent);
}
.marquee__track{display:flex;width:max-content;animation:marquee 62s linear infinite}
.marquee__list{display:flex;align-items:stretch;gap:var(--sp-3);padding-right:var(--sp-3)}

/* Each award is a slim horizontal chip: medal · title stacked over category */
.marquee__list li{
  --award-icon:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%236FD6C9'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Ccircle%20cx='12'%20cy='8'%20r='6'/%3E%3Cpath%20d='M8.5%2013.2%207%2022l5-2.8L17%2022l-1.5-8.8'/%3E%3C/svg%3E");
  flex:none;width:340px;
  display:grid;grid-template-columns:auto minmax(0,1fr);
  column-gap:var(--sp-4);align-items:center;
  padding:var(--sp-3) var(--sp-4);
  border:1px solid rgba(245,244,240,.1);border-radius:14px;
  background:linear-gradient(140deg,rgba(245,244,240,.058),rgba(245,244,240,.014) 72%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.05),0 10px 26px -20px rgba(0,0,0,.7);
}
/* Badge, vertically centred, spanning both text rows. The glyph itself comes
   from --award-icon so each card can carry an icon that matches its citation. */
.marquee__list li::before{
  content:"";grid-column:1;grid-row:1 / span 2;align-self:center;
  width:38px;height:38px;border-radius:50%;
  border:1px solid rgba(111,214,201,.3);
  background:
    var(--award-icon) center/19px no-repeat,
    radial-gradient(circle at 32% 26%,rgba(23,162,168,.3),rgba(23,162,168,.05));
  box-shadow:0 5px 14px -8px rgba(23,162,168,.5),inset 0 0 0 1px rgba(11,18,20,.4);
}
/* Per-award glyphs — each citation gets a mark that reads its subject */
.marquee__list li[data-award="trophy"]{--award-icon:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%236FD6C9'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M6%209H4.5a2.5%202.5%200%200%201%200-5H6'/%3E%3Cpath%20d='M18%209h1.5a2.5%202.5%200%200%200%200-5H18'/%3E%3Cpath%20d='M4%2021h16'/%3E%3Cpath%20d='M10%2014.7V17c0%20.8-.6%201.2-1.2%201.5C7.6%2019%207%2020%207%2021'/%3E%3Cpath%20d='M14%2014.7V17c0%20.8.6%201.2%201.2%201.5C16.4%2019%2017%2020%2017%2021'/%3E%3Cpath%20d='M18%203H6v6a6%206%200%200%200%2012%200V3Z'/%3E%3C/svg%3E")}
.marquee__list li[data-award="home"]{--award-icon:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%236FD6C9'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M3%2010.6%2012%203.2l9%207.4'/%3E%3Cpath%20d='M5.6%209.5V20.8h12.8V9.5'/%3E%3Cpath%20d='M9.8%2020.8v-6.2h4.4v6.2'/%3E%3C/svg%3E")}
.marquee__list li[data-award="units"]{--award-icon:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%236FD6C9'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M2.5%2020.8h19'/%3E%3Cpath%20d='M5%2020.8V7.6l6.5-3.6v16.8'/%3E%3Cpath%20d='M11.5%2020.8V11l7%203.1v6.7'/%3E%3Cpath%20d='M7.6%209.4v1.6M7.6%2014v1.6M14.6%2015v1.6'/%3E%3C/svg%3E")}
.marquee__list li[data-award="key"]{--award-icon:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%236FD6C9'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Ccircle%20cx='7.5'%20cy='15.5'%20r='3.4'/%3E%3Cpath%20d='m10%2013%208.6-8.6'/%3E%3Cpath%20d='m15.6%207.4%202.4%202.4'/%3E%3Cpath%20d='m18.6%204.4%202.4%202.4'/%3E%3C/svg%3E")}
.marquee__list li[data-award="briefcase"]{--award-icon:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%236FD6C9'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Crect%20x='2.6'%20y='7.4'%20width='18.8'%20height='12.4'%20rx='2.2'/%3E%3Cpath%20d='M8.6%207.4V5.2a2%202%200%200%201%202-2h2.8a2%202%200%200%201%202%202v2.2'/%3E%3Cpath%20d='M2.6%2012.4h18.8'/%3E%3C/svg%3E")}
.marquee__list li[data-award="gem"]{--award-icon:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%236FD6C9'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M6%203.4h12l3%205.8-9%2011.4L3%209.2Z'/%3E%3Cpath%20d='M3%209.2h18'/%3E%3Cpath%20d='M9.4%203.4%208%209.2l4%2011.4%204-11.4-1.4-5.8'/%3E%3C/svg%3E")}
.marquee__list li[data-award="crane"]{--award-icon:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%236FD6C9'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M4.4%2014.6a7.6%207.6%200%200%201%2015.2%200'/%3E%3Cpath%20d='M2.6%2014.6h18.8v3.2H2.6z'/%3E%3Cpath%20d='M9.4%208.4V4.6h5.2v3.8'/%3E%3C/svg%3E")}
.marquee__list li[data-award="metro"]{--award-icon:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%236FD6C9'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Crect%20x='5.2'%20y='3.2'%20width='13.6'%20height='13'%20rx='3.2'/%3E%3Cpath%20d='M5.2%2010.6h13.6'/%3E%3Cpath%20d='M8.6%2013.4h.01M15.4%2013.4h.01'/%3E%3Cpath%20d='m8.6%2019.4-2.2%202.4M15.4%2019.4l2.2%202.4'/%3E%3Cpath%20d='M8.6%2016.2h6.8'/%3E%3C/svg%3E")}
.marquee__list li[data-award="leaf"]{--award-icon:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%236FD6C9'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M11.2%2020.4A7.2%207.2%200%200%201%204%2013.2C4%206.8%2011.2%203.6%2020.4%203.6c0%209.2-3.2%2016.8-9.2%2016.8Z'/%3E%3Cpath%20d='M4%2020.4c2.2-6.4%205.6-9.6%209.6-11.6'/%3E%3C/svg%3E")}
.marquee__list li[data-award="star"]{--award-icon:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%236FD6C9'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='m12%203.2%202.8%205.7%206.2.9-4.5%204.4%201.1%206.2-5.6-3-5.6%203%201.1-6.2L3%209.8l6.2-.9z'/%3E%3C/svg%3E")}
.marquee__list li[data-award="bricks"]{--award-icon:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%236FD6C9'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Cpath%20d='M3%206h18v5.4H3z'/%3E%3Cpath%20d='M3%2012.6h18V18H3z'/%3E%3Cpath%20d='M9%206v5.4M15%206v5.4M6%2012.6V18M12%2012.6V18M18%2012.6V18'/%3E%3C/svg%3E")}
.marquee__list li[data-award="medal"]{--award-icon:url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%236FD6C9'%20stroke-width='1.6'%20stroke-linecap='round'%20stroke-linejoin='round'%3E%3Ccircle%20cx='12'%20cy='8'%20r='6'/%3E%3Cpath%20d='M8.5%2013.2%207%2022l5-2.8L17%2022l-1.5-8.8'/%3E%3C/svg%3E")}

.marquee__list b{
  grid-column:2;grid-row:1;align-self:end;
  font-family:var(--font-display);font-weight:400;font-size:.92rem;line-height:1.22;
  color:var(--color-text-on-dark);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.marquee__list span{
  grid-column:2;grid-row:2;align-self:start;margin-top:4px;
  font-size:.73rem;line-height:1.4;color:var(--color-text-muted);
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
@keyframes marquee{to{transform:translateX(-50%)}}
/* Pause the river on hover/focus — a calm affordance, not a visual effect */
.marquee:hover .marquee__track,.marquee:focus-within .marquee__track{animation-play-state:paused}

/* Developer — editorial two-column layout on desktop: identity left, narrative
   right, credentials band spanning beneath. Halves the section's vertical height. */
@media (min-width:1024px){
  .dev__inner{
    display:grid;
    grid-template-columns:minmax(0,0.82fr) minmax(0,1.18fr);
    column-gap:clamp(48px,5vw,92px);row-gap:var(--sp-7);
    align-items:start;
  }
  .dev__head{grid-column:1;grid-row:1;text-align:left;margin:0}
  .developer .prose{grid-column:2;grid-row:1;max-width:none;margin:0}
  .stats--dev{grid-column:1/-1;grid-row:2;margin:0}
  .developer .h2{font-size:clamp(2rem,2.7vw,2.6rem)}
  .developer .prose p{font-size:1rem}
}

/* ---------------------------- 18. FINAL CTA ---------------------------- */
.cta{position:relative;padding-block:var(--section-y);overflow:clip;isolation:isolate}
/* Lighter grade so the dusk tower reads through — the darkness is now weighted to
   the left (behind the headline) and to the very bottom (grounds the section into
   the footer), leaving the centre/right open so the building shows behind the glass
   card. A low teal wash from below ties it to the brand. */
.cta__scrim{
  background:
    linear-gradient(90deg,rgba(11,18,20,.66) 0%,rgba(11,18,20,.34) 44%,rgba(11,18,20,.16) 100%),
    linear-gradient(180deg,rgba(11,18,20,.40) 0%,rgba(11,18,20,.14) 30%,rgba(11,18,20,.34) 66%,rgba(11,18,20,.78) 100%),
    radial-gradient(150% 72% at 50% 122%,rgba(14,116,144,.24),transparent 62%);
}
.cta__body{position:relative;display:grid;gap:var(--head-gap)}
.cta__rera{margin-top:var(--sp-4);font-size:.78rem;letter-spacing:.1em;text-transform:uppercase;color:var(--color-gold-accent)}

/* --- Site + contact cards ------------------------------------------------
   The address and RERA lines used to float loose under the headline with
   nothing holding them. These two carry the same material as the enquiry
   form — frosted pane, hairline edge, top-edge highlight, teal pooled at the
   base — at a smaller radius, so they read as the form's siblings rather than
   as a second, competing card style. Stacked at every width. */
.infocards{
  list-style:none;margin:var(--sp-6) 0 0;padding:0;
  display:grid;gap:var(--sp-3);max-width:460px;
}
.infocard{
  position:relative;overflow:hidden;isolation:isolate;
  border:1px solid rgba(255,255,255,.14);border-radius:16px;
  background:
    linear-gradient(180deg,rgba(255,255,255,.11) 0%,rgba(255,255,255,.03) 30%,rgba(255,255,255,0) 60%),
    linear-gradient(180deg,rgba(24,30,32,.46),rgba(11,17,19,.6));
  box-shadow:
    0 26px 60px -34px rgba(0,0,0,.9),
    inset 0 1px 0 rgba(255,255,255,.3),
    inset 0 0 0 1px rgba(255,255,255,.04),
    inset 0 -30px 56px -40px rgba(14,116,144,.34);
  -webkit-backdrop-filter:blur(22px) saturate(155%);backdrop-filter:blur(22px) saturate(155%);
}
/* Brand hairline across the top edge — the form's device, inset by the radius
   for the same reason: backdrop-filter promotes the card to its own layer, so a
   full-bleed line would overhang the rounded corners. */
.infocard::before{
  content:"";position:absolute;top:0;left:16px;right:16px;height:1px;z-index:1;
  background:var(--color-gradient);opacity:.6;
}
/* Specular sheen, scaled down from the form's. */
.infocard::after{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:
    radial-gradient(120% 70% at 16% -16%,rgba(255,255,255,.2),rgba(255,255,255,0) 58%),
    linear-gradient(118deg,rgba(255,255,255,0) 36%,rgba(255,255,255,.1) 48%,rgba(255,255,255,0) 60%);
}
/* One rule drives both cards: the plain one lays out its own children, the
   contact one lays out the anchor's, so the tap target is the whole card. */
.infocard,.infocard__link{
  display:flex;align-items:center;gap:var(--sp-4);
  padding:16px 18px;text-decoration:none;color:inherit;
}
/* The link fills its card, so the padding moves to the anchor and the tap
   target is the whole card rather than just the text. */
.infocard--link{padding:0}
.infocard__link{flex:1 1 auto;min-width:0}

.infocard__ico{
  flex:0 0 auto;display:grid;place-items:center;
  width:40px;height:40px;border-radius:11px;
  color:var(--color-teal-light);
  border:1px solid rgba(111,214,201,.24);
  background:linear-gradient(160deg,rgba(111,214,201,.16),rgba(111,214,201,.04));
  box-shadow:inset 0 1px 0 rgba(255,255,255,.18);
}
.infocard__ico svg{width:20px;height:20px}
.infocard__txt{display:grid;gap:3px;min-width:0}
.infocard__label{
  font-size:.66rem;letter-spacing:.16em;text-transform:uppercase;
  color:rgba(245,244,240,.56);
}
.infocard__value{
  font-size:.95rem;line-height:1.45;color:var(--color-text-on-dark);
  text-wrap:pretty;
}
/* The contact card is actionable, so it gets the affordance the address card
   deliberately doesn't. */
.infocard__link:hover .infocard__value,
.infocard__link:focus-visible .infocard__value{color:var(--color-teal-light)}
.infocard__link:focus-visible{outline:2px solid var(--color-teal-light);outline-offset:-3px;border-radius:16px}

/* Enquiry card — liquid-gloss glass. Two columns from 560px so the four fields
   occupy two rows instead of four. The chrome is layered: a frosted translucent
   pane (so the lit tower diffuses through the blur), a bright specular sheen that
   catches across the top-left like light on glass, a crisp top edge highlight, and
   a low teal glow pooled at the base. isolation keeps the negative-z sheen scoped
   to the card. */
.form{
  display:grid;grid-template-columns:1fr;gap:var(--sp-5);align-items:start;
  padding:clamp(24px,2.4vw,34px);
  background:
    linear-gradient(180deg,rgba(255,255,255,.13) 0%,rgba(255,255,255,.035) 24%,rgba(255,255,255,0) 52%),
    linear-gradient(180deg,rgba(24,30,32,.50),rgba(11,17,19,.66));
  border:1px solid rgba(255,255,255,.16);border-radius:24px;
  box-shadow:
    0 46px 104px -46px rgba(0,0,0,.92),
    0 10px 28px -18px rgba(0,0,0,.6),
    inset 0 1px 0 rgba(255,255,255,.36),
    inset 0 0 0 1px rgba(255,255,255,.05),
    inset 0 -46px 88px -54px rgba(14,116,144,.32);
  -webkit-backdrop-filter:blur(26px) saturate(160%);backdrop-filter:blur(26px) saturate(160%);
  position:relative;overflow:hidden;isolation:isolate;
}
/* Hairline of brand gradient across the top edge of the card.
   Inset by the corner radius so its ends land on the straight part of the edge:
   backdrop-filter promotes the card to its own layer where overflow:hidden no
   longer clips this pseudo, so a full-bleed line would overhang the rounded
   corners. Keeping it inside the radius makes it correct with or without the clip. */
.form::before{
  content:"";position:absolute;top:0;left:20px;right:20px;height:1px;z-index:1;
  background:var(--color-gradient);opacity:.85;
}
/* Specular gloss — a soft diagonal band of light raked across the upper card, and a
   broad highlight pooling at the top edge. Negative z sits it above the frosted
   pane but beneath the fields, so it reads as a sheen on the glass, not a veil over
   the inputs. */
.form::after{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:
    radial-gradient(130% 66% at 20% -12%,rgba(255,255,255,.24),rgba(255,255,255,0) 56%),
    radial-gradient(90% 62% at 110% 118%,rgba(111,214,201,.12),rgba(111,214,201,0) 60%),
    linear-gradient(118deg,rgba(255,255,255,0) 33%,rgba(255,255,255,.13) 47%,rgba(255,255,255,0) 59%);
}

/* Card header — now a single line, so it carries the card as a headline rather
   than a label: display face, sized against the section heading, with the brand
   gradient washed through the type. Sits above the hairline that starts the
   field set. */
.form__head{
  display:grid;gap:6px;margin-bottom:var(--sp-3);
  padding-bottom:var(--sp-5);
  border-bottom:1px solid rgba(245,244,240,.09);
}
.form__eyebrow{
  display:flex;align-items:center;gap:.6em;margin:0;
  font-family:var(--font-display);font-weight:400;
  font-size:clamp(1.5rem,4.6vw,1.9rem);line-height:1.1;
  letter-spacing:.01em;text-transform:none;
  /* Gradient type, with a flat teal fallback underneath for engines that skip
     background-clip. */
  color:var(--color-teal-light);
  background-image:linear-gradient(96deg,#8FE3D6 0%,#6FD6C9 34%,#38B9C6 68%,#17A2A8 100%);
  -webkit-background-clip:text;background-clip:text;
  -webkit-text-fill-color:transparent;
  filter:drop-shadow(0 2px 18px rgba(23,162,168,.35));
}
/* The tick grows with the headline and keeps its own colour — it sits outside the
   clipped text box, so it cannot inherit the transparent fill. */
.form__eyebrow-rule{
  flex:none;width:clamp(28px,4vw,40px);height:2px;border-radius:2px;
  -webkit-text-fill-color:initial;
  background:linear-gradient(90deg,rgba(111,214,201,0),var(--color-teal-light));
  box-shadow:0 0 14px rgba(111,214,201,.5);
}

.field{display:grid;gap:7px;min-width:0}
.field__top{display:flex;align-items:baseline;justify-content:space-between;gap:var(--sp-3);min-height:14px}
.field label{font-size:.68rem;letter-spacing:.14em;text-transform:uppercase;color:var(--color-text-muted)}
.field label span{color:var(--color-gold-accent)}
/* Kept for any field that needs a right-side note; the Project field now says
   "locked" with a glyph instead of the words. */
.field__hint{font-size:.66rem;letter-spacing:.04em;color:rgba(245,244,240,.42)}

.field input,.field select{
  min-height:56px;width:100%;padding:14px 17px;
  background:
    linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,0) 55%),
    rgba(8,13,15,.42);
  color:var(--color-text-on-dark);
  border:1px solid rgba(255,255,255,.11);border-radius:13px;
  box-shadow:inset 0 1px 2px rgba(0,0,0,.34),inset 0 1px 0 rgba(255,255,255,.06);
  font-size:1rem;letter-spacing:.005em;
  transition:border-color var(--dur-fast) linear,box-shadow var(--dur-fast) linear,
             background-color var(--dur-fast) linear;
}
.field input::placeholder{color:rgba(245,244,240,.34)}
@media (hover:hover){
  .field input:hover,.field select:hover{
    border-color:rgba(255,255,255,.26);background-color:rgba(8,13,15,.5);
  }
}
/* Chevron drawn as an inline SVG so it stays crisp and centres at any height */
.field select{
  appearance:none;padding-right:42px;cursor:pointer;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236FD6C9' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 9 7 7 7-7'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 14px center;background-size:16px 16px;
}
.field input:focus,.field select:focus{
  outline:none;border-color:var(--color-teal-mid);background-color:rgba(8,13,15,.7);
  box-shadow:0 0 0 3px rgba(23,162,168,.24),0 0 22px -6px rgba(23,162,168,.5),
             inset 0 1px 2px rgba(0,0,0,.34);
}
.field input[aria-invalid="true"]{border-color:#FF8A7A;box-shadow:0 0 0 3px rgba(255,138,122,.14)}

/* Read-only "Project" field — reads as locked: dimmer, no cursor/hover/focus lift */
.field input[readonly]{
  color:var(--color-text-muted);
  background:rgba(8,13,15,.28);box-shadow:inset 0 1px 2px rgba(0,0,0,.24);cursor:default;
}
.field input[readonly]:hover,.field input[readonly]:focus{
  border-color:rgba(255,255,255,.13);background:rgba(8,13,15,.28);
  box-shadow:inset 0 1px 2px rgba(0,0,0,.24);
}

/* Consent row — the native control is kept for semantics and keyboard use but
   taken out of the paint; the box beside it is ours, so the tick matches the
   card's hairlines instead of the platform's chunky default. */
.form__consent{
  display:flex;align-items:flex-start;gap:var(--sp-3);
  font-size:.82rem;line-height:1.45;color:var(--color-text-muted);cursor:pointer;
}
.form__consent input{
  position:absolute;width:1px;height:1px;margin:0;padding:0;
  clip-path:inset(50%);overflow:hidden;white-space:nowrap;
}
.form__box{
  flex:none;display:grid;place-items:center;
  width:19px;height:19px;margin-top:1px;
  border:1px solid rgba(245,244,240,.26);border-radius:5px;
  background:rgba(8,13,15,.42);
  transition:border-color var(--dur-fast) linear,background var(--dur-fast) linear,
             box-shadow var(--dur-fast) linear;
}
.form__box svg{width:12px;height:12px;color:#06171A;opacity:0;transform:scale(.7);
  transition:opacity var(--dur-fast) linear,transform var(--dur-mid) var(--ease-out)}
.form__consent input:checked + .form__box{
  border-color:transparent;background-image:var(--color-gradient-btn);
  box-shadow:0 4px 14px -6px rgba(34,200,206,.9);
}
.form__consent input:checked + .form__box svg{opacity:1;transform:none}
/* :focus as well as :focus-visible — the validator calls consent.focus() on a
   failed submit, and a programmatic focus does not always match :focus-visible.
   The input itself is clipped, so without this the focus would be invisible. */
.form__consent input:focus + .form__box,
.form__consent input:focus-visible + .form__box{
  outline:2px solid var(--color-teal-light);outline-offset:3px;
}
@media (hover:hover){
  .form__consent:hover .form__box{border-color:rgba(245,244,240,.44)}
  .form__consent:hover input:checked + .form__box{border-color:transparent}
}
.form__privacy{color:var(--color-teal-light);text-decoration:underline;text-underline-offset:2px;white-space:nowrap}
@media (hover:hover){.form__privacy:hover{color:var(--color-text-on-dark)}}

.err{font-size:.76rem;color:#FF9B8C;margin:0;display:flex;align-items:center;gap:6px}
.err::before{content:"!";flex:none;display:inline-grid;place-items:center;width:15px;height:15px;
  border-radius:50%;background:#FF9B8C;color:#2A0E0A;font-size:.64rem;font-weight:700}
.err[hidden]{display:none}

.form__submit{
  margin-top:var(--sp-2);min-height:58px;border-radius:999px;
  gap:.7em;font-weight:600;letter-spacing:.14em;
  box-shadow:0 14px 34px -12px rgba(23,162,168,.85),0 2px 6px rgba(0,0,0,.28),
             inset 0 1px 0 rgba(255,255,255,.55),inset 0 -8px 18px -10px rgba(6,23,26,.45);
}
/* Top sheen on the pill — pulled well back from the old high-gloss dome, which
   read as plastic. A thin band of light along the upper edge is enough. */
.form__submit::before{
  content:"";position:absolute;inset:1px 1px 58%;border-radius:999px 999px 46% 46%;
  background:linear-gradient(180deg,rgba(255,255,255,.30),rgba(255,255,255,0));
  pointer-events:none;opacity:.62;
}
/* Slow specular travel across the pill — the same gesture the brochure button
   uses, so the page has one vocabulary for "this is the action". */
.form__submit::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(105deg,transparent 38%,rgba(255,255,255,.5) 50%,transparent 62%);
  transform:translateX(-120%);
  animation:brochure-sheen 6.5s cubic-bezier(.4,0,.2,1) 2.2s infinite;
}
/* Label and glyph ride above both pseudos so the sweep passes behind them. */
.form__submit > span,.form__submit-ico{position:relative;z-index:1}
.form__submit-ico{
  flex:none;width:17px;height:17px;
  transition:transform var(--dur-mid) var(--ease-out);
}
@media (hover:hover){
  .form__submit:hover{box-shadow:0 20px 44px -12px rgba(23,162,168,.82),0 3px 8px rgba(0,0,0,.3),
                       inset 0 1px 0 rgba(255,255,255,.65),inset 0 -8px 18px -10px rgba(6,23,26,.45)}
  .form__submit:hover .form__submit-ico{transform:translateX(4px)}
}
/* Collapses to nothing until JS writes a result, so it costs no height at rest */
.form__status{margin:0;font-size:.88rem}
.form__status:empty{display:none}
.form__status.is-ok{color:var(--color-teal-light)}
.form__status.is-bad{color:#FF9B8C}
.form__legal{margin:0;font-size:.7rem;line-height:1.5;color:rgba(245,244,240,.5)}

@media (min-width:560px){
  .form{grid-template-columns:1fr 1fr;gap:var(--sp-5) var(--sp-5)}
  .form__head,.form__consent,.form__submit,.form__status,.form__legal{grid-column:1/-1}
}

/* ------------------------------- 19. FAQ ------------------------------- */
.acc{margin-top:var(--block-gap);border-top:1px solid var(--color-hairline-dark)}
.acc__item{border-bottom:1px solid var(--color-hairline-dark)}
.acc__item h3{margin:0;font-family:var(--font-body)}
.acc__btn{
  display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4);
  width:100%;min-height:64px;padding:var(--sp-4) 0;text-align:left;
  font-family:var(--font-display);font-size:1.1rem;line-height:1.3;font-weight:400;
  color:var(--color-text-on-light);
  -webkit-tap-highlight-color:transparent;touch-action:manipulation;
}
.acc__ico{width:22px;height:22px;flex:none;color:var(--color-teal-deep);
  transition:transform var(--dur-mid) var(--ease-out),color var(--dur-mid) var(--ease-out)}
.acc__btn[aria-expanded="true"] .acc__ico{transform:rotate(180deg);color:var(--color-gold-accent)}
.acc__panel{height:0;overflow:hidden;transition:height var(--dur-mid) var(--ease-out)}
.acc__inner{padding-bottom:var(--sp-5)}
.acc__inner p{margin:0;font-size:.96rem;color:var(--color-text-muted-dark);max-width:64ch}
.acc__inner a{color:var(--color-teal-deep);text-decoration:underline;text-underline-offset:3px}

/* ------------------------------ 20. FOOTER ------------------------------ */
/* Three-part footer: brand | project + trust badge | disclaimer + legal,
   divided by hairlines. Stacks on small screens; a brand-gradient accent
   replaces the flat top border. */
.footer{
  position:relative;background:#fff;color:var(--color-text-on-light);
  border-top:1px solid var(--color-hairline-dark);
  /* Compact, symmetric top/bottom. The extra bottom clearance only exists to
     sit above the mobile sticky CTA bar; it's removed at >=1024 where that bar
     is hidden (see breakpoint 1024). */
  padding-block:var(--sp-6) calc(var(--sp-6) + 76px);
}
.footer::before{
  content:"";position:absolute;inset:0 0 auto;height:1px;
  background:linear-gradient(90deg,transparent,rgba(111,214,201,.5) 22%,rgba(23,162,168,.5) 78%,transparent);
}

.footer__grid{display:grid;gap:var(--block-gap)}
.footer__col{min-width:0}

/* Brand */
.footer__brand{display:inline-flex;flex:none}
.footer__brand .brand__logo--footer{max-width:230px}

/* Project column */
.footer__eyebrow{
  margin:0 0 var(--sp-4);font-size:.72rem;font-weight:500;
  letter-spacing:.24em;text-transform:uppercase;color:var(--color-teal-deep);
}
.footer__blurb{
  margin:0 0 var(--sp-5);max-width:42ch;
  font-size:.96rem;line-height:1.6;color:var(--color-text-muted-dark);
}
.footer__badge{
  margin:0;display:inline-flex;align-self:flex-start;align-items:center;gap:.6em;
  padding:12px 22px;border-radius:999px;white-space:nowrap;
  border:1px solid rgba(14,116,144,.4);
  background:linear-gradient(180deg,rgba(23,162,168,.08),transparent);
  color:var(--color-teal-deep);
  font-size:.7rem;font-weight:500;letter-spacing:.14em;text-transform:uppercase;
}
.footer__badge svg{width:16px;height:16px;flex:none}

/* Legal column */
.footer__disclaimer{
  margin:0 0 var(--sp-5);font-size:.72rem;line-height:1.65;
  color:rgba(28,31,34,.6);
}
.footer__disclaimer strong{color:var(--color-text-on-light);font-weight:700}
.footer__copy{margin:0 0 var(--sp-2);font-size:.78rem;letter-spacing:.02em;color:var(--color-text-muted-dark)}
.footer__rera{
  margin:0;font-size:.72rem;letter-spacing:.04em;
  color:rgba(28,31,34,.6);display:flex;align-items:center;flex-wrap:wrap;gap:.5em;
}
.footer__rera span{color:var(--color-teal-deep);letter-spacing:.06em}
.footer__rera i{font-style:normal;color:rgba(28,31,34,.3)}
.footer__rera a{
  color:var(--color-teal-deep);text-decoration:none;
  border-bottom:1px solid rgba(14,116,144,.4);padding-bottom:1px;
  transition:border-color var(--dur-fast) linear;
}
.footer__rera a:hover{border-bottom-color:var(--color-teal-deep)}

/* ------------------------- 22. REVEAL ANIMATIONS ------------------------- */
/* Travel is 18px, not 40. Forty pixels at this duration is a visible slide —
   the eye tracks the movement instead of reading the words. Eighteen reads as
   the type settling into place. --reveal-delay is stamped by script.js from
   data-delay; it lives in the transition rather than in a setTimeout so the
   browser schedules the whole thing on the compositor in one go. */
.reveal{opacity:0;transform:translateY(18px);
  transition:opacity var(--dur-reveal) var(--ease-reveal),
             transform var(--dur-reveal) var(--ease-reveal);
  transition-delay:var(--reveal-delay,0ms)}
.reveal--right{transform:translateX(22px) translateY(10px)}
.reveal.is-in{opacity:1;transform:none}

.lines .line{display:block;overflow:hidden}
/* The mask is a hard clip, so descenders on the last line (g, y, p) were being
   shaved. Pad the box and pull the same amount back off the flow: the glyphs
   clear, the layout doesn't move. */
.lines .line{padding-bottom:.14em;margin-bottom:-.14em}
.lines .line-inner{
  display:block;transform:translateY(105%);opacity:0;
  transition:transform var(--dur-reveal) var(--ease-reveal),
             opacity var(--dur-reveal) var(--ease-reveal);
  /* Per-line stagger, composed with the element's own delay. 42ms is enough to
     read as a cascade without the last line of a four-line heading landing a
     fifth of a second after the first. */
  transition-delay:calc(var(--reveal-delay,0ms) + var(--line-i,0) * 42ms);
}
.lines.is-in .line-inner{transform:none;opacity:1}

/* Mobile only (<=767px): the Niva-meaning statement is authored as three
   hard lines, each masked in its own clipping box. At 393px every one of
   those lines wraps again inside its own mask, so the copy breaks twice —
   once by design, once by accident — leaving the stranded "word" and "hope"
   lines. Here we dissolve the per-line boxes and let the sentence set as one
   continuous, balanced block. Inline boxes can't be transformed, so the
   reveal degrades to a fade, which is the right read at this size anyway.
   The masked slide-up is untouched from 768px up. */
@media (max-width:767px){
  /* Left-aligned at this size. The section's container is capped at 92vw —
     16px of side room, tighter than the page gutter — which is invisible when
     the type is centred but would strand the new left edge inboard of every
     other section. Reset it to the standard gutter so the statement starts on
     the same rail as the rest of the page. */
  .meaning .container--narrow{max-width:none;margin-inline:var(--gutter)}
  .meaning .center{text-align:left}

  /* balance evens a centred rag; for flush-left copy pretty is the right tool —
     it only guards the last line against an orphan. */
  .meaning__title{text-wrap:pretty;line-height:1.22}
  /* 6.4vw set the statement in five lines on a 393pt phone. 5.85vw is the
     largest ramp that holds it to four across the whole phone range (checked
     320 → 600px), so the block reads as one tight paragraph rather than a
     five-line column. The 2.5rem cap is the base one, untouched. */
  .meaning .h2{font-size:clamp(1.1rem,5.85vw,2.5rem)}
  .meaning__title .line,
  .meaning__title .line-inner{display:inline;overflow:visible}
  .meaning__title .line-inner{transform:none}
  /* script.js sets display:block inline on each authored span — outrank it. */
  .meaning__title .line-inner > span{display:inline!important}

  /* Creed: four ruled cells become one running paragraph. At 393px each
     statement wrapped to two lines anyway, so the rules and lozenges were
     dividing a block that already read as prose — and cost it half a screen.
     The four <p> stay in the markup (the 768px grid still needs them) and are
     simply run inline here; the source newline between them supplies the space. */
  .creed{display:block;text-align:left;padding:clamp(16px,2.2vw,22px) 18px 18px}
  /* justify-self was doing the centring while this was a grid item. */
  .creed__mark{display:block;margin-inline:auto}
  .creed p{
    display:inline;padding:0;border:0;
    font-size:14px;line-height:1.62;
  }
  /* No bullets and no per-line stagger — one paragraph fades in as a whole. */
  .creed p::before{content:none}
  .creed p + p{border-top:0}
  .creed p,.creed.is-in p{transform:none}
  .creed.is-in p:nth-of-type(n){transition-delay:0ms}

  /* ---------------------- Amenities: intro + carousel ----------------------
     The intro read as five loosely stacked lines rather than a paragraph, and
     sat too far under its own heading. */
  .amen__head .h2{margin-bottom:var(--sp-3)}
  .amen__head .lead{line-height:1.38}
  .amen__head{margin-bottom:var(--sp-6)}

  /* Four full-width spreads meant four screens of vertical scrolling. Here the
     rail becomes one snapped, horizontally scrolled row: gradient frame, a
     single photograph inset 10px inside it, copy beneath. The paired inset and
     cut-out figures are dropped — at card width a second image only competed
     with the subject of the first. */
  .amen__rail{
    display:flex;align-items:stretch;gap:14px;
    overflow-x:auto;overscroll-behavior-x:contain;
    scroll-snap-type:x mandatory;
    scroll-padding-inline:var(--gutter);
    /* overflow-x:auto makes this a scroll container, which clips on the block
       axis too — the panels' drop shadow was being sliced off along the bottom
       edge. The padding is what the shadow gets to live in. */
    padding:6px var(--gutter) 30px;
    -webkit-overflow-scrolling:touch;scrollbar-width:none;
  }
  .amen__rail::-webkit-scrollbar{display:none}
  /* Leaves ~30px of the next card showing, which is the only cue that the row
     scrolls at all. */
  .amen__rail > .band{
    flex:0 0 calc(100% - 30px);
    margin-block:0;scroll-snap-align:center;
  }
  /* Cards are flex items in a stretch row, so they already share the tallest
     one's height; the frame just has to fill it. */
  .amen__rail .band__grid{
    display:grid;grid-template-columns:1fr;grid-template-rows:auto 1fr;
    width:100%;max-width:none;height:100%;padding:0;margin:0;
  }
  .amen__rail .band__panel{
    grid-column:1;grid-row:1/3;align-self:stretch;border-radius:16px;
  }
  /* The full-spread shadow is thrown 46px down with a 90px blur — far more than a
     315px card can carry, and the reason it fouled the rail's edge. Scaled to
     the card so it seats without needing half a screen of clearance. */
  .amen__rail .band__panel,
  .amen__rail .band__panel--bleed{box-shadow:0 14px 26px -14px rgba(4,58,84,.72)}
  .amen__rail .band__media,
  .amen__rail .band__media--cine{
    box-shadow:0 10px 20px -12px rgba(4,32,46,.55),0 2px 0 rgba(255,255,255,.10) inset;
  }
  /* The photograph, floated 10px inside the frame on every side. */
  .amen__rail .band__media{
    grid-column:1;grid-row:1;
    margin:10px !important;aspect-ratio:4/3;border-radius:8px;
  }
  .amen__rail .band__copy{
    grid-column:1;grid-row:2;padding:12px 16px 16px;
  }
  /* Second images and feature chips: gone on the carousel. The chips were three
     rows of pills per card — the single biggest thing standing between these and
     a compact card, and the rooms they name are all in the copy above them. */
  .amen__rail .band__inset,
  .amen__rail .band__figure,
  .amen__rail .band__tags{display:none}

  /* Band 03 is built the other way round — its panel is the outer box and holds
     a split inside — so it is normalised into the same card here. */
  .amen__rail .band--bleed{margin-block:0}
  .amen__rail .band__panel--bleed{
    display:grid;grid-template-rows:auto 1fr;height:100%;
    width:100%;margin-inline:0;padding:0;border-radius:16px;
  }
  /* .band__split also carries .container, whose margin-inline:max(gutter,…) would
     otherwise push it 24px off the panel it sits inside. */
  .amen__rail .band__split{
    display:grid;grid-template-rows:auto 1fr;gap:0;
    width:100%;max-width:none;padding:0;margin:0;
  }
  .amen__rail .band__media--cine{margin:10px !important;aspect-ratio:4/3;border-radius:8px}
  .amen__rail .band__copy--split{padding:12px 16px 16px}
  .amen__rail .band__sun{width:min(75%,320px);right:-16%}

  /* Type steps down to card width. */
  .amen__rail .band__idx{margin-bottom:var(--sp-2);font-size:.62rem}
  .amen__rail .band__num{font-size:.95rem}
  .amen__rail .band__title{font-size:1.32rem;line-height:1.16}
  .amen__rail .band__text{font-size:.85rem;line-height:1.5;margin-top:10px}

  /* Cards 2–4 sit outside the viewport horizontally, so a scroll-triggered
     reveal would never fire for them and they would stay invisible. The rail
     arrives as one object instead. */
  .amen__rail .band.reveal{opacity:1;transform:none;transition:none}
  .amen__rail .lines .line-inner{transform:none;opacity:1}
}

/* --------------------------- 23. BREAKPOINT: 768 --------------------------- */
@media (min-width:768px){
  :root{--section-y:76px;--head-gap:36px;--block-gap:32px;--gutter:64px}
  body{font-size:1.0625rem}

  .h1{font-size:clamp(3.4rem,7vw,4.4rem)}
  .h2{font-size:clamp(2.2rem,4.6vw,2.8rem)}
  .h3{font-size:1.5rem}

  /* The four creed lines pair off into two rows once there is width for it —
     same lines at the same size, half the card height. */
  /* Two columns of two, split by a hairline so the pairs read as a set. Columns
     size to their own content (not equal fractions) so no line ever wraps. */
  /* Equal columns, not auto: auto-sized columns took their width from whichever
     line was longest, so one cell wrapped to two lines while the rest sat on one
     and the pairs stopped reading as a set. */
  .creed{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}
  .creed__mark{grid-column:1/-1}
  /* The ruled cross: a hairline down the gutter, one between the rows. Both are
     cell edges, so they span whole rows and meet exactly at the centre. */
  .creed p:nth-of-type(even){border-left:1px solid rgba(111,214,201,.13)}
  .creed p:nth-of-type(-n+2){border-top:0}
  .creed p:nth-of-type(n+3){border-top:1px solid rgba(111,214,201,.13)}

  .hero__cta{flex-direction:row;gap:var(--sp-4)}
  .hero__cta .btn{width:auto}
  .hero__sub{font-size:1.125rem}

  /* Tablet: the map is still stacked, so cap and centre it — at full rail width a
     portrait map that tall would swamp the section. */
  .map{max-width:540px;margin-inline:auto}
  .address .quote{max-width:70ch;margin-inline:auto}

  /* The copy-plate: a directional wash that sinks the left of the frame so type
     reads at full contrast, then releases before the tower so the render keeps
     its highlights. This is what separates the two halves of the composition. */
  .hero__scrim{
    background:
      /* Copy pool, centred on the copy block rather than the frame — an
         elliptical well of shade that follows the type. */
      radial-gradient(66% 62% at 26% 50%,rgba(3,9,11,.62),rgba(3,9,11,.2) 62%,transparent 84%),
      /* Left copy-plate — softened so the road and tree canopy read through it;
         the headline is carried the rest of the way by its own shadow, not a wall. */
      linear-gradient(100deg,
        rgba(4,11,13,.76) 0%,rgba(4,11,13,.5) 24%,rgba(4,11,13,.22) 46%,
        rgba(4,11,13,.04) 64%,transparent 82%),
      /* Vertical: the nav now carries its own scrim, so the top stays open; a wide
         clear window over the towers, then a lightened bottom hand-off — a slim base
         just enough to seat the sub-copy and hand off to the section below. */
      linear-gradient(180deg,
        rgba(6,13,15,.12) 0%,transparent 14%,
        transparent 56%,rgba(11,18,20,.14) 74%,rgba(11,18,20,.4) 88%,
        rgba(11,18,20,.68) 96%,#0B1214 100%),
      /* Framing vignette, opened up so the render keeps its highlights. */
      radial-gradient(150% 106% at 64% 42%,transparent 46%,rgba(3,9,11,.5) 100%),
      /* Teal ground-glow — the brand gradient rising from the base. */
      radial-gradient(84% 50% at 36% 110%,rgba(23,162,168,.34),transparent 72%);
  }

  .hero__frame{inset:22px}
  .hero__frame::before,.hero__frame::after{width:52px;height:52px}
  .hero__copy{max-width:640px}
  .hero .eyebrow--hero{font-size:.72rem}
  .hero__flourish{width:132px;margin-bottom:var(--sp-5)}

  :root{--nav-h:62px}

  .cards{gap:var(--sp-5)}

  .stats{grid-template-columns:repeat(4,1fr)}
  /* Credentials band becomes a single row of four — vertical dividers only. */
  .stats--dev{grid-template-columns:repeat(4,1fr)}
  .stats--dev .stat{border-top:0}
  .stats--dev .stat:nth-child(3){border-left:1px solid var(--color-hairline)}

  /* Three across. The cards were a tall 3:4 portrait, which made this a very
     deep band; a square crop keeps the same width but takes ~25% off the height. */
  .moodstrip{grid-template-columns:repeat(3,1fr)}
  .mood img{aspect-ratio:1/1}

  /* Floor plans: landscape drawing on the left, toggle + spec table on the right.
     The drawing keeps its own 3:2 aspect rather than being matted into a frame
     stretched to the spec column — that was padding the panel with ~250px of
     empty black. The columns centre against each other instead. */
  /* Both columns share one height, so the toggle's top edge and the card's
     bottom edge line up with the drawing's frame. Whichever column is taller
     sets the row: the schedule was trimmed to sit close to the drawing's own
     height, so what's left over is a shallow mat inside the blueprint frame
     rather than the ~250px of dead black this used to carry. */
  .plans__layout{gap:var(--block-gap);align-items:stretch}
  .plans__head{text-align:center}
  .plans__figs{display:flex}
  .plans__fig{flex:1 1 auto;height:100%}
  .plans__fig .plans__zoom{flex:1 1 auto;min-height:0;display:flex;align-items:center}
  .plans__fig .plans__zoom img{width:100%;height:100%;object-fit:contain}
  .plans__right{gap:var(--sp-4);height:100%}
  .plans__tblpanel{flex:1 1 auto}

  /* Footer: brand sits beside a stacked project/legal pair on tablet. */
  .footer__grid{grid-template-columns:auto 1fr;gap:var(--block-gap) var(--sp-8);align-items:center}
  .footer__col--brand{grid-row:span 2;padding-right:var(--sp-8);border-right:1px solid var(--color-hairline-dark)}

  .day{width:min(74vw,780px)}
  .motif{width:min(52vw,520px)}

  /* Tablet: band 03's split opens into image | copy while the other three
     stay stacked — the photograph still runs off the left edge. */
  .band__split{grid-template-columns:1.1fr .9fr;align-items:center;gap:clamp(28px,3.4vw,48px)}
  .band__media--cine{aspect-ratio:4/3}
}

/* --------------------------- 24. BREAKPOINT: 1024 --------------------------- */
@media (min-width:1024px){
  /* 100px side gutter across the whole page. --maxw is raised well past common
     desktop widths so the gutter is measured from the true viewport edge (padding
     lives inside the cap); it only re-engages as a centering cap beyond ~2400px so
     ultra-wide rows don't get unreadable. */
  :root{--section-y:96px;--head-gap:44px;--block-gap:40px;--gutter:120px;--maxw:2400px}

  /* Floor plans go side by side here, not at 768: below this the spec column is
     too narrow to seat four unit columns without a horizontal scroll. */
  .plans__layout{grid-template-columns:1.22fr 1fr}

  .h1{font-size:clamp(4.4rem,5.6vw,5.5rem)}
  .h2{font-size:clamp(2.6rem,3.4vw,3.2rem)}
  .h3{font-size:1.75rem}

  /* Neighbourhood amenities: paired tiles in the left rail beside the map, with
     the fifth running the rail's full width (see the 768 block). */
  .card{padding:var(--sp-5)}

  :root{--nav-h:68px}
  .burger{display:none}
  .nav__links{display:flex;align-items:center;flex-wrap:nowrap;gap:clamp(20px,2.2vw,36px)}
  .nav__links a{
    position:relative;font-size:.8rem;letter-spacing:.1em;text-transform:uppercase;
    white-space:nowrap;
    color:rgba(245,244,240,.8);padding:8px 0;transition:color var(--dur-fast) linear;
    text-shadow:0 1px 12px rgba(3,9,11,.65);
  }
  .nav.is-solid .nav__links a{color:var(--color-text-muted);text-shadow:none}
  .nav__links a::after{
    content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
    background:var(--color-gradient);transform:scaleX(0);transform-origin:left;
    transition:transform var(--dur-mid) var(--ease-out);
  }
  .nav__links a:hover,.nav__links a.is-active{color:var(--color-text-on-dark)}
  .nav__links a:hover::after,.nav__links a.is-active::after{transform:scaleX(1)}
  .nav__cta{display:inline-flex;flex:none;min-height:44px;padding:12px 24px;font-size:.74rem;white-space:nowrap}

  /* Slightly deeper base than top clearance, so the block lands on the optical
     centre rather than the arithmetic one — type always reads high. */
  .hero{padding-bottom:120px}
  .hero__sub{font-size:1.2rem;max-width:52ch}
  .hero__copy{max-width:720px}
  .hero__frame{inset:28px}
  .hero__frame::before,.hero__frame::after{width:64px;height:64px}

  /* Hold the copy inside the darkened half so it never crosses the tower, while
     leaving each authored line room to sit unbroken on one line. */
  .hero__body .h1{max-width:24ch}
  .hero__body .h1 span{display:block;text-wrap:nowrap}

  /* Footer: three columns divided by hairlines, brand : project : legal.
     Sticky bar is hidden here, so drop the bottom clearance for equal,
     compact top/bottom spacing. */
  .footer{padding-block:var(--sp-6)}
  .footer__grid{
    grid-template-columns:minmax(200px,0.85fr) 1.15fr 1.5fr;
    gap:0;align-items:stretch;
  }
  .footer__col{display:flex;flex-direction:column;justify-content:center;padding:var(--sp-2) var(--sp-8)}
  .footer__col--brand{padding-left:0;border-right:1px solid var(--color-hairline-dark);grid-row:auto}
  .footer__col--about{border-right:1px solid var(--color-hairline-dark)}
  .footer__col--legal{padding-right:0}
  .hero__body .hero__sub{max-width:54ch}
  .hero__media img{object-position:62% 44%}

  .split{grid-template-columns:1fr 1fr;align-items:center;gap:var(--sp-9)}
  /* Sized so the longest of the three lines clears the container with room to
     spare at every desktop width — the statement never rewraps. */
  .meaning .h2{font-size:clamp(2.6rem,3.5vw,3.45rem);line-height:1.14}
  /* Break out of the 820px narrow container: at that width the longest creed line
     cannot sit on one line inside a half-column. The negative side margins keep
     the plate centred on the section rather than pushing it right. */
  .creed{width:min(1240px,94vw);margin-inline:calc(50% - min(1240px,94vw)/2)}
  .creed p{font-size:1.06rem;line-height:1.4}
  .creed__mark{width:min(260px,44%)}

  /* Address: centred header over the neighbourhood cards in the left rail, the
     full portrait map in the right. The map spans both rows and holds the top of
     the grid, so the cards read down the page beside it. */
  .address__grid{
    grid-template-columns:minmax(380px,1fr) minmax(0,clamp(348px,33vw,470px));
    grid-template-rows:auto 1fr;
    /* stretch, not start: both columns run the full height of the grid so the
       left and right content begin and end on the same two lines. */
    gap:clamp(40px,3.2vw,64px);align-items:stretch;
  }
  .address__head{grid-column:1;grid-row:1}
  .amencards{grid-column:1;grid-row:2;margin-top:0}
  /* The rail re-forms as a column: map, then the closing statement under it, so
     the right side runs as deep as the cards on the left. */
  .address__rail{
    display:flex;flex-direction:column;gap:clamp(32px,3vw,48px);
    grid-column:2;grid-row:1 / span 2;justify-self:end;width:100%;
  }
  .map{margin:0;width:100%;max-width:none}
  /* In the rail the quote is a pull-quote, not a full-measure statement: it takes
     the rail's width and steps down a size so the lines stay readable.
     margin-top:auto drops it to the foot of the stretched rail, so it lands level
     with the last card on the left instead of hanging under the map. */
  .address .quote{margin:auto 0 0;max-width:none}
  .address .quote p{font-size:clamp(1.02rem,1.35vw,1.18rem);line-height:1.5;max-width:none}

  /* Desktop bands: a 12-column grid does the overlap. The panel takes 9 columns
     on one side, the photograph 8–9 on the other, and they share grid rows — so
     roughly two thirds of the image sits on the gradient and a third breaks out
     over the page, exactly as the brochure lays it out. */
  .band__grid{
    grid-template-columns:repeat(12,1fr);
    grid-template-rows:clamp(24px,2vw,36px) auto auto clamp(26px,2.2vw,42px);
  }
  .band__media{margin:0 !important}

  .band--right .band__panel{grid-column:4/13}
  .band--right .band__media{grid-column:1/10}
  .band--right .band__copy{grid-column:5/12}

  .band--left .band__panel{grid-column:1/10}
  .band--left .band__media{grid-column:5/13}
  .band--left .band__copy{grid-column:2/9}

  .band__media--tall{aspect-ratio:16/9}
  /* On very wide screens a full-width 2:1 frame would grow past the fold on its
     own — cap it so the band stays a band. */
  .band__media{max-height:min(58vh,580px)}
  .band__copy{padding:clamp(20px,1.8vw,30px) 0 0}

  /* Duo bands (02, 04): the paired photograph moves up beside the main frame,
     filling the open gradient the shorter frame leaves behind and stacking
     against it on a shared baseline. The copy then runs the panel's full width,
     so its chips sit on one row and the band loses a whole line of height. */
  .band--duo .band__inset{
    grid-row:2;align-self:end;width:auto;aspect-ratio:4/5;margin:0;
  }
  /* The diver rides the panel's right edge and breaks out of it: pinned to the
     end of its columns, then pushed 30% of his own width past the gradient so
     roughly a third of him is clear of the panel — the same break-out gesture
     the photograph makes on the opposite side. */
  .band__figure{
    grid-column:9/13;grid-row:2/4;align-self:center;justify-self:end;
    width:min(24vw,330px);margin:0;
    transform:translateX(calc(30% - 30px));
  }

  /* The inset now breaks the panel edge the way the main frame does: roughly 30%
     of the photograph hangs past the gradient onto the page. The overhang is
     capped at the gutter, because the section clips its overflow and anything
     past that margin would be shaved off the image.
     The matching positive margin on the opposite side keeps the photograph the
     same size as before — the pair only shifts it outward. */
  /* The plate now grows past its grid area instead of only shifting inside it:
     the outward margin is negative and nothing compensates on the inner side, so
     the frame ends up ~25% wider than the columns it sits in and roughly a fifth
     of that wider frame clears the gradient. Still capped at the gutter — the
     section clips its overflow, and anything past the margin would be shaved. */
  .band--duo .band__inset{--inset-out:min(25%,var(--gutter))}
  /* The landscape plate drops clear of the main photograph's baseline, so the two
     read as two plates rather than one block. */
  .band--duo .band__inset--land{aspect-ratio:16/9;margin-bottom:-100px}
  .band--right.band--duo .band__copy{grid-column:5/12}
  .band--right.band--duo .band__inset{
    grid-column:10/13;justify-self:stretch;
    margin-left:clamp(12px,1.2vw,20px);
    margin-right:calc(var(--inset-out) * -1);
  }
  .band--left.band--duo .band__copy{grid-column:2/9}
  .band--left.band--duo .band__inset{
    grid-column:1/4;justify-self:stretch;
    margin-right:clamp(12px,1.2vw,20px);
    margin-left:calc(var(--inset-out) * -1);
  }

  /* Band 03: image | copy, both held to the page gutter so the photograph's left
     edge lines up with the nav and every other section rather than bleeding off
     the screen. The photograph takes a wider share of the row and the copy is
     nudged further into its own column, so the two sit further apart. */
  .band__split{grid-template-columns:1.5fr .82fr;gap:clamp(40px,4vw,72px)}
  /* The copy centres inside the gradient, not inside the photograph. Without the
     top inset it would centre on the frame and its first lines would ride up into
     the protruding zone, where there is no panel behind the white text. */
  .band--bleed .band__copy--split{
    align-self:stretch;display:flex;flex-direction:column;justify-content:center;
    padding-left:clamp(8px,1.4vw,28px);padding-top:var(--cine-out);
  }
  /* Height is pinned rather than derived from an aspect ratio: the frame gets
     wider without getting taller, and the panel below can be positioned against
     a height it knows. The image inside is object-fit:cover, so the extra width
     shows more of the frame rather than stretching it. */
  .band__media--cine{
    aspect-ratio:auto;height:var(--cine-h);max-height:none;margin-left:0 !important;
  }

  /* The photograph breaks the top edge of the gradient: the panel itself goes
     transparent and the gradient is redrawn by a pseudo that starts 30% of the
     way down the image, so that top third stands on the page. overflow must go
     visible for the protrusion to survive — the sun motif it used to clip only
     spills sideways, where the section's own overflow:clip catches it. */
  .band__panel--bleed{
    --cine-h:clamp(360px,34vw,540px);
    --cine-out:calc(var(--cine-h) * .3);
    overflow:visible;background:none;box-shadow:none;
    padding-block:0 50px;
  }
  .band__panel--bleed::before{
    content:"";position:absolute;inset:var(--cine-out) 0 0;z-index:0;
    background:var(--grad-band);
    box-shadow:0 46px 90px -56px rgba(4,58,84,.85);
  }
  /* The lit-surface sheen belongs to the gradient, not to the transparent box. */
  .band__panel--bleed .band__sheen{top:var(--cine-out)}
  /* Same for the sun watermark: sized off the gradient band it decorates, so it
     cannot drift up into the protruding strip where there is no panel to hold it. */
  .band__panel--bleed .band__sun{
    top:var(--cine-out);bottom:0;translate:none;
    width:auto;height:calc(100% - var(--cine-out));
  }

  .cta__body{grid-template-columns:1.05fr .95fr;gap:var(--sp-9);align-items:center}
  .form{padding:var(--sp-6) var(--sp-6) var(--sp-5)}

  /* Pinned horizontal carousel: the tall .week__track (height set by JS) gives
     the scroll length; the stage pins; JS translates .week__rail right→left.
     Once the rail is fully travelled, the pin releases to normal scroll. */
  .week__track{position:relative}          /* height set inline by JS */
  /* The pinned stage is a full viewport tall and centres the cards inside it, so
     on the way in there is half a stage of empty space under the heading on top
     of the normal header gap. Drop the intro's own bottom pad and pull the track
     up by that same step — the pin itself is unaffected (the stage is sticky to
     the viewport, not to this margin). */
  .week__intro{padding-bottom:0}
  .week__track{margin-top:calc(var(--head-gap) * -1)}
  /* The band centres in the pinned stage, against the full viewport height. */
  .week__stage{
    position:sticky;top:0;height:100svh;
    display:flex;align-items:center;overflow:hidden;isolation:isolate;
  }
  .week__rail{
    overflow:visible;scroll-snap-type:none;
    gap:clamp(24px,3vw,52px);
    padding:0 clamp(40px,10vw,180px);
    will-change:transform;
  }
  .day{width:min(66vw,1120px)}
  /* Width is fixed by .day; the frame is deepened (15/7 → 16/10) so the band
     fills the pinned stage instead of floating in it. The svh cap is the guard:
     on short laptop viewports the frame gives up height, never width. */
  .day__media{aspect-ratio:16/10;max-height:64svh}
}

/* Desktop users who prefer reduced motion keep the native swipe strip instead
   of the pinned scroll-driven carousel (JS also skips the pin for them). */
@media (min-width:1024px) and (prefers-reduced-motion:reduce){
  /* No pin here, so there is no half-stage of empty space to claw back — the
     header step goes back to the standard one. */
  .week__intro{padding-bottom:var(--head-gap)}
  .week__track{height:auto !important;margin-top:0}
  .week__stage{position:static;height:auto;display:block;overflow:visible}
  .week__rail{
    overflow-x:auto;scroll-snap-type:x mandatory;transform:none !important;
    padding:var(--sp-2) clamp(40px,10vw,120px) var(--sp-7);
  }
  .day{width:min(66vw,1040px)}
  .day__media{aspect-ratio:16/10;max-height:none}
}


/* --------------------------- 25. 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;scroll-behavior:auto !important;
  }
  .reveal{opacity:1;transform:none}
  .eyebrow__rule{transform:scaleX(1)}
  .lines .line-inner{transform:none;opacity:1}
  /* transition-duration is already neutralised above; the delays are separate
     properties and would otherwise still hold content back. */
  .reveal,.lines .line-inner{transition-delay:0ms !important}
  .motif--spin{animation:none}
  .creed__sheen{animation:none;opacity:0}
  .form__submit::after{animation:none;opacity:0}
  .marquee__track{animation:none;transform:none}
  .marquee{overflow-x:auto}
  .hero__media,.cta__media{transform:none !important;inset:0}
  .band__panel,.band__media,.band__inset,.band__media img{transform:none !important}
  .hero__media img{animation:none !important;transform:none !important}
  .scrollcue__line{animation:none;opacity:.8}
  .hero__cta .btn--primary::after{display:none}
}

/* Perf escape hatch — set by JS on low-core devices */
html.perf-lite .hero__media,
html.perf-lite .cta__media{transform:none !important;inset:0}
html.perf-lite .band__panel,
html.perf-lite .band__media,
html.perf-lite .band__inset,
html.perf-lite .band__media img{transform:none !important}
html.perf-lite .form,
html.perf-lite .creed,
html.perf-lite .nav.is-solid,
html.perf-lite .lightbox{-webkit-backdrop-filter:none;backdrop-filter:none}
/* Without the blur the plate loses its separation from the section wash — trade
   the frost for a slightly denser fill and drop the sheen repaint. */
html.perf-lite .creed{background:linear-gradient(180deg,rgba(24,36,39,.72),rgba(10,16,18,.8))}
html.perf-lite .creed__sheen{animation:none;opacity:0}
html.perf-lite .nav.is-solid{background:rgba(11,18,20,.97)}
/* Without the blur the frosted pane would show the tower sharply behind the fields —
   fall back to a near-opaque glass so labels and inputs stay legible. */
html.perf-lite .form{
  background:
    linear-gradient(180deg,rgba(255,255,255,.10),rgba(255,255,255,0) 46%),
    rgba(15,21,23,.94);
}
/* Grading a full-bleed image and compositing a blended grain layer both cost a
   repaint per parallax frame — the gradients alone carry the look well enough. */
html.perf-lite .hero__media img{filter:none;animation:none;transform:none}
html.perf-lite .hero::after{display:none}
/* The hero's glass surfaces each cost a backdrop pass over a full-bleed image —
   swap the blur for a flat tint and drop the sheen loop. */
html.perf-lite .hero .eyebrow--hero{-webkit-backdrop-filter:none;backdrop-filter:none;background:rgba(11,18,20,.5)}
html.perf-lite .hero__cta .btn--primary::after{display:none}
html.perf-lite .hero__glow{display:none}

/* ------------------------------ 26. PRELOADER ------------------------------
   A ~4s cinematic branded intro. Everything is CSS-timed off first paint;
   JS only runs the counter, flips .is-done at 3550ms for the horizon split,
   then unmounts the node ~700ms later.
   Layering, from back to front:
     panels (opaque split field) → bg (atmosphere) → inner (content) → seam.
   -------------------------------------------------------------------------- */
html.is-loading,
html.is-loading body{overflow:hidden}

.preloader{
  position:fixed;inset:0;z-index:2000;
  display:grid;place-items:center;
  background:var(--color-bg-dark);
  pointer-events:none;
}

/* ---- Split field. Two opaque halves that part at the horizon on exit. ---- */
.preloader__panel{
  position:absolute;left:0;right:0;height:50.5%;z-index:0;
  background:var(--color-bg-dark);
  will-change:transform;
}
.preloader__panel--t{top:0;transform-origin:top}
.preloader__panel--b{bottom:0;transform-origin:bottom}

/* ---- Atmosphere: layered teal + gold glow with a soft vignette. ---- */
.preloader__bg{
  position:absolute;inset:0;z-index:1;pointer-events:none;
  background:
    radial-gradient(115% 80% at 50% 44%, rgba(23,162,168,.18), rgba(23,162,168,0) 56%),
    radial-gradient(70% 55% at 80% 84%, rgba(23,162,168,.10), rgba(23,162,168,0) 60%),
    radial-gradient(60% 48% at 18% 20%, rgba(111,214,201,.07), rgba(111,214,201,0) 60%),
    radial-gradient(145% 130% at 50% 50%, transparent 52%, rgba(0,0,0,.6) 100%);
  opacity:0;
  animation:pl-bg-in 1500ms var(--ease-out) forwards,
            pl-breathe 6.5s ease-in-out 1500ms infinite;
}

/* ---- Light-leak along the seam as the two halves part. ---- */
.preloader__seam{
  position:absolute;left:0;right:0;top:50%;height:2px;z-index:5;
  transform:translateY(-50%) scaleX(.16);transform-origin:center;
  background:linear-gradient(90deg,transparent,var(--color-teal-light) 28%,var(--color-gold-accent) 50%,var(--color-teal-light) 72%,transparent);
  box-shadow:0 0 26px 5px rgba(111,214,201,.55);
  opacity:0;pointer-events:none;
}

.preloader__inner{
  position:relative;z-index:2;
  width:100%;max-width:440px;
  display:flex;flex-direction:column;align-items:center;
  gap:var(--sp-6);
  /* Centred splash — a fixed small inset, independent of the page's 120px gutter,
     so the wordmark never gets squeezed on wide screens. */
  padding-inline:var(--sp-5);
  animation:pl-handoff 360ms var(--ease-out) 3200ms forwards;
}

/* ---- Motif: halo + gold orbit arc + sunburst + drawing ring + core. ---- */
.preloader__motif{position:relative;width:152px;height:152px}
.preloader__motif>svg{position:absolute;inset:0;width:100%;height:100%}

.preloader__halo{
  position:absolute;inset:-30%;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,rgba(23,162,168,.30) 0%,rgba(23,162,168,0) 62%);
  opacity:0;
  animation:pl-halo-in 1200ms var(--ease-out) 200ms forwards,
            pl-halo-pulse 3.6s ease-in-out 1400ms infinite;
}

.preloader__arc{
  opacity:0;transform-origin:50% 50%;
  filter:drop-shadow(0 0 4px rgba(23,162,168,.5));
  animation:pl-fade 800ms var(--ease-out) 560ms forwards,
            pl-orbit 7s linear 560ms infinite;
}

.preloader__burst{
  opacity:0;transform:scale(.42) rotate(-42deg);transform-origin:50% 50%;
  animation:pl-burst 1100ms var(--ease-out) forwards,
            pl-spin 30s linear 1100ms infinite;
}

.preloader__ring-track{stroke:var(--color-hairline)}
.preloader__ring-draw{
  stroke-dasharray:100;stroke-dashoffset:100;
  transform:rotate(-90deg);transform-origin:50% 50%;
  filter:drop-shadow(0 0 5px rgba(23,162,168,.55));
  animation:pl-draw 2900ms cubic-bezier(.55,0,.2,1) 260ms forwards;
}

.preloader__core{
  position:absolute;left:50%;top:50%;width:9px;height:9px;border-radius:50%;
  background:var(--color-teal-light);
  box-shadow:0 0 16px 3px rgba(111,214,201,.75);
  transform:translate(-50%,-50%) scale(0);
  animation:pl-core-in 800ms var(--ease-out) 680ms forwards,
            pl-core-pulse 2.6s ease-in-out 1500ms infinite;
}

/* ---- Wordmark: wipes in from the left, then a sheen sweeps across it. ---- */
.preloader__mark{position:relative;max-width:100%;overflow:hidden;line-height:0}
.preloader__mark img{
  display:block;width:min(66vw,300px);max-width:100%;height:auto;
  opacity:0;transform:translateY(14px);
  clip-path:inset(0 100% 0 0);
  animation:pl-mark 1200ms var(--ease-out) 420ms forwards;
}
.preloader__gleam{
  position:absolute;top:0;left:0;height:100%;width:55%;pointer-events:none;
  background:linear-gradient(100deg,transparent 0%,rgba(255,255,255,.42) 50%,transparent 100%);
  mix-blend-mode:screen;opacity:0;
  transform:translateX(-170%) skewX(-16deg);
  animation:pl-gleam 1600ms var(--ease-out) 1500ms forwards;
}

/* ---- Progress: a centre-out hairline + tabular percentage. ---- */
.preloader__progress{
  display:flex;flex-direction:column;align-items:center;gap:var(--sp-3);
  width:100%;
}
.preloader__meter{
  position:relative;width:min(58vw,244px);max-width:100%;height:1px;
  background:var(--color-hairline);overflow:hidden;
  opacity:0;animation:pl-fade 700ms var(--ease-out) 700ms forwards;
}
.preloader__bar{
  position:absolute;inset:0;
  background:var(--color-gradient);
  box-shadow:0 0 12px rgba(23,162,168,.65);
  transform:scaleX(0);transform-origin:center;
  animation:pl-meter 2900ms cubic-bezier(.55,0,.2,1) 260ms forwards;
}
.preloader__pct{
  font-family:var(--font-body);font-size:.62rem;
  letter-spacing:.32em;padding-left:.32em;
  color:var(--color-text-muted);font-variant-numeric:tabular-nums;
  opacity:0;animation:pl-fade 700ms var(--ease-out) 900ms forwards;
}
.preloader__pct::after{content:"%";opacity:.55}

/* ---- Exit: content lifts, halves part, the seam flashes. ---- */
.preloader.is-done{pointer-events:none}
.preloader.is-done .preloader__inner{animation:none;opacity:0;transform:translateY(-14px) scale(.982)}
.preloader.is-done .preloader__bg{animation:none;opacity:0;transition:opacity 260ms linear}
.preloader.is-done .preloader__panel--t{animation:pl-out-up 640ms cubic-bezier(.76,0,.24,1) forwards}
.preloader.is-done .preloader__panel--b{animation:pl-out-down 640ms cubic-bezier(.76,0,.24,1) forwards}
.preloader.is-done .preloader__seam{animation:pl-seam 640ms cubic-bezier(.76,0,.24,1) forwards}

@keyframes pl-bg-in{to{opacity:1}}
@keyframes pl-breathe{0%,100%{opacity:.9}50%{opacity:1}}
@keyframes pl-fade{to{opacity:1}}
@keyframes pl-fade-up{to{opacity:1;transform:translateY(0)}}
@keyframes pl-halo-in{to{opacity:1}}
@keyframes pl-halo-pulse{0%,100%{opacity:.7;transform:scale(.96)}50%{opacity:1;transform:scale(1.05)}}
@keyframes pl-orbit{from{transform:rotate(0)}to{transform:rotate(360deg)}}
@keyframes pl-burst{to{opacity:.9;transform:scale(.78) rotate(0deg)}}
@keyframes pl-spin{from{transform:scale(.78) rotate(0deg)}to{transform:scale(.78) rotate(360deg)}}
@keyframes pl-draw{to{stroke-dashoffset:0}}
@keyframes pl-core-in{to{transform:translate(-50%,-50%) scale(1)}}
@keyframes pl-core-pulse{0%,100%{transform:translate(-50%,-50%) scale(1);opacity:.85}50%{transform:translate(-50%,-50%) scale(1.5);opacity:1}}
@keyframes pl-mark{to{opacity:1;transform:translateY(0);clip-path:inset(0 0 0 0)}}
@keyframes pl-gleam{
  0%{transform:translateX(-170%) skewX(-16deg);opacity:0}
  22%{opacity:1}
  78%{opacity:1}
  100%{transform:translateX(240%) skewX(-16deg);opacity:0}
}
@keyframes pl-meter{to{transform:scaleX(1)}}
@keyframes pl-handoff{to{opacity:0;transform:translateY(-14px) scale(.982)}}
@keyframes pl-out-up{to{transform:translateY(-101%)}}
@keyframes pl-out-down{to{transform:translateY(101%)}}
@keyframes pl-seam{
  0%{opacity:0;transform:translateY(-50%) scaleX(.16)}
  26%{opacity:1}
  60%{opacity:1;transform:translateY(-50%) scaleX(1)}
  100%{opacity:0;transform:translateY(-50%) scaleX(1)}
}

/* Small screens: tighten the stack. */
@media (max-width:480px){
  .preloader__motif{width:120px;height:120px}
  .preloader__inner{gap:var(--sp-5)}
}

/* Low-power devices: drop the glow-heavy atmosphere and orbit, keep the core beats. */
html.perf-lite .preloader__bg{animation:pl-bg-in 1200ms var(--ease-out) forwards}
html.perf-lite .preloader__arc,
html.perf-lite .preloader__gleam{display:none}

/* Reduced motion / low power: skip the whole intro, show the page at once. */
@media (prefers-reduced-motion:reduce){
  .preloader{display:none!important}
  html.is-loading,html.is-loading body{overflow:visible}
}


/* ------------------------- 27. SCHEDULE-A-VISIT MODAL -------------------------
   Reuses .form / .field / .err from the enquiry card so the two stay in sync.
   ----------------------------------------------------------------------------- */
.modal{
  position:fixed;inset:0;z-index:var(--z-modal);
  display:flex;align-items:flex-start;justify-content:center;
  padding:var(--sp-4);
  padding-top:max(var(--sp-4),env(safe-area-inset-top));
  padding-bottom:max(var(--sp-6),env(safe-area-inset-bottom));
  overflow-y:auto;overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch;
}
.modal[hidden]{display:none}

.modal__backdrop{
  position:fixed;inset:0;
  background:rgba(6,10,11,.72);
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  opacity:0;transition:opacity var(--dur-mid) linear;
}
.modal.is-open .modal__backdrop{opacity:1}

.modal__dialog{
  position:relative;z-index:1;overflow:hidden;isolation:isolate;
  width:100%;max-width:560px;margin:auto;
  padding:var(--sp-6) var(--sp-5) var(--sp-5);
  background:
    radial-gradient(120% 82% at 50% -12%,rgba(23,162,168,.18),rgba(23,162,168,0) 60%),
    radial-gradient(96% 60% at 50% 116%,rgba(14,116,144,.16),rgba(14,116,144,0) 62%),
    linear-gradient(180deg,rgba(245,244,240,.055),rgba(245,244,240,0) 30%),
    #13181A;
  border:1px solid rgba(245,244,240,.16);border-radius:18px;
  box-shadow:
    0 60px 120px -50px rgba(0,0,0,.95),
    0 12px 30px -18px rgba(0,0,0,.6),
    inset 0 1px 0 rgba(245,244,240,.10),
    inset 0 -70px 110px -70px rgba(14,116,144,.24);
  opacity:0;transform:translateY(18px) scale(.985);
  transition:opacity var(--dur-mid) var(--ease-out),transform var(--dur-mid) var(--ease-out);
}
.modal.is-open .modal__dialog{opacity:1;transform:none}
/* Brand hairline across the top edge — inset from the corners exactly like the
   enquiry card (.form::before), so its ends land on the straight part of the edge. */
.modal__dialog::before{
  content:"";position:absolute;top:0;left:20px;right:20px;height:1px;z-index:3;
  background:var(--color-gradient);opacity:.85;
}
/* Faint rotating Niva sun, clipped into the top-right corner as a brand watermark */
.modal__sun{
  position:absolute;top:-46px;right:-46px;z-index:0;pointer-events:none;
  width:200px;height:200px;opacity:.05;
}

.modal__close{
  position:absolute;top:10px;right:10px;z-index:4;
  width:44px;height:44px;font-size:1.75rem;line-height:1;
  color:var(--color-text-muted);border-radius:50%;
  transition:color var(--dur-fast) linear,background-color var(--dur-fast) linear;
}
.modal__close:hover{color:var(--color-text-on-dark);background:rgba(245,244,240,.08)}
.modal__close:focus-visible{outline:2px solid var(--color-teal-mid);outline-offset:2px}

/* Keep the header and fields above the corner watermark */
.modal__head,.form--modal{position:relative;z-index:1}
.modal__head{
  margin-bottom:var(--sp-6);padding-right:var(--sp-7);padding-bottom:var(--sp-5);
  border-bottom:1px solid rgba(245,244,240,.09);
}
.modal__head .eyebrow{display:inline-flex;align-items:center;gap:.7em;margin-bottom:var(--sp-3)}
.modal__head .eyebrow__rule{
  width:clamp(22px,5vw,38px);height:1px;transform:scaleX(1);
  background:linear-gradient(90deg,rgba(111,214,201,0),var(--color-teal-light));
}
.modal__title{
  margin:var(--sp-2) 0 var(--sp-3);
  font-family:var(--font-display);font-weight:400;
  font-size:clamp(1.6rem,5.4vw,2.1rem);line-height:1.12;letter-spacing:-.01em;
}
.modal__sub{margin:0;font-size:.9rem;line-height:1.6;color:var(--color-text-muted)}

/* Read-only "Project" field — a small lock glyph confirms it is fixed */
.field--readonly{position:relative}
.field__lock{
  position:absolute;right:16px;bottom:20px;width:15px;height:15px;
  color:var(--color-teal-light);opacity:.5;pointer-events:none;
}

/* Inside the dialog the card chrome is redundant — flatten it. */
.form--modal{
  padding:0;background:none;border:0;border-radius:0;box-shadow:none;
  -webkit-backdrop-filter:none;backdrop-filter:none;overflow:visible;
}
.form--modal::before,.form--modal::after{display:none}
/* The perf-lite escape hatch repaints .form with an opaque glass background; its
   `html.perf-lite .form` selector out-specifies the flatten rule above and would
   otherwise bleed a grey panel behind the modal fields. Neutralise it here. */
html.perf-lite .form--modal{background:none}
/* Group the agreement + submit apart from the inputs with a hairline divider */
.form--modal .form__consent{
  padding-top:var(--sp-5);margin-top:var(--sp-2);
  border-top:1px solid rgba(245,244,240,.08);
}
/* Native date/time pickers render their indicator dark on dark otherwise. */
.form--modal input[type="date"]{min-height:48px}
.form--modal input[type="date"]::-webkit-calendar-picker-indicator{
  filter:invert(78%) sepia(38%) saturate(560%) hue-rotate(122deg) brightness(94%);
  cursor:pointer;
}

@media (min-width:560px){
  .form--modal{grid-template-columns:1fr 1fr}
  .modal__dialog{padding:var(--sp-7) var(--sp-6) var(--sp-6)}
}

@media (prefers-reduced-motion:reduce){
  .modal__dialog{opacity:1;transform:none}
  .modal__backdrop{opacity:1}
}


/* Residences moodstrip: on a phone the three stacked portraits eat most of the
   scroll, so the strip becomes a native swipe/scroll-snap card catalogue (same
   idiom as .week__rail) with every frame cropped to a landscape 3:2. It escapes
   the container gutters so the next card peeks in at the right edge. */
@media (max-width:767px){
  .moodstrip{
    display:flex;gap:var(--sp-3);
    margin:var(--sp-6) calc(var(--gutter) * -1) var(--sp-2);
    /* The rail scrolls, so overflow-y:hidden clips anything painted outside the
       padding box — with only 4px underneath, each card's drop shadow was sliced
       off mid-falloff, leaving a hard horizontal edge under the row. The shadow
       reaches ~14px below the frame (18px offset, −22px spread, 36px blur), so
       the bottom pad is opened to 24px to let it finish, and the strip's bottom
       margin gives up the same 24px so the gap to the next block is unchanged. */
    padding:var(--sp-1) var(--gutter) var(--sp-5);
    overflow-x:auto;overflow-y:hidden;
    scroll-snap-type:x mandatory;scroll-padding-inline:var(--gutter);
    -webkit-overflow-scrolling:touch;scrollbar-width:none;
  }
  .moodstrip::-webkit-scrollbar{display:none}
  .mood{
    flex:0 0 auto;width:calc(100vw - var(--gutter) * 2 - var(--sp-6));
    scroll-snap-align:start;
    box-shadow:0 18px 36px -22px rgba(0,0,0,.45);
  }
  .mood img{aspect-ratio:3/2}
  /* "Accent" is the only portrait source (455x682); a centred 3:2 crop cuts the
     chair in half, so bias the window downwards to keep it whole. */
  .mood:nth-child(2) img{object-position:center 76%}
  /* Cards 2–3 sit outside the viewport in the rail, so the reveal observer
     would hold them at opacity 0 until swiped in — showing an empty frame
     mid-swipe. In a horizontal rail the entrance animation is redundant. */
  .mood.reveal{opacity:1;transform:none;transition:none}
}

/* ============================================================================
   MOBILE-ONLY OVERRIDES (≤767px) — desktop/tablet layout untouched
   ========================================================================= */
@media (max-width:767px){
  /* Brochure CTA spans the full column width on phones */
  .echelons__cta{display:block}
  .echelons__brochure{
    display:flex;width:100%;justify-content:center;padding-inline:var(--sp-4);
  }
}

/* Developer heading: desktop keeps its two hand-set lines, phones use the
   three-line regroup. The [data-lines] script wraps each span in a .line mask
   and sets display:block inline, so the variant is switched at the mask. */
.developer .h2 .ln-m{display:none}
.developer .h2 .line:has(.ln-m){display:none}

@media (max-width:767px){
  .developer .h2{font-size:clamp(1.5rem,6.8vw,1.9rem);line-height:1.16}
  .developer .h2 .ln-d{display:none}
  .developer .h2 .line:has(.ln-d){display:none}
  .developer .h2 .line:has(.ln-m){display:block}
  .developer .h2 .ln-m{display:block}
  /* Ranged left, matching every other block in the phone reading column — the
     centred setting is a desktop-only treatment (the ≥1024px grid re-lefts it
     anyway, so this is the same alignment at both ends of the range). */
  .dev__head{text-align:left}
}

/* ---------------------------------------------------------------------------
   Enquiry / modal form — phone build (≤559px, i.e. before the 2-column split).
   The card ran ~770px tall on a 393px screen; this tightens every step of its
   vertical rhythm (card padding, header rule, label→input gap, control height)
   and folds the locked Project row onto one line, without touching the glass
   treatment that gives the card its character. Input font stays at 16px so iOS
   does not zoom the viewport on focus.
   ------------------------------------------------------------------------ */
@media (max-width:559px){
  .form{
    gap:13px;padding:20px 18px 22px;border-radius:20px;
  }
  .form::before{left:16px;right:16px}

  /* Header: the rule sits closer to the title and to the first field */
  .form__head{gap:4px;margin-bottom:0;padding-bottom:13px}
  .form__eyebrow{font-size:1.32rem}
  .form__eyebrow-rule{width:24px}

  /* Fields: micro-label hugs its control; controls lose 10px of height each */
  .field{gap:5px}
  .field__top{min-height:0}
  .field label{font-size:.62rem;letter-spacing:.13em}
  .field input,.field select{
    min-height:46px;padding:11px 15px;border-radius:12px;
  }

  /* Locked "Project" row folds to a single line — label left, value right —
     since it is confirmation, not an input to fill in. */
  #enquiry .field--readonly{
    grid-template-columns:auto minmax(0,1fr);align-items:center;gap:12px;
  }
  #enquiry .field--readonly input{min-height:42px;padding-block:9px;padding-right:38px}
  #enquiry .field--readonly .field__lock{
    right:14px;top:50%;bottom:auto;transform:translateY(-50%);
  }

  /* Active field lights its own label — the only cue left once the labels are
     this small, and it replaces the hover states a touch screen never gets. */
  .field:focus-within label{color:var(--color-teal-light)}

  /* Consent + action + fine print */
  .form__consent{gap:10px;font-size:.78rem;line-height:1.4}
  .form__submit{min-height:52px;margin-top:2px}
  .form__legal{font-size:.64rem;line-height:1.45}
}

/* ---------------------------------------------------------------------------
   Eyebrow → heading gap: 16px on desktop, 8px on phones so the label reads as
   part of the heading block rather than a line floating above it. Covers every
   eyebrow variant on the page — the plain/dark/centred/marked labels, the
   developer wordmark that plays the same role, and the modal head. Where the
   heading carries its own top margin the two collapse, so both are set.
   ------------------------------------------------------------------------ */
@media (max-width:767px){
  .eyebrow{margin-bottom:var(--sp-2)}
  .devmark{margin-bottom:var(--sp-2)}
  .modal__head .eyebrow{margin-bottom:var(--sp-2)}
  #residences .res__head .h2{margin-top:var(--sp-2)}
}

/* ==========================================================================
   MOBILE-ONLY OVERRIDES  (<=1023px)
   Desktop (>=1024px) never sees anything in this section.
   ========================================================================== */

@media (max-width:1023px){

  /* --- Nav: larger wordmark + larger burger ----------------------------- */
  /* The bar grows just enough to carry a 54px mark with the same breathing
     room it had at 36px. --nav-h also drives the hero's top padding. */
  :root{--nav-h:66px}
  .brand__logo{max-height:54px;max-width:230px}
  .burger{width:52px;height:52px;gap:6px}
  .burger span{height:2px}
  .burger span:nth-child(1),.burger span:nth-child(3){width:34px}
  .burger span:nth-child(2){width:26px}
  .burger[aria-expanded="true"] span:nth-child(1){width:34px;transform:translateY(8px) rotate(45deg)}
  .burger[aria-expanded="true"] span:nth-child(3){width:34px;transform:translateY(-8px) rotate(-45deg)}

  /* --- Hero art: whole frame, no crop ----------------------------------- */
  /* mobb is a portrait 1691x3119 composition. The hero is sized to that exact
     ratio and the image is contained inside it, so nothing is cut off and no
     letterbox bars appear. The -8% parallax bleed, the rAF parallax transform
     and the ken-burns scale all crop or expose an edge here, so all three are
     switched off — the JS writes an inline transform, hence !important. */
  .hero{min-height:calc(100vw * 1.84447)}
  .hero__media{inset:0;transform:none !important}
  .hero__media img{object-fit:contain;object-position:center center;animation:none;transform:none}

  /* --- Hero copy -------------------------------------------------------- */
  .hero .eyebrow--hero{display:none}
  .hero__body{transform:translateY(-70px)}
  /* Desktop keeps the hard break after "finest."; on a phone the sentence
     wraps to two lines on its own and the break makes an orphaned third. */
  .hero__sub-br{display:none}

  /* --- Buttons: uniform 44px ------------------------------------------- */
  /* Vertical padding is zeroed so min-height is the height, not a floor. */
  .btn{min-height:44px;padding-top:0;padding-bottom:0}
  .hero__cta .btn--primary{min-height:44px;padding:0 32px;font-size:.86rem}
  .form__submit{min-height:44px}
}

/* Footer bottom padding matches the top on phones. The extra 76px was reserved
   for a mobile sticky CTA bar that the page no longer carries, so it was just
   dead space under the RERA line. */
@media (max-width:767px){
  .footer{padding-block:var(--sp-6)}

  /* Stacked into one column, the three footer blocks ran ~645px — most of a
     screen of legal boilerplate. Every vertical step is taken down one notch on
     the spacing scale and the two long text blocks lose some leading; no font
     size, colour or horizontal measure changes, so it reads the same, just
     tighter. */
  .footer__grid{gap:var(--sp-4)}
  .footer__eyebrow{margin-bottom:var(--sp-3)}
  .footer__blurb{margin-bottom:var(--sp-4);line-height:1.5}
  .footer__badge{padding:9px 18px}
  /* The disclaimer alone was ~170px. Legal copy is set small and read once, so
     it carries tighter leading than body prose without becoming a wall. */
  .footer__disclaimer{margin-bottom:var(--sp-4);line-height:1.5}
  .footer__copy{margin-bottom:var(--sp-1)}
}

/* ---------------------------------------------------------------------------
   The Address — phone build. Stacked into one column the section ran ~1980px,
   and most of that was air: every block carried its own top margin *on top of*
   the grid's 28px row gap, so the four junctions measured 60 / 52 / 92px and the
   closing statement floated a screen away from the cards it summarises.

   The row gap becomes the single source of vertical spacing — each block's own
   margin is zeroed, so all three junctions land on a flat 16px. The map also
   loses its top fifth: the frame is a tall portrait and that band is upstream of
   the site, carrying nothing the reader needs.
   --------------------------------------------------------------------------- */
@media (max-width:767px){
  .address__grid{gap:var(--sp-4)}
  /* Zeroed so the grid gap alone sets each junction — otherwise these stack on
     top of it and the spacing doubles. */
  .map{margin-top:0}
  .amencards{margin-top:0}
  .address .quote{margin-top:0}

  /* Inside the header: the italic note and its gradient flourish had 32px above
     and below, which read as a section break rather than a closing line. */
  .vertical-note{
    margin-top:var(--sp-4);padding-bottom:var(--sp-4);
    /* One line, no wrap: at 1.2rem the sentence broke after "it", stranding
       "all." on a line of its own above the flourish. 4.45vw is the largest
       ramp that holds it on a single line across the phone range (checked
       320 → 430px); the 1.2rem cap keeps the original size once there is room. */
    font-size:min(4.45vw,1.2rem);
  }
  .address .lead{margin-top:var(--sp-4)}

  /* Crop the top 20% of the map. The panel already clips (overflow:hidden), so a
     negative top margin both hides the band and reclaims its height. The image is
     744x1257, so its rendered height is 1.6895x its width — 20% of that height is
     33.79% of the width, and percentage margins resolve against width. */
  .map__img{margin-top:-33.79%}
}

/* Final-CTA backdrop: the dusk tower is a 2:1 landscape plate and the section is
   roughly 393x877 on a phone, so object-fit:cover has to blow the frame up until
   its *height* fits — leaving barely a fifth of the tower's width in shot, which
   is why the building reads as an anonymous slab.

   Cover can never scale below "fills the box", so the only way to widen the crop
   is to hand the media a shorter box. It is anchored to the top of the section and
   masked out towards the bottom, where the frosted enquiry card already blurs
   whatever sits behind it — so the fade goes unnoticed and roughly twice as much of
   the frame survives. The section's own height, padding and rhythm are untouched;
   only the image's box changes.

   The paired html.perf-lite selector matches the specificity of the perf-lite
   escape hatch above, which would otherwise restore inset:0 and undo this. */
@media (max-width:767px){
  /* The media no longer reaches the bottom, so the section carries the base
     colour the scrim used to land on. */
  .cta{background:var(--color-bg-dark)}
  .cta__media,html.perf-lite .cta__media{
    inset:0 0 auto 0;height:56%;
    -webkit-mask-image:linear-gradient(180deg,#000 0%,#000 58%,transparent 100%);
            mask-image:linear-gradient(180deg,#000 0%,#000 58%,transparent 100%);
  }
}

/* ---------------------------------------------------------------------------
   Hero, phone build (≤767px). Two changes to the stack:
   1. The headline + sub-copy sit 25px higher than the old centred-and-nudged
      position. They are now anchored proportionally to the hero's own height
      (which is a fixed ratio of the viewport width, since the portrait artwork
      is contained, not cropped) so the copy keeps the same spot on the image at
      any phone width instead of drifting with a fixed pixel offset.
      34.9vw = the target top edge; the -90px removes the hero's top padding,
      which the margin is measured from.
   2. "Schedule a Visit" sits directly under the sub-copy, 20px below it, so
      the eyebrow-less stack reads as one block — headline, rule, promise,
      action — instead of a paragraph at the top and a button stranded at the
      foot of a 725px banner with 340px of artwork between them. The animated
      scroll cue is still dropped, so the frame carries one call to action.
   3. The whole block is tightened: the headline comes down from 40px, and the
      three steps between headline, rule, sub-copy and button each drop a notch
      on the spacing scale. Same copy, noticeably less height.
   ------------------------------------------------------------------------ */
@media (max-width:767px){
  .hero{
    justify-content:flex-start;
    padding-bottom:calc(28px + env(safe-area-inset-bottom));
  }
  .hero__body{
    flex:1 1 auto;min-height:0;display:flex;flex-direction:column;
    transform:none;                       /* replaces the -70px nudge */
  }
  .hero__copy{flex:1 1 auto;display:flex;flex-direction:column}
  /* 8.2vw tracks the phone range (≈29.5px at 360, 33px at 393, 35px at 430)
     and the 2.2rem ceiling holds it at the top of the range. Two lines either
     way, so the shape of the headline is unchanged — just smaller. */
  .hero .h1{font-size:clamp(1.8rem,8.2vw,2.2rem);margin-bottom:var(--sp-3)}
  /* -110px, not the -90px the anchor formula started at: the extra 20 lifts the
     whole block — headline, rule, sub-copy, button — twenty pixels up the
     banner, since everything under the headline is in normal flow behind it. */
  .hero__copy .h1{margin-top:max(0px,calc(34.9vw - 110px))}
  .hero__flourish{margin-bottom:var(--sp-3)}
  .hero__sub{margin-bottom:0;font-size:1rem;line-height:1.55}
  .hero__cta{margin-top:20px}

  /* --- Scrim: shade the copy, release the render ------------------------ */
  /* The base scrim is built for a cropped landscape frame: a copy pool across
     the middle, a full-frame vignette and a heavy 50–92% ramp. On phones the
     artwork is the whole portrait composition, contained rather than cropped,
     and all three of those land squarely on the towers — the render was sitting
     under a grey wash for its entire height.

     Replaced with a single top-down ramp that ends where the copy does. The
     button bottoms out at 43–50% of the hero across the phone range, so the
     shade is fully clear by 54% and every pixel of the building below it is the
     render at full contrast. The type keeps its own text-shadow, which is what
     was carrying its edge definition anyway.

     The last two stops are not a wash over the image: the hero's base has to
     meet the light section under it, and the artwork's own foliage is already
     near-black there, so a short seat at the very foot keeps that hand-off from
     turning into a hard line. */
  .hero__scrim{
    background:
      linear-gradient(180deg,
        rgba(4,11,13,.60) 0%,
        rgba(4,11,13,.50) 24%,
        rgba(4,11,13,.30) 40%,
        rgba(4,11,13,.09) 49%,
        transparent 54%,
        transparent 90%,
        rgba(11,18,20,.30) 100%);
  }

  /* The scroll cue and its pulsing hairline are gone on phones. */
  .scrollcue{display:none}
}

/* ===================== Honeypot + Form Success Popup (animated tick) ===================== */
.hp { position:absolute!important; left:-9999px!important; width:1px!important; height:1px!important; opacity:0!important; pointer-events:none; }

.success-pop { position: fixed; inset: 0; z-index: 4000; display: grid; place-items: center; padding: 24px; }
.success-pop[hidden] { display: none; }
.success-pop__backdrop { position: absolute; inset: 0; background: rgba(8,12,14,.72);
  -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); opacity: 0; transition: opacity .35s ease; }
.success-pop.is-open .success-pop__backdrop { opacity: 1; }
.success-pop__card { position: relative; z-index: 1; width: min(92vw, 400px); text-align: center;
  background: var(--color-bg-charcoal, #1C1F22); color: var(--color-text-on-dark, #F5F4F0);
  border: 1px solid rgba(111,214,201,.18); border-radius: 20px; padding: 40px 32px 32px;
  box-shadow: 0 30px 80px rgba(0,0,0,.5); transform: translateY(14px) scale(.96); opacity: 0;
  transition: transform .4s cubic-bezier(.22,1,.36,1), opacity .4s ease; }
.success-pop.is-open .success-pop__card { transform: none; opacity: 1; }
.success-pop__tick { width: 92px; height: 92px; margin: 0 auto 22px; border-radius: 50%;
  display: grid; place-items: center; background: rgba(23,162,168,.10); }
.success-pop__tick svg { width: 62px; height: 62px; }
.success-pop__circle { stroke: var(--color-teal-mid,#17A2A8); stroke-width: 2.5;
  stroke-dasharray: 151; stroke-dashoffset: 151; }
.success-pop__check { stroke: var(--color-teal-light,#6FD6C9); stroke-width: 3.5;
  stroke-linecap: round; stroke-linejoin: round; stroke-dasharray: 40; stroke-dashoffset: 40; }
.success-pop.is-open .success-pop__circle { animation: sp-circle .5s ease forwards .1s; }
.success-pop.is-open .success-pop__check  { animation: sp-check .35s ease forwards .5s; }
@keyframes sp-circle { to { stroke-dashoffset: 0; } }
@keyframes sp-check  { to { stroke-dashoffset: 0; } }
.success-pop__title { font-family: var(--font-display,serif); font-weight: 400; font-size: 1.7rem; margin: 0 0 8px; letter-spacing: -.01em; }
.success-pop__msg { font-family: var(--font-body,sans-serif); font-size: .98rem; opacity: .82; margin: 0 0 26px; }
.success-pop__btn { min-width: 140px; }
@media (prefers-reduced-motion: reduce) {
  .success-pop__circle, .success-pop__check { animation: none !important; stroke-dashoffset: 0 !important; }
  .success-pop__card, .success-pop__backdrop { transition: none; }
}
