/* ==========================================================================
   Mira Verde / Trussardi Residences — design system
   ==========================================================================

   Structure, layout rhythm and interaction model follow the reference build
   (avenewdevelopment.ae/projects/cheval-residences-dubai-islands): a 72px page
   gutter, an 80px transparent nav over a full-height hero, alternating light /
   band / dark sections, full-bleed image blocks with the copy set into the top
   left and an accent rule along the bottom edge, 50/50 gallery-and-text rows,
   a four-up amenities carousel, and a centred two-column contact form.

   Colour, typography and the accent are Percent&Co's, not the reference's:
   green #26332F, cream #F3F1EC, burgundy #5E1B1B, Cormorant Garamond and
   EB Garamond. Every token name below is unchanged from the previous system —
   lead-capture.css is layered on top of them and must keep resolving.
   ========================================================================== */

:root {
  /* Colour */
  --green:        #26332F;   /* dark sections, buttons, ink on light */
  --green-soft:   #4E5C56;   /* secondary button fill */
  --footer-green: #1A2320;
  --shell:        #12160F;   /* logo lockup panel — community */
  --shell-alt:    #171C19;   /* logo lockup panel — project */
  --grey:         #EFEFEC;   /* primary light background */
  --grey-alt:     #E9E9E6;
  --band:         #C7CDC8;   /* the mid band between light and dark */
  --band-deep:    #B7BEB9;
  --white:        #FFFFFF;
  --cream:        #F3F1EC;   /* text on dark, light buttons */
  --muted:        #5F6E6A;   /* body copy on light */
  --muted-soft:   #6C7A75;
  --label:        #8F9993;   /* eyebrows, micro-labels on light */
  --hairline:     #DFE2DE;
  --hairline-alt: #E8E8E5;
  --burgundy:     #5E1B1B;   /* the accent — rules, borders, marks */

  --on-dark-90: rgba(243, 241, 236, .9);
  --on-dark-85: rgba(243, 241, 236, .85);
  --on-dark-70: rgba(243, 241, 236, .7);
  --on-dark-62: rgba(243, 241, 236, .62);
  --on-dark-50: rgba(243, 241, 236, .5);
  --on-dark-38: rgba(243, 241, 236, .38);
  --rule-dark:  rgba(243, 241, 236, .18);
  --fill-dark:  rgba(243, 241, 236, .06);

  /* The accent rule under every full-bleed image. The reference runs a gold
     texture here; this is its Percent&Co equivalent — burgundy lit through the
     centre so the edge reads as a struck line rather than a flat border. */
  --accent-rule: linear-gradient(90deg,
      #2F3E39 0%, #5E1B1B 24%, #8E3E3E 50%, #5E1B1B 76%, #2F3E39 100%);

  /* Type */
  --display: 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
  --body:    'EB Garamond', Georgia, 'Times New Roman', serif;

  /* Geometry — the reference's 72px page gutter and 28.8px full-bleed inset */
  --container: 1600px;
  --container-narrow: 1440px;
  --pad:     clamp(20px, 5vw, 72px);
  --gutter:  var(--pad);
  --edge:    clamp(12px, 2vw, 28.8px);
  --rhythm:  clamp(72px, 9vw, 144px);
  --gap-tight: clamp(12px, 1.2vw, 20px);
  --gap-card:  clamp(14px, 1.6vw, 26px);
  /* Flat corners throughout, as the reference is. --r-btn is the lead layer's
     input radius as well as the button's, so it stays a small real value —
     pill buttons set 999px themselves rather than through this token. */
  --r-lg: 0px;
  --r-md: 0px;
  --r-sm: 0px;
  --r-btn: 4px;

  /* Motion */
  --ease: cubic-bezier(.2, .8, .2, 1);
  --header-h: 80px;
}

/* --------------------------------------------------------------- base --- */

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: var(--header-h);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--grey);
  color: var(--green);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
}

/* Any component that sets `display` outranks the UA's [hidden] rule, and the
   floor-plan panel is toggled by the hidden attribute alone — without this the
   "released on request" fallback renders underneath a real drawing. */
[hidden] { display: none !important; }

img, svg, video { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
input, button, textarea, select { font: inherit; color: inherit; }
::placeholder { color: #93A09B; opacity: 1; }
::selection { background: var(--burgundy); color: var(--cream); }

:focus-visible { outline: 2px solid currentColor; outline-offset: 3px; }

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

.skip-link {
  position: absolute;
  left: 12px; top: -100px;
  z-index: 200;
  background: var(--cream);
  color: var(--green);
  padding: 12px 20px;
  transition: top .2s;
}
.skip-link:focus { top: 12px; }

/* ---------------------------------------------------------- typography --- */

h1, h2, h3, h4 { margin: 0; font-family: var(--display); font-weight: 300; }
p { margin: 0; text-wrap: pretty; }
p + p { margin-top: 1.1em; }

/* The reference's h1: uppercase, light, and opened up with a wide track. */
.h-hero {
  font-weight: 300;
  font-size: clamp(38px, 5.4vw, 88px);
  line-height: 1.02;
  letter-spacing: .1em;
  text-transform: uppercase;
  text-wrap: balance;
}
.h-hero strong { font-weight: 500; }

/* The reference's h2 — one size everywhere, uppercase, tight leading. */
.h-section {
  font-weight: 300;
  font-size: clamp(24px, 2.5vw, 38px);
  line-height: 1.08;
  letter-spacing: .06em;
  text-transform: uppercase;
  text-wrap: balance;
}
.h-section--lg { font-size: clamp(28px, 3.2vw, 52px); }

/* The reference's h3 — the tiny label that sits above every h2. `.eyebrow` is
   the same thing under its previous name; both are live in the markup. */
.label,
.eyebrow {
  margin: 0;
  font-family: var(--body);
  font-weight: 600;
  font-size: 12px;
  letter-spacing: .24em;
  line-height: 1;
  text-transform: uppercase;
}

.micro {
  font-size: 11px;
  letter-spacing: .2em;
  text-transform: uppercase;
  line-height: 1.4;
}

.h-card {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(20px, 1.7vw, 27px);
  line-height: 1.18;
  letter-spacing: .04em;
  text-transform: uppercase;
}

.figure {
  font-family: var(--display);
  font-weight: 400;
  font-size: clamp(24px, 2.6vw, 42px);
  line-height: 1;
  font-variant-numeric: lining-nums tabular-nums;
}

/* The reference keeps body copy inside a narrow measure everywhere. */
.copy { font-size: 17px; line-height: 1.55; }
.copy--set { max-width: 42ch; }
.lead { font-size: clamp(17px, 1.25vw, 20px); line-height: 1.6; }

.muted { color: var(--muted); }
/* Was --on-dark-62 (5.5:1). Body copy is not a caption: on the dark bands it
   is the only thing carrying the argument, and 62% cream on #26332F reads as
   grey rather than as text. 85% measures 8.9:1 composited, and the headings
   above it are full cream, so the hierarchy survives the change. */
.muted-dark { color: var(--on-dark-85); }
.section--dark .muted-dark,
.section--dark .duo__text > p { font-size: clamp(17px, 1.15vw, 18px); line-height: 1.6; }

/* -------------------------------------------------------------- layout --- */

.section { padding: var(--rhythm) var(--pad); }
.section--tight { padding-block: clamp(52px, 6vw, 104px); }
.section--flush { padding: 0; }
.section--edge  { padding-inline: var(--edge); }
/* Full-bleed blocks are laid edge to edge and carry no padding of their own,
   so two in a row butt together. This is the air between them, and it takes
   the colour of the section it belongs to, which keeps the band boundaries
   reading as deliberate rather than as a seam. */
.section--flush + .section--flush { padding-top: clamp(40px, 5vw, 84px); }
/* A flush block followed by a band of a different colour has no air under it:
   the next band's own top padding is that band's colour, so the two read as one
   object butted together. This gives the block a gap underneath in its OWN
   colour, matching the air above it. Used on the developer block, which runs
   straight into the dark agency band below it. */
.section--gap-below { padding-bottom: var(--rhythm); }
.section--dark  { background: var(--green); color: var(--cream); }
.section--light { background: var(--grey);  color: var(--green); }
.section--band  { background: var(--band);  color: var(--green); }

.wrap { max-width: var(--container); margin-inline: auto; }
.wrap--narrow { max-width: var(--container-narrow); margin-inline: auto; }
.wrap--text { max-width: 760px; margin-inline: auto; }

.split { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(24px, 3vw, 60px); }
.split--wide  { grid-template-columns: minmax(0, 1fr) minmax(0, .8fr); }
.split--lead  { grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr); }
.split--layouts   { grid-template-columns: minmax(0, .6fr) minmax(0, 1.4fr); gap: clamp(16px, 1.6vw, 26px); }
.split--lead-card { grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); }
.split--flush { gap: 0; align-items: stretch; }
.split--end   { align-items: end; }
.split--start { align-items: start; }
.split--stretch { align-items: stretch; }

.grid { display: grid; gap: var(--gap-tight); }
.grid--cards { gap: var(--gap-card); }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }

.stack-head { margin-bottom: clamp(28px, 3.2vw, 52px); }
.center { text-align: center; }

/* ----------------------------------------------------------------- nav --- */

/* 80px, transparent over the hero, and it takes a solid ground the moment the
   hero has passed. Cream ink stranded on a light section is the one failure
   this must never have, so the solid ground is the markup default and JS only
   ever removes it. */
.site-header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 80;
  height: var(--header-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding-inline: var(--pad);
  background: rgba(239, 239, 236, .96);
  -webkit-backdrop-filter: blur(14px);
  backdrop-filter: blur(14px);
  color: var(--green);
  transition: background .5s ease, color .4s ease, box-shadow .5s ease;
}
.site-header::after {
  content: "";
  position: absolute; inset: auto 0 0;
  height: 1px;
  background: var(--hairline);
  opacity: 1;
  transition: opacity .5s ease;
}
.site-header.is-top {
  background: transparent;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  color: var(--cream);
}
.site-header.is-top::after { opacity: 0; }

/* Agency mark · hairline · project logotype — the lockup carries both brands
   at every width. Both marks take their colour from the bar, so the pair
   inverts with `.is-top` for free. */
.brand { display: flex; align-items: center; gap: clamp(11px, 1.1vw, 18px); flex-shrink: 0; }
.brand__stack { display: flex; flex-direction: column; gap: 3px; }
.brand__rule { width: 1px; align-self: stretch; min-height: 26px; background: currentColor; opacity: .3; }

.brand__logo {
  position: relative;
  display: block;
  height: var(--brand-logo-h, clamp(13px, 1.3vw, 19px));
  width: calc(var(--brand-logo-h, clamp(13px, 1.3vw, 19px)) * var(--brand-logo-ratio));
  background-color: currentColor;
  -webkit-mask: var(--brand-logo-src) no-repeat center / contain;
  mask: var(--brand-logo-src) no-repeat center / contain;
}
.brand__logo--mv { --brand-logo-ratio: 9.83; --brand-logo-src: url(../logo/mira-verde.svg); }
.brand__logo--tr {
  --brand-logo-ratio: 9.05;
  --brand-logo-h: clamp(19px, 2vw, 28px);
  --brand-logo-src: url(../logo/trussardi-mira-verde.svg);
}
.brand__logo span {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}
@supports not ((-webkit-mask-image: url(#m)) or (mask-image: url(#m))) {
  .brand__logo { width: auto; height: auto; background: none; }
  .brand__logo span {
    position: static; width: auto; height: auto; margin: 0;
    clip-path: none; overflow: visible;
    font-family: var(--display);
    font-size: clamp(17px, 1.4vw, 23px);
    letter-spacing: .22em;
    text-transform: uppercase;
  }
}
.brand__mark {
  font-family: var(--display);
  font-weight: 500;
  font-size: clamp(15px, 1.2vw, 19px);
  letter-spacing: .2em;
  line-height: 1.1;
  text-transform: uppercase;
}
.brand__sub { font-size: clamp(8px, .62vw, 10px); letter-spacing: .3em; text-transform: uppercase; opacity: .65; line-height: 1.2; }

.header__right { display: flex; align-items: center; gap: clamp(14px, 1.8vw, 30px); flex-shrink: 0; }
.header__nav { display: flex; align-items: center; gap: clamp(14px, 1.6vw, 26px); }
.header__nav a {
  position: relative;
  font-size: 12px;
  letter-spacing: .18em;
  text-transform: uppercase;
  padding-block: 4px;
  transition: opacity .3s;
}
/* The rule is drawn from the left rather than switched on, so the nav answers
   the pointer with movement instead of a state change. */
.header__nav a::after {
  content: "";
  position: absolute; inset: auto 0 0;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform .4s var(--ease);
}
.header__nav a:hover::after { transform: scaleX(1); transform-origin: left; }

/* MENU, then the two rules — the reference's mark, in the agency's ink. */
.menu-btn {
  display: flex; align-items: center; gap: 14px;
  background: none; border: none; padding: 8px 0; cursor: pointer;
}
.menu-btn .micro { font-size: 12px; letter-spacing: .2em; }
.menu-btn__lines { display: flex; flex-direction: column; gap: 5px; }
.menu-btn__lines i {
  display: block; width: 46px; height: 1px;
  background: currentColor;
  transition: transform .4s var(--ease), width .4s var(--ease);
}
.menu-btn:hover .menu-btn__lines i:last-child { width: 30px; }
.menu-btn[aria-expanded="true"] .menu-btn__lines i:first-child { transform: translateY(3px) rotate(5deg); }
.menu-btn[aria-expanded="true"] .menu-btn__lines i:last-child  { transform: translateY(-3px) rotate(-5deg); width: 46px; }

/* -------------------------------------------------------------- button --- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 12px 32px;
  border: 1px solid transparent;
  border-radius: 999px;
  font-size: 12px;
  letter-spacing: .2em;
  /* Letter-spacing appends a trailing space after the last glyph, so centred
     text sits one track-width left of true centre. Indenting by the same
     amount puts it back. Every letter-spaced, centred control needs this. */
  text-indent: .2em;
  text-transform: uppercase;
  line-height: 1.2;
  cursor: pointer;
  white-space: nowrap;
  transition: background .35s, color .35s, border-color .35s,
              transform .35s var(--ease), box-shadow .35s var(--ease);
}
/* Every button answers the pointer with the same small lift, so the page has
   one hover language rather than a different one per component. */
.btn:hover { transform: translateY(-2px); box-shadow: 0 10px 24px rgba(24, 34, 30, .16); }
.btn:active { transform: translateY(0); box-shadow: none; }
.btn--pill { border-radius: 999px; }
.btn--solid { background: var(--green); color: var(--cream); }
.btn--solid:hover { background: var(--green-soft); }
.btn--cream { background: var(--cream); color: var(--green); }
.btn--cream:hover { background: var(--white); }
.btn--soft { background: var(--green-soft); color: var(--cream); }
.btn--soft:hover { background: var(--green); }
/* The reference's outline pill — a hairline in the accent, nothing else. */
.btn--line { border-color: var(--burgundy); color: var(--green); background: none; }
.btn--line:hover { background: var(--burgundy); border-color: var(--burgundy); color: var(--cream); }
.btn--outline-dark { border-color: rgba(243, 241, 236, .4); color: var(--cream); }
.btn--outline-dark:hover { background: var(--cream); color: var(--green); }
.btn--glass {
  background: rgba(243, 241, 236, .14);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-color: rgba(243, 241, 236, .35);
  color: var(--cream);
}
.btn--glass:hover { background: var(--cream); color: var(--green); }
.btn--block { display: flex; width: 100%; }

/* A download control carries its arrow, as in the reference. */
.btn--dl::after { content: "↓"; margin-left: 12px; font-size: 13px; letter-spacing: 0; }

/* Every other letter-spaced pill in the system needs the same optical
   correction as .btn — see the note there. */
.bed-pill { text-indent: .16em; }
.pill-badge,
.chips span,
.doc-links a,
.doc-links button,
.lead-submit { text-indent: .16em; }

/* The document chips are the one control that had drifted: two different
   sizes across two stylesheets, and no letter-spacing while everything around
   them is tracked. One definition, matching the small-pill treatment. */
.doc-links a,
.doc-links button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 38px;
  padding: 8px 18px;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  background: none;
  font-family: var(--body);
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  line-height: 1.2;
  color: var(--muted);
  cursor: pointer;
  transition: border-color .3s, color .3s, background .3s, transform .3s var(--ease);
}
.doc-links a:hover,
.doc-links button:hover { border-color: var(--burgundy); color: var(--green); transform: translateY(-2px); }

.link-rule {
  display: inline-block;
  padding-bottom: 5px;
  border-bottom: 1px solid currentColor;
  font-size: 13px;
  letter-spacing: .14em;
  text-transform: uppercase;
  transition: opacity .35s;
}
.link-rule:hover { opacity: .7; }

/* ---------------------------------------------------------- nav panel --- */

.nav-panel {
  position: fixed;
  inset: 0;
  z-index: 79;
  background: rgba(26, 35, 32, .985);
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  padding: clamp(90px, 10vw, 140px) var(--pad) clamp(40px, 5vw, 80px);
  color: var(--cream);
  opacity: 0;
  visibility: hidden;
  transition: opacity .4s ease, visibility .4s;
}
.nav-panel[data-open="true"] { opacity: 1; visibility: visible; }
.nav-panel a {
  font-family: var(--display);
  font-weight: 300;
  font-size: clamp(22px, 2.8vw, 42px);
  letter-spacing: .08em;
  text-transform: uppercase;
  padding: 11px 0;
  border-bottom: 1px solid rgba(243, 241, 236, .12);
  transition: padding-left .35s var(--ease), color .3s;
}
.nav-panel a:hover { padding-left: 14px; }
.nav-panel a:last-child { border-bottom: 0; }
.nav-panel .nav-panel__back {
  font-family: var(--body);
  font-size: 11px;
  letter-spacing: .24em;
  padding: 0 0 22px;
  border-bottom: 0;
  color: var(--on-dark-50);
}

/* ---------------------------------------------------------------- hero --- */

/* The reference hero: full height, copy pinned to the bottom edge, the H1 on
   the left and a short kicker plus the scroll cue on the right. */
.hero {
  position: relative;
  height: 100vh;
  height: 100svh;
  min-height: 620px;
  overflow: hidden;
}
.hero__slides { position: absolute; inset: 0; }
.hero__slide { position: absolute; inset: 0; opacity: 0; transition: opacity 1.7s ease; }
.hero__slide.is-active { opacity: 1; }
/* The renders put the horizon a little below centre; a default crop on a
   viewport wider than the source loses the ridge line to sky. */
.hero__slide img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 62%; }
.hero__slide.is-active img { animation: mvDrift 16s ease-out forwards; }

.hero__scrim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg,
    rgba(26, 35, 32, .42) 0%,
    rgba(26, 35, 32, .10) 38%,
    rgba(26, 35, 32, .72) 100%);
}

.hero__inner {
  position: absolute;
  inset: auto 0 0;
  z-index: 2;
  padding: 0 var(--pad) clamp(44px, 6vw, 90px);
  color: var(--cream);
}
.hero__grid {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: clamp(24px, 3vw, 56px);
}
.hero__h1 { flex: 1 1 auto; min-width: 0; }
/* Wide enough that the CTA pair sits on one line beside the kicker — the pair
   is the page's revenue path and must not stack into a column here. */
.hero__aside { flex: 0 0 auto; width: min(580px, 48vw); display: flex; flex-direction: column; gap: clamp(16px, 1.8vw, 26px); }
.hero__kicker {
  font-size: clamp(15px, 1.15vw, 19px);
  line-height: 1.35;
  letter-spacing: .06em;
  text-transform: uppercase;
  font-family: var(--display);
  font-weight: 300;
  color: var(--cream);
}
.hero .eyebrow { color: var(--on-dark-70); margin-bottom: clamp(16px, 1.8vw, 26px); }

.hero__scroll {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  align-self: flex-start;
  padding-bottom: 5px;
  border-bottom: 1px solid var(--cream);
  font-size: 13px;
  letter-spacing: .1em;
  color: var(--cream);
}
.hero__scroll i {
  display: block; width: 9px; height: 9px;
  border-right: 1px solid currentColor;
  border-bottom: 1px solid currentColor;
  transform: rotate(45deg) translate(-1px, -1px);
  animation: mvNudge 2.4s var(--ease) infinite;
}

/* The word-by-word rise the reference runs on its hero, done with CSS only. */
.split-word { display: inline-block; overflow: clip; vertical-align: bottom; }
.split-word > span { display: inline-block; transform: translateY(105%); opacity: 0; }
.is-revealed .split-word > span {
  transform: none;
  opacity: 1;
  transition: transform 1s var(--ease), opacity .8s ease;
  transition-delay: calc(var(--i, 0) * 70ms);
}

/* --------------------------------------------------------------- intro --- */

/* Centred logotype, heading and one paragraph — the reference's opening beat. */
.intro { padding: clamp(90px, 10vw, 144px) var(--pad); text-align: center; }
.intro__inner { display: flex; flex-direction: column; align-items: center; }
.intro__mark { width: clamp(140px, 14vw, 200px); height: auto; margin-bottom: clamp(26px, 3vw, 44px); opacity: .9; }
.intro .h-section { max-width: 16em; }
.intro__copy { margin-top: clamp(22px, 2.6vw, 38px); max-width: 68ch; font-size: clamp(17px, 1.2vw, 19px); line-height: 1.6; color: var(--muted); }
.section--dark .intro__copy { color: var(--on-dark-70); }

/* ------------------------------------------------------ full-bleed block --- */

/* An image that runs the width of the page inside a small inset, the copy set
   into its top left, and the accent rule struck along the bottom edge. */
.imgfull { position: relative; overflow: hidden; height: clamp(420px, 56vw, 720px); }
.imgfull > img,
.imgfull > picture img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  transition: transform 1.6s var(--ease);
}
.imgfull:hover > img,
.imgfull:hover > picture img { transform: scale(1.04); }
/* The copy used to rely on a heavy corner scrim, which asked the render to be
   dark exactly where it is often brightest and left the text sitting in a grey
   wash across a third of the picture. The copy now carries its own plate, so
   the scrim is back to a light vignette — legibility is the plate's job, and
   the render is left looking like a render. */
.imgfull__scrim {
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(22, 30, 27, .30) 0%, rgba(22, 30, 27, 0) 32%),
    linear-gradient(0deg,   rgba(22, 30, 27, .34) 0%, rgba(22, 30, 27, 0) 30%);
}
/* The plate. A frosted panel with the accent struck down its leading edge —
   the copy sits ON something rather than floating over the picture, and the
   contrast no longer depends on which render is behind it. */
.imgfull__body {
  position: absolute;
  top: clamp(20px, 3.4vw, 50px);
  left: clamp(14px, 4vw, 60px);
  right: clamp(14px, 4vw, 60px);
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: clamp(12px, 1.4vw, 20px);
  max-width: min(56ch, 640px);
  padding: clamp(20px, 2.2vw, 36px) clamp(20px, 2.4vw, 40px);
  background: rgba(19, 27, 24, .62);
  -webkit-backdrop-filter: blur(16px) saturate(1.08);
  backdrop-filter: blur(16px) saturate(1.08);
  border-left: 3px solid var(--burgundy);
  box-shadow: 0 24px 60px rgba(10, 16, 13, .3);
  color: var(--cream);
}
/* No backdrop-filter (older Safari, Firefox with it disabled) means the panel
   would be a flat 62% wash over a busy render. Fall back to near-opaque. */
@supports not ((-webkit-backdrop-filter: blur(1px)) or (backdrop-filter: blur(1px))) {
  .imgfull__body { background: rgba(19, 27, 24, .88); }
}
.imgfull__body--right { left: auto; right: clamp(14px, 4vw, 60px); text-align: right; align-items: flex-end; border-left: 0; border-right: 3px solid var(--burgundy); }
.imgfull__body--bottom { top: auto; bottom: clamp(30px, 4vw, 60px); }
.imgfull__body .label { color: var(--on-dark-70); }
.imgfull__body p { color: var(--on-dark-90); max-width: 48ch; }
.imgfull__body--right p { margin-left: auto; }

/* ------------------------------------------------------- master plan --- */

/* Edge to edge, and NOT cropped: this is a drawing whose labels are the
   content, so `cover` would cut "Trussardi Residences Tower A" off the left
   edge on a wide viewport. Height follows the aspect ratio instead. */
.masterplan { position: relative; margin: clamp(30px, 3.4vw, 54px) 0 0; }
.masterplan__zoom {
  display: block;
  position: relative;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  cursor: zoom-in;
}
.masterplan img { width: 100%; height: auto; display: block; }
.masterplan__hint {
  position: absolute;
  right: clamp(14px, 2vw, 28px); bottom: clamp(18px, 2.2vw, 32px);
  padding: 8px 16px;
  border-radius: 999px;
  border: 1px solid rgba(243, 241, 236, .22);
  background: rgba(18, 22, 15, .78);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  color: var(--cream);
  font-size: 12px;
  letter-spacing: .14em;
  text-transform: uppercase;
  white-space: nowrap;
  pointer-events: none;
  transition: background .3s;
}
.masterplan__zoom:hover .masterplan__hint { background: var(--burgundy); }
/* Bottom right is where the drawing's own labels are densest, and at phone
   width the hint lands on top of three of them. */
@media (max-width: 760px) {
  .masterplan__hint {
    top: 12px; right: 12px; bottom: auto;
    padding: 6px 12px;
    font-size: 11px;
  }
}

/* The rule. 4px, and it reads as struck metal rather than a flat border. */
.accent-line {
  position: absolute; inset: auto 0 0;
  height: 4px;
  background: var(--accent-rule);
  z-index: 2;
}

/* --------------------------------------------------- gallery + text row --- */

/* Half the row is a gallery, half is a centred block of copy. `--flip` swaps
   the sides on wide screens; DOM order stays reading order. */
/* minmax(0,1fr), not 1fr: a grid item's automatic minimum is its min-content,
   and a slider track full of 100%-wide slides has a large one. With plain 1fr
   the column refuses to shrink and the page gains a horizontal scrollbar on a
   phone. Same reason for .dev below. */
.duo { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: center; }
/* Held inside the same inset as the full-bleed blocks, so every block on the
   page shares one left and right edge. The reference lets its gallery rows run
   edge to edge while its image blocks sit inset, and the two-pixel disagreement
   between them is visible at every boundary. */
.duo, .dev { margin-inline: var(--edge); }
.duo__media { position: relative; min-width: 0; }
.duo__text {
  display: flex; flex-direction: column; align-items: center;
  text-align: center;
  gap: clamp(24px, 3vw, 50px);
  padding: clamp(40px, 5vw, 80px) clamp(24px, 4vw, 72px);
}
.duo__text > p { max-width: 46ch; color: var(--muted); }
.section--dark .duo__text > p,
.section--band .duo__text > p { color: inherit; }
.section--band .duo__text > p { color: #3B4844; }
@media (min-width: 1001px) {
  .duo--flip .duo__media { order: 2; }
}

/* --------------------------------------------------------------- slider --- */

/* One vanilla slider drives the gallery rows, the amenities row and the
   developer row. No CDN: the reference loads Splide and Swiper; this is
   ~120 lines of CSS and JS against two dependencies. */
.slider { position: relative; min-width: 0; }
.slider__viewport { overflow: hidden; }
.slider__track {
  display: flex;
  transition: transform .8s var(--ease);
  will-change: transform;
}
.slider__slide { flex: 0 0 100%; min-width: 0; }

.slider--gallery .slider__viewport { position: relative; }
.slider--gallery .slider__slide img {
  width: 100%;
  height: clamp(320px, 46vw, 648px);
  object-fit: cover;
  display: block;
  transition: transform 1.6s var(--ease);
}
/* The reference lifts its gallery slightly on hover. Scaling the image rather
   than the slide keeps the track transform — which is what pages the carousel
   — free of anything else. */
.slider--gallery:hover .slider__slide img { transform: scale(1.035); }
.slider--gallery .accent-line { z-index: 4; }

/* Enlarge control over the gallery. */
.slider__zoom {
  position: absolute;
  top: clamp(14px, 1.6vw, 24px); right: clamp(14px, 1.6vw, 24px);
  z-index: 4;
  width: 44px; height: 44px;
  border-radius: 50%;
  border: 1px solid rgba(243, 241, 236, .5);
  background: rgba(26, 35, 32, .3);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  color: var(--cream);
  font-size: 16px; line-height: 1;
  cursor: zoom-in;
  opacity: 0;
  transition: opacity .35s, background .35s;
}
.slider:hover .slider__zoom, .slider__zoom:focus-visible { opacity: 1; }
.slider__zoom:hover { background: var(--burgundy); border-color: var(--burgundy); }

/* Counter — "10 / 18", as the reference announces its slide position. */
.slider__count {
  position: absolute;
  left: clamp(14px, 1.6vw, 24px); bottom: clamp(20px, 2.2vw, 32px);
  z-index: 4;
  font-size: 12px;
  letter-spacing: .2em;
  color: var(--cream);
  text-shadow: 0 1px 12px rgba(20, 28, 24, .8);
  font-variant-numeric: lining-nums tabular-nums;
}

/* Dot rail. */
.slider__dots {
  position: absolute;
  inset: auto clamp(14px, 1.6vw, 24px) clamp(20px, 2.2vw, 32px) auto;
  z-index: 4;
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 6px;
  max-width: 60%;
}
.slider__dots button {
  width: 22px; height: 2px;
  padding: 0;
  border: 0;
  background: rgba(243, 241, 236, .38);
  cursor: pointer;
  transition: background .3s;
}
.slider__dots button[aria-selected="true"] { background: var(--cream); }
.slider__dots button:hover { background: rgba(243, 241, 236, .75); }

/* Round arrows, hairlined in the accent — the reference's control. */
.slider__arrow {
  width: 46px; height: 46px;
  border-radius: 50%;
  border: 1px solid var(--burgundy);
  background: rgba(255, 255, 255, .4);
  color: var(--green);
  font-size: 17px; line-height: 1;
  cursor: pointer;
  transition: background .35s, color .35s, transform .35s var(--ease), border-color .35s;
}
.slider__arrow:hover { background: var(--burgundy); color: var(--cream); }
.slider__arrow--prev:hover { transform: translateX(-3px); }
.slider__arrow--next:hover { transform: translateX(3px); }
.slider__arrow[disabled] { opacity: .3; cursor: default; }
.slider__arrow[disabled]:hover { transform: none; background: rgba(255, 255, 255, .4); color: var(--green); }
.section--dark .slider__arrow { border-color: var(--on-dark-50); background: rgba(243, 241, 236, .06); color: var(--cream); }
.section--dark .slider__arrow:hover { background: var(--cream); color: var(--green); }
/* Both disabled-hover resets must be restated on the dark ground: the dark
   hover rule above carries the same specificity and comes later, so without
   this a paged-out arrow lights up cream. */
.section--dark .slider__arrow[disabled]:hover { background: rgba(243, 241, 236, .06); color: var(--cream); transform: none; }
.slider__arrows { display: flex; gap: 10px; justify-content: center; margin-top: clamp(24px, 2.6vw, 40px); }

/* ----------------------------------------------------------- amenities --- */

/* Four up, static. This was a paged, autoplaying rail; with exactly four cards
   it had nothing to page on a desktop and only ever moved under the reader.
   It is a grid now — four across, two on a tablet, one on a phone. */
.amenities__head { text-align: center; display: flex; flex-direction: column; align-items: center; }
.amenities__head .intro__mark { margin-bottom: clamp(20px, 2.4vw, 34px); }
.amenity-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(20px, 2.4vw, 38px) clamp(10px, 1.2vw, 18px);
  margin-top: clamp(34px, 4vw, 62px);
}
/* Six amenities here, so three across rather than four — four would leave a
   widow pair on the second row. The 1100px rule further down still takes it to
   two and 640px to one; this only sets the desktop count. */
.amenity-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* The facet is centred in its column by `margin-inline:auto`, so the title and
   the sentence have to be centred against it or the card reads as two pieces
   that miss each other. One centred column, and the copy takes a measure
   rather than the full column width so the ragged edge stays symmetrical. */
.amenity-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}
/* The reference cuts each amenity image into a faceted crystal inside a struck
   metal edge, and gives each one a different cut so the row reads as four
   objects rather than four thumbnails. Same device here, in the brand accent:
   the frame is the accent gradient, the image is clipped 2px inside it.

   Each facet is a closed polygon on the same five-point armature, nudged per
   card. Keep them convex — a concave point reads as a rendering fault, not a
   cut stone. */
.amenity__frame {
  --facet: polygon(38% 0%, 100% 22%, 88% 88%, 20% 100%, 0% 42%);
  position: relative;
  width: min(100%, 300px);
  aspect-ratio: 1 / 1;
  margin-inline: auto;
  padding: 3px;
  background: var(--accent-rule);
  clip-path: var(--facet);
  transition: filter .5s var(--ease), transform .5s var(--ease);
}
.amenity__frame img {
  width: 100%; height: 100%;
  object-fit: cover;
  clip-path: var(--facet);
  transition: transform 1.4s var(--ease);
}
.amenity-card:hover .amenity__frame img { transform: scale(1.06); }
.amenity-card:hover .amenity__frame { filter: brightness(1.06); transform: translateY(-5px); }
.amenity-card .amenity__title { transition: color .4s; }
.amenity-card:hover .amenity__title { color: var(--burgundy); }
.section--dark .amenity-card:hover .amenity__title { color: var(--cream); }

.amenity-card:nth-child(4n+2) .amenity__frame {
  --facet: polygon(58% 2%, 100% 42%, 74% 100%, 10% 90%, 0% 26%);
}
.amenity-card:nth-child(4n+3) .amenity__frame {
  --facet: polygon(44% 0%, 96% 14%, 100% 74%, 32% 100%, 0% 58%);
}
.amenity-card:nth-child(4n+4) .amenity__frame {
  --facet: polygon(64% 0%, 100% 50%, 64% 100%, 6% 84%, 0% 22%);
}
/* Two lines' worth of room whether the title needs it or not, so the
   paragraphs below sit on one baseline across the row. */
.amenity__title {
  margin-top: clamp(16px, 1.8vw, 24px);
  min-height: 2.4em;
  font-family: var(--display);
  font-weight: 300;
  font-size: clamp(18px, 1.5vw, 24px);
  letter-spacing: .08em;
  text-transform: uppercase;
  line-height: 1.2;
}
.amenity__text { margin-top: 10px; max-width: 32ch; margin-inline: auto; font-size: 16px; line-height: 1.5; color: #3E4B47; }
.section--dark .amenity__text { color: var(--on-dark-62); }

/* ------------------------------------------------------- reason cards --- */

/* Nine equal boxes stacked three-by-three read as a specification sheet: the
   eye has no entry point and no reason to move. The same nine reasons on a
   paged rail give it one — three at a time, numbered, with the accent struck
   across the top of each so the row reads as a sequence being worked through
   rather than a wall. Same slider as the amenities row, wider slides. */
.slider--cards { margin-top: clamp(28px, 3.2vw, 48px); }
.slider--cards .slider__track { gap: var(--gap-card); align-items: stretch; }
.slider--cards .slider__slide { flex: 0 0 calc((100% - 2 * var(--gap-card)) / 3); display: flex; }

.reason {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 100%;
  padding: clamp(24px, 2.4vw, 38px) clamp(20px, 2.2vw, 32px);
  background: var(--white);
  overflow: hidden;
  transition: transform .5s var(--ease), box-shadow .5s var(--ease);
}
.reason::before {
  content: "";
  position: absolute; inset: 0 0 auto;
  height: 3px;
  background: var(--accent-rule);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .6s var(--ease);
}
.reason:hover { transform: translateY(-6px); box-shadow: 0 22px 50px rgba(24, 34, 30, .13); }
.reason:hover::before { transform: scaleX(1); }
.reason__no {
  font-family: var(--display);
  font-size: clamp(30px, 2.8vw, 44px);
  line-height: 1;
  letter-spacing: .04em;
  color: var(--burgundy);
  opacity: .32;
  font-variant-numeric: lining-nums tabular-nums;
  transition: opacity .5s var(--ease);
}
.reason:hover .reason__no { opacity: .7; }
.reason__t { font-family: var(--display); font-weight: 400; font-size: clamp(19px, 1.6vw, 25px); line-height: 1.2; letter-spacing: .04em; text-transform: uppercase; }
.reason__p { font-size: 16px; line-height: 1.55; color: var(--muted); }

/* Three reasons fit on one row, so they are a static grid rather than the
   paged rail nine of them need. `.reason` is self-contained — it sets its own
   width, ground and padding — so it drops into a plain grid unchanged. */
.reason-grid { margin-top: clamp(28px, 3.2vw, 48px); align-items: stretch; }

/* A project card with no page behind it yet is an <article>, not an <a>. The
   hover zoom is the affordance of a link, so it is switched off here — the
   button inside the card is the thing that is actually clickable. */
.project-card--static:hover img { transform: none; }

/* ---------------------------------------------------------- developer --- */

.dev { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); align-items: stretch; }
.dev__media { position: relative; overflow: hidden; min-height: clamp(340px, 40vw, 620px); }
/* :not() matters — the logotype is a sibling <img> in the same box, and a bare
   `> img` rule stretches it to the full panel. The ground is inside a
   <picture> now, so that arm is named too: a `> img` rule alone stops
   matching the moment the image gains a webp source set. */
.dev__media > img:not(.dev__logo),
.dev__media > picture img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.dev__media .lockup__scrim { position: absolute; inset: 0; background: linear-gradient(125deg, rgba(12, 18, 14, .38), rgba(12, 18, 14, .74)); }
.dev__logo {
  position: absolute;
  left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: min(280px, 52%);
  max-height: 34%;
  height: auto;
  object-fit: contain;
  z-index: 2;
}
.dev__body {
  display: flex; flex-direction: column; justify-content: center;
  padding: clamp(40px, 5vw, 86px) clamp(24px, 4vw, 72px);
  text-align: center;
  align-items: center;
}
.dev__body .slider { width: 100%; }
.dev__slide { display: flex; flex-direction: column; align-items: center; gap: clamp(18px, 2vw, 30px); padding-inline: 4px; }
.dev__slide p { max-width: 52ch; color: var(--muted); }
.section--dark .dev__slide p { color: var(--on-dark-70); }

/* The strip of partner house marks that stood here has been removed, along
   with assets/logo/brands/. Percent&Co have no licence to reproduce Bentley,
   ETRO, ELIE SAAB, Jacob & Co., Trussardi, John Richmond or Gianfranco Ferré
   trade marks, and a brochure is not a licence. The developer paragraph still
   names the houses in running text, which is nominative use and needs none. */

/* The developer row is a full-bleed block with no padding of its own, so the
   dark agency band below butted straight onto it. It gets the same air below
   it that the section above gives it. */
#developer.section--flush { padding-bottom: var(--rhythm); }

/* ------------------------------------------------------------- contact --- */

.contact { padding: clamp(80px, 9vw, 140px) var(--pad); }
.contact__head { text-align: center; display: flex; flex-direction: column; align-items: center; gap: clamp(16px, 2vw, 26px); }
.contact__head p { max-width: 52ch; color: var(--muted); }
.contact__form { margin: clamp(40px, 4.6vw, 72px) auto 0; max-width: 860px; }

/* The reference lays its contact fields out two to a row. The form itself is
   built by lead-capture.js as a flex column and is shared with the dialogs, so
   the two-column arrangement is applied here, on this one mount, rather than
   in the module — the dialogs stay single-column where width is scarce (§11).
   The three fields are the first three divs in the form; everything after them
   (honeypot, consent, submit, note) runs the full width. */
.contact__form .lead-form {
  display: grid;
  grid-template-columns: 1fr 1fr;
  column-gap: clamp(20px, 3vw, 44px);
  align-items: start;
}
.contact__form .lead-form > .lead-field:nth-of-type(3),
.contact__form .lead-form > .lead-trap,
.contact__form .lead-form > .lead-consent,
.contact__form .lead-form > .lead-submit,
.contact__form .lead-form > .lead-note { grid-column: 1 / -1; }
/* The shared submit is width:100% for the dialogs; here it becomes the
   reference's centred 270px pill. */
.contact__form .lead-form > .lead-submit {
  justify-self: center;
  width: auto;
  min-width: 270px;
  border-radius: 999px;
  font-size: 12px;
  letter-spacing: .2em;
  text-transform: uppercase;
}

@media (max-width: 700px) {
  .contact__form .lead-form { grid-template-columns: 1fr; }
  .contact__form .lead-form > .lead-field { grid-column: 1 / -1; }
}

/* ------------------------------------------------------------ invest --- */

/* A dark band carrying only two bordered boxes of text reads as a placeholder.
   This gives it a ground (a render held well back so the copy still measures
   past 4.5:1), a figure strip built from the numbers the approved copy already
   states, and an accent edge on each panel. */
.invest { position: relative; overflow: hidden; }
/* Lift the content off the ground image by naming the wrapper, not `> *`. A
   bare child selector matches .accent-line too and, at equal specificity,
   beats its `position: absolute` — which drops the rule into the flow and
   lands it on top of the CTA. */
.invest > .wrap--narrow { position: relative; z-index: 1; }
.invest__bg { position: absolute; inset: 0; z-index: 0; }
.invest__bg img { width: 100%; height: 100%; object-fit: cover; }
.invest__bg::after {
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(30, 41, 37, .90) 0%, rgba(30, 41, 37, .95) 55%, rgba(30, 41, 37, .99) 100%);
}
.invest .accent-line { z-index: 2; }

.panel {
  position: relative;
  padding: clamp(26px, 3vw, 46px);
  background: rgba(243, 241, 236, .05);
  border: 1px solid rgba(243, 241, 236, .13);
  transition: background .4s, border-color .4s;
}
.panel::before {
  content: "";
  position: absolute; inset: 0 0 auto;
  height: 2px;
  background: var(--accent-rule);
}
.panel:hover { background: rgba(243, 241, 236, .08); border-color: rgba(243, 241, 236, .22); }

/* ------------------------------------------------------------- cards --- */

.card {
  background: var(--white);
  padding: clamp(26px, 2.8vw, 46px);
  transition: transform .5s var(--ease), box-shadow .5s var(--ease);
}
.card:hover { transform: translateY(-5px); box-shadow: 0 20px 46px rgba(24, 34, 30, .12); }
.card--sm { padding: clamp(20px, 2.2vw, 32px); }
.card--dark { background: var(--fill-dark); border: 1px solid rgba(243, 241, 236, .12); padding: clamp(20px, 2.2vw, 34px); }
.card--line { background: none; border: 1px solid var(--hairline); }
.section--band .card--line { border-color: rgba(38, 51, 47, .18); }

.figure-card { border-top: 1px solid var(--hairline); padding-top: clamp(14px, 1.4vw, 22px); }
.section--dark .figure-card { border-top-color: var(--rule-dark); }

/* -------------------------------------------------------- project card --- */

.project-card { display: block; position: relative; overflow: hidden; color: var(--cream); }
.project-card img { width: 100%; height: clamp(340px, 46vw, 700px); object-fit: cover; transition: transform 1.4s var(--ease); }
.project-card:hover img { transform: scale(1.04); }
.project-card__scrim { position: absolute; inset: 0; background: linear-gradient(180deg, rgba(26, 35, 32, .1) 30%, rgba(26, 35, 32, .88)); }
.project-card__body { position: absolute; inset: 0; padding: clamp(22px, 2.8vw, 48px); display: flex; flex-direction: column; justify-content: space-between; }
.project-card__foot { display: flex; flex-wrap: wrap; gap: clamp(20px, 3vw, 56px); align-items: flex-end; justify-content: space-between; }
.pill-badge {
  align-self: flex-start;
  background: rgba(243, 241, 236, .14);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(243, 241, 236, .3);
  padding: 8px 18px;
  border-radius: 999px;
  font-size: 11px;
  letter-spacing: .2em;
  text-transform: uppercase;
}
.project-card__cta { background: var(--cream); color: var(--green); }
.project-card:hover .project-card__cta { background: var(--burgundy); color: var(--cream); }

/* ------------------------------------------------------------ location --- */

/* Name over time, not name-then-time-across-a-gap. On one line the two halves
   of each pair sat a third of the row apart and the eye had to travel to pair
   them up; stacked, each destination is one object. */
.travel {
  display: flex; flex-direction: column; align-items: flex-start;
  gap: 6px; padding: clamp(14px, 1.4vw, 20px) 0;
  border-top: 1px solid var(--hairline);
  transition: border-top-color .4s, padding-left .4s var(--ease);
}
.travel:hover { border-top-color: var(--burgundy); padding-left: 8px; }
.section--dark .travel { border-top-color: var(--rule-dark); }
.travel span:first-child {
  font-size: 11px; letter-spacing: .2em; text-transform: uppercase;
  color: var(--label);
}
.section--dark .travel span:first-child { color: var(--on-dark-50); }
.travel span:last-child { font-family: var(--display); font-size: clamp(22px, 1.9vw, 30px); line-height: 1; white-space: nowrap; transition: color .4s; }
.travel:hover span:last-child { color: var(--burgundy); }
.section--dark .travel:hover span:last-child { color: var(--cream); }

/* The map is a real Google embed, built lazily — nothing is requested from
   Google on a visit that never reaches Location. It used to run the full width
   of the page, where a raw Google tile set is simply a large ugly rectangle;
   it is a framed panel beside the travel times now, at half the row. */
.location__row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(28px, 3.4vw, 60px);
  align-items: stretch;
  margin-top: clamp(30px, 3.4vw, 52px);
}
.location__times { display: flex; flex-direction: column; justify-content: center; }
.map {
  position: relative;
  margin: 0;
  min-height: clamp(300px, 34vw, 480px);
  overflow: hidden;
  border: 1px solid var(--hairline);
  background-color: #2E3C37;
  background-image: repeating-linear-gradient(135deg, rgba(243, 241, 236, .05) 0 2px, transparent 2px 12px);
}
@media (max-width: 1000px) {
  .location__row { grid-template-columns: minmax(0, 1fr); }
  .map { min-height: clamp(260px, 52vw, 380px); }
}
.map iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; opacity: 0; transition: opacity .7s var(--ease); }
.map[data-loaded="true"] iframe { opacity: 1; }
.map[data-touch="true"]:not([data-active="true"]) iframe { pointer-events: none; }
.map__hint {
  position: absolute; z-index: 3;
  left: 50%; bottom: 22px; transform: translateX(-50%);
  padding: 8px 16px;
  border-radius: 999px;
  border: 1px solid rgba(243, 241, 236, .18);
  background: rgba(18, 22, 15, .82);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  color: var(--cream);
  font-size: 12px;
  letter-spacing: .14em;
  text-transform: uppercase;
  white-space: nowrap;
  pointer-events: none;
  transition: opacity .3s;
}
.map:not([data-touch="true"]) .map__hint,
.map[data-active="true"] .map__hint { opacity: 0; }
.map__fallback {
  position: absolute; inset: 0;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px; text-align: center; padding: 24px;
  background: linear-gradient(rgba(24, 34, 30, .72), rgba(24, 34, 30, .72));
  color: var(--cream);
}
.map__fallback p { max-width: 40ch; font-size: 16px; color: var(--on-dark-70); }

/* ------------------------------------------------------------ lightbox --- */

.lightbox {
  position: fixed; inset: 0; z-index: 120;
  background: rgba(20, 28, 25, .96);
  display: flex; align-items: center; justify-content: center;
  padding: clamp(16px, 4vw, 64px);
  cursor: zoom-out;
  opacity: 0; visibility: hidden;
  transition: opacity .4s ease, visibility .4s;
}
.lightbox[data-open="true"] { opacity: 1; visibility: visible; }
.lightbox img { max-width: 100%; max-height: 100%; object-fit: contain; transition: opacity .35s ease; }
.lightbox[data-swapping="true"] img { opacity: 0; }
.lightbox__close {
  position: absolute; top: clamp(14px, 2vw, 28px); right: clamp(14px, 2vw, 28px);
  width: 48px; height: 48px; border-radius: 50%;
  border: 1px solid rgba(243, 241, 236, .4);
  background: none; color: var(--cream);
  font-size: 22px; line-height: 1; cursor: pointer;
  transition: background .3s, color .3s;
}
.lightbox__close:hover { background: var(--cream); color: var(--green); }

/* An enlarged gallery image that can only be closed and re-opened to see the
   next one is a dead end — the visitor is deepest in the imagery at exactly
   the moment the interface stops helping. The arrows page the gallery the
   image came from, and the slider is moved to match on close, so the two are
   never showing different pictures. */
.lightbox__nav {
  position: absolute; top: 50%;
  transform: translateY(-50%);
  width: 54px; height: 54px;
  border-radius: 50%;
  border: 1px solid rgba(243, 241, 236, .4);
  background: rgba(20, 28, 25, .4);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
  color: var(--cream);
  font-size: 19px; line-height: 1;
  cursor: pointer;
  transition: background .3s, color .3s, border-color .3s, transform .3s var(--ease);
}
.lightbox__nav--prev { left: clamp(10px, 2vw, 30px); }
.lightbox__nav--next { right: clamp(10px, 2vw, 30px); }
.lightbox__nav:hover { background: var(--burgundy); border-color: var(--burgundy); }
.lightbox__nav--prev:hover { transform: translateY(-50%) translateX(-3px); }
.lightbox__nav--next:hover { transform: translateY(-50%) translateX(3px); }
.lightbox__count {
  position: absolute;
  left: 50%; bottom: clamp(14px, 2.4vw, 30px);
  transform: translateX(-50%);
  margin: 0;
  font-size: 12px;
  letter-spacing: .22em;
  color: var(--on-dark-70);
  font-variant-numeric: lining-nums tabular-nums;
}
/* A single-image target keeps the plain lightbox it had. */
.lightbox[data-single="true"] .lightbox__nav,
.lightbox[data-single="true"] .lightbox__count { display: none; }

@media (max-width: 640px) {
  .lightbox { padding-inline: 12px; }
  .lightbox__nav { width: 44px; height: 44px; }
  .lightbox__nav--prev { left: 6px; }
  .lightbox__nav--next { right: 6px; }
}

/* --------------------------------------------------------- units table --- */

/* Every secondary size in this table used to be set at the smallest value in
   the system — 11px tracked labels, a 13px unit conversion, a 15px note — all
   of it in a low-alpha cream on dark green. On a 15-inch laptop that is a
   squint. The row values were already large; the supporting text now sits at a
   size and an alpha that can be read at arm's length. */
.table-scroll { border: 1px solid var(--rule-dark); overflow-x: auto; }
.units-table { min-width: 760px; }
.units-head, .units-row { display: grid; grid-template-columns: 1.2fr .9fr 1.1fr .9fr; gap: 16px; align-items: center; }
.units-head {
  padding: 16px clamp(16px, 2vw, 32px);
  color: var(--on-dark-70);
  background: rgba(243, 241, 236, .04);
  border-bottom: 1px solid var(--rule-dark);
}
.units-head.micro { font-size: 13px; letter-spacing: .18em; }
.units-row { padding: clamp(18px, 1.8vw, 26px) clamp(16px, 2vw, 32px); transition: background .35s; }
.units-row + .units-row { border-top: 1px solid var(--rule-dark); }
.units-row:hover { background: rgba(243, 241, 236, .05); }
.units-row .cell {
  font-family: var(--display);
  font-size: clamp(21px, 1.6vw, 27px);
  line-height: 1.2;
  letter-spacing: .04em;
  font-variant-numeric: lining-nums tabular-nums;
}
.units-row .cell small { display: block; margin-top: 3px; font-family: var(--body); font-size: 16px; letter-spacing: .04em; color: var(--on-dark-70); }
.units-row .cell-action {
  font-size: 13px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--on-dark-70);
  text-align: right;
  transition: color .3s;
}
.units-row:hover .cell-action { color: var(--cream); }
.table-note { margin-top: clamp(16px, 1.8vw, 26px); font-size: 17px; line-height: 1.55; color: var(--on-dark-70); }

/* ---------------------------------------------------------- unit cards --- */

.unit-card {
  position: relative;
  background: var(--white);
  padding: clamp(24px, 2.4vw, 38px);
  display: flex; flex-direction: column;
  overflow: hidden;
  transition: transform .5s var(--ease), box-shadow .5s var(--ease);
}
.unit-card::before {
  content: "";
  position: absolute; inset: 0 0 auto;
  height: 3px;
  background: var(--accent-rule);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .6s var(--ease);
}
.unit-card:hover { transform: translateY(-5px); box-shadow: 0 20px 46px rgba(24, 34, 30, .12); }
.unit-card:hover::before { transform: scaleX(1); }
.unit-card h4 { font-family: var(--display); font-weight: 300; font-size: clamp(21px, 1.9vw, 30px); letter-spacing: .06em; text-transform: uppercase; line-height: 1.15; margin-bottom: clamp(14px, 1.6vw, 22px); }
.unit-card dl { margin: 0; display: grid; gap: 12px; }
.unit-card dt { font-size: 11px; letter-spacing: .2em; text-transform: uppercase; color: var(--label); }
.unit-card dd { margin: 4px 0 0; font-family: var(--display); font-size: clamp(18px, 1.4vw, 24px); line-height: 1.25; font-variant-numeric: lining-nums tabular-nums; }
/* margin-top:auto pins the button to the card's bottom edge so a row of cards
   with unequal copy still lines its buttons up. It must not also carry
   padding-top — that pads the button itself and pushes its label off centre. */
.unit-card dl { margin-bottom: clamp(22px, 2.4vw, 32px); }
.unit-card .btn { margin-top: auto; }

/* ------------------------------------------------------------- layouts --- */

.bed-pills { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: clamp(18px, 1.8vw, 26px); }
.bed-pill {
  flex: 0 0 auto;
  min-width: 54px; height: 46px;
  padding-inline: 18px;
  border-radius: 999px;
  border: 1px solid var(--hairline);
  background: var(--white);
  color: var(--green);
  font-size: 12px; letter-spacing: .16em; text-transform: uppercase;
  cursor: pointer;
  transition: background .3s, color .3s, border-color .3s;
}
.bed-pill[aria-selected="true"] { background: var(--green); border-color: var(--green); color: var(--cream); }

.plan-choice { position: relative; text-align: left; background: var(--white); border: 1px solid var(--hairline); padding: 14px; cursor: pointer; transition: border-color .3s; }
.plan-choice[aria-selected="true"] { border-color: var(--burgundy); }
.plan-choice__radio { position: absolute; top: 12px; right: 12px; width: 16px; height: 16px; border-radius: 50%; background: var(--grey); border: 1px solid #DDDFDC; }
.plan-choice[aria-selected="true"] .plan-choice__radio { background: var(--burgundy); border-color: var(--burgundy); }
.plan-choice__thumb { display: block; width: 100%; height: clamp(80px, 8vw, 110px); background: var(--grey); object-fit: contain; padding: 6px; }
.plan-choice__size { display: block; margin-top: 10px; font-family: var(--display); font-size: 18px; }

.plan-panel { background: var(--white); padding: clamp(24px, 2.6vw, 44px); text-align: center; }
.plan-panel__img { margin: clamp(20px, 2.2vw, 34px) auto 0; max-width: 620px; height: clamp(240px, 28vw, 430px); background: #F5F5F3; object-fit: contain; padding: 12px; width: 100%; }
.chips { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin-top: clamp(20px, 2.2vw, 34px); }
.chips span { border: 1px solid var(--hairline); border-radius: 999px; padding: 9px 18px; font-size: 14px; color: var(--muted); }
.plan-cta { background: var(--white); padding: clamp(20px, 2.2vw, 34px); display: flex; flex-wrap: wrap; gap: 16px; align-items: center; justify-content: space-between; }

/* ------------------------------------------------------- instalments --- */

/* Same correction as the units table above: the schedule is the single most
   scrutinised block on the page and it was set in 12px tracked caps and 15px
   copy at 62% cream. The "when" column now carries --on-dark-85 (8.9:1 on
   #26332F, measured composited) at 17px. */
.instalments { border: 1px solid var(--rule-dark); overflow-x: auto; }
.instalments__inner { min-width: 620px; }
.instalment { display: grid; grid-template-columns: 1.2fr .5fr 2fr; gap: 16px; align-items: center; padding: clamp(18px, 1.8vw, 26px) clamp(16px, 2vw, 32px); transition: background .35s; }
.instalment + .instalment { border-top: 1px solid var(--rule-dark); }
.instalment:hover { background: rgba(243, 241, 236, .05); }
.instalment__name { font-size: 14px; letter-spacing: .14em; text-transform: uppercase; color: var(--on-dark-85); }
.instalment__pct { font-family: var(--display); font-size: clamp(24px, 2.1vw, 34px); line-height: 1; font-variant-numeric: lining-nums tabular-nums; }
.instalment__when { color: var(--on-dark-85); font-size: 17px; line-height: 1.5; }
.instalment--final { background: rgba(243, 241, 236, .07); }
.instalment--final .instalment__when { color: var(--cream); }

/* --------------------------------------------------------- checklist --- */

.checklist { list-style: none; margin: clamp(20px, 2.2vw, 32px) 0 0; padding: 0; display: grid; gap: 13px; }
.checklist li { display: flex; gap: 14px; align-items: flex-start; font-size: 16px; line-height: 1.55; }
.checklist li::before { content: ""; flex: 0 0 auto; width: 6px; height: 6px; margin-top: .6em; border-radius: 50%; background: var(--burgundy); }
.checklist--dark li::before { background: var(--cream); }

/* -------------------------------------------------------- service cards --- */

/* The four things the agency actually does. As a bulleted list inside one
   bordered box on a dark ground they ran together into a paragraph of grey;
   four cards give each one its own edge, its own numeral and its own measure. */
.svc-cards {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--gap-card);
  margin-top: clamp(24px, 2.6vw, 40px);
}
.svc-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: clamp(12px, 1.2vw, 18px);
  padding: clamp(22px, 2.2vw, 34px) clamp(20px, 2vw, 30px);
  background: var(--fill-dark);
  border: 1px solid rgba(243, 241, 236, .13);
  overflow: hidden;
  transition: transform .5s var(--ease), background .4s, border-color .4s;
}
.svc-card::before {
  content: "";
  position: absolute; inset: 0 0 auto;
  height: 2px;
  background: var(--accent-rule);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .6s var(--ease);
}
.svc-card:hover { transform: translateY(-5px); background: rgba(243, 241, 236, .09); border-color: rgba(243, 241, 236, .22); }
.svc-card:hover::before { transform: scaleX(1); }
.svc-card__no {
  font-family: var(--display);
  font-size: clamp(26px, 2.2vw, 36px);
  line-height: 1;
  letter-spacing: .04em;
  color: var(--cream);
  opacity: .38;
  font-variant-numeric: lining-nums tabular-nums;
  transition: opacity .5s var(--ease);
}
.svc-card:hover .svc-card__no { opacity: .8; }
.svc-card p { font-size: 16px; line-height: 1.55; color: var(--on-dark-70); }

/* The light-ground version is not used yet; it exists so the component can be
   reused without being redefined at the point of use. */
.section--light .svc-card { background: var(--white); border-color: transparent; }
.section--light .svc-card__no { color: var(--burgundy); }
.section--light .svc-card p { color: var(--muted); }

@media (max-width: 1100px) { .svc-cards { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px)  { .svc-cards { grid-template-columns: minmax(0, 1fr); } }

/* --------------------------------------------------------- photo CTA --- */

/* A centred heading, a line of copy and two buttons on flat green is a slide,
   not a section. Same copy and the same two buttons, on a render held back far
   enough that both still measure past 4.5:1. */
.cta-photo { position: relative; overflow: hidden; }
.cta-photo__bg { position: absolute; inset: 0; z-index: 0; }
.cta-photo__bg img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 58%; }
/* Held back far enough that cream copy still measures 5.6:1 against the
   BRIGHTEST patch of the render behind it (a sunlit window at sRGB 220
   composites to 95), not against its average — but no further, or the band is
   just a slightly darker green and the render might as well not be there. */
.cta-photo__bg::after {
  content: "";
  position: absolute; inset: 0;
  background:
    linear-gradient(180deg, rgba(24, 33, 30, .76) 0%, rgba(24, 33, 30, .66) 45%, rgba(24, 33, 30, .84) 100%);
}
.cta-photo > .wrap--text { position: relative; z-index: 1; }
.cta-photo .accent-line { z-index: 2; }
.cta-photo { padding-block: clamp(80px, 9vw, 150px); }
/* The lead variant is the one that has to be read across a room: heading one
   step up, body copy at reading size in near-full cream rather than the muted
   grey the flat-green version used. */
.cta-photo__lead { max-width: 900px; }
.cta-photo__lead > p { font-size: clamp(18px, 1.35vw, 21px); line-height: 1.55; color: var(--on-dark-90); }
/* This band is half the height of the community page's, so a `cover` crop of a
   wide render keeps only the dark middle of it and the picture disappears into
   the overlay. Hold the sky, and lighten the overlay to match — the measured
   contrast behind the smallest control here is recorded in site/README.md. */
.cta-photo--lead .cta-photo__bg img { object-position: 50% 34%; }
.cta-photo--lead .cta-photo__bg::after {
  background:
    linear-gradient(180deg, rgba(24, 33, 30, .70) 0%, rgba(24, 33, 30, .62) 45%, rgba(24, 33, 30, .80) 100%);
}

/* ------------------------------------------------------- agency stats --- */

.agency-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--gap-tight); margin-top: clamp(28px, 3vw, 46px); }
.agency-stat {
  position: relative;
  border-top: 1px solid var(--hairline);
  padding-top: clamp(14px, 1.4vw, 22px);
}
/* The figure strip is the one place the accent can appear without competing
   with an image, so the rule above each number is redrawn on hover. */
.agency-stat::before {
  content: "";
  position: absolute; inset: -1px 0 auto;
  height: 1px;
  background: var(--burgundy);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .55s var(--ease);
}
.agency-stat:hover::before { transform: scaleX(1); }
.section--dark .agency-stat::before { background: var(--cream); }
.agency-stat .figure { transition: transform .55s var(--ease); }
.agency-stat:hover .figure { transform: translateY(-3px); }
.agency-stat .micro { margin-top: 8px; color: var(--label); }
.section--dark .agency-stat { border-top-color: var(--rule-dark); }
.section--dark .agency-stat .micro { color: var(--on-dark-50); }

/* ------------------------------------------------------------ lead card --- */

.lead-card { background: var(--white); overflow: hidden; }
.lead-card__body { padding: clamp(28px, 3.4vw, 60px); display: flex; flex-direction: column; justify-content: center; }
.lead-card__media { min-height: clamp(240px, 30vw, 480px); overflow: hidden; }
.lead-card__media img { width: 100%; height: 100%; object-fit: cover; }
.doc-links { display: flex; flex-wrap: wrap; gap: 10px; margin-top: clamp(18px, 2vw, 28px); }
.doc-links a {
  display: inline-flex; align-items: center; gap: 8px;
  border: 1px solid var(--hairline);
  border-radius: 999px;
  padding: 9px 18px;
  font-size: 14px;
  color: var(--muted);
  transition: border-color .3s, color .3s;
}
.doc-links a:hover { border-color: var(--burgundy); color: var(--green); }
.doc-links a::before { content: "↓"; font-size: 13px; }

/* --------------------------------------------------------------- faq --- */

.faq { background: var(--white); padding: 0 clamp(22px, 2.4vw, 42px); }
.faq__item + .faq__item { border-top: 1px solid var(--hairline); }
.faq__q { width: 100%; background: none; border: 0; padding: clamp(22px, 2.2vw, 30px) 0; display: flex; justify-content: space-between; align-items: center; gap: 24px; cursor: pointer; text-align: left; color: var(--green); }
.faq__q span:first-child { font-family: var(--display); font-weight: 400; font-size: clamp(19px, 1.6vw, 26px); line-height: 1.25; letter-spacing: .04em; }
.faq__icon { flex-shrink: 0; font-family: var(--display); font-weight: 300; font-size: 28px; line-height: 1; transition: transform .45s var(--ease); }
.faq__q[aria-expanded="true"] .faq__icon { transform: rotate(45deg); }
.faq__a { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .5s var(--ease); }
.faq__q[aria-expanded="true"] + .faq__a { grid-template-rows: 1fr; }
.faq__a > div { overflow: hidden; }
.faq__a p { padding-bottom: clamp(22px, 2.2vw, 30px); max-width: 78ch; font-size: 16px; line-height: 1.65; color: var(--muted); }

/* -------------------------------------------------------------- footer --- */

/* The reference footer is one dark bar: legal left, the mark and the phone in
   the centre, contact right. */
.site-footer { background: var(--footer-green); color: var(--cream); }
.footer-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(20px, 3vw, 48px);
  padding: clamp(26px, 3vw, 34px) var(--pad);
}
.footer-bar__side { flex: 1 1 0; display: flex; flex-wrap: wrap; gap: 8px 22px; align-items: center; }
.footer-bar__side--end { justify-content: flex-end; }
.footer-bar__mid { flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; gap: 12px; }
.footer-bar__mid img { width: clamp(140px, 15vw, 200px); }
.footer-bar a, .footer-bar address {
  font-size: 12px;
  letter-spacing: .18em;
  text-transform: uppercase;
  font-style: normal;
  color: var(--on-dark-62);
  transition: color .3s;
}
.footer-bar a:hover { color: var(--cream); }
.footer-bar__phone { font-family: var(--display); font-size: clamp(19px, 1.6vw, 26px) !important; letter-spacing: .16em !important; color: var(--cream) !important; text-transform: none !important; }

.footer-cols {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) repeat(3, minmax(0, 1fr));
  gap: clamp(24px, 3vw, 56px);
  padding: clamp(50px, 6vw, 88px) var(--pad) clamp(30px, 3.4vw, 48px);
  border-bottom: 1px solid rgba(243, 241, 236, .1);
}
.footer-col { display: flex; flex-direction: column; gap: 11px; }
.footer-col > span:first-child { font-size: 11px; letter-spacing: .22em; text-transform: uppercase; color: var(--on-dark-38); margin-bottom: 4px; }
.footer-col a, .footer-col address { font-size: 15px; font-style: normal; color: var(--on-dark-70); transition: color .3s, transform .35s var(--ease); }
.footer-col a { display: inline-block; }
.footer-col a:hover { color: var(--cream); transform: translateX(5px); }
.footer-col p { font-size: 15px; color: var(--on-dark-50); }
.footer-legal { padding: 0 var(--pad) clamp(24px, 3vw, 36px); }
.footer-legal p { font-size: 13px; line-height: 1.6; color: var(--on-dark-38); max-width: 92ch; }

/* ------------------------------------------------------------ reveals --- */

@keyframes mvFadeUp { from { opacity: 0; transform: translateY(28px); } to { opacity: 1; transform: none; } }
@keyframes mvDrift  { from { transform: scale(1); } to { transform: scale(1.08); } }
@keyframes mvNudge {
  0%, 100% { transform: rotate(45deg) translate(-1px, -1px); }
  50%      { transform: rotate(45deg) translate(2px, 2px); }
}

/* Content is visible by default; JS only adds .is-hidden once it is running. */
.reveal { transition: opacity 1s var(--ease), transform 1s var(--ease); }
.reveal.is-hidden { opacity: 0; transform: translateY(26px); }

/* A full-bleed block is far too large for a 26px nudge to read as movement, so
   it settles out of a slight overscale instead — the block arrives, rather
   than the block sliding. Its own 1.6s image transition carries it. */
.imgfull.reveal.is-hidden > img,
.imgfull.reveal.is-hidden > picture img,
.project-card.reveal.is-hidden img { transform: scale(1.07); }

/* The gallery rows and the developer panel enter from the side they sit on, so
   the two halves of a 50/50 row do not arrive as one slab. */
.reveal--left.is-hidden  { transform: translateX(-32px); }
.reveal--right.is-hidden { transform: translateX(32px); }
@media (max-width: 1000px) {
  .reveal--left.is-hidden,
  .reveal--right.is-hidden { transform: translateY(26px); }
}

/* -------------------------------------------------------- responsive --- */

@media (max-width: 1200px) { .header__nav { display: none; } }

@media (max-width: 1100px) {
  .amenity-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .slider--cards .slider__slide { flex: 0 0 calc((100% - var(--gap-card)) / 2); }
}

@media (max-width: 1000px) {
  :root { --header-h: 70px; }
  .desktop-only { display: none !important; }
  .split, .split--wide, .split--lead, .split--layouts, .split--lead-card { grid-template-columns: 1fr; }
  .grid-3, .grid-4 { grid-template-columns: repeat(2, 1fr); }
  .duo, .dev { grid-template-columns: minmax(0, 1fr); }
  .duo__text { padding-inline: var(--pad); }
  .dev__media { min-height: clamp(300px, 60vw, 460px); }
  .footer-cols { grid-template-columns: repeat(2, 1fr); }
  .footer-bar { flex-direction: column; text-align: center; }
  .footer-bar__side, .footer-bar__side--end { justify-content: center; }
  .imgfull { height: clamp(400px, 78vw, 560px); }
  .imgfull__body { max-width: none; }
  .hero__grid { flex-direction: column; align-items: flex-start; gap: clamp(22px, 4vw, 40px); }
  .hero__aside { width: 100%; }
}

@media (max-width: 760px) {
  .slider--cards .slider__slide { flex: 0 0 100%; }
}

@media (min-width: 1001px) { .mobile-only { display: none !important; } }

@media (max-width: 640px) {
  .site-header { padding-inline: 16px; gap: 10px; }
  .header__right { gap: 10px; }
  .brand { flex-direction: column; align-items: flex-start; gap: 5px; }
  .brand__rule { display: none; }
  .brand__sub { display: none; }
  .brand__mark { font-size: 14px; letter-spacing: .14em; }
  .brand__logo--mv { --brand-logo-h: 11px; }
  .brand__logo--tr { --brand-logo-h: 14px; }
  .menu-btn__lines i { width: 28px; }
  .menu-btn[aria-expanded="true"] .menu-btn__lines i:last-child { width: 28px; }
  /* The header CTA stays at every width (playbook §9). It is shortened to
     "Request Details" and tightened by lead-capture.css, which loads after this
     file — the stacked brand lockup above is what makes room for it. */

  .grid-3, .grid-4 { grid-template-columns: 1fr; }
  .amenity-grid { grid-template-columns: 1fr; }
  .footer-cols { grid-template-columns: 1fr; }
  .instalment { grid-template-columns: 1fr .5fr 1.4fr; }
  .agency-stats { grid-template-columns: repeat(2, 1fr); }
  .slider__dots { max-width: 50%; }
  .slider__dots button { width: 14px; }
}

/* The setting asks us to remove *travel*, not to remove the interface. Killing
   every transition also kills hover feedback and cross-fades, which reads as a
   broken page rather than a calm one. So: no movement, no loops, no parallax —
   but opacity and colour still transition, and the reveals still fade in. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-property: opacity, background-color, color, border-color, box-shadow, fill, stroke, filter !important;
    transition-duration: .35s !important;
  }
  .reveal.is-hidden,
  .reveal--left.is-hidden,
  .reveal--right.is-hidden { transform: none; }
  .split-word > span { transform: none; }
  [data-parallax] { transform: none !important; }
  .hero__slide.is-active img { animation: none; }
  .imgfull.reveal.is-hidden > img,
  .imgfull.reveal.is-hidden > picture img,
  .project-card.reveal.is-hidden img,
  .imgfull:hover > img,
  .imgfull:hover > picture img,
  .project-card:hover img,
  .amenity-card:hover .amenity__frame,
  .amenity-card:hover .amenity__frame img,
  .slider--gallery:hover .slider__slide img { transform: none; }
  /* No lift on anything — the whole hover language above is movement, and the
     colour half of each rule still fires through the allowed properties. */
  .btn:hover,
  .card:hover,
  .unit-card:hover,
  .reason:hover,
  .travel:hover,
  .doc-links a:hover,
  .doc-links button:hover,
  .footer-col a:hover,
  .agency-stat:hover .figure,
  .svc-card:hover,
  .slider__arrow--prev:hover,
  .slider__arrow--next:hover { transform: none; box-shadow: none; }
  /* The struck rules stay — they are a state change, not travel, and without a
     transition they simply appear on hover. */
}

@media print {
  .site-header, .nav-panel, .lightbox, .hero__scroll, .slider__arrows, .slider__zoom { display: none !important; }
  body { background: #fff; color: #000; }
}
