/* ==========================================================================
   NOVA — private residences
   Palette: white and a cool grey, near-black charcoal, one bronze.
   Type:    Instrument Serif for display, Inter Tight for text and labels.
   Motion:  GSAP + ScrollTrigger own every animated transform. CSS never
            declares a transform on an element the script animates.
   ========================================================================== */

:root{
  --white:#FFFFFF;
  --mist:#F0F0F3;
  --stone:#E3E3E8;
  --char:#0E0E11;
  --ink:#17171A;
  --gray:#8B8B93;
  --bronze:#A8834F;
  --line:rgba(23,23,26,.16);
  --line-soft:rgba(23,23,26,.08);

  --pad:clamp(20px,4.4vw,72px);
  /* the hero sits on the page as an inset plate rather than bleeding to the
     window edge */
  --plate:clamp(10px,1.1vw,18px);
  --plate-r:0px;   /* square: every card and plate. One value flips it back. */
  --hero-r:clamp(14px,1.6vw,24px);  /* the hero plate keeps its corners */
  --ease:cubic-bezier(.22,.61,.24,1);
  --ease-out:cubic-bezier(.16,1,.3,1);

  /* Instrument Serif carries the display moments, Inter Tight everything else */
  --serif:"Instrument Serif",Georgia,serif;
  --sans:"Inter Tight",ui-sans-serif,system-ui,sans-serif;

  /* the unstuck bar: its padding twice over, plus the tallest thing in it */
  /* the pill row only: its top padding plus a pill. The bar is transparent,
     so this is the real bottom edge of the chrome. */
  --chrome-h:calc(clamp(14px,1.9vw,26px) + 39px);
  /* how far the footer rides up onto the closing plate */
  --foot-rise:clamp(80px,8vw,120px);
}

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

html{
  -webkit-text-size-adjust:100%;
  /* Lenis drives scrolling; a native smooth behaviour on top of it makes the
     page drift on its own. */
  scroll-behavior:auto;
}

body{
  margin:0;
  background:var(--mist);
  color:var(--ink);
  font:400 16px/1.65 var(--sans);
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}

body.is-locked{overflow:hidden}

img{display:block;max-width:100%;height:auto}
a{color:inherit;text-decoration:none}
button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer}
::selection{background:var(--bronze);color:var(--white)}

/* ---------- type primitives ---------------------------------------------- */

.display{
  font-family:var(--serif);
  font-weight:400;
  line-height:.98;
  letter-spacing:-.015em;
  margin:0;
}
.display em{font-style:italic;font-weight:400}

.eyebrow{
  margin:0;
  font-size:11px;
  letter-spacing:.34em;
  text-transform:uppercase;
  color:var(--bronze);
  font-weight:500;
}
.eyebrow em{font-style:normal;color:color-mix(in srgb,var(--bronze) 62%,transparent)}

.lede{
  margin:0;
  max-width:42ch;
  font-size:clamp(14px,1.12vw,17px);
  line-height:1.72;
  color:color-mix(in srgb,var(--ink) 74%,transparent);
}

/* masked line reveal — the <i> is what GSAP moves */
.ln{display:block;overflow:hidden;padding-bottom:.08em}
.ln > i{display:block;font-style:inherit}

/* ---------- the button. There is one. ----------------------------------- */

.btn{
  display:inline-flex;align-items:center;justify-content:center;
  padding:13px 26px;border-radius:999px;border:0;
  background:var(--ink);color:var(--white);
  font-size:11px;font-weight:500;letter-spacing:.24em;text-transform:uppercase;white-space:nowrap;
  transition:background .5s var(--ease),color .5s var(--ease),letter-spacing .6s var(--ease);
}
.btn:hover{background:var(--bronze);letter-spacing:.275em}
.btn[disabled]{opacity:.4;pointer-events:none}

/* two sizes of the same thing, and an icon-only round one for carousels */
.btn-sm{padding:10px 19px;font-size:11.5px}
.btn-wide{width:100%}
.btn-round{
  width:clamp(38px,3vw,46px);height:clamp(38px,3vw,46px);
  padding:0;border-radius:50%;
}
.btn-round svg{width:20px;height:8px;overflow:visible}
.btn-round svg path{fill:none;stroke:currentColor;stroke-width:1.2}

/* ==========================================================================
   cursor, rail, nav
   ========================================================================== */

.cursor{
  position:fixed;top:0;left:0;z-index:110;
  width:64px;height:64px;margin:-32px 0 0 -32px;
  pointer-events:none;
  display:grid;place-items:center;
  opacity:0;
  mix-blend-mode:difference;
}
.cursor-dot{
  width:7px;height:7px;border-radius:50%;background:var(--white);
  grid-area:1/1;
}
.cursor-label{
  grid-area:1/1;
  font-size:11px;letter-spacing:.24em;text-transform:uppercase;color:var(--white);
  opacity:0;white-space:nowrap;
}
.cursor-ring{
  grid-area:1/1;width:64px;height:64px;
  opacity:0;
}
.cursor-ring circle{fill:none;stroke:rgba(255,255,255,.55);stroke-width:1}
body.no-cursor .cursor{display:none}


/* ---------- navbar: pill links, centred mark, one phone pill ------------ */

.nav{
  position:fixed;top:0;left:0;right:0;z-index:80;
  display:grid;
  grid-template-columns:1fr auto auto;
  align-items:center;
  gap:20px;
  padding:clamp(14px,1.9vw,26px) clamp(16px,2.6vw,40px);
  color:var(--white);
  transition:color .6s var(--ease),padding .6s var(--ease),background-color .5s var(--ease);
}
/* No bar. The pills already carry their own glass, so a tinted, blurred
   strip on top of them only added a hard edge cutting across the page —
   on scroll the bar just tightens its padding and recolours. */
.nav.is-stuck{
  padding:10px clamp(16px,2.6vw,40px);
  color:var(--ink);
}
.nav.is-dark,.nav.is-stuck.is-dark{color:var(--white)}

/* every item in the bar is the same glass pill */
.nav-pill{
  display:inline-flex;align-items:center;gap:9px;
  padding:9px clamp(13px,1.1vw,19px);
  border:1px solid rgba(255,255,255,.26);
  border-radius:999px;
  background:rgba(255,255,255,.07);
  backdrop-filter:blur(10px);
  -webkit-backdrop-filter:blur(10px);
  font-size:11.5px;letter-spacing:.2em;text-transform:uppercase;white-space:nowrap;
  transition:background .5s var(--ease),border-color .5s var(--ease),color .5s var(--ease);
}
.nav-pill:hover{background:var(--white);border-color:var(--white);color:var(--ink)}
.nav.is-stuck .nav-pill{border-color:var(--line);background:rgba(23,23,26,.04)}
.nav.is-stuck .nav-pill:hover{background:var(--ink);border-color:var(--ink);color:var(--white)}
.nav.is-stuck.is-dark .nav-pill{border-color:rgba(255,255,255,.26);background:rgba(255,255,255,.07)}
.nav.is-stuck.is-dark .nav-pill:hover{background:var(--white);border-color:var(--white);color:var(--char)}

.nav-links{grid-column:1;display:flex;align-items:center;gap:clamp(5px,.5vw,9px);justify-self:start}

/* the lockup sits at the right edge; the burger, when it shows, to its left */
.nav-mark{grid-column:3;justify-self:end;display:grid;place-items:center}
/* Two prints of the supplied lockup: the white artwork vanishes on the light
   bar, so an ink remap of it fades in there instead. The height lives on the
   images — a height on the anchor leaves the grid row auto-sized by the
   artwork and the lockup renders at full size. */
.nav-logo{
  grid-area:1/1;display:block;
  filter:drop-shadow(0 1px 10px rgba(8,8,10,.30));
  height:clamp(21px,2.05vw,29px);width:auto;
  transition:opacity .55s var(--ease);
}
.nav-logo-ink{opacity:0}
.nav.is-stuck:not(.is-dark) .nav-logo-champagne{opacity:0}
.nav.is-stuck:not(.is-dark) .nav-logo-ink{opacity:1}

.nav-end{grid-column:2;display:flex;align-items:center;gap:14px;justify-self:end}

.nav-burger{display:none;width:26px;height:14px;position:relative}
.nav-burger i{position:absolute;left:0;right:0;height:1px;background:currentColor;transition:transform .6s var(--ease),opacity .4s}
.nav-burger i:first-child{top:2px}
.nav-burger i:last-child{bottom:2px}
body.menu-open .nav-burger i:first-child{transform:translateY(5px) rotate(15deg)}
body.menu-open .nav-burger i:last-child{transform:translateY(-5px) rotate(-15deg)}

@media (max-width:860px){
  /* the pill row folds into the burger, which sits left of the lockup */
  .nav-links{display:none}
  .nav-burger{display:block}
}

/* ---------- full-screen menu --------------------------------------------- */

.menu{
  position:fixed;inset:0;z-index:70;
  background:var(--char);
  color:var(--white);
  display:grid;
  grid-template-columns:1.1fr .9fr;
  align-items:center;
  padding:0 var(--pad);
  clip-path:inset(0 0 100% 0);
  visibility:hidden;
}
.menu-list{display:grid;gap:clamp(2px,.6vw,10px);padding-top:6vh}
.menu-list a{
  display:flex;align-items:baseline;gap:clamp(14px,2vw,34px);
  padding:clamp(6px,1vw,12px) 0;
  overflow:hidden;
}
.menu-no{font-size:11px;letter-spacing:.22em;color:var(--bronze)}
.menu-word{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(38px,6.4vw,92px);line-height:1.05;
  transition:opacity .6s var(--ease),transform .8s var(--ease);
}
.menu-list:hover .menu-word{opacity:.35}
.menu-list a:hover .menu-word{opacity:1;transform:translateX(18px)}
.menu-view{
  position:relative;aspect-ratio:3/4;width:min(34vw,420px);justify-self:end;
  overflow:hidden;
}
.menu-view img{width:100%;height:100%;object-fit:cover;opacity:.9}
.menu-foot{
  position:absolute;left:var(--pad);right:var(--pad);bottom:clamp(20px,3vh,38px);
  display:flex;flex-wrap:wrap;gap:clamp(14px,2.4vw,34px);
  font-size:11px;letter-spacing:.24em;text-transform:uppercase;color:rgba(255,255,255,.45);
}

@media (max-width:860px){
  /* one column: the list carries the menu, the preview plate is dropped */
  .menu{grid-template-columns:1fr;align-content:center;gap:30px}
  .menu-view{display:none}
}

/* ==========================================================================
   hero
   ========================================================================== */

.hero{
  position:relative;
  height:104svh;
  min-height:620px;
  overflow:hidden;
  color:var(--white);
  isolation:isolate;
}
/* The stage is a fixed layer, not a ScrollTrigger pin: the sections that
   follow carry their own opaque ground and rise over it, which is the whole
   "emerging from beneath" effect and costs no pin-spacer. */
.hero-stage{
  position:fixed;
  top:var(--plate);left:var(--plate);
  width:calc(100% - var(--plate) * 2);
  height:calc(100svh - var(--plate) * 2);
  overflow:hidden;perspective:1500px;z-index:0;
  border-radius:var(--hero-r);
  background:var(--char);
}
.hero.is-past .hero-stage{visibility:hidden}
.hero-frame{
  position:absolute;
  top:var(--plate);left:var(--plate);
  width:calc(100% - var(--plate) * 2);
  height:calc(100svh - var(--plate) * 2);
  z-index:2;
}
.hero-layer{position:absolute;overflow:hidden;will-change:transform}
.hero-layer img{width:100%;height:100%;object-fit:cover}

/* The photograph behind the words and the SAME photograph with the house cut
   out in front of them — identical geometry, so at rest they register exactly
   and the composite is just the original frame. They only come apart when
   something moves, and the blur on the rear plate turns that into depth
   rather than a doubled building. */
.hero-scene{inset:-6%;z-index:0}
.hero-scene img{object-fit:cover;object-position:50% 42%}
/* warm light gathered where the house will stand */
.hero-glow{
  position:absolute;left:50%;top:38%;width:120vw;height:70vh;translate:-50% -50%;
  z-index:0;pointer-events:none;
  background:radial-gradient(42% 48% at 50% 62%,rgba(255,196,122,.30),transparent 70%);
}
/* THE SANDWICH: the wordmark sits above the sky, below the house. SVG with
   textLength so it measures the plate exactly at any width. */
.hero-mark{
  position:absolute;left:clamp(14px,2.4vw,40px);right:clamp(14px,2.4vw,40px);
  /* measured off the bottom of the pill row, and the plate inset taken
     back out, because this sits inside the plate rather than on the page */
  top:calc(var(--chrome-h) - var(--plate) + clamp(18px,3.2vh,50px));
  z-index:1;margin:0;line-height:0;
}
.hero-mark svg{display:block;width:100%;height:auto;overflow:visible}
/* The scroll timeline scales .hero-mark (to .94) while it moves. Scaling SVG
   text makes the browser re-rasterise the glyphs every frame, which reads as
   a flicker on the wordmark. Promoting it to its own layer and fixing the
   backface stops the re-raster; the glyph edges then just resample. */
.hero-mark{will-change:transform;backface-visibility:hidden;-webkit-backface-visibility:hidden;transform-style:flat}
.hero-mark svg{shape-rendering:geometricPrecision}
.hero-mark text{
  font-family:var(--serif);
  font-weight:400;font-size:280px;
  fill:var(--white);
  paint-order:stroke;
}
@media (max-height:780px){
  /* the house is sized off the stage height: on a short window it reaches
     further up, so the wordmark moves out of its way */
}
.sr-only{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0;
}
/* the house, cut out of its own photograph, in front of the words */
/* the same frame, registered exactly over the plate behind it: at rest the
   two are one photograph, and the wordmark is simply inside it. The extra
   2% keeps the twin covered while the planes drift apart. */
/* the plate is an empty site, so the cut-out just stands on the plinth —
   no registration, and the planes are free to move at their own speeds */
/* Planted on the bottom edge of the hero, sized off the STAGE HEIGHT so a
   short window cannot blow it up.

   The centring and the 9.8% push-down (the empty canvas under the building
   in the PNG) live on the IMG, not on the layer: GSAP takes ownership of an
   element's transform by wiping the CSS `translate` property and baking its
   percentages into pixels, which then go stale on the next resize and slide
   the house off-centre. GSAP animates the layer; the img keeps its own
   transform and stays correct at every width. */
.hero-house{
  position:absolute;inset:0;z-index:2;overflow:visible;
  transform-origin:50% 100%;   /* any scale grows from the ground */
}
.hero-house img{
  position:absolute;left:50%;bottom:0;
  height:126%;width:auto;
  aspect-ratio:1521 / 1034;
  transform:translate(-50%, 20.5%);
  object-fit:fill;
  filter:drop-shadow(0 26px 44px rgba(8,8,10,.34));
}
/* no strip in front of the house: it cut across the base and read as a gap */
.hero-grass{display:none}
.hero-grass img{
  object-position:50% 100%;
  -webkit-mask-image:linear-gradient(180deg,transparent 0,#000 58%);
  mask-image:linear-gradient(180deg,transparent 0,#000 58%);
}
/* a pool of shade under the copy only — never a veil over the whole frame */
.hero-shade{
  position:absolute;inset:0;pointer-events:none;z-index:4;
  background:
    radial-gradient(70% 52% at 22% 84%,rgba(10,10,12,.72),transparent 72%),
    linear-gradient(180deg,rgba(10,10,12,.42),transparent 22%),
    /* seats the house: the bottom crop reads as shadow, not as a cut */
    linear-gradient(0deg,rgba(10,10,12,.84),rgba(10,10,12,.46) 11%,rgba(10,10,12,.16) 20%,transparent 30%);
}

/* ---------- hero interface: corners, cards, pill ------------------------ */


.hn-statement{
  position:absolute;left:clamp(24px,3.4vw,58px);bottom:clamp(38px,6vh,70px);z-index:2;
  margin:0;max-width:34ch;
  font-size:clamp(14px,1.05vw,16px);line-height:1.72;
  color:rgba(255,255,255,.86);
  text-shadow:0 1px 20px rgba(8,8,10,.7);
}


/* the pill is also the hover-to-explore control: a fill sweeps across it
   while the pointer rests, then the page moves on its own */
/* the hero's is the same pill in reverse: ivory on the photograph, with a
   hairline so it keeps an edge where the sky behind it goes pale */
.hn-pill{
  position:absolute;right:clamp(24px,3.4vw,58px);bottom:clamp(30px,5.2vh,62px);z-index:3;
  background:var(--white);color:var(--ink);
  border:1px solid rgba(23,23,26,.16);
  box-shadow:0 18px 50px rgba(10,8,14,.34);
  transition:background .5s var(--ease),color .5s var(--ease),
             border-color .5s var(--ease),letter-spacing .6s var(--ease);
}
.hn-pill:hover{background:var(--bronze);color:var(--white);border-color:var(--bronze)}

/* The statement sits bottom-left and the pill bottom-right. There is not
   room for both on one line on a phone, and they overlapped — so the pill
   drops to the left edge and the statement lifts clear above it. */
@media (max-width:620px){
  .hn-pill{left:clamp(20px,5vw,58px);right:auto}
  .hn-statement{
    left:clamp(20px,5vw,58px);right:clamp(20px,5vw,58px);
    max-width:none;
    bottom:calc(clamp(30px,5.2vh,62px) + 64px);
  }
}

/* the wordmark is redundant with the nav lockup while the hero is on screen */
/* the mark is a monogram now, not a second wordmark, so it stays visible
   over the hero instead of fading in on scroll */

/* ==========================================================================
   about — a tag on the left, the sentence held to the right, three rows
   under it on the same two columns. The first section after the hero, so
   it needs the background and the z-index that cover the fixed plate.
   ========================================================================== */

.about{
  position:relative;z-index:2;background:var(--mist);
  display:grid;
  grid-template-columns:1fr 1.06fr;
  column-gap:clamp(24px,5vw,80px);
  row-gap:clamp(56px,9vh,120px);
  padding:clamp(96px,16vh,190px) var(--pad) clamp(80px,13vh,150px);
}
.ab-tag{margin:0;align-self:start}

.ab-say{
  grid-column:2;margin:0;
  font-size:clamp(28px,3.5vw,58px);
  line-height:1.16;letter-spacing:-.01em;
  text-wrap:balance;
}
/* the word spans the script builds; dim until the scroll fills them in */
.ab-say .w{opacity:.2}
.ab-say .ab-tail{display:inline}

.ab-rows{grid-column:1/-1;margin:0;display:grid}
.ab-row{
  display:grid;grid-template-columns:1fr 1.06fr;
  column-gap:clamp(24px,5vw,80px);align-items:start;
  padding:clamp(20px,3.2vh,34px) 0;
  border-top:1px solid var(--line-soft);
}
.ab-row:last-child{border-bottom:1px solid var(--line-soft)}
.ab-row dt{
  font-family:var(--serif);
  font-size:clamp(19px,1.8vw,28px);font-weight:400;letter-spacing:-.005em;
}
.ab-row dd{
  margin:0;max-width:52ch;
  font-size:15px;line-height:1.78;
  color:color-mix(in srgb,var(--ink) 58%,transparent);
}

/* ==========================================================================
   gallery
   ========================================================================== */

.sec-head{
  display:grid;gap:18px;
  padding:clamp(90px,15vh,170px) var(--pad) clamp(34px,6vh,72px);
  grid-template-columns:1fr;
  max-width:1680px;margin:0 auto;
}
.sec-note{margin:0;max-width:52ch;font-size:14px;line-height:1.8;color:color-mix(in srgb,var(--ink) 62%,transparent)}

.gallery{position:relative;z-index:2;background:var(--mist)}
.gal{
  display:grid;
  grid-template-columns:repeat(12,1fr);
  gap:clamp(14px,2.2vw,34px) clamp(14px,2vw,28px);
  padding:0 var(--pad) clamp(80px,14vh,170px);
  max-width:1680px;margin:0 auto;
}
.gal-item{position:relative;margin:0;cursor:pointer}
.gal-mask{display:block;position:relative;overflow:hidden;border-radius:var(--plate-r);background:var(--stone)}
.gal-mask img{width:100%;height:100%;object-fit:cover}
/* the caption is part of the plate, not a hover reveal: it stays readable
   and only firms up in colour when you are on the picture */
.gal-item figcaption{
  display:flex;gap:14px;padding-top:12px;
  font-size:11px;letter-spacing:.22em;text-transform:uppercase;color:var(--gray);
  transition:color .6s var(--ease);
}
.gal-item figcaption span:first-child{color:var(--bronze)}
.gal-item:hover figcaption{color:var(--ink)}

.g1{grid-column:1/8}      .g1 .gal-mask{aspect-ratio:16/9}
.g2{grid-column:9/13;align-self:end}  .g2 .gal-mask{aspect-ratio:3/4}
.g3{grid-column:2/9;margin-top:clamp(10px,5vh,60px)} .g3 .gal-mask{aspect-ratio:16/10}
.g4{grid-column:10/13;align-self:center} .g4 .gal-mask{aspect-ratio:5/4}
.g5{grid-column:1/6}      .g5 .gal-mask{aspect-ratio:4/3}
.g6{grid-column:6/13;margin-top:clamp(10px,7vh,90px)} .g6 .gal-mask{aspect-ratio:16/9}

/* The spans above are a twelve-column composition and they do not survive a
   phone: at 375px they gave frames of 190, 131 and 73px and cut a caption
   off the screen. Below these widths the grid is abandoned for plain
   columns; each frame keeps its own aspect ratio so the rhythm survives. */
@media (max-width:860px){
  .gal{grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(14px,2.6vw,26px)}
  .g1,.g2,.g3,.g4,.g5,.g6{grid-column:auto;margin-top:0;align-self:auto}
}
@media (max-width:600px){
  .gal{grid-template-columns:minmax(0,1fr)}
}

/* ==========================================================================
   horizontal journey
   ========================================================================== */

.journey{position:relative;background:var(--white)}
/* head and track are rows, not an absolute overlay: a tall card used to
   rise up and paint straight over the heading */
.jr-pin{
  position:relative;height:100svh;overflow:hidden;
  display:grid;grid-template-rows:auto minmax(0,1fr);
  /* the track is far wider than the pin; without a capped column the grid
     stretches to it and carries the heading row off the right of the screen */
  grid-template-columns:minmax(0,1fr);
  gap:clamp(18px,3.4vh,40px);
  padding:clamp(74px,11vh,124px) 0 clamp(36px,6vh,72px);
}
.jr-head{
  padding:0 var(--pad);
  display:flex;align-items:center;justify-content:space-between;gap:20px;
}
.jr-title{font-size:clamp(24px,3vw,48px)}

.jr-track{display:flex;width:max-content;height:100%;gap:clamp(14px,1.8vw,28px);padding:0 var(--pad);will-change:transform}

/* each residence is a rounded plate with its name and file laid over it */
.jr-card{
  position:relative;flex:0 0 auto;display:block;overflow:hidden;
  width:clamp(260px,42vw,600px);height:100%;
  max-height:clamp(380px,62vh,620px);align-self:center;
  border-radius:var(--plate-r);
  background:#cfc7b9;
}
.jr-shot{position:absolute;inset:0;display:block;overflow:hidden}
/* GSAP owns the x on this image, so it is given headroom on both sides and
   the offset lives on left, never on transform */
.jr-shot img{position:absolute;top:0;left:-9%;width:118%;max-width:none;height:100%;object-fit:cover}
.jr-veil{
  position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,transparent 36%,rgba(8,8,10,.30) 58%,rgba(8,8,10,.78) 88%,rgba(8,8,10,.82));
}
.jr-copy{
  position:absolute;left:clamp(18px,2vw,30px);right:clamp(18px,2vw,30px);
  bottom:clamp(16px,2vh,26px);
  display:grid;gap:clamp(9px,1.2vh,14px);color:var(--white);
}
.jr-name{
  margin:0;font-family:var(--serif);font-weight:400;
  font-size:clamp(21px,2.3vw,34px);line-height:1.1;letter-spacing:-.01em;
  text-shadow:0 1px 18px rgba(8,8,10,.4);
  transition:transform .8s var(--ease);
}
.jr-card:hover .jr-name{transform:translateX(7px)}
.jr-meta{
  list-style:none;margin:0;padding:0;
  display:flex;flex-wrap:wrap;gap:6px clamp(12px,1.5vw,22px);
}
.jr-meta li{
  display:inline-flex;align-items:center;gap:7px;
  font-size:11.5px;color:rgba(255,255,255,.82);white-space:nowrap;
}
.jr-meta svg{
  width:14px;height:14px;flex:0 0 auto;
  fill:none;stroke:rgba(255,255,255,.66);stroke-width:1.1;
  stroke-linecap:round;stroke-linejoin:round;
}

@media (max-width:860px){
  .jr-head{flex-direction:column;align-items:flex-start;gap:14px}
  .jr-card{width:clamp(240px,78vw,420px);max-height:none}
}

/* ==========================================================================
   type / image composition
   ========================================================================== */

/* ==========================================================================
   depth scene
   ========================================================================== */

.depth{position:relative;height:210svh;background:#0C0C0D;color:var(--white)}
.dp-stage{
  position:relative;height:100svh;overflow:hidden;
  background:linear-gradient(180deg,#14151A,#0C0C0D);
}
.dp-layer{position:absolute;left:-6%;right:-6%;display:block;overflow:hidden;will-change:transform}
.dp-layer img{width:100%;height:100%;object-fit:cover}
/* the three bands are cut from one plate; feathering the seams is what makes
   them read as distance rather than as three photographs */
.dp-far{top:-6%;height:54%;-webkit-mask-image:linear-gradient(180deg,#000 62%,transparent);mask-image:linear-gradient(180deg,#000 62%,transparent)}
.dp-far img{filter:saturate(.9) brightness(.86)}
.dp-mid{top:24%;height:56%;-webkit-mask-image:linear-gradient(180deg,transparent,#000 22%,#000 74%,transparent);mask-image:linear-gradient(180deg,transparent,#000 22%,#000 74%,transparent)}
.dp-mid img{filter:saturate(1.02)}
.dp-near{bottom:-14%;height:50%;-webkit-mask-image:linear-gradient(180deg,transparent,#000 34%);mask-image:linear-gradient(180deg,transparent,#000 34%)}
.dp-near img{filter:brightness(.72) saturate(.92)}
.dp-layer::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,rgba(12,12,13,.55),transparent 22%,transparent 72%,rgba(12,12,13,.72));
}
.dp-type{
  position:absolute;left:0;right:0;text-align:center;
  font-family:var(--serif);font-weight:400;
  font-size:clamp(64px,13.5vw,220px);line-height:.9;letter-spacing:-.02em;
  will-change:transform;
}
.dp-type-back{top:16%;color:rgba(255,255,255,.9)}
.dp-type-front{top:46%;color:var(--white);text-shadow:0 2px 40px rgba(0,0,0,.45)}
.dp-type-front em{font-style:italic;color:var(--bronze)}
.dp-note{
  position:absolute;left:var(--pad);bottom:clamp(44px,8vh,90px);z-index:3;
  display:grid;gap:10px;max-width:min(42vw,460px);
  text-shadow:0 1px 20px rgba(0,0,0,.6);
}
.dp-note .k{font-size:11px;letter-spacing:.3em;text-transform:uppercase;color:var(--bronze)}
.dp-note .k em{font-style:normal;color:rgba(255,255,255,.5)}
.dp-note .v{font-size:15px;line-height:1.78;color:rgba(255,255,255,.74)}


/* ==========================================================================
   the film — a pinned stage, WebGL over a still fallback
   ========================================================================== */

.film{position:relative;height:460svh;background:var(--char)}
.fl-stage{
  position:relative;height:100svh;overflow:hidden;
  background:var(--char);color:var(--white);
}
/* five plates in one cell; the frame in play is the one at opacity 1 */
.fl-shot{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;
  opacity:0;transition:opacity .9s var(--ease);
}
.fl-shot.is-on{opacity:1}
.fl-shade{
  position:absolute;inset:0;pointer-events:none;
  background:
    linear-gradient(180deg,rgba(8,8,10,.6),transparent 26%),
    linear-gradient(0deg,rgba(8,8,10,.72),transparent 40%);
}
.fl-head{position:absolute;left:var(--pad);top:clamp(88px,14vh,150px);z-index:2}

/* the five captions share one grid cell and cross-fade in place */
.fl-caps{
  position:absolute;left:var(--pad);bottom:clamp(74px,12vh,130px);z-index:2;
  display:grid;
}
.fl-cap{
  grid-area:1/1;margin:0;display:grid;gap:10px;
  opacity:0;transform:translateY(14px);
  transition:opacity .7s var(--ease),transform .9s var(--ease);
  text-shadow:0 1px 22px rgba(8,8,10,.6);
}
.fl-cap.is-on{opacity:1;transform:none}
.fl-cap .k{font-size:11px;letter-spacing:.32em;text-transform:uppercase;color:var(--bronze)}
.fl-cap .v{font-family:var(--serif);font-size:clamp(28px,4.4vw,74px);line-height:1.04}

.fl-bar{
  position:absolute;left:var(--pad);right:var(--pad);bottom:clamp(38px,6vh,64px);z-index:2;
  height:1px;background:rgba(255,255,255,.2);
}
.fl-bar i{display:block;height:100%;background:var(--white);transform-origin:left;transform:scaleX(0)}

@media (max-width:860px){
  .film{height:420svh}
  .depth{height:180svh}
  .dp-note{max-width:none;right:var(--pad);bottom:clamp(22px,4vh,44px)}
  .dp-note .v{font-size:13px;line-height:1.7}
  .dp-type{font-size:clamp(44px,15vw,120px)}
  .dp-type-back{top:14%}
  .dp-type-front{top:40%}
  .fl-cap .v{font-size:clamp(28px,8vw,44px)}
}

@media (prefers-reduced-motion:reduce){
  .film,.depth{height:auto}
  .fl-stage{height:auto;min-height:100svh}
  .fl-caps{position:static;padding:clamp(120px,20vh,220px) 0 0}
  .fl-cap{grid-area:auto;opacity:1;margin-bottom:26px}
  .dp-stage{height:auto;min-height:100svh}
}

/* ==========================================================================
   selected residences — alternating plates that bleed off the page
   ========================================================================== */

.index{position:relative;background:var(--mist);padding-bottom:clamp(90px,15vh,180px);overflow:hidden}

.rx{display:grid;gap:clamp(76px,12vh,150px);padding:0 var(--pad)}
.rx-link{
  display:grid;grid-template-columns:1.22fr .78fr;
  gap:clamp(24px,4vw,72px);align-items:center;
}
/* the plate runs off its own edge of the page; the sides alternate so the
   eye crosses the measure on the way down */
.rx-frame{
  position:relative;margin:0;overflow:hidden;
  aspect-ratio:16/10;background:var(--stone);
  margin-left:calc(var(--pad) * -1);
  /* it runs off one edge, so only the corners still on the page are rounded */
  border-radius:0 var(--plate-r) var(--plate-r) 0;
}
.rx-item:nth-child(even) .rx-link{grid-template-columns:.78fr 1.22fr}
.rx-item:nth-child(even) .rx-frame{order:2;margin-left:0;margin-right:calc(var(--pad) * -1);border-radius:var(--plate-r) 0 0 var(--plate-r)}
.rx-item:nth-child(even) .rx-body{order:1}

/* GSAP owns yPercent on the img, so the hover push lives on the span around
   it — two transforms on one element would fight */
.rx-shot{position:absolute;inset:0;display:block;transition:transform 1.1s var(--ease)}
.rx-shot img{position:absolute;left:0;top:-9%;width:100%;height:118%;object-fit:cover}
.rx-link:hover .rx-shot{transform:scale(1.035)}

.rx-body{display:grid;gap:clamp(14px,2vh,24px);justify-items:start}
.rx-no em{font-style:normal;color:var(--bronze)}
.rx-name{
  font-size:clamp(30px,3.5vw,62px);
  transition:transform .8s var(--ease);
}
.rx-link:hover .rx-name{transform:translateX(9px)}

.rx-file{margin:0;width:100%;max-width:38ch;display:grid}
.rx-file div{
  display:flex;justify-content:space-between;align-items:baseline;gap:18px;
  padding:11px 0;border-top:1px solid var(--line-soft);
}
.rx-file div:last-child{border-bottom:1px solid var(--line-soft)}
.rx-file dt{font-size:11.5px;letter-spacing:.24em;text-transform:uppercase;color:var(--gray)}
.rx-file dd{
  margin:0;font-family:var(--serif);
  font-size:clamp(15px,1.3vw,21px);letter-spacing:.02em;
}

.rx-link:hover .rx-go > span::after{right:0}
.rx-link:hover .rx-go svg{transform:translateX(7px)}

@media (max-width:860px){
  /* one column, and the plate bleeds off both edges instead of one */
  .rx{gap:clamp(54px,9vh,90px)}
  .rx-link,.rx-item:nth-child(even) .rx-link{grid-template-columns:1fr;gap:clamp(18px,3vh,28px)}
  .rx-frame,.rx-item:nth-child(even) .rx-frame{
    order:0;aspect-ratio:4/3;border-radius:0;
    margin-left:calc(var(--pad) * -1);margin-right:calc(var(--pad) * -1);
  }
  .rx-item:nth-child(even) .rx-body{order:0}
  .rx-file{max-width:none}
}

/* ==========================================================================
   what owners say — a bled rail of tall cards, text and portrait alternating
   ========================================================================== */

.say{
  position:relative;background:var(--mist);color:var(--ink);
  display:grid;gap:clamp(26px,4.2vh,48px);
  padding:clamp(80px,14vh,170px) var(--pad);
}
.sy-head{display:grid;gap:clamp(9px,1.5vh,16px);justify-items:center;text-align:center}
.sy-title{font-size:clamp(30px,4.2vw,68px)}

/* The rail runs past the page gutter on both sides, so cards are always cut
   by the window rather than stopping politely inside the column. The snap
   port is inset by the gutter to match the first card — without that the row
   can never rest at its own start. */
.sy-rail{
  display:flex;gap:clamp(13px,1.3vw,20px);
  margin:0 calc(var(--pad) * -1);padding:4px 0;
  overflow-x:auto;overscroll-behavior-x:contain;
  scroll-snap-type:x mandatory;scroll-behavior:smooth;
  scroll-padding-left:var(--pad);
  scrollbar-width:none;-ms-overflow-style:none;
}
.sy-rail::-webkit-scrollbar{display:none}

.sy-card{
  flex:0 0 clamp(236px,25vw,320px);
  height:clamp(360px,44vh,460px);
  scroll-snap-align:start;
  margin:0;overflow:hidden;
  border-radius:var(--plate-r);
}
.sy-card:first-child{margin-left:var(--pad)}
.sy-card:last-child{margin-right:var(--pad)}

/* -- the written ones: a line at the top, the quote settled at the foot --- */
.sy-text{
  display:grid;
  grid-template-columns:minmax(0,1fr);
  grid-template-rows:auto minmax(0,1fr) auto;
  gap:clamp(13px,1.6vh,18px);
  padding:clamp(22px,2vw,32px);
  background:var(--white);
}
.sy-h{
  grid-column:1;grid-row:1;margin:0;
  font-family:var(--serif);font-weight:400;
  font-size:clamp(20px,1.9vw,29px);line-height:1.08;letter-spacing:-.01em;
}
.sy-quote{
  grid-column:1/-1;grid-row:2;align-self:end;margin:0;
  font-size:clamp(13.5px,1.02vw,15px);line-height:1.68;
  color:color-mix(in srgb,var(--ink) 74%,transparent);
}
.sy-by{
  grid-column:1/-1;grid-row:3;
  display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  padding-top:clamp(11px,1.3vh,15px);border-top:1px solid var(--line-soft);
}
.sy-who{font-size:13.5px;font-weight:500}
.sy-place{
  display:inline-flex;align-items:center;gap:5px;
  font-size:12.5px;color:color-mix(in srgb,var(--ink) 58%,transparent);
}
.sy-place svg{width:10px;height:12px;flex:0 0 auto;fill:none;stroke:currentColor;stroke-width:1.3}

/* -- the photographed ones: the name sits on the picture ----------------- */
.sy-photo{position:relative;background:var(--stone)}
.sy-photo img{width:100%;height:100%;object-fit:cover;object-position:50% 25%}
.sy-photo .sy-by{
  position:absolute;left:0;right:0;bottom:0;
  padding:clamp(18px,2vw,26px);border-top:0;color:var(--white);
  background:linear-gradient(to top,rgba(8,8,10,.74),rgba(8,8,10,.28) 52%,rgba(8,8,10,0));
}
.sy-photo .sy-place{color:rgba(255,255,255,.74)}

/* -- where you are in the row -------------------------------------------- */
.sy-dots{display:flex;justify-content:center;align-items:center;gap:8px}
.sy-dot{
  width:7px;height:7px;padding:0;border-radius:999px;
  background:color-mix(in srgb,var(--ink) 17%,transparent);
  transition:background .45s var(--ease),width .45s var(--ease);
}
.sy-dot.is-on{width:24px;background:var(--ink)}

@media (max-width:760px){
  .sy-card{flex-basis:min(74vw,300px);height:min(78vw,400px)}
}

/* ==========================================================================
   second CTA + footer — the reference composition, in Nova's palette:
   a soft limestone-to-ivory wash, centred type, a pill, and the house
   standing on the gradient with its sky cut away
   ========================================================================== */

.cta2{
  position:relative;overflow:hidden;
  background:var(--white);
  display:grid;justify-items:center;
  padding:clamp(80px,14vh,170px) var(--pad) 0;
  z-index:0;
}
.c2-copy{display:grid;justify-items:center;gap:clamp(16px,2.6vh,26px);text-align:center}
.c2-title{font-size:clamp(32px,5vw,86px);line-height:1.04}
.c2-lede{
  margin:0;max-width:44ch;
  font-size:15px;line-height:1.78;
  color:color-mix(in srgb,var(--ink) 58%,transparent);
}

/* the house stands on the wash, edge to edge: the negative inline margins
   cancel the section padding so the plate reaches the window on both sides */
.c2-shot{
  margin:clamp(34px,6vh,70px) calc(var(--pad) * -1) 0;
  justify-self:stretch;width:auto;
}
.c2-shot img{width:100%;height:auto;display:block}

/* the scene keeps going behind the footer: the plate fades out into ivory
   and the footer rides up onto that fade, so the two read as one picture */
.c2-fade{
  position:absolute;left:0;right:0;bottom:0;z-index:1;pointer-events:none;
  height:calc(var(--foot-rise) + clamp(90px,8vw,130px));
  /* solid ivory by the exact line the footer starts on, so every word in it
     sits on a clean field; above that it tapers off over the plate */
  background:linear-gradient(180deg,transparent,var(--white) calc(100% - var(--foot-rise)));
}
.c2-copy{position:relative;z-index:2}

.foot2{
  position:relative;z-index:2;background:transparent;color:var(--ink);
  /* the top of the footer overlaps the fade and must stay see-through;
     everything below the closing section paints its own ivory */
  margin-top:calc(var(--foot-rise) * -1);
  display:grid;gap:clamp(20px,3.4vh,34px);
  padding:clamp(28px,5vh,60px) var(--pad) clamp(20px,3vh,30px);
}
.foot2::before{
  content:'';position:absolute;z-index:-1;
  left:0;right:0;top:var(--foot-rise);bottom:0;
  background:var(--white);
}
.f2-top{
  display:grid;grid-template-columns:1fr auto;
  gap:clamp(20px,4vw,60px);align-items:center;
}
.f2-say{display:grid;gap:7px}
.f2-title{
  margin:0;font-family:var(--serif);font-weight:400;
  font-size:clamp(24px,2.6vw,40px);line-height:1.1;letter-spacing:-.01em;
}
.f2-note{margin:0;font-size:13.5px;color:color-mix(in srgb,var(--ink) 62%,transparent)}

.f2-form{
  display:flex;align-items:center;gap:8px;
  padding:6px 6px 6px 20px;border-radius:999px;
  background:color-mix(in srgb,var(--stone) 70%,transparent);
  border:1px solid var(--line-soft);
  transition:border-color .5s var(--ease);
}
.f2-form:focus-within{border-color:var(--bronze)}
.f2-form input{
  width:min(220px,40vw);background:transparent;border:0;outline:none;
  font:400 12.5px/1.6 var(--sans);color:var(--ink);
}
.f2-form input::placeholder{color:color-mix(in srgb,var(--ink) 42%,transparent)}
.f2-msg{margin:0;font-size:11px;color:var(--bronze);min-height:0}
.f2-msg:empty{display:none}

.f2-base{
  display:grid;grid-template-columns:1fr auto 1fr;align-items:center;gap:16px;
  padding-top:clamp(16px,2.6vh,26px);border-top:1px solid var(--line-soft);
  font-size:11.5px;letter-spacing:.18em;text-transform:uppercase;
  color:color-mix(in srgb,var(--ink) 62%,transparent);
}
.f2-mark{justify-self:center;display:block;height:21px}
.f2-mark img{height:100%;width:auto;opacity:.75;transition:opacity .5s var(--ease)}
.f2-mark:hover img{opacity:1}
.f2-links{justify-self:end;display:flex;gap:clamp(12px,1.8vw,26px)}
.f2-links a{transition:color .4s var(--ease)}
.f2-links a:hover{color:var(--ink)}

@media (max-width:860px){
  .f2-top{grid-template-columns:1fr;gap:clamp(16px,3vh,24px)}
  .f2-form{justify-self:start;width:100%;max-width:340px}
  .f2-form input{width:100%}
  .f2-base{grid-template-columns:1fr;justify-items:start;gap:14px;text-align:left}
  .f2-mark,.f2-links{justify-self:start}
}

/* ==========================================================================
   the full-screen viewer
   ========================================================================== */

body.viewer-open{overflow:hidden}
.viewer{position:fixed;inset:0;z-index:100;visibility:hidden}
.viewer-bg{position:absolute;inset:0;background:rgba(9,9,11,.94);opacity:0}
/* GSAP drives top/left/width/height, so no transform is declared here */
.viewer-fig{position:absolute;margin:0;overflow:hidden;background:var(--char)}
.viewer-fig img{width:100%;height:100%;object-fit:cover}
.viewer-meta{
  position:absolute;left:clamp(20px,5vw,60px);bottom:clamp(18px,3.6vh,38px);
  display:grid;gap:5px;color:var(--white);opacity:0;
}
.viewer-name{font-family:var(--serif);font-size:clamp(19px,2vw,32px)}
.viewer-place{font-size:11.5px;letter-spacing:.26em;text-transform:uppercase;color:rgba(255,255,255,.6)}
.viewer-close{
  position:absolute;right:clamp(20px,5vw,60px);top:clamp(18px,3.6vh,38px);
  opacity:0;
}
.viewer-close i{font-style:normal;font-size:13px}


/* ==========================================================================
   how a viewing works — a two-tone heading, a link opposite it, three
   numbered columns each sitting on its own rule
   ========================================================================== */

.steps{
  position:relative;background:var(--mist);
  display:grid;gap:clamp(44px,7vh,90px);
  padding:clamp(80px,14vh,170px) var(--pad);
}

.sp-head{
  display:grid;grid-template-columns:1fr auto;
  gap:clamp(18px,3vw,50px) clamp(24px,4vw,70px);
  align-items:end;
}
.sp-no{grid-column:1;grid-row:1;align-self:start}
.sp-no em{font-style:normal;color:var(--bronze)}
.sp-terms{grid-column:2;grid-row:2;justify-self:end;align-self:end;white-space:nowrap}
.sp-title{grid-column:1;grid-row:2;font-size:clamp(30px,4.2vw,72px);line-height:1.08}
/* the second line steps back, the way the reference greys its own */
.sp-dim{color:color-mix(in srgb,var(--ink) 34%,transparent)}

.sp-row{
  list-style:none;margin:0;padding:0;
  display:grid;grid-template-columns:repeat(3,1fr);
  gap:clamp(24px,4vw,70px);
}
/* the rule is a real element so it can be drawn in, not a border */
.sp-step{
  position:relative;
  display:grid;gap:clamp(12px,1.8vh,20px);align-content:start;
  padding-top:clamp(18px,2.6vh,28px);
}
.sp-rule{
  position:absolute;left:0;right:0;top:0;height:1px;
  background:var(--line);transform-origin:left;
}
.sp-n{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(30px,3.2vw,54px);line-height:1;letter-spacing:.01em;
}
.sp-name{
  margin:0;font-family:var(--serif);font-weight:400;
  font-size:clamp(19px,1.7vw,27px);line-height:1.2;letter-spacing:-.005em;
}
.sp-body{
  margin:0;max-width:40ch;
  font-size:15px;line-height:1.8;
  color:color-mix(in srgb,var(--ink) 58%,transparent);
}

@media (max-width:860px){
  .sp-head{grid-template-columns:1fr}
  .sp-terms{grid-column:1;grid-row:3;justify-self:start}
  .sp-row{grid-template-columns:1fr;gap:0}
  .sp-step{padding:clamp(20px,3vh,28px) 0}
  .sp-rule{top:0}
  .sp-body{max-width:none}
}


/* ==========================================================================
   the residence page
   ========================================================================== */

body.is-residence{background:var(--mist)}
.rs{position:relative}

/* ---------- hero: plate, paragraph, the name across the bottom ---------- */

.rs-hero{
  position:relative;
  height:clamp(560px,92svh,980px);
  overflow:hidden;
  background:var(--char);color:var(--white);
  border-radius:0 0 var(--plate-r) var(--plate-r);
}
.rs-plate{position:absolute;inset:-4%;margin:0;overflow:hidden}
.rs-plate img{width:100%;height:100%;object-fit:cover}
.rs-plate-shade{
  position:absolute;inset:0;pointer-events:none;
  /* the top band is where the nav sits, and some plates are bright sky up
     there — hold the scrim longer so the pills always have ground */
  background:
    linear-gradient(180deg,rgba(8,8,10,.72),rgba(8,8,10,.42) 15%,transparent 42%),
    linear-gradient(0deg,rgba(8,8,10,.78),rgba(8,8,10,.2) 34%,transparent 58%);
}
.rs-intro{
  position:absolute;left:clamp(24px,3.4vw,58px);top:clamp(104px,15vh,168px);
  display:grid;gap:14px;max-width:38ch;
  text-shadow:0 1px 20px rgba(8,8,10,.6);
}
.rs-eyebrow{color:#C9A46A}
.rs-lede{
  margin:0;font-size:clamp(14.5px,1.12vw,17px);line-height:1.72;
  color:rgba(255,255,255,.88);
}
/* the name spans the plate exactly — textLength, not a vw font-size */
.rs-name{
  position:absolute;left:clamp(14px,2.2vw,36px);right:clamp(14px,2.2vw,36px);
  bottom:clamp(-14px,-1.4vw,-6px);
  margin:0;line-height:0;
}
.rs-name svg{display:block;width:100%;height:auto;overflow:visible}
.rs-name text{
  font-family:var(--serif);font-weight:400;font-size:176px;
  fill:var(--white);
}

/* ---------- the statement ---------------------------------------------- */

.rs-say{
  display:grid;gap:clamp(24px,4vh,44px);
  padding:clamp(80px,14vh,170px) var(--pad) clamp(50px,8vh,100px);
  max-width:1680px;margin:0 auto;
}
.rs-statement{font-size:clamp(28px,3.9vw,66px);max-width:20ch}

/* ---------- plate beside the account ------------------------------------ */

.rs-split{
  display:grid;grid-template-columns:.95fr 1.05fr;
  gap:clamp(28px,5vw,90px);align-items:center;
  padding:clamp(30px,6vh,80px) var(--pad);
  max-width:1680px;margin:0 auto;
}
/* the plate runs out to the window rather than stopping at the column, so
   the page has an edge to it and the text keeps a readable measure */
.rs-split-shot{
  margin:0 0 0 calc(var(--pad) * -1);
  overflow:hidden;aspect-ratio:4/5;background:var(--stone);
}
.rs-split-shot img{width:100%;height:112%;object-fit:cover}
.rs-split-text{display:grid;gap:clamp(16px,2.4vh,26px);max-width:52ch}
.rs-split-text p{
  margin:0;font-size:clamp(15px,1.1vw,17px);line-height:1.85;
  color:color-mix(in srgb,var(--ink) 68%,transparent);
}

/* ---------- three frames ------------------------------------------------ */

.rs-grid{
  display:grid;
  grid-template-columns:repeat(12,1fr);
  gap:clamp(14px,2.2vw,32px);
  padding:clamp(40px,8vh,110px) var(--pad);
  max-width:1680px;margin:0 auto;
  align-items:start;
}
.rs-grid figure{margin:0;overflow:hidden;background:var(--stone)}
.rs-grid img{width:100%;height:100%;object-fit:cover}
.rs-grid-note{grid-column:1/5;display:grid;gap:14px;align-content:start;padding-top:clamp(8px,3vh,40px)}
.rs-grid-note p{margin:0;font-size:15px;line-height:1.8;color:color-mix(in srgb,var(--ink) 66%,transparent)}
/* Two frames at the top, then a wide one that runs off the right edge — the
   eye is walked across the page rather than down a stack of thirds.
   Scoped to .rs-grid on purpose: `.rs-grid figure{margin:0}` above is a class
   AND a type, so a bare `.rs-f2` loses to it and every margin here would
   silently compute to zero. */
.rs-grid .rs-f1{grid-column:5/10;aspect-ratio:4/5}
.rs-grid .rs-f2{grid-column:10/13;aspect-ratio:3/4;margin-top:clamp(28px,9vh,120px)}
.rs-grid .rs-f3{
  grid-column:4/13;aspect-ratio:16/9;
  margin-top:clamp(14px,3vh,40px);margin-right:calc(var(--pad) * -1);
}

/* ---------- the file ---------------------------------------------------- */

/* a spec sheet reads as a sheet: the label column stays put on the left and
   the file itself occupies the page, instead of the two stacking */
.rs-specs{
  display:grid;
  grid-template-columns:minmax(150px,.5fr) minmax(0,1.7fr);
  grid-template-rows:auto 1fr;
  gap:clamp(20px,3.4vh,40px) clamp(28px,5vw,80px);
  padding:clamp(40px,8vh,110px) var(--pad) clamp(70px,12vh,150px);
  max-width:1680px;margin:0 auto;
  align-items:start;
}
.rs-specs > .eyebrow{grid-column:1;grid-row:1}
.rs-table{
  grid-column:2;grid-row:1/3;
  margin:0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:0 clamp(28px,5vw,90px);
}
.rs-row{
  display:flex;align-items:baseline;justify-content:space-between;gap:20px;
  padding:clamp(13px,2vh,20px) 0;border-bottom:1px solid var(--line-soft);
}
.rs-row dt{font-size:11.5px;letter-spacing:.24em;text-transform:uppercase;color:var(--gray)}
.rs-row dd{margin:0;font-family:var(--serif);font-size:clamp(17px,1.5vw,23px)}
.rs-ask{grid-column:1;grid-row:2;justify-self:start;align-self:start}

/* ---------- the rest of the collection ---------------------------------- */

/* no background of its own: the width is capped like every other section
   here, and painting a colour on a capped box makes it read as a floating
   panel with gutters instead of part of the page */
.rs-more{
  display:grid;gap:clamp(20px,3.4vh,40px);
  padding:clamp(46px,9vh,120px) var(--pad) clamp(70px,12vh,150px);
  max-width:1680px;margin:0 auto;
}
.rs-more-head{
  display:flex;align-items:center;justify-content:space-between;
  gap:20px;flex-wrap:wrap;
}
.rs-more-title{font-size:clamp(24px,3vw,48px)}
.rs-more-grid{
  display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  gap:clamp(12px,1.6vw,24px);
}

/* the same plate language as the index cards: picture, veil, name at the foot */
.rs-card{
  position:relative;display:block;overflow:hidden;
  aspect-ratio:3/4;border-radius:var(--plate-r);
  background:#cfc7b9;color:var(--white);
}
.rs-card-shot{position:absolute;inset:0;display:block;overflow:hidden}
.rs-card-shot img{
  width:100%;height:100%;object-fit:cover;
  transition:transform 1.1s var(--ease);
}
.rs-card:hover .rs-card-shot img{transform:scale(1.045)}
.rs-card-veil{
  position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,transparent 34%,rgba(8,8,10,.34) 58%,rgba(8,8,10,.80) 88%,rgba(8,8,10,.84));
}
.rs-card-copy{
  position:absolute;left:0;right:0;bottom:0;
  display:grid;gap:5px;
  padding:clamp(14px,1.5vw,22px);
}
.rs-card-name{
  font-family:var(--serif);font-weight:400;
  font-size:clamp(17px,1.5vw,25px);line-height:1.1;
  transition:transform .8s var(--ease);
}
.rs-card:hover .rs-card-name{transform:translateX(6px)}
.rs-card-place{
  font-size:10.5px;letter-spacing:.22em;text-transform:uppercase;
  color:rgba(255,255,255,.7);
}

@media (max-width:900px){
  .rs-more-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:460px){
  .rs-more-grid{grid-template-columns:1fr}
  .rs-card{aspect-ratio:4/3}
}

@media (max-width:1100px){
  /* once these stack, a bleed is just a photograph falling off the page */
  .rs-split{grid-template-columns:1fr;gap:clamp(24px,5vh,48px)}
  .rs-split-shot{aspect-ratio:4/3;margin-left:calc(var(--pad) * -1);margin-right:calc(var(--pad) * -1)}
  .rs-grid-note{grid-column:1/13}
  .rs-grid .rs-f1{grid-column:1/8}
  .rs-grid .rs-f2{grid-column:8/13;margin-top:0}
  .rs-grid .rs-f3{grid-column:1/13;margin-right:0}
  .rs-specs{grid-template-columns:1fr;grid-template-rows:auto auto auto}
  .rs-specs > .eyebrow{grid-column:1;grid-row:1}
  .rs-table{grid-column:1;grid-row:2}
  .rs-ask{grid-column:1;grid-row:3}
}

@media (max-width:860px){
  .rs-hero{height:clamp(480px,78svh,720px)}
  .rs-intro{top:clamp(92px,13vh,130px);max-width:none;right:clamp(18px,4vw,30px)}
  .rs-statement{font-size:clamp(26px,7vw,40px);max-width:none}
  .rs-table{grid-template-columns:1fr}
  .rs-grid .rs-f1,.rs-grid .rs-f2,.rs-grid .rs-f3{grid-column:1/13;margin-top:0;margin-right:0}
}


/* ── WordPress / Elementor compatibility ────────────────────────────────────
   Only relevant if this page is rebuilt inside Elementor. Its frontend.min.css
   ships `.elementor img{height:auto}` (0,1,1), which outranks a single-class
   rule such as `.nav-logo` or `.fl-shot` (0,1,0) regardless of source order, so
   the height set on those images is silently dropped and the nav lockup renders
   at its full artwork size. Re-assert the SAME values at a specificity Elementor
   cannot beat. No value changes; this block is inert outside WordPress. Rules
   already at (0,1,1) (e.g. `.gal-mask img`) tie and win on source order. */
.elementor .nav-logo{height:clamp(21px,2.05vw,29px);width:auto}
.elementor .fl-shot{height:100%;width:100%}

/* ── WordPress / Elementor compatibility · figure margins ────────────────────
   Elementor's frontend.min.css ships, at specificity (0,4,1):
     .elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) figure{margin:0}
   Every <figure> in this design sits inside an Elementor widget, so that one
   rule flattens the margins the layout is built on: the plates that bleed past
   the page padding (the closing image, the residence-index frames, the split
   shot), the gallery's vertical stagger, and the review rail's end padding.
   What you see is white gutters where the picture should reach the window.
   Re-assert the SAME values behind Elementor's own prefix plus our selector,
   which lands above (0,4,1) and wins outright rather than relying on load
   order. Generated from the rules above — no value is changed, and the whole
   block is inert outside WordPress. */
.elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .gal-item{margin:0}
.elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .g3{margin-top:clamp(10px,5vh,60px)}
.elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .g6{margin-top:clamp(10px,7vh,90px)}
.elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .rx-frame{margin:0;margin-left:calc(var(--pad) * -1)}
.elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .rx-item:nth-child(even) .rx-frame{margin-left:0;margin-right:calc(var(--pad) * -1)}
.elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .sy-card{margin:0}
.elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .sy-card:first-child{margin-left:var(--pad)}
.elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .sy-card:last-child{margin-right:var(--pad)}
.elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .c2-shot{margin:clamp(34px,6vh,70px) calc(var(--pad) * -1) 0}
.elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .viewer-fig{margin:0}
.elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .rs-split-shot{margin:0 0 0 calc(var(--pad) * -1)}
.elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .rs-grid .rs-f2{margin-top:clamp(28px,9vh,120px)}
.elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .rs-grid .rs-f3{margin-top:clamp(14px,3vh,40px);margin-right:calc(var(--pad) * -1)}
@media (max-width:860px){
  .elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .g1,.elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .g2,.elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .g3,.elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .g4,.elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .g5,.elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .g6{margin-top:0}
  .elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .rx-frame,.elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .rx-item:nth-child(even) .rx-frame{margin-left:calc(var(--pad) * -1);margin-right:calc(var(--pad) * -1)}
}
@media (max-width:1100px){
  .elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .rs-split-shot{margin-left:calc(var(--pad) * -1);margin-right:calc(var(--pad) * -1)}
  .elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .rs-grid .rs-f2{margin-top:0}
  .elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .rs-grid .rs-f3{margin-right:0}
}
@media (max-width:860px){
  .elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .rs-grid .rs-f1,.elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .rs-grid .rs-f2,.elementor .elementor-widget:not(.elementor-widget-text-editor):not(.elementor-widget-theme-post-content) .rs-grid .rs-f3{margin-top:0;margin-right:0}
}

/* ── Hero house: fit the frame, never distort ─────────────────────────────
   The shipped rule sizes the cut-out by HEIGHT (126%) with width:auto, so the
   global img{max-width:100%} clamps the width while the height stands and
   object-fit:fill stretches it. How badly depends on the stage's aspect, so it
   is not a phone problem: at 1024x900 the 1521x1034 photograph renders at ratio
   0.89, and at 390x844 at 0.356. Letting both axes be auto under a max-width
   and a max-height makes the image scale to fit whichever binds first, always
   at its own ratio. Above 1200px the original sizing is left exactly as shipped.
   Caveat: a viewport wider than 1200px but nearly square (e.g. 1280x1024) still
   squashes, because that is the shipped desktop rule. */
@media (max-width:1200px){
  .hero-house img,
  .elementor .hero-house img{
    width:auto;height:auto;
    max-width:125vw;max-height:64%;
    transform:translate(-50%,6%);
  }
}

/* ── Mobile hero + nav ────────────────────────────────────────────────────
   Three things go wrong on a narrow frame and all three are here.
   1. The house is sized by HEIGHT (126%) with width:auto, so the global
      img{max-width:100%} clamps its width while the height stands — and
      object-fit:fill then stretches a 1521x1034 photograph into a 370x1038
      box. Size it by width instead and the natural ratio comes back; the width is in vw,
      not %, so it does not shift when Elementor changes the containing block.
   2. A full-height stage leaves the grounded house sitting under a sea of
      sky, so the plate is shortened to 78svh. The house is then sized to the
      frame width and lifted off the floor, so the WHOLE building reads at a
      glance instead of a tight crop of its middle.
   3. .nav-links is display:none here, which takes it out of the grid; the
      lockup then claims row 1 / column 3 and auto-placement pushes the
      burger onto a SECOND row. Both are pinned to row 1, logo left,
      burger right. */
@media (max-width:860px){
  .hero-stage,.hero-frame,
  .elementor .hero-stage,.elementor .hero-frame{height:calc(78svh - var(--plate) * 2)}
  .nav-mark,.elementor .nav-mark{grid-column:1;grid-row:1;justify-self:start}
  /* The bar is transparent by design. On a narrow screen the display type runs
     straight under it and the lockup and burger stop being readable, so once it
     sticks it gets a scrim in the page's own colour. */
  .nav.is-stuck,.elementor .nav.is-stuck{background:rgba(240,240,243,.88);-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}
  .nav.is-stuck.is-dark,.elementor .nav.is-stuck.is-dark{background:rgba(14,14,17,.74)}
  .nav-end,.elementor .nav-end{grid-column:3;grid-row:1;justify-self:end}
  /* At this size the two bars cross at only 30deg, which reads as a bowtie
     rather than a close icon. Desktop keeps the original shallow angle. */
  body.menu-open .nav-burger i:first-child,
  .elementor body.menu-open .nav-burger i:first-child{transform:translateY(5px) rotate(45deg)}
  body.menu-open .nav-burger i:last-child,
  .elementor body.menu-open .nav-burger i:last-child{transform:translateY(-5px) rotate(-45deg)}
}

/* WordPress / Elementor compatibility — admin bar offset.
   A logged-in WordPress view adds html{margin-top:32px} (46px at <=782px) for
   the admin bar. .hero-stage is position:fixed so it ignores that margin, but
   .hero-frame — which carries the statement and the Consultation button — is
   position:absolute, so it moves down by exactly that much and the copy drifts
   off the bottom of the plate. Measured at 768x706: frame top 42 against stage
   top 10, leaving the button 5px of clearance. Cancel the offset. */
body.admin-bar .hero-frame{margin-top:-32px}
@media screen and (max-width:782px){
  body.admin-bar .hero-frame{margin-top:-46px}
}
