/* ═══════════════════════════════════════════════════════════════════════
   NOVA Habitat — its own design system.

   Deliberately unlike the other three demos: a warm stone ground rather than
   cream or navy, a high-contrast display serif against a neutral grotesk,
   an editorial 12-column grid that different sections use differently, and
   motion built on masked reveals rather than simple fades.
   ═══════════════════════════════════════════════════════════════════════ */

:root {
  --stone: #f3f0ea; /* page ground, warm off-white           */
  --stone-2: #e9e4da; /* recessed panels                       */
  --ink: #16171a; /* near black                            */
  --ink-2: #3a3934;
  --taupe: #77746e; /* secondary type                        */
  --line: #d7d1c5;
  --clay: #955f48; /* the single accent: numerals, rules    */

  /* The serif was dropped in the reference-alignment pass; the token stays
     mapped to the grotesk so any stray reference still renders correctly. */
  --serif: var(--sans);
  --sans: "DM Sans", ui-sans-serif, system-ui, -apple-system, sans-serif;

  /* One easing language across the whole site. */
  --ease: cubic-bezier(0.22, 0.61, 0.27, 1);
  --ease-o: cubic-bezier(0.16, 1, 0.3, 1);

  --r: 18px;          /* every media panel is rounded, as in the reference */
  --nav-h: 74px;      /* replaced at runtime with the measured height */
  --gut: clamp(20px, 4.5vw, 68px);
  --shell: 1440px;
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  scroll-padding-top: 92px;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--stone);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 17px;
  line-height: 1.6;
  font-weight: 400;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
body.ov-open,
body.menu-open {
  overflow: hidden;
}

img,
video {
  max-width: 100%;
  display: block;
}
figure {
  margin: 0;
}

a {
  color: inherit;
  text-decoration: none;
}
button {
  font: inherit;
  color: inherit;
  background: none;
  border: 0;
  cursor: pointer;
}

:focus-visible {
  outline: 2px solid var(--clay);
  outline-offset: 3px;
}

.shell {
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gut);
}

/* ── type scale ───────────────────────────────────────────────────────── */
h1, h2, h3 { margin: 0; font-weight: 400; }

/* One display treatment, used by every headline on the page. */
.hero-title, .statement, .sec-title, .feature-title, .agency-title,
.method-title, .detail-title, .est-title, .ov-title, .prop-name {
  font-family: var(--sans);
  font-weight: 500;
  letter-spacing: -.032em;
  line-height: 1.02;
}
.hero-title em, .statement em, .feature-title em, .agency-title em,
.method-title em, .detail-title em, .est-title em {
  font-style: normal;
  color: var(--taupe);
}
.feature-title em, .est-title em { color: #9b968c; }

.kicker {
  display: block;
  font-size: 0.72rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--clay);
  font-weight: 500;
}

em {
  font-style: italic;
}

/* ── demo ribbon ──────────────────────────────────────────────────────── */
.demo-bar {
  background: var(--ink);
  color: rgba(243, 240, 234, 0.72);
  font-size: 0.76rem;
  letter-spacing: 0.04em;
  text-align: center;
  padding: 9px 16px;
  position: relative;
  z-index: 90;
}
.demo-bar a {
  color: #fff;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ── buttons ──────────────────────────────────────────────────────────── */
.btn {
  --bg: var(--ink);
  --fg: var(--stone);
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 17px 30px;
  background: var(--bg);
  color: var(--fg);
  font-size: 0.84rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 500;
  border: 1px solid var(--bg);
  overflow: hidden;
  isolation: isolate;
  transition:
    color 0.34s var(--ease),
    border-color 0.34s var(--ease);
}
/* The fill wipes up from the bottom rather than cross-fading. */
.btn::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: var(--stone);
  transform: translateY(101%);
  transition: transform 0.42s var(--ease-o);
}
.btn .arw {
  transition: transform 0.34s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .btn:hover {
    color: var(--ink);
  }
  .btn:hover::before {
    transform: translateY(0);
  }
  .btn:hover .arw {
    transform: translateX(4px);
  }
}
.btn-ghost {
  --bg: transparent;
  --fg: currentColor;
  border-color: currentColor;
}
.btn-ghost::before {
  background: var(--stone);
}
@media (hover: hover) and (pointer: fine) {
  .btn-ghost:hover {
    color: var(--ink);
  }
}
.btn-sm {
  padding: 12px 20px;
  font-size: 0.74rem;
}
.btn-block {
  width: 100%;
  justify-content: center;
}

/* Text link with a rule that draws in from the left. */
.lnk {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 4px 0;
  font-size: 0.82rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-weight: 500;
}
.lnk::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.42s var(--ease-o);
}
.lnk .arw {
  transition: transform 0.34s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .lnk:hover::after {
    transform: scaleX(1);
  }
  .lnk:hover .arw {
    transform: translate(3px, -3px);
  }
}

/* ── navigation ───────────────────────────────────────────────────────── */
.nav {
  position: sticky;
  top: 0;
  z-index: 80;
  transition:
    background 0.4s var(--ease),
    border-color 0.4s var(--ease);
  border-bottom: 1px solid transparent;
}
.nav-in {
  max-width: var(--shell);
  margin-inline: auto;
  padding: 20px var(--gut);
  display: flex;
  align-items: center;
  gap: 28px;
  transition: padding 0.4s var(--ease);
}
/* Over the hero the bar is transparent and the type is light; once the page
   moves it lands on stone. */
.nav:not(.is-stuck) {
  color: var(--stone);
}
.nav.is-stuck {
  background: rgba(243, 240, 234, 0.92);
  backdrop-filter: blur(12px);
  border-bottom-color: var(--line);
  color: var(--ink);
}
.nav.is-stuck .nav-in {
  padding-block: 13px;
}

.mark {
  font-family: var(--serif);
  font-size: 1.32rem;
  letter-spacing: 0.01em;
  white-space: nowrap;
  margin-right: auto;
}
.mark span {
  letter-spacing: 0.12em;
  text-transform: uppercase;
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.82em;
}

.nav-links {
  display: flex;
  gap: 30px;
}
.nav-links a {
  position: relative;
  font-size: 0.82rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-weight: 500;
  padding: 4px 0;
}
.nav-links a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.38s var(--ease-o);
}
@media (hover: hover) and (pointer: fine) {
  .nav-links a:hover::after {
    transform: scaleX(1);
  }
}

.nav:not(.is-stuck) .btn {
  --bg: transparent;
  --fg: var(--stone);
  border-color: rgba(243, 240, 234, 0.5);
}

.burger {
  display: none;
  position: relative;
  width: 30px;
  height: 30px;
  flex: none;
}
/* 44x44 hit area without enlarging the icon. */
.burger::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 44px;
  height: 44px;
}
.burger span,
.burger span::before,
.burger span::after {
  display: block;
  width: 24px;
  height: 1.5px;
  background: currentColor;
  margin-inline: auto;
  transition:
    transform 0.34s var(--ease),
    opacity 0.2s linear;
}
.burger span {
  position: relative;
}
.burger span::before,
.burger span::after {
  content: "";
  position: absolute;
  left: 0;
}
.burger span::before {
  top: -7px;
}
.burger span::after {
  top: 7px;
}
body.menu-open .burger span {
  background: transparent;
}
body.menu-open .burger span::before {
  transform: translateY(7px) rotate(45deg);
}
body.menu-open .burger span::after {
  transform: translateY(-7px) rotate(-45deg);
}

/* ── hero ─────────────────────────────────────────────────────────────── */
.hero {
  position: relative;
  min-height: 100svh;
  margin-top: -74px; /* the nav sits over it */
  display: flex;
  align-items: flex-end;
  color: var(--stone);
  overflow: hidden;
}
.hero-media {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: var(--ink);
}
.hero-media::after {
  /* poster, held until the video paints */
  content: "";
  position: absolute;
  inset: 0;
  background: url("media/hero-poster.webp") center/cover no-repeat;
}
.hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 58%;
  z-index: 1;
  opacity: 0;
  transition: opacity 0.9s var(--ease);
}
.hero-video.is-on {
  opacity: 1;
}
.hero-scrim {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: linear-gradient(to top, rgba(18,18,17,.88) 0%, rgba(18,18,17,.62) 34%, rgba(18,18,17,.30) 66%, rgba(18,18,17,.34) 100%);
}
.hero-body {
  position: relative;
  z-index: 3;
  width: 100%;
  max-width: var(--shell);
  margin-inline: auto;
  padding: 0 var(--gut) clamp(64px, 9vh, 120px);
}
.hero-eyebrow {
  margin: 0 0 clamp(20px, 3vh, 34px);
  font-size: 0.74rem;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: rgba(243, 240, 234, 0.78);
  font-weight: 500;
}
.hero-title {
  font-family: var(--serif);
  font-size: clamp(2.9rem, 8.4vw, 8.5rem);
  line-height: 0.96;
  letter-spacing: -0.02em;
  margin: 0;
}
.hero-title em {
  color: #e6e0d2;
}

/* Each line rides up out of its own mask. */
.hero-title .line, .hero-eyebrow .line { display: block; overflow: hidden; padding-bottom: .06em; }
.hero-title .line > span, .hero-eyebrow .line > span { display: block; }

.hero-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 26px clamp(30px, 5vw, 70px);
  margin-top: clamp(28px, 4vh, 48px);
}
.hero-lead {
  margin: 0;
  max-width: 34ch;
  color: rgba(243, 240, 234, 0.84);
  font-size: 1.02rem;
}
.hero-cta {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.scroll-cue {
  position: absolute;
  z-index: 3;
  left: 50%;
  bottom: 26px;
  transform: translateX(-50%);
  width: 44px;
  height: 44px;
  display: grid;
  place-items: center;
}
.scroll-cue-line {
  display: block;
  width: 1px;
  height: 34px;
  background: rgba(243, 240, 234, 0.45);
  overflow: hidden;
  position: relative;
}
.scroll-cue-line::after {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--stone);
  animation: cue 2.4s var(--ease) infinite;
}
@keyframes cue {
  0% {
    transform: translateY(-100%);
  }
  55% {
    transform: translateY(0);
  }
  100% {
    transform: translateY(100%);
  }
}

/* ── intro ────────────────────────────────────────────────────────────── */
.intro {
  padding: clamp(80px, 12vw, 170px) 0 clamp(70px, 10vw, 140px);
}
.intro-grid {
  display: grid;
  gap: clamp(34px, 5vw, 90px);
}
@media (min-width: 940px) {
  .intro-grid {
    grid-template-columns: 1.15fr 0.85fr;
    align-items: start;
  }
}
.statement {
  font-family: var(--serif);
  font-size: clamp(1.9rem, 4vw, 3.5rem);
  line-height: 1.08;
  letter-spacing: -0.015em;
  max-width: 18ch;
}
.statement em {
  color: var(--taupe);
}
.intro-side p {
  margin: 0 0 20px;
  color: var(--ink-2);
  max-width: 46ch;
}

.stats {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 24px;
  margin: clamp(30px, 4vw, 44px) 0 0;
  padding-top: 26px;
  border-top: 1px solid var(--line);
}
.stats div {
  margin: 0;
}
.stats dt {
  font-family: var(--serif);
  font-size: clamp(2rem, 3.4vw, 2.9rem);
  line-height: 1;
  color: var(--clay);
}
.stats dd {
  margin: 8px 0 0;
  font-size: 0.84rem;
  color: var(--taupe);
  line-height: 1.4;
}

/* ── section heads ────────────────────────────────────────────────────── */
.sec-head {
  margin-bottom: clamp(40px, 6vw, 80px);
}
.sec-title {
  font-family: var(--serif);
  font-size: clamp(2.4rem, 6vw, 5rem);
  line-height: 1;
  letter-spacing: -0.02em;
  margin-top: 14px;
}

/* ── properties ───────────────────────────────────────────────────────── */
.props {
  padding: clamp(20px, 3vw, 40px) 0 clamp(80px, 11vw, 160px);
}

.prop {
  display: grid;
  gap: clamp(22px, 3vw, 44px);
  margin-bottom: clamp(64px, 9vw, 130px);
  padding-inline: var(--gut);
  max-width: var(--shell);
  margin-inline: auto;
}
.prop:last-child {
  margin-bottom: 0;
}

.prop-fig {
  overflow: hidden;
  background: var(--stone-2);
  aspect-ratio: 3 / 2;
}
/* Each cover is cropped to its subject rather than shown whole: the villa
   sits high in its frame with a lot of lawn below, so the box is wider than
   the file and the crop is pulled up onto the house. */
.prop-a .prop-fig { aspect-ratio: 2 / 1; }
.prop-a .prop-fig img { object-position: 50% 38%; }
.prop-b .prop-fig img { object-position: 50% 46%; }
.prop-c .prop-fig img { object-position: 50% 52%; }

.prop-fig img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.001);
  transition: transform 0.8s var(--ease-o);
}
@media (hover: hover) and (pointer: fine) {
  .prop-fig {
    cursor: pointer;
  }
  .prop:hover .prop-fig img {
    transform: scale(1.022);
  }
  .prop:hover .prop-idx {
    color: var(--clay);
  }
  .prop:hover .lnk::after {
    transform: scaleX(1);
  }
}

.prop-body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}
.prop-idx {
  font-family: var(--serif);
  font-size: clamp(2.4rem, 4vw, 3.6rem);
  line-height: 1;
  color: var(--line);
  transition: color 0.5s var(--ease);
}
.prop-name {
  font-family: var(--serif);
  font-size: clamp(1.9rem, 3.4vw, 3rem);
  line-height: 1.02;
  letter-spacing: -0.015em;
  margin-top: 14px;
}
.prop-loc {
  margin: 8px 0 0;
  color: var(--taupe);
  font-size: 0.92rem;
}

.prop-specs {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, auto));
  gap: 0 clamp(22px, 3vw, 44px);
  margin: clamp(22px, 3vw, 34px) 0 clamp(24px, 3vw, 36px);
  padding-top: 20px;
  border-top: 1px solid var(--line);
  width: 100%;
}
.prop-specs div {
  margin: 0;
}
.prop-specs dt {
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--taupe);
  font-weight: 500;
}
.prop-specs dd {
  margin: 7px 0 0;
  font-family: var(--serif);
  font-size: clamp(1.05rem, 1.5vw, 1.35rem);
  white-space: nowrap;
}

/* Three different compositions, one rhythm. */
@media (min-width: 900px) {
  .prop-a {
    grid-template-columns: 1.9fr 1fr;
    align-items: end;
  }
  .prop-b {
    grid-template-columns: 1fr 1.9fr;
  }
  .prop-b .prop-fig {
    order: 2;
  }
  .prop-b .prop-body {
    order: 1;
    justify-content: flex-end;
  }
  .prop-b .prop-fig {
    aspect-ratio: 4 / 3;
  }
  .prop-c {
    grid-template-columns: 1.35fr 1fr;
    align-items: center;
  }
  .prop-c {
    max-width: calc(var(--shell) - 12vw);
  }
  .prop-c .prop-fig {
    aspect-ratio: 16 / 10;
  }
}

/* ── flagship editorial ───────────────────────────────────────────────── */
.feature {
  background: var(--ink);
  color: var(--stone);
  padding: clamp(80px, 11vw, 160px) 0 clamp(80px, 11vw, 160px);
}
.feature-head {
  margin-bottom: clamp(44px, 6vw, 86px);
}
.feature .kicker {
  color: #a9a48a;
}
.feature-title {
  font-family: var(--serif);
  font-size: clamp(2.6rem, 7vw, 6.2rem);
  line-height: 0.98;
  letter-spacing: -0.022em;
  margin-top: 18px;
}
.feature-title em {
  color: #a9a48a;
}

.feature-grid {
  max-width: var(--shell);
  margin-inline: auto;
  padding-inline: var(--gut);
  display: grid;
  gap: clamp(20px, 3vw, 40px);
}
.ff {
  overflow: hidden;
  background: #232320;
}
.ff img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.ff-note {
  align-self: center;
}
.ff-note p {
  color: #c9c4b6;
  max-width: 40ch;
  margin: 0 0 24px;
}

@media (min-width: 900px) {
  .feature-grid {
    grid-template-columns: 1.5fr 1fr;
    grid-template-areas:
      "one  two"
      "note two"
      "three three";
    align-items: start;
  }
  .ff-1 {
    grid-area: one;
    aspect-ratio: 16 / 10;
  }
  .ff-2 {
    grid-area: two;
    aspect-ratio: 4 / 5;
  }
  .ff-note {
    grid-area: note;
    padding: clamp(20px, 3vw, 40px) 0 0;
  }
  .ff-3 {
    grid-area: three;
    aspect-ratio: 21 / 8;
    margin-top: clamp(20px, 3vw, 40px);
  }
}
@media (max-width: 899px) {
  .ff-1 {
    aspect-ratio: 3 / 2;
  }
  .ff-2 {
    aspect-ratio: 4 / 5;
  }
  .ff-3 {
    aspect-ratio: 3 / 2;
  }
}

/* ── agency ───────────────────────────────────────────────────────────── */
.agency {
  padding: clamp(80px, 12vw, 170px) 0;
}
.agency-grid {
  display: grid;
  gap: clamp(34px, 5vw, 80px);
  align-items: center;
}
@media (min-width: 900px) {
  .agency-grid {
    grid-template-columns: 38fr 55fr;
  }
}
.agency-portrait {
  overflow: hidden;
  background: var(--stone-2);
  aspect-ratio: 4 / 5;
}
.agency-portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 26%;
}
.agency-title {
  font-family: var(--serif);
  font-size: clamp(2.1rem, 4.4vw, 3.9rem);
  line-height: 1.03;
  letter-spacing: -0.02em;
  margin: 16px 0 clamp(24px, 3vw, 36px);
}
.agency-title em {
  color: var(--taupe);
}
.agency-body p {
  margin: 0 0 20px;
  color: var(--ink-2);
  max-width: 48ch;
}
.sig {
  margin-top: clamp(26px, 3vw, 38px) !important;
  padding-top: 22px;
  border-top: 1px solid var(--line);
}
.sig-name {
  display: block;
  font-family: var(--serif);
  font-size: 1.5rem;
  color: var(--ink);
}
.sig-role {
  display: block;
  margin-top: 4px;
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--taupe);
}

/* ── method ───────────────────────────────────────────────────────────── */
.method {
  background: var(--stone-2);
  padding: clamp(80px, 12vw, 165px) 0;
}
.method-grid {
  display: grid;
  gap: clamp(36px, 5vw, 80px);
  align-items: start;
}
@media (min-width: 940px) {
  .method-grid {
    grid-template-columns: 42fr 52fr;
  }

}
.method-media figure {
  overflow: hidden;
  aspect-ratio: 4 / 5;
  background: var(--stone);
}
.method-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 45%;
}
.method-title {
  font-family: var(--serif);
  font-size: clamp(2.2rem, 5vw, 4.2rem);
  line-height: 1;
  letter-spacing: -0.02em;
  margin: 16px 0 clamp(34px, 4vw, 54px);
}
.method-title em {
  color: var(--taupe);
}

.steps {
  list-style: none;
  margin: 0;
  padding: 0;
}
.steps li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px clamp(18px, 3vw, 34px);
  padding: clamp(22px, 3vw, 32px) 0;
  border-top: 1px solid var(--line);
}
.steps li:last-child {
  border-bottom: 1px solid var(--line);
}
.st-n {
  grid-row: span 2;
  font-family: var(--serif);
  font-size: clamp(1.5rem, 2.4vw, 2.1rem);
  line-height: 1;
  color: var(--clay);
}
.steps h3 {
  font-family: var(--serif);
  font-size: clamp(1.3rem, 2vw, 1.75rem);
  line-height: 1.1;
}
.steps p {
  margin: 8px 0 0;
  color: var(--ink-2);
  font-size: 0.95rem;
  max-width: 44ch;
}

/* ── architectural break ──────────────────────────────────────────────── */
.detail {
  padding: clamp(80px, 12vw, 170px) 0;
}
.detail-grid {
  display: grid;
  gap: clamp(34px, 5vw, 80px);
  align-items: center;
}
@media (min-width: 900px) {
  .detail-grid {
    grid-template-columns: 42fr 50fr;
  }
}
.detail-fig {
  overflow: hidden;
  background: var(--stone-2);
  aspect-ratio: 2 / 3;
}
.detail-fig img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 42%;
}
.detail-title {
  font-family: var(--serif);
  font-size: clamp(2rem, 4.4vw, 3.7rem);
  line-height: 1.03;
  letter-spacing: -0.02em;
  margin-bottom: clamp(24px, 3vw, 34px);
}
.detail-title em {
  color: var(--taupe);
}
.detail-body p {
  margin: 0 0 20px;
  color: var(--ink-2);
  max-width: 46ch;
}

/* ── testimonials ─────────────────────────────────────────────────────── */
.says {
  padding: 0 0 clamp(80px, 12vw, 165px);
}
.says-grid {
  display: grid;
  gap: 1px;
  background: var(--line);
  border-block: 1px solid var(--line);
}
@media (min-width: 860px) {
  .says-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}
.say {
  background: var(--stone);
  margin: 0;
  padding: clamp(30px, 4vw, 46px) clamp(24px, 3vw, 38px);
  display: flex;
  flex-direction: column;
}
.say p {
  font-family: var(--serif);
  font-size: clamp(1.15rem, 1.7vw, 1.42rem);
  line-height: 1.34;
  margin: 0 0 26px;
}
.say cite {
  margin-top: auto;
  font-style: normal;
  font-size: 0.74rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--taupe);
}

/* ── estimation ───────────────────────────────────────────────────────── */
.est {
  background: var(--ink);
  color: var(--stone);
  padding: clamp(80px, 12vw, 165px) 0;
}
.est .kicker {
  color: #a9a48a;
}
.est-grid {
  display: grid;
  gap: clamp(40px, 5vw, 90px);
  align-items: start;
}
@media (min-width: 940px) {
  .est-grid {
    grid-template-columns: 1fr 1fr;
  }
}
.est-title {
  font-family: var(--serif);
  font-size: clamp(2.2rem, 5vw, 4.2rem);
  line-height: 1;
  letter-spacing: -0.02em;
  margin: 16px 0 clamp(24px, 3vw, 34px);
}
.est-title em {
  color: #a9a48a;
}
.est-intro p {
  color: #c9c4b6;
  max-width: 44ch;
  margin: 0;
}
.est-facts {
  list-style: none;
  margin: clamp(28px, 4vw, 40px) 0 0;
  padding: 0;
  display: grid;
  gap: 12px;
}
.est-facts li {
  display: flex;
  gap: 14px;
  align-items: baseline;
  font-size: 0.92rem;
  color: #c9c4b6;
}
.est-facts li::before {
  content: "";
  flex: none;
  width: 16px;
  height: 1px;
  background: #a9a48a;
  transform: translateY(-4px);
}

.est-form {
  display: grid;
  gap: 18px;
}
.f2 {
  display: grid;
  gap: 18px;
}
@media (min-width: 560px) {
  .f2 {
    grid-template-columns: 1fr 1fr;
  }
}
.field label {
  display: block;
  margin-bottom: 9px;
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #a9a48a;
  font-weight: 500;
}
.est-form input,
.est-form select,
.est-form textarea {
  width: 100%;
  background: transparent;
  border: 0;
  border-bottom: 1px solid rgba(243, 240, 234, 0.26);
  color: var(--stone);
  font: inherit;
  font-size: 1rem;
  padding: 11px 0;
  border-radius: 0;
  transition: border-color 0.3s var(--ease);
}
.est-form textarea {
  resize: vertical;
  min-height: 96px;
}
.est-form input::placeholder,
.est-form textarea::placeholder {
  color: rgba(243, 240, 234, 0.38);
}
.est-form input:focus,
.est-form select:focus,
.est-form textarea:focus {
  outline: none;
  border-bottom-color: #a9a48a;
}
.est-form select option {
  color: var(--ink);
}
.est-form .btn {
  --bg: var(--stone);
  --fg: var(--ink);
  margin-top: 10px;
}
.est-form .btn::before {
  background: #a9a48a;
}

.form-ok {
  border: 1px solid rgba(243, 240, 234, 0.3);
  padding: 26px 28px;
  font-size: 0.96rem;
}
.form-ok strong {
  display: block;
  margin-bottom: 8px;
  font-weight: 500;
}
.form-ok span {
  display: block;
  color: #a9a48a;
  font-size: 0.88rem;
}

/* ── footer ───────────────────────────────────────────────────────────── */
.ftr {
  background: var(--stone);
  padding: clamp(60px, 8vw, 100px) 0 40px;
  border-top: 1px solid var(--line);
}
.ftr-grid {
  display: grid;
  gap: clamp(30px, 4vw, 60px);
}
@media (min-width: 720px) {
  .ftr-grid {
    grid-template-columns: repeat(2, 1fr);
  }
}
@media (min-width: 1000px) {
  .ftr-grid {
    grid-template-columns: 1.6fr 1fr 1fr 1fr;
  }
}
.mark-ftr {
  font-size: 1.7rem;
  margin: 0;
}
.ftr-tag {
  margin: 12px 0 0;
  color: var(--taupe);
  font-family: var(--serif);
  font-size: 1.12rem;
  max-width: 26ch;
}
.ftr-col h2 {
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--taupe);
  font-weight: 500;
  margin-bottom: 14px;
}
.ftr-col p {
  margin: 0;
  line-height: 1.9;
  font-size: 0.94rem;
}
.ftr-col a {
  transition: color 0.25s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .ftr-col a:hover {
    color: var(--clay);
  }
}
.ftr-foot {
  margin-top: clamp(44px, 6vw, 74px);
  padding-top: 24px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 10px 30px;
  justify-content: space-between;
  font-size: 0.8rem;
  color: var(--taupe);
}
.ftr-foot p {
  margin: 0;
}
.ftr-legal a {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* ── property overlay ─────────────────────────────────────────────────── */
.ov {
  position: fixed;
  inset: 0;
  z-index: 120;
}
.ov-back {
  position: absolute;
  inset: 0;
  background: rgba(18, 18, 17, 0.62);
  opacity: 0;
  transition: opacity 0.42s var(--ease);
}
.ov-panel {
  position: absolute;
  inset: 0 0 0 auto;
  width: min(960px, 100%);
  background: var(--stone);
  transform: translateX(3%);
  opacity: 0;
  transition:
    transform 0.5s var(--ease-o),
    opacity 0.38s var(--ease);
  display: flex;
  flex-direction: column;
}
.ov.is-on .ov-back {
  opacity: 1;
}
.ov.is-on .ov-panel {
  transform: none;
  opacity: 1;
}

.ov-close {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 3;
  width: 46px;
  height: 46px;
  display: grid;
  place-items: center;
  font-size: 1.9rem;
  line-height: 1;
  background: var(--stone);
  border: 1px solid var(--line);
  transition:
    background 0.25s var(--ease),
    color 0.25s var(--ease);
}
@media (hover: hover) and (pointer: fine) {
  .ov-close:hover {
    background: var(--ink);
    color: var(--stone);
  }
}
.ov-scroll {
  overflow-y: auto;
  height: 100%;
  -webkit-overflow-scrolling: touch;
}
.ov-hero {
  aspect-ratio: 3 / 2;
  background: var(--stone-2);
  overflow: hidden;
}
.ov-hero img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.ov-body {
  padding: clamp(28px, 4vw, 52px);
}
.ov-idx {
  font-family: var(--serif);
  font-size: 1.5rem;
  color: var(--clay);
}
.ov-title {
  font-family: var(--serif);
  font-size: clamp(2rem, 4vw, 3.1rem);
  line-height: 1;
  letter-spacing: -0.02em;
  margin-top: 8px;
}
.ov-loc {
  margin: 10px 0 0;
  color: var(--taupe);
  font-size: 0.95rem;
}
.ov-specs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(96px, 1fr));
  gap: 20px 24px;
  margin: clamp(26px, 3vw, 36px) 0;
  padding: 24px 0;
  border-block: 1px solid var(--line);
}
.ov-specs div {
  margin: 0;
}
.ov-specs dt {
  font-size: 0.66rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--taupe);
  font-weight: 500;
}
.ov-specs dd {
  margin: 7px 0 0;
  font-family: var(--serif);
  font-size: 1.25rem;
}
.ov-desc {
  color: var(--ink-2);
  max-width: 56ch;
  margin: 0 0 clamp(26px, 3vw, 38px);
}
.ov-gal {
  display: grid;
  gap: 12px;
  margin-bottom: clamp(28px, 4vw, 40px);
}
@media (min-width: 620px) {
  .ov-gal {
    grid-template-columns: 1fr 1fr;
  }
}
.ov-gal figure {
  overflow: hidden;
  aspect-ratio: 4 / 3;
  background: var(--stone-2);
}
.ov-gal img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ── "Voir" cursor ────────────────────────────────────────────────────── */
.cursor {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 110;
  pointer-events: none;
  width: 74px;
  height: 74px;
  border-radius: 50%;
  background: var(--ink);
  color: var(--stone);
  display: grid;
  place-items: center;
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  opacity: 0;
  scale: .6;
  transition: opacity .28s var(--ease), scale .35s var(--ease-o);
}
.cursor.is-on {
  opacity: 1;
  scale: 1;
}
@media (hover: none), (pointer: coarse) {
  .cursor {
    display: none;
  }
}

/* ── reveals ──────────────────────────────────────────────────────────── */
/* Applied only once JS is present, so nothing is hidden if it never runs. */
.reveals-armed .rv {
  opacity: 0;
  transform: translateY(26px);
}
.reveals-armed .rv.in {
  opacity: 1;
  transform: none;
  transition:
    opacity 0.85s var(--ease),
    transform 0.95s var(--ease-o);
}
/* Reveals inside a section stagger by position rather than by a JS timer. */
.js .prop-body > *,
.js .steps li {
  transition-delay: 0s;
}
.reveals-armed .says-grid .rv:nth-child(2).in {
  transition-delay: 0.1s;
}
.reveals-armed .says-grid .rv:nth-child(3).in {
  transition-delay: 0.2s;
}

/* Hero entrance: each masked line rides up, then the supporting row. */
@keyframes riseIn {
  from {
    transform: translateY(105%);
  }
  to {
    transform: translateY(0);
  }
}
@keyframes fadeUp {
  from {
    opacity: 0;
    transform: translateY(16px);
  }
  to {
    opacity: 1;
    transform: none;
  }
}
/* The inner span moves; its parent is the mask. */
.js .hero-eyebrow .line > span,
.js .hero-title .line > span { animation: riseIn 1.05s var(--ease-o) both; }
.js .hero-eyebrow .line > span { animation-delay: .15s; }
.js .hero-title .line:nth-child(1) > span { animation-delay: .28s; }
.js .hero-title .line:nth-child(2) > span { animation-delay: .40s; }
.js .hero-foot {
  animation: fadeUp 0.9s var(--ease-o) 0.72s both;
}
.js .scroll-cue {
  animation: fadeUp 0.8s var(--ease-o) 1.1s both;
}


/* ── responsive ───────────────────────────────────────────────────────── */
@media (max-width: 1000px) {
  .nav-links {
    position: fixed;
    inset: 0 0 0 auto;
    width: min(330px, 84vw);
    background: var(--stone);
    color: var(--ink);
    flex-direction: column;
    justify-content: center;
    gap: 4px;
    padding: 40px;
    transform: translateX(100%);
    /* Hidden, not just moved: an off-screen panel still widened the document
       and kept its links in the tab order. */
    visibility: hidden;
    pointer-events: none;
    transition: transform .46s var(--ease-o), visibility 0s linear .46s;
    z-index: 85;
  }
  body.menu-open .nav-links {
    transform: none;
    visibility: visible;
    pointer-events: auto;
    transition: transform .46s var(--ease-o), visibility 0s;
  }
  .nav-links a {
    font-size: 1.05rem;
    padding: 14px 0;
    letter-spacing: 0.06em;
  }
  .burger {
    display: block;
  }
  .nav-cta {
    display: none;
  }
  .mark {
    margin-right: auto;
  }
}

@media (max-width: 899px) {
  .prop-fig {
    aspect-ratio: 3 / 2;
  }
  .prop-c {
    max-width: var(--shell);
  }
}

@media (max-width: 560px) {
  .prop-specs {
    grid-template-columns: 1fr 1fr;
    gap: 18px clamp(18px, 4vw, 30px);
  }
  .stats {
    grid-template-columns: 1fr;
    gap: 20px;
  }
  .ov-panel {
    width: 100%;
  }
  .ov-hero {
    aspect-ratio: 4 / 3;
  }
}

/* ── reduced motion ───────────────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .reveals-armed .rv {
    opacity: 1 !important;
    transform: none !important;
  }
  .js .hero-eyebrow .line > span, .js .hero-title .line > span,
  .js .hero-foot, .js .scroll-cue { animation: none; opacity: 1; transform: none; }
  .hero-video {
    opacity: 1;
  }
  .scroll-cue-line::after {
    animation: none;
    transform: none;
  }
  [data-par] {
    transform: none !important;
  }
  .cursor {
    display: none;
  }
}


/* ══════════════════════════════════════════════════════════════════════════
   Reference alignment layer
   Studied from the source motion piece: rounded inset media panels, a
   sentence-case grotesk display, pill buttons carrying a circular arrow
   badge, and a hero where the photograph leads and the words sit quietly
   in its corner rather than covering it.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── rounded media, everywhere ─────────────────────────────────────────── */
.prop-fig, .ff, .agency-portrait, .method-media figure, .detail-fig,
.ov-hero, .ov-gal figure, .hero-media { border-radius: var(--r); }
.hero-media { overflow: hidden; }

/* ── pill buttons with an arrow badge ──────────────────────────────────── */
.btn {
  border-radius: 999px;
  padding: 11px 12px 11px 26px;
  text-transform: none;
  letter-spacing: -.005em;
  font-size: .95rem;
  gap: 14px;
}
.btn .arw {
  display: grid; place-items: center;
  width: 34px; height: 34px;
  border-radius: 50%;
  background: var(--stone);
  color: var(--ink);
  font-size: .9rem;
  flex: none;
}
.btn-ghost .arw { background: rgba(243,240,234,.16); color: currentColor; }
.est-form .btn .arw { background: var(--ink); color: var(--stone); }
/* Buttons without an explicit arrow keep an even pill. */
.btn:not(:has(.arw)) { padding: 15px 28px; }
.btn-sm { padding: 8px 9px 8px 20px; font-size: .86rem; gap: 11px; }
.btn-sm .arw { width: 28px; height: 28px; font-size: .8rem; }
.btn-block { justify-content: space-between; }

/* ── nav: sparser, lighter, no uppercase tracking ──────────────────────── */
.nav-links a, .lnk {
  text-transform: none;
  letter-spacing: -.005em;
  font-size: .95rem;
  font-weight: 400;
}
.mark { font-family: var(--sans); font-weight: 500; letter-spacing: -.02em; font-size: 1.15rem; }
.mark span { font-size: 1em; letter-spacing: -.02em; text-transform: none; }

/* ── hero: an inset panel, words in its lower-left ─────────────────────── */
.hero {
  min-height: auto;
  margin-top: 0;
  padding: 0 var(--gut) clamp(28px, 4vw, 46px);
  display: block;
  color: var(--stone);
}
.hero-media {
  position: relative;
  height: clamp(520px, 78svh, 860px);
  max-width: var(--shell);
  margin-inline: auto;
}
.hero-scrim {
  background: linear-gradient(to top, rgba(16,17,20,.86) 0%, rgba(16,17,20,.34) 46%,
    rgba(16,17,20,.14) 72%, rgba(16,17,20,.30) 100%);
}
.hero-body {
  /* The containing block is .hero, whose padding box starts at x=0, so this
     has to carry the gutter itself or the copy is clipped by the panel edge. */
  position: absolute; inset: auto var(--gut) 0 var(--gut); z-index: 3;
  padding: clamp(28px, 4vw, 56px);
  /* width:100% from the base rule over-constrains left+right+width, which
     makes the browser drop `right` and run the copy past the panel. */
  /* The panel caps at --shell and centres above 1440, so the copy has to
     share that constraint or it sits outside the panel on both sides. */
  width: auto; max-width: var(--shell); margin-inline: auto;
}
/* The reference keeps the hero sentence small and lets the photograph carry
   the moment; the oversized type moves to the sections below. */
.hero-title { font-size: clamp(1.9rem, 3.4vw, 3.4rem); max-width: 19ch; letter-spacing: -.03em; }
.hero-eyebrow { margin-bottom: clamp(12px, 2vw, 20px); letter-spacing: .16em; font-size: .7rem; }
.hero-foot { margin-top: clamp(22px, 3vw, 34px); align-items: center; }
.hero-lead { font-size: .95rem; max-width: 40ch; color: rgba(243,240,234,.76); }
.scroll-cue { display: none; }

/* The nav is no longer over the media, so it takes the page ground. */
.nav:not(.is-stuck) { color: var(--ink); }
.nav:not(.is-stuck) .btn {
  --bg: var(--ink); --fg: var(--stone); border-color: var(--ink);
}
.nav { background: var(--stone); }

/* ── stats as a horizontal row of figures ──────────────────────────────── */
.stats { grid-template-columns: repeat(2, auto); justify-content: start; gap: clamp(34px, 6vw, 76px); }
.stats dt { font-family: var(--sans); font-weight: 500; letter-spacing: -.03em; color: var(--ink); }
.stats dd { color: var(--taupe); }

/* ── property index sits on the image, not beside it ───────────────────── */
.prop-fig { position: relative; }
.prop-idx {
  font-family: var(--sans); font-weight: 500; letter-spacing: -.03em;
  color: var(--taupe);
}
.prop-specs dd { font-family: var(--sans); font-weight: 500; letter-spacing: -.02em; }
.prop-specs dt, .ov-specs dt, .field label, .kicker,
.sig-role, .say cite, .ftr-col h2 { letter-spacing: .14em; }
.ov-specs dd, .sig-name, .ov-idx, .st-n {
  font-family: var(--sans); font-weight: 500; letter-spacing: -.02em;
}
.say p { font-family: var(--sans); font-weight: 400; letter-spacing: -.015em; line-height: 1.42; }

/* ── overlay: full-bleed image, rounded panel ──────────────────────────── */
.ov-panel { border-radius: var(--r) 0 0 var(--r); }
@media (max-width: 560px) { .ov-panel { border-radius: 0; } }
.ov-close { border-radius: 50%; }
.form-ok { border-radius: var(--r); }
.says-grid { border-radius: var(--r); overflow: hidden; }

/* ── section joins: the dark blocks become rounded slabs ───────────────── */
.feature, .est { border-radius: var(--r); }
.feature, .est { margin-inline: var(--gut); }
.method { border-radius: var(--r); margin-inline: var(--gut); }
@media (max-width: 620px) {
  .feature, .est, .method { margin-inline: 0; border-radius: 0; }
}

/* The base rules for these set --serif and come later in the cascade than the
   display block above, so the family has to be restated here. The reference
   uses a grotesk throughout; no serif remains on the page. */
.hero-title, .statement, .sec-title, .feature-title, .agency-title,
.method-title, .detail-title, .est-title, .ov-title, .prop-name,
.prop-idx, .stats dt, .say p, .sig-name, .ov-idx, .ov-specs dd,
.st-n, .prop-specs dd, .mark, .mark-ftr, .ftr-tag {
  font-family: var(--sans);
}
.ftr-tag { font-weight: 400; letter-spacing: -.015em; }
.sec-title, .prop-name { font-weight: 500; letter-spacing: -.032em; }

/* ══════════════════════════════════════════════════════════════════════════
   Scroll-scrubbed hero + directional property entrances
   ══════════════════════════════════════════════════════════════════════════ */

/* The section is taller than the panel; the panel sticks while the extra
   height is scrolled through, and that travel is what drives currentTime.
   The composition itself is unchanged — same inset, same radius, same copy
   position inside the panel. */
.hero { height: 200vh; padding-bottom: 0; }
.hero-media { position: sticky; top: 86px; }
/* The copy now lives inside the panel, so it no longer needs the gutter. */
.hero-body { inset: auto 0 0 0 !important; max-width: none !important; margin-inline: 0 !important; }
/* Poster only: no scrubbing under reduced motion or save-data. */
.hero.no-scrub { height: auto; padding-bottom: clamp(28px, 4vw, 46px); }
.hero.no-scrub .hero-media { position: relative; top: 0; }

/* Property entrances: 01 from the left, 02 from the right, 03 from the left.
   Layout, grid and final position are untouched — this is transform only. */
.reveals-armed .prop.rv { opacity: 0; transform: translateX(-110px); }
.reveals-armed .prop-b.rv { transform: translateX(110px); }
.reveals-armed .prop.rv.in {
  opacity: 1;
  transform: none;
  transition: opacity .9s cubic-bezier(.22, 1, .36, 1),
              transform .95s cubic-bezier(.22, 1, .36, 1);
}

@media (prefers-reduced-motion: reduce) {
  .hero { height: auto; padding-bottom: clamp(28px, 4vw, 46px); }
  .hero-media { position: relative; top: 0; }
  .reveals-armed .prop.rv, .reveals-armed .prop-b.rv { opacity: 1 !important; transform: none !important; }
}

/* ══════════════════════════════════════════════════════════════════════════
   Unfold reveal — the panel opens top to bottom while the picture inside
   settles back from a slight push-in. clip-path animates, border-radius does
   not, so the rounded corners stay honest throughout.
   ══════════════════════════════════════════════════════════════════════════ */
@keyframes unfoldIn {
  from { clip-path: inset(0 0 100% 0); }
  to   { clip-path: inset(0 0 0 0); }
}
@keyframes settleIn {
  from { transform: scale(1.07); }
  to   { transform: scale(1); }
}

/* The hero opens on load, once. */
.js .hero.unfold .hero-media {
  animation: unfoldIn 1.2s cubic-bezier(.22, 1, .36, 1) both;
}
.js .hero.unfold .hero-video,
.js .hero.unfold .hero-media::after {
  animation: settleIn 1.5s cubic-bezier(.22, 1, .36, 1) both;
}

/* Selected media further down open the same way, when scrolled to. */
.reveals-armed .unfold.rv { opacity: 1; transform: none; clip-path: inset(0 0 100% 0); }
.reveals-armed .unfold.rv > img,
.reveals-armed .unfold.rv figure > img { transform: scale(1.07); }
.reveals-armed .unfold.rv.in {
  clip-path: inset(0 0 0 0);
  transition: clip-path 1.2s cubic-bezier(.22, 1, .36, 1);
}
.reveals-armed .unfold.rv.in > img,
.reveals-armed .unfold.rv.in figure > img {
  transform: scale(1);
  transition: transform 1.5s cubic-bezier(.22, 1, .36, 1);
}

@media (prefers-reduced-motion: reduce) {
  .js .hero.unfold .hero-media,
  .js .hero.unfold .hero-video,
  .js .hero.unfold .hero-media::after { animation: none; }
  .reveals-armed .unfold.rv, .reveals-armed .unfold.rv.in { clip-path: none; }
  .reveals-armed .unfold.rv > img, .reveals-armed .unfold.rv figure > img,
  .reveals-armed .unfold.rv.in > img, .reveals-armed .unfold.rv.in figure > img { transform: none; }
}


/* ══════════════════════════════════════════════════════════════════════════
   Hero: top of page, navigation over the media
   The panel used to sit below a full navbar's worth of stone, which pushed
   the property out of the first impression. It now starts at the very top;
   the nav floats on it and only takes a background once the hero has gone.
   ══════════════════════════════════════════════════════════════════════════ */
.nav { background: transparent; border-bottom-color: transparent; }
.nav:not(.is-stuck) { color: var(--stone); }
.nav:not(.is-stuck) .btn {
  --bg: rgba(243,240,234,.14); --fg: var(--stone);
  border-color: rgba(243,240,234,.42);
  backdrop-filter: blur(6px);
}
.nav:not(.is-stuck) .btn .arw { background: var(--stone); color: var(--ink); }
.nav.is-stuck { background: rgba(243,240,234,.92); color: var(--ink); }

/* The section is pulled up under the sticky nav so the media is the first
   thing on the page. Horizontal gutter and rounding stay; the top corners
   go square because the panel now meets the top edge. */
.hero {
  height: 195vh;
  margin-top: calc(-1 * var(--nav-h));
  padding: 0 var(--gut) 0;
}
.hero-media {
  position: sticky;
  top: 0;
  height: min(94svh, 940px);
  border-radius: 0 0 var(--r) var(--r);
}
/* A slightly stronger top gradient so the nav stays legible over bright
   frames, without dimming the property itself. */
.hero-scrim {
  background:
    linear-gradient(to bottom, rgba(16,17,20,.52) 0%, rgba(16,17,20,.12) 18%, transparent 34%),
    linear-gradient(to top, rgba(16,17,20,.88) 0%, rgba(16,17,20,.55) 30%,
      rgba(16,17,20,.14) 62%, transparent 100%);
}
.hero-body { padding: clamp(28px, 4vw, 60px) clamp(28px, 4vw, 60px) clamp(34px, 4.5vw, 68px); }

/* Static fallback keeps the same top composition, just without the travel. */
.hero.no-scrub { height: auto; }
.hero.no-scrub .hero-media { position: relative; }

@media (max-width: 900px) {
  /* Less travel on a phone: a full desktop scrub distance is a lot of
     thumb-work for a 10-second clip. */
  .hero { height: 160vh; }
  .hero-media { height: min(88svh, 720px); }
}

@media (prefers-reduced-motion: reduce) {
  .hero { height: auto; }
  .hero-media { position: relative; top: 0; }
}

/* Over the hero the nav sits inside the media panel, so it takes the panel's
   own padding rather than the page gutter — otherwise the wordmark is flush
   against the rounded edge. It returns to the page gutter once solid. */
.nav:not(.is-stuck) .nav-in {
  padding-inline: calc(var(--gut) + clamp(28px, 4vw, 60px));
}


/* ══════════════════════════════════════════════════════════════════════════
   Hero experiment: near full-bleed media
   The stone side strips made the first screen read as a card on a page. The
   gutter drops to a hairline so the property fills the viewport, with the
   lower corners still rounded to keep the NOVA panel character.
   ══════════════════════════════════════════════════════════════════════════ */
.hero { padding-inline: 12px; height: 168vh; }
.hero-media { max-width: none; border-radius: 0 0 22px 22px; height: min(96svh, 1000px); }
/* Copy keeps a real margin even though the panel no longer has one. */
.hero-body { padding-inline: clamp(24px, 5vw, 96px); }
.nav:not(.is-stuck) .nav-in { padding-inline: clamp(24px, 5vw, 96px); }

@media (max-width: 900px) {
  .hero { padding-inline: 8px; height: 150vh; }
  .hero-media { height: min(90svh, 760px); border-radius: 0 0 16px 16px; }
}


/* Canvas sequence occupies the same box as the video did. Only the drawn
   frame changes on scroll — the element itself never moves. */
.hero-canvas {
  position: absolute; inset: 0; z-index: 1;
  width: 100%; height: 100%;
  display: block;
  opacity: 0;
  transition: opacity .6s var(--ease);
}
.hero-canvas.is-on { opacity: 1; }
/* Shares the intro unfold's scale settle with the video. */
.js .hero.unfold .hero-canvas { animation: settleIn 1.5s cubic-bezier(.22,1,.36,1) both; }
@media (prefers-reduced-motion: reduce) { .hero-canvas { display: none; } }

/* Phones and reduced-motion get one sharp still rather than a 120-frame set. */
.hero.static-hero .hero-media::after {
  background-image: url("media/hero-frame0.webp");
}




/* The off-screen mobile menu is position:fixed, so body's overflow-x cannot
   clip it. The root can — but overflow:clip on the root also kills
   position:sticky everywhere, which broke the hero pin. Only widths that
   actually have the menu get the clip; those widths use the static hero. */
@media (max-width: 1000px) {
  html { overflow-x: clip; }
}

/* Left over from the original full-bleed video hero. It makes .hero a scroll
   container, which silently downgrades the sticky media to static — the media
   then never covers its own scroll spacer, leaving a blank band below it.
   The media clips itself, so the section does not need to. */
.hero { overflow: visible; }

/* The property entrances translate +/-110px before settling. The root clip
   used to absorb that, but it also disabled the hero sticky — so contain the
   overshoot on the section itself instead. */
.props { overflow-x: clip; }

/* Longer hero: the sequence now spans more scroll so the orbit reads at a
   calmer pace. Travel is hero height minus the pinned media. */
.hero { height: 210vh; }

/* The method image was sticky, so it hung behind the steps while they scrolled
   past — it read as the section lagging. It now scrolls with its column. */
.method-media { position: static; }

/* ══════════════════════════════════════════════════════════════════════════
   Refinement pass — composition and rhythm only
   ══════════════════════════════════════════════════════════════════════════ */

/* 1 — True full bleed. The media reaches both edges; the copy and the nav
   keep their own inset so nothing sits against the glass. */
.hero { padding-inline: 0; }
.hero-media { border-radius: 0 0 22px 22px; }
@media (max-width: 900px) {
  .hero { padding-inline: 0; }
  .hero-media { border-radius: 0 0 16px 16px; }
}

/* 2 — Hero to statement: 170px -> 108px at desktop (-36%), still generous.
   Kept as a clamp so it scales rather than snapping at one breakpoint. */
.intro { padding-top: clamp(56px, 8vw, 108px); }

/* 3 — Property rhythm: 130px -> 106px between entries (-18%). The imagery
   still dominates; only the dead air between entries comes down. */
.prop { margin-bottom: clamp(52px, 7.4vw, 106px); }

/* 4 — Modal: a real safe inset for the close control, and a little more
   backdrop so the panel reads as layered over the page rather than welded
   to the edge. */
.ov-close { top: 22px; right: 22px; }
.ov-panel { width: min(880px, 100%); }
@media (max-width: 560px) {
  .ov-close { top: 14px; right: 14px; }
  .ov-panel { width: 100%; }
}

/* 8 — Staircase: a barely-there settle so the section is not dead still.
   Scale only, on the image, so the layout never moves. */
.detail-fig img { transform: scale(1.03); transition: transform 1.2s var(--ease-o); }
.detail-fig.rv.in img { transform: scale(1); }

/* 11 — Footer: -22% vertical, same layout and hierarchy. */
.ftr { padding: clamp(48px, 6.4vw, 78px) 0 32px; }
.ftr-foot { margin-top: clamp(34px, 4.6vw, 56px); padding-top: 20px; }

@media (prefers-reduced-motion: reduce) {
  .detail-fig img, .detail-fig.rv.in img { transform: none; transition: none; }
}

/* The hero is full-bleed now, so hero-foot's space-between was throwing the
   buttons to the far edge — a whole viewport away from the sentence they
   belong to. Capping the row to roughly the headline measure keeps the lead
   and the actions reading as one block. */
@media (min-width: 1001px) {
  .hero-foot { max-width: min(820px, 100%); }
}

/* ══════════════════════════════════════════════════════════════════════════
   Brand mark
   The wordmark is the supplied NOVA Habitat lockup rather than set type.
   Two state variants sit in the same grid cell and cross-fade, so the bar
   never reflows when it changes state — the height is governed by the CTA
   button (45px), and the mark is deliberately kept under that.
   ══════════════════════════════════════════════════════════════════════════ */
.mark {
  display: grid;
  margin-right: auto;
  line-height: 0;
  font-size: 0;
}
.mark-img {
  grid-area: 1 / 1;
  display: block;
  height: 40px;
  width: auto;
  object-fit: contain;
  transition: opacity 0.4s var(--ease);
}
/* Over the hero photography the light variant; on stone, the supplied dark
   one. Same geometry in both, so the switch is a pure cross-fade. */
.nav:not(.is-stuck) .mark-img--dark { opacity: 0; }
/* The thin roof line and the HABITAT rules are hairlines; over bright
   foliage they need help. A drop-shadow follows the logo silhouette, so the
   mark stays readable without sitting on a panel. */
.mark-img--light { filter: drop-shadow(0 1px 2px rgba(10, 12, 9, 0.72)); }
.nav.is-stuck .mark-img--light { opacity: 0; }

.mark-ftr { margin: 0; line-height: 0; font-size: 0; }
.mark-ftr img {
  display: block;
  height: 46px;
  width: auto;
  object-fit: contain;
}

@media (max-width: 700px) {
  .mark-img { height: 36px; }
  .mark-ftr img { height: 40px; }
}

@media (prefers-reduced-motion: reduce) {
  .mark-img { transition: none; }
}

/* Below 1000px the CTA button is gone, so the bar height is set by the mark
   itself. An image lockup stands taller than the text wordmark it replaces,
   so the padding comes back a little to hold the previous bar height. */
@media (max-width: 1000px) {
  .nav-in { padding-block: 15px; }
  .nav.is-stuck .nav-in { padding-block: 11px; }
}


/* ══════════════════════════════════════════════════════════════════════════
   FINAL POLISH PASS
   Spacing, modal hierarchy and micro-interaction refinement only. The art
   direction, palette, type system and layout logic are unchanged.
   ══════════════════════════════════════════════════════════════════════════ */

/* ── 1. header: mark up ~17%, bar height held by trimming the padding ───── */
.mark-img { height: 47px; }
.nav-in { padding-block: 19px; }
.nav.is-stuck .nav-in { padding-block: 12px; }

@media (max-width: 1000px) {
  .mark-img { height: 44px; }
  .nav-in { padding-block: 13px; }
  .nav.is-stuck .nav-in { padding-block: 9px; }
}
@media (max-width: 700px) {
  .mark-img { height: 42px; }
  .nav-in { padding-block: 12px; }
  .nav.is-stuck .nav-in { padding-block: 8px; }
}

/* One easing and one duration for every property that changes when the bar
   lands on stone, so the whole header resolves as a single move instead of
   several overlapping ones. */
.nav {
  transition:
    background 0.55s var(--ease-o),
    border-color 0.55s var(--ease-o),
    color 0.55s var(--ease-o),
    backdrop-filter 0.55s var(--ease-o);
}
.nav-in { transition: padding 0.55s var(--ease-o); }
.mark-img { transition: opacity 0.55s var(--ease-o); }
.nav .btn {
  transition:
    background 0.55s var(--ease-o),
    border-color 0.55s var(--ease-o),
    color 0.34s var(--ease);
}

/* ── 2. property rhythm: −21%, asymmetry untouched ─────────────────────── */
.props-head { margin-bottom: clamp(52px, 7.2vw, 104px); }
.prop { margin-bottom: clamp(42px, 5.9vw, 84px); }

/* ── 3. property overlay ───────────────────────────────────────────────── */
/* The photograph leads, then the name, then the facts. Extra air around the
   title and before the description so the panel reads as a page rather than
   a data sheet. */
.ov-body {
  padding: clamp(30px, 4.2vw, 58px) clamp(28px, 4vw, 52px) clamp(34px, 4.4vw, 62px);
}
.ov-title {
  font-size: clamp(2.3rem, 4.6vw, 3.7rem);
  margin-top: 10px;
}
.ov-loc { margin-top: 14px; }
.ov-specs {
  margin: clamp(32px, 3.6vw, 46px) 0 clamp(34px, 3.8vw, 50px);
  padding: 26px 0;
}
.ov-desc {
  max-width: 62ch;
  margin-bottom: clamp(36px, 4.2vw, 54px);
}
.ov-gal { gap: 14px; margin-bottom: clamp(32px, 4.2vw, 46px); }
/* Editorial rather than a product grid: the first frame runs the full width
   in a wider crop, the rest pair off beneath it. */
@media (min-width: 620px) {
  .ov-gal figure:first-child { grid-column: 1 / -1; aspect-ratio: 16 / 9; }
}
/* More room to work with on a large screen. */
@media (min-width: 1600px) {
  .ov-panel { width: min(1040px, 100%); }
}

/* A thin drawn cross reads quieter than the × glyph at this size. */
.ov-close {
  font-size: 0;
  background: rgba(243, 240, 234, 0.9);
  backdrop-filter: blur(8px);
  transition:
    background 0.28s var(--ease),
    color 0.28s var(--ease),
    border-color 0.28s var(--ease);
}
.ov-close::before,
.ov-close::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 15px;
  height: 1px;
  background: currentColor;
}
.ov-close::before { transform: translate(-50%, -50%) rotate(45deg); }
.ov-close::after { transform: translate(-50%, -50%) rotate(-45deg); }

/* Opening stagger: image, then the words. Nothing waits on it — the panel is
   already interactive, and the overlay is display:none until JS opens it, so
   nothing is hidden from a no-JS reader. */
.ov-hero,
.ov-body {
  opacity: 0;
  transform: translateY(10px);
  transition:
    opacity 0.5s var(--ease-o),
    transform 0.5s var(--ease-o);
}
.ov.is-on .ov-hero { opacity: 1; transform: none; transition-delay: 0.06s; }
.ov.is-on .ov-body { opacity: 1; transform: none; transition-delay: 0.16s; }

/* ── 4. dark feature section: −10% ─────────────────────────────────────── */
.feature { padding: clamp(72px, 9.9vw, 144px) 0; }
.feature-head { margin-bottom: clamp(40px, 5.4vw, 78px); }

/* ── 5. measure ────────────────────────────────────────────────────────── */
.agency-body p { max-width: min(640px, 100%); }
.steps li p { max-width: 54ch; }

/* -- 6. testimonials -------------------------------------------------- */
/* An oversized opening quote was tried here and removed: at any size that
   read as "editorial" it collided with the thin rule above each quote and
   got clipped, leaving a stray tick in the corner. The section is stronger
   left alone. */

/* ── 7. micro-interactions ─────────────────────────────────────────────── */
/* The focus underline moves to the brand bronze rather than a stray olive. */
.est-form input:focus,
.est-form select:focus,
.est-form textarea:focus {
  border-bottom-color: #c9a184;
}
/* outline:none above removed the keyboard ring entirely; put a real one back
   for keyboard users without showing it on mouse focus. */
.est-form input:focus-visible,
.est-form select:focus-visible,
.est-form textarea:focus-visible {
  outline: 2px solid rgba(201, 161, 132, 0.6);
  outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
  .ov-hero, .ov-body,
  .ov.is-on .ov-hero, .ov.is-on .ov-body {
    opacity: 1;
    transform: none;
    transition: none;
    transition-delay: 0s;
  }
}
