/* Eagle Crest Properties. Hand-written, one file, no framework.
   World: the developer sales gallery. Navy wall for the opening and close of a page, gallery-white
   ground for reading, crest gold only as hairline rules, the price line and the seal. Marcellus for
   names and headings (the crest's own Roman lettering), Archivo for everything that is read or
   compared, with tabular numerals wherever numbers sit in columns. */

/* ── Tokens ─────────────────────────────────────────────────────────────── */
:root {
  --navy-950: #08162B;
  --navy-900: #0B1F3A;
  --navy-800: #12294A;
  --navy-700: #1C3A66;
  --navy-100: #E4E9F1;
  --ink:      #101826;
  --ink-2:    #3A4657;
  --muted:    #64708A;
  --muted-2:  #98A2B3;
  --ground:   #F5F5F2;
  --paper:    #FFFFFF;
  --line:     #E1E4E9;
  --line-2:   #C7CDD6;
  --gold:       #D4AF37;
  --gold-deep:  #B8941E;
  --gold-text:  #826619;   /* the only gold allowed as text on a light ground: 5.4:1 on white, 5.0:1 on the ground */
  --on-navy:     #F4F1E8;   /* warm white text on the navy wall */
  --on-navy-2:   #C9D1DE;
  --on-navy-3:   #8F9DB3;
  --whatsapp:    #25D366;
  --whatsapp-deep: #1DA851;
  --ok:  #1E6B47; --ok-bg:  #E6F3EC;
  --err: #A83232; --err-bg: #FBEAEA;

  --font-display: 'Marcellus', 'Times New Roman', Georgia, serif;
  --font-text: 'Archivo', system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;

  --step--1: 0.875rem;
  --step-0: 1rem;
  --step-1: 1.125rem;
  --step-2: clamp(1.25rem, 1.1rem + 0.6vw, 1.5rem);
  --step-3: clamp(1.5rem, 1.25rem + 1.2vw, 2.125rem);
  --step-4: clamp(2rem, 1.5rem + 2.2vw, 3rem);
  --step-5: clamp(2.5rem, 1.6rem + 3.6vw, 4.25rem);
  --step-6: clamp(2.75rem, 1.6rem + 4vw, 5rem);

  --space-2: 0.5rem; --space-3: 0.75rem; --space-4: 1rem; --space-5: 1.5rem;
  --space-6: 2rem; --space-7: 3rem; --space-8: 4rem;
  --section: clamp(3.5rem, 6vw, 6.5rem);
  --wrap: 1240px;
  --gutter: clamp(1rem, 4vw, 2.5rem);
  --header-h: 76px;      /* the sticky header's height; the hero subtracts it to fit one screen */

  --radius: 10px;        /* controls: buttons, inputs, chips, tags, pager */
  --radius-ring: 12px;   /* the gold ring around the Contact button: one control radius plus its 2px padding */
  --radius-lg: 16px;     /* surfaces: cards, panels, tiles, the filter box */
  --radius-photo: 16px;  /* photographs, galleries, the viewer */
  --shadow: 0 18px 40px -22px rgba(11, 31, 58, .35), 0 2px 6px -2px rgba(11, 31, 58, .12);
  --shadow-lg: 0 32px 64px -28px rgba(11, 31, 58, .45), 0 4px 10px -4px rgba(11, 31, 58, .15);
  --ease: cubic-bezier(.16, 1, .3, 1);
  --hero-amp: 1;                        /* halved on touch: scroll-linked transforms judder there */
  --dur: 320ms;
  --dur-reveal: 600ms;                  /* a block or a line arriving */
  --dur-photo: 750ms;                   /* a photograph wiping open */
  --stagger-step: 60ms;                 /* between sibling blocks */
  --line-step: 70ms;                    /* between lines of a heading */
}

/* ── Fonts (self-hosted, SIL Open Font Licence, see assets/fonts/) ───────── */
@font-face { font-family: 'Marcellus'; font-style: normal; font-weight: 400; font-display: swap; src: url('../fonts/marcellus-400.woff2') format('woff2'); }
@font-face { font-family: 'Archivo'; font-style: normal; font-weight: 100 900; font-display: swap; src: url('../fonts/archivo-variable.woff2') format('woff2'); }
@font-face { font-family: 'Archivo'; font-style: italic; font-weight: 400; font-display: swap; src: url('../fonts/archivo-italic.woff2') format('woff2'); }

/* ── Reset and base ──────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body { margin: 0; font-family: var(--font-text); font-size: var(--step-0); line-height: 1.55; color: var(--ink); background: var(--ground); -webkit-font-smoothing: antialiased; min-height: 100vh; display: flex; flex-direction: column; }
main { flex: 1 0 auto; }
img, svg, video { display: block; max-width: 100%; }
img { height: auto; }
a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: .18em; }
a:hover { text-decoration-color: var(--gold-deep); }
button, input, select, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
h1, h2, h3, h4 { font-family: var(--font-display); font-weight: 400; line-height: 1.1; margin: 0; letter-spacing: -0.005em; text-wrap: balance; }
h1 { font-size: var(--step-5); }
h2 { font-size: var(--step-4); }
h3 { font-size: var(--step-2); }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
dl, dd { margin: 0; }
::selection { background: var(--gold); color: var(--navy-950); }
:focus-visible { outline: 2px solid var(--navy-700); outline-offset: 3px; border-radius: var(--radius); }
.wall :focus-visible { outline-color: var(--gold); }
* { scrollbar-width: thin; scrollbar-color: var(--navy-700) transparent; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-thumb { background: var(--navy-700); border-radius: 999px; border: 3px solid var(--ground); }
::-webkit-scrollbar-track { background: transparent; }
.visually-hidden { position: absolute !important; 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: var(--space-4); top: -100px; background: var(--navy-900); color: var(--on-navy); padding: .6rem 1rem; z-index: 100; border-radius: var(--radius); }
.skip-link:focus { top: var(--space-4); }
.num { font-variant-numeric: tabular-nums lining-nums; font-feature-settings: 'tnum' 1, 'lnum' 1; }
.muted { color: var(--muted); }
.measure { max-width: 68ch; }

/* ── Layout primitives ───────────────────────────────────────────────────── */
.wrap { width: min(var(--wrap), 100% - 2 * var(--gutter)); margin-inline: auto; }
.section { padding-block: var(--section); }
.section--tight { padding-block: calc(var(--section) * .6); }
.wall { background: var(--navy-900); color: var(--on-navy); }
.wall a:hover { text-decoration-color: var(--gold); }
.wall .muted { color: var(--on-navy-3); }
.paper { background: var(--paper); }
.grid { display: grid; gap: var(--space-5); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 340px), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fill, minmax(min(100%, 300px), 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fill, minmax(min(100%, 250px), 1fr)); }
.stack > * + * { margin-top: var(--space-4); }
.row { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }
.row--between { justify-content: space-between; }
.rule { border: 0; border-top: 1px solid var(--line); margin: 0; }
.wall .rule { border-color: rgba(212, 175, 55, .45); }

/* Section heading: a heading and one line of intent, no eyebrow. */
.sec-head { display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between; gap: var(--space-3) var(--space-6); margin-bottom: var(--space-6); }
.sec-head p { color: var(--muted); max-width: 52ch; }
.wall .sec-head p { color: var(--on-navy-2); }
.sec-head .btn { margin-bottom: .15rem; }

@media (hover: none) { :root { --hero-amp: .5; } }

/* ── Header ──────────────────────────────────────────────────────────────── */
.site-header { position: sticky; top: 0; z-index: 50; background: rgba(255, 255, 255, .94); backdrop-filter: saturate(140%) blur(10px); border-bottom: 1px solid var(--line); }
.site-header .wrap { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); min-height: var(--header-h); }
.brand { display: inline-flex; align-items: center; gap: .75rem; text-decoration: none; }
.brand img { height: 56px; width: auto; }
.brand-name { white-space: nowrap; font-family: var(--font-display); font-size: 1.05rem; letter-spacing: .06em; text-transform: uppercase; color: var(--navy-900); line-height: 1.1; }
.brand-name small { display: block; font-family: var(--font-text); font-size: .62rem; letter-spacing: .22em; color: var(--gold-text); }
.nav { display: none; }
.nav ul { display: flex; gap: .25rem; }
.nav a { display: inline-block; padding: .55rem .8rem; text-decoration: none; font-size: .95rem; color: var(--ink-2); border-bottom: 2px solid transparent; transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease); }
.nav a:hover { color: var(--navy-900); }
.nav a[aria-current="page"] { color: var(--navy-900); border-bottom-color: var(--gold); }
.header-cta { display: none; }
.menu-btn { display: inline-grid; place-items: center; width: 44px; height: 44px; border: 1px solid var(--line-2); border-radius: var(--radius); background: var(--paper); }
.menu-btn svg { width: 22px; height: 22px; }
.menu-btn [data-when="open"] { display: none; }
.menu-btn[aria-expanded="true"] [data-when="closed"] { display: none; }
.menu-btn[aria-expanded="true"] [data-when="open"] { display: block; }
.mobile-nav { display: none; border-top: 1px solid var(--line); background: var(--paper); }
.mobile-nav.is-open { display: block; }
.mobile-nav a { display: flex; align-items: center; justify-content: space-between; padding: .95rem 0; border-bottom: 1px solid var(--line); text-decoration: none; font-size: 1.05rem; color: var(--ink); }
.mobile-nav a[aria-current="page"] { color: var(--gold-text); }
.mobile-nav .star-border { display: block; margin-block: var(--space-4); }
.mobile-nav .btn { width: 100%; justify-content: center; gap: .6rem; }
@media (min-width: 900px) {
  .nav { display: block; }
  .menu-btn { display: none; }
  .header-cta { display: inline-flex; }
}

/* ── Buttons ─────────────────────────────────────────────────────────────── */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: .55rem; padding: .8rem 1.25rem; border: 1px solid transparent; border-radius: var(--radius); font-weight: 500; font-size: .95rem; line-height: 1.2; text-decoration: none; white-space: nowrap; transition: background var(--dur) var(--ease), color var(--dur) var(--ease), border-color var(--dur) var(--ease), transform var(--dur) var(--ease); }
.btn svg { width: 18px; height: 18px; flex: 0 0 auto; }
.btn:active { transform: translateY(1px); }
.btn--navy { background: var(--navy-900); color: var(--on-navy); }
.btn--navy:hover { background: var(--navy-700); }
.btn--gold { background: var(--gold); color: var(--navy-950); }
.btn--gold:hover { background: var(--gold-deep); color: var(--navy-950); }
.btn--ghost { background: transparent; color: var(--navy-900); border-color: var(--line-2); }
.btn--ghost:hover { border-color: var(--navy-900); }
.wall .btn--ghost { color: var(--on-navy); border-color: rgba(244, 241, 232, .35); }
.wall .btn--ghost:hover { border-color: var(--gold); color: var(--on-navy); }
.btn--whatsapp { background: var(--whatsapp); color: var(--navy-950); }
.btn--whatsapp:hover { background: var(--whatsapp-deep); color: var(--navy-950); }
.btn--sm { padding: .55rem .9rem; font-size: .875rem; }
.btn--lg { padding: 1rem 1.6rem; font-size: 1.05rem; }
.btn--block { width: 100%; }
.link-arrow { display: inline-flex; align-items: center; gap: .4rem; text-decoration: none; font-weight: 500; color: var(--navy-900); }
.link-arrow svg { width: 18px; height: 18px; transition: transform var(--dur) var(--ease); }
.link-arrow:hover svg { transform: translateX(4px); }
.wall .link-arrow { color: var(--gold); }

/* ── The brochure spread ─────────────────────────────────────────────────── */
.spread { position: relative; display: grid; gap: var(--space-6); align-items: start; }
.spread__media { position: relative; }
.spread__media img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: var(--radius-photo); box-shadow: var(--shadow-lg); }
.spread__tag { position: absolute; top: 1rem; left: 1rem; background: var(--navy-950); color: var(--on-navy); font-size: 0.72rem; letter-spacing: .08em; text-transform: uppercase; padding: .4rem .7rem; border-radius: var(--radius); }
.spread__copy h2, .spread__copy h3 { margin-bottom: var(--space-2); }
.spread__loc { display: inline-flex; align-items: center; gap: .4rem; color: var(--on-navy-2); }
.spread__loc svg { width: 16px; height: 16px; color: var(--gold); }
.spread .facts { margin-top: var(--space-5); }
@media (min-width: 900px) {
  .spread { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: var(--space-8); }
  .spread--flip { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
  .spread--flip .spread__media { order: 2; }
}
/* Registration corners: the mark a printer leaves on a proof. One per spread, top-left. */
.corners::before, .corners::after { content: ""; position: absolute; width: 22px; height: 22px; border-color: var(--gold); border-style: solid; pointer-events: none; }
.corners::before { top: -10px; left: -10px; border-width: 1px 0 0 1px; }
.corners::after { bottom: -10px; right: -10px; border-width: 0 1px 1px 0; }

/* Fact table: hairline gold rules, like a payment-plan schedule. */
.facts { display: grid; grid-template-columns: 1fr; border-top: 1px solid rgba(212, 175, 55, .55); }
.facts > div { display: flex; justify-content: space-between; gap: var(--space-4); padding: .7rem 0; border-bottom: 1px solid rgba(212, 175, 55, .35); }
.facts dt { color: var(--on-navy-3); font-size: .9rem; }
.facts dd { font-variant-numeric: tabular-nums lining-nums; text-align: right; }
.facts--light { border-top-color: var(--line-2); }
.facts--light > div { border-bottom-color: var(--line); }
.facts--light dt { color: var(--muted); }
.facts--cols { grid-template-columns: repeat(2, 1fr); column-gap: var(--space-6); }
.facts--cols > div { padding: .9rem 0; }
.price-line { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; margin-top: var(--space-5); padding-top: var(--space-4); border-top: 1px solid rgba(212, 175, 55, .55); }
.price-line strong { font-family: var(--font-text); font-size: var(--step-3); font-weight: 500; color: var(--gold); font-variant-numeric: tabular-nums lining-nums; letter-spacing: -.01em; }
.price-line span { color: var(--on-navy-3); font-size: .9rem; }
.paper .price-line, .ground .price-line { border-top-color: var(--line-2); }
.paper .price-line strong, .ground .price-line strong { color: var(--navy-900); }
.paper .price-line span { color: var(--muted); }

/* ── Doors: the two ways in ───────────────────────────────────────────────── */

/* ── Listing card ────────────────────────────────────────────────────────── */
.card { display: flex; flex-direction: column; background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-lg); overflow: hidden; text-decoration: none; color: inherit; transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease), transform var(--dur) var(--ease); }
.card:hover { border-color: var(--gold); box-shadow: var(--shadow); transform: translateY(-2px); }
.card__media { position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: var(--navy-100); }
.card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform 600ms var(--ease); }
.card:hover .card__media img { transform: scale(1.03); }
.card__tag { position: absolute; top: .75rem; left: .75rem; background: var(--navy-950); color: var(--on-navy); font-size: .72rem; letter-spacing: .08em; text-transform: uppercase; padding: .35rem .6rem; border-radius: var(--radius); }
.card__body { padding: 1.1rem 1.15rem 1.2rem; display: flex; flex-direction: column; gap: .5rem; flex: 1; }
.card__title { font-family: var(--font-display); font-size: 1.2rem; line-height: 1.25; color: var(--ink); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.card__loc { display: flex; align-items: center; gap: .35rem; color: var(--muted); font-size: .9rem; }
.card__loc svg { width: 15px; height: 15px; flex: 0 0 auto; color: var(--gold-text); }
.card__loc span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.card__facts { display: flex; gap: 1rem; margin-top: auto; padding-top: .8rem; border-top: 1px solid var(--line); color: var(--ink-2); font-size: .88rem; font-variant-numeric: tabular-nums; }
.card__facts span { display: inline-flex; align-items: center; gap: .35rem; }
.card__facts svg { width: 16px; height: 16px; color: var(--muted); }
.card__price { font-family: var(--font-text); font-weight: 500; font-size: 1.15rem; letter-spacing: -.01em; color: var(--navy-900); font-variant-numeric: tabular-nums lining-nums; }

/* ── Filters ─────────────────────────────────────────────────────────────── */
.filters { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: var(--space-5); margin-bottom: var(--space-6); }
.filters form { display: grid; gap: var(--space-4); grid-template-columns: repeat(auto-fit, minmax(min(100%, 170px), 1fr)); align-items: end; }
.filters .field--search { grid-column: 1 / -1; }
@media (min-width: 900px) { .filters .field--search { grid-column: span 2; } }
.results-bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-5); color: var(--muted); }
.results-bar strong { color: var(--ink); font-weight: 500; }
.chip { display: inline-flex; align-items: center; gap: .35rem; padding: .3rem .65rem; border: 1px solid var(--line-2); border-radius: 999px; font-size: .82rem; color: var(--ink-2); text-decoration: none; }
.chip:hover { border-color: var(--navy-900); }

/* ── Forms ───────────────────────────────────────────────────────────────── */
.field { display: flex; flex-direction: column; gap: .4rem; }
.field label { font-size: .88rem; color: var(--ink-2); font-weight: 500; }
.field label .req { color: var(--gold-text); }
.input, .field input, .field select, .field textarea { width: 100%; padding: .78rem .9rem; border: 1px solid var(--line-2); border-radius: var(--radius); background: var(--paper); color: var(--ink); transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease); }
.field select { appearance: none; -webkit-appearance: none; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='none' stroke='%233A4657' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4 6 4 4 4-4'/%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right .8rem center; padding-right: 2.4rem; }
.field input:focus, .field select:focus, .field textarea:focus, .input:focus { outline: none; border-color: var(--navy-700); box-shadow: 0 0 0 3px rgba(28, 58, 102, .18); }
.field textarea { min-height: 9rem; resize: vertical; }
.field input::placeholder, .field textarea::placeholder { color: var(--muted); }
.field .help { font-size: .82rem; color: var(--muted); }
.form-grid { display: grid; gap: var(--space-4); grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr)); }
.form-grid .field--wide { grid-column: 1 / -1; }
.alert { padding: .9rem 1.1rem; border-radius: var(--radius); border: 1px solid; font-size: .95rem; }
.alert--ok { background: var(--ok-bg); border-color: #BFDDCB; color: var(--ok); }
.alert--err { background: var(--err-bg); border-color: #EFC2C2; color: var(--err); }

/* ── Pager, breadcrumb, tabs ─────────────────────────────────────────────── */
.pager { display: flex; flex-wrap: wrap; gap: .35rem; justify-content: center; margin-top: var(--space-7); }
.pager a, .pager span { min-width: 2.5rem; padding: .55rem .8rem; text-align: center; border: 1px solid var(--line-2); border-radius: var(--radius); text-decoration: none; color: var(--navy-900); font-variant-numeric: tabular-nums; }
.pager a:hover { border-color: var(--navy-900); }
.pager [aria-current="page"] { background: var(--navy-900); color: var(--on-navy); border-color: var(--navy-900); }
.pager .dis { color: var(--muted-2); pointer-events: none; }
.crumbs { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; font-size: .88rem; color: var(--muted); }
.crumbs a { text-decoration: none; color: var(--ink-2); }
.crumbs a:hover { color: var(--navy-900); text-decoration: underline; }
.crumbs svg { width: 14px; height: 14px; color: var(--muted-2); }
.crumbs [aria-current] { color: var(--ink); }
.subbar { background: var(--paper); border-bottom: 1px solid var(--line); }
/* One line, always. With wrapping on, a flex container moves an item to a new row before it tries
   to shrink one, so on a phone the breadcrumb kept its full width and the share button dropped
   beneath it and stranded at the left. The breadcrumb truncates instead (see .crumbs below). */
.subbar .wrap { display: flex; flex-wrap: nowrap; align-items: center; justify-content: space-between; gap: var(--space-3); min-height: 54px; }
.tabs { display: flex; gap: .25rem; border-bottom: 1px solid var(--line-2); margin-bottom: var(--space-6); overflow-x: auto; }
.tabs [role="tab"] { background: none; border: 0; border-bottom: 2px solid transparent; margin-bottom: -1px; padding: .8rem 1rem; color: var(--ink-2); font-weight: 500; white-space: nowrap; }
.tabs [role="tab"] .num { color: var(--muted); margin-left: .35rem; }
.tabs [role="tab"][aria-selected="true"] { color: var(--navy-900); border-bottom-color: var(--gold); }
[role="tabpanel"][hidden] { display: none; }

/* ── Page opening on the wall ─────────────────────────────────────────────── */
.opening { padding-block: clamp(2.5rem, 5vw, 4.5rem); }
.opening h1 { max-width: 20ch; }
.opening p { margin-top: var(--space-3); color: var(--on-navy-2); max-width: 58ch; font-size: var(--step-1); }
.opening .facts { max-width: 520px; margin-top: var(--space-5); }

/* ── Home hero: one navy stage. The copy sits top-left, the building bottom-right, and the two overlap.
   A single scroll value (--hp, 0 at the top of the page to 1 a viewport later, set by site.js) drives
   every transform below, so the words lift and fade while the building grows past them. ────────────── */
.hero {
  --hp: 0;
  --hero-pt: clamp(1.75rem, 3vw, 3rem);
  /* One scale driver for the whole composition. The first term is the width-driven size the hero was
     tuned on; the second is what the screen can actually show, once the sticky header and the hero's
     own top padding are off it. The smaller wins, so a tall window is untouched and a short one steps
     the stage, the display type and the villa down together, which is what keeps the roof sitting over
     the end of the headline instead of the building being cropped. The plain vh line is the fallback:
     svh is the SMALL viewport, so a phone still fits with its toolbars showing, where vh would not. */
  --hero-fit: min(clamp(620px, 66vw, 860px), calc(100vh  - var(--header-h) - var(--hero-pt) - 1px));
  --hero-fit: min(clamp(620px, 66vw, 860px), calc(100svh - var(--header-h) - var(--hero-pt) - 1px));
  /* Below this the display type stops being display type, so the hero stops shrinking and the page scrolls. */
  --hero-h: max(440px, var(--hero-fit));
  position: relative; overflow: hidden; padding-block: var(--hero-pt) 0;
}
.hero__stage { --stage-pb: clamp(2rem, 5vw, 4rem); position: relative; display: flex; flex-direction: column; gap: var(--space-5); padding-bottom: var(--stage-pb); }
.hero__copy { position: relative; z-index: 1; }
.hero .lede { color: var(--on-navy-2); font-size: var(--step-1); max-width: 46ch; margin-top: var(--space-4); }
.hero h1 { transform: translateY(calc(var(--hp) * -80px * var(--hero-amp))) scale(calc(1 - var(--hp) * .06)); transform-origin: left top; opacity: clamp(0, calc(1 - var(--hp) * .75), 1); }
.hero__sub, .hero__cta { transform: translateY(calc(var(--hp) * -40px * var(--hero-amp))); opacity: clamp(0, calc(1 - var(--hp) * 1.4), 1); }
.hero__ctawrap { position: relative; z-index: 3; }
.hero__art { position: relative; z-index: 2; pointer-events: none; transform: translateY(calc(var(--hp) * -140px * var(--hero-amp))) scale(calc(1 + var(--hp) * .08)); transform-origin: 70% 100%; }
.hero canvas.dots { transform: translateY(calc(var(--hp) * 40px * var(--hero-amp))); }
.hero-actions { margin-top: 0; }
.wall .btn--ghost { color: var(--on-navy); }
.hero h1 { font-size: var(--step-6); max-width: 15ch; line-height: 1.02; }
/* The owner's two-tone headline: everything after the bar in hero_title is set in crest gold on its own line.
   Gold as display text on the navy wall is theirs by decision (2026-09-23); it measures 7.4:1 there. */
.hero__accent { display: block; width: fit-content; color: var(--gold); }

/* The photograph, framed (any listing photo) or cut out (a PNG with a transparent background). */
.hero__frame { position: relative; }
/* The registration corners belong to the brochure spreads. The hero photograph carries none: on a
   wide screen it bleeds off the edge with no frame to mark, so a corner on the phone alone would
   read as a stray mark rather than a motif. */
.hero__frame.corners::before, .hero__frame.corners::after { display: none; }
.hero__media { overflow: hidden; border-radius: var(--radius-photo); box-shadow: var(--shadow-lg); background: var(--navy-800); }
/* The edge where the photograph meets the navy is softened rather than cut. Which edge that is depends
   on the layout, so the gradient itself is set per breakpoint: the left on a wide screen, the top once
   it stacks. */
.hero--framed .hero__media::after { content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.hero__media img { display: block; width: 100%; aspect-ratio: 16 / 10; object-fit: cover; }
.hero__cut { display: block; width: 100%; height: auto; object-fit: contain; object-position: bottom right; filter: drop-shadow(0 26px 44px rgba(0, 0, 0, .45)); }
.hero--cutout .hero__art::after { content: ""; position: absolute; inset: auto 2% -3% 6%; height: 14%; background: radial-gradient(ellipse at 50% 100%, rgba(8, 22, 43, .55), transparent 72%); z-index: -1; }

@media (min-width: 900px) {
  /* Height follows the viewport width, as the display type does, so the villa and the headline keep the
     same relationship at every window height and the roof always clips the end of the line by the same amount. */
  .hero__stage { --stage-pb: clamp(2.5rem, 5vw, 4rem); min-height: var(--hero-h); }
  .hero__copy { max-width: 58%; }
  .hero__ctawrap { margin-top: auto; }
  /* The z-index has to live here, not on .hero__art: this wrapper carries the settle animation, so it makes
     its own stacking context and any z-index inside it is scoped to that. With it on the wrapper the villa
     paints over the copy (z 1) and under the buttons (z 3), which is what puts the words behind the roof. */
  .hero__artwrap { position: absolute; right: 0; bottom: 0; margin: 0; z-index: 2; pointer-events: none; }
  /* An owner's hero photograph fills the right of the stage at full height and bleeds one gutter past
     the wrap, the way the cut-out does. It used to sit in a 16:10 panel, which cropped a tall city
     view down to a mid band and lost the Burj out of the top of the shot it was given. Absolute
     insets rather than a chain of percentage heights, because a percentage against a parent whose
     height is auto resolves to 0 on older iOS Safari. */
  /* calc(50% - 50vw) is half the wrap minus half the viewport, which is exactly the offset that puts
     the right edge on the screen edge whatever the wrap is doing. The hero clips its overflow, so
     the scrollbar width inside 100vw cannot push the page sideways. */
  /* Pulled up by the hero's own top padding, which the stage sits inside, so the photograph meets the
     header with no navy band above it and the section below with none under it. */
  .hero--framed .hero__artwrap { left: auto; right: calc(50% - 50vw); top: calc(var(--hero-pt) * -1); bottom: 0; width: min(58%, 780px); }
  .hero--framed .hero__art,
  .hero--framed .hero__frame { position: absolute; inset: 0; }
  /* The 140px lift belongs to the cut-out, where the building rising past the words is the point.
     A photograph that fills its box edge to edge would just pull a navy band in under itself, so it
     takes the scale alone, from the centre, which can never expose an edge. */
  .hero--framed .hero__art { transform: scale(calc(1 + var(--hp) * .08)); transform-origin: 50% 50%; }
  .hero--framed .hero__media { position: absolute; inset: 0; border-radius: 0; box-shadow: none; }
  .hero--framed .hero__media img { position: absolute; inset: 0; width: 100%; height: 100%; aspect-ratio: auto; object-fit: cover; object-position: center right; }
  /* The photograph meets the navy softly instead of on a hard edge, so the lede stays readable where
     the two overlap. Ends fully transparent at 58% so the picture itself is untouched. */
  .hero--framed .hero__media::after { background: linear-gradient(90deg, var(--navy-900) 0%, rgba(11, 31, 58, .72) 18%, rgba(11, 31, 58, 0) 58%); }
  /* The villa fills the stage like a backdrop: full height, standing on the line where the navy meets the
     ground below, bleeding past the wrap. The headline runs into the sky wedge under its roof. */
  .hero--cutout .hero__artwrap { left: auto; right: calc(var(--gutter) * -1); bottom: 0; width: auto; }
  /* The copy stays in the upper half so it clears the fold on a tall villa, and keeps the button under
     the lede rather than stranded at the foot of the stage when the art is a photograph. */
  .hero--cutout .hero__ctawrap, .hero--framed .hero__ctawrap { margin-top: var(--space-6); }
  .hero--cutout .hero__cut { height: calc(var(--hero-h) * 1.021); width: auto; max-height: none; }
  .hero--cutout .hero__copy { max-width: 68%; }
  .hero--cutout h1 { max-width: 20ch; }
  .hero--cutout .hero__sub { max-width: 30ch; }   /* keeps the body copy clear of the building */
  .hero--noart .hero__stage { min-height: 0; }
}
/* A short window leaves room for a villa about as wide as the stage is tall, well under the 885px the
   composition was drawn at, so at its own right edge the building no longer reaches the headline. It is
   nudged inboard by the height it lost, but only 0.6 of it: at a fuller pull the opaque roof crosses the
   last letters of both lines instead of the transparent sky wedge under it, which reads worse than no
   overlap at all. The term is 0 at the reference size, so a tall window is untouched, and the 200px cap
   stops a very short one stranding the building mid-screen. */
@media (min-width: 1200px) {
  .hero--cutout .hero__artwrap { right: calc(var(--gutter) * -1 + min(200px, (860px - var(--hero-h)) * 0.6)); }
}
/* Below this the copy column and the building are close enough that the last line of the lede grazes it. */
@media (min-width: 900px) and (max-width: 1199px) {
  .hero--cutout .hero__sub, .hero--framed .hero__sub { max-width: 26ch; }
}
@media (max-width: 899px) {
  /* The villa rises over the button on phones too, so the layering reads at every size. It sits above the
     button here (z 4 against the button's 3), and the overlap lands on the button's lower edge, where the
     roof is still transparent, so the label is never touched. */
  .hero--cutout .hero__artwrap { position: relative; z-index: 4; pointer-events: none; margin-inline: calc(var(--gutter) * -1); }
  /* Stacked, the villa takes what is left after the copy rather than a flat share of the screen, so a
     short phone and a tablet fit too. 21rem is the copy block plus its padding; the 200px floor keeps
     a landscape phone, which cannot fit whatever we do, from losing the building altogether. svh is the
     small viewport, so the browser's toolbars are already counted; the vh line above is the fallback. */
  .hero__cut { max-height: 62vh; max-height: min(62svh, max(200px, calc(100svh - var(--header-h) - 21rem))); }
  /* Same reason as the desktop rule: a 16:10 crop of a tall city view loses the top of it. */
  .hero--framed .hero__media img { aspect-ratio: 4 / 5; max-height: 52vh;
    max-height: min(52svh, max(180px, calc(100svh - var(--header-h) - 24rem))); }
  /* Full bleed on a phone: left, right and bottom run to the screen edges so the picture ends the hero
     instead of sitting on it as a card. The negative bottom margin cancels the stage's own padding,
     which is why that padding is named. The top is the only edge left to soften, the same job the left
     edge does on a wide screen. */
  .hero--framed .hero__artwrap { margin-inline: calc(var(--gutter) * -1); margin-bottom: calc(var(--stage-pb) * -1); }
  .hero--framed .hero__media { border-radius: 0; box-shadow: none; }
  .hero--framed .hero__media::after { background: linear-gradient(180deg, var(--navy-900) 0%, rgba(11, 31, 58, .7) 12%, rgba(11, 31, 58, 0) 46%); }
  .hero--cutout .hero__art { margin-top: calc(var(--space-7) * -1); }
}

/* Reveal on load: the home opening's copy and photograph. */
@media (prefers-reduced-motion: no-preference) {
  /* The load-in runs on the wrappers, so it never fights the scroll transforms on the children. */
  .hero .reveal { animation: rise 700ms var(--ease) both; }
  .hero__copy .reveal:nth-child(2) { animation-delay: 80ms; }
  .hero__ctawrap { animation: rise 700ms var(--ease) 160ms both; }
  .hero__artwrap { animation: settle 1100ms var(--ease) 120ms both; }
  @keyframes rise { from { opacity: 0; transform: translateY(14px); } to { opacity: 1; transform: none; } }
  @keyframes settle { from { opacity: 0; transform: translateY(18px) scale(.985); } to { opacity: 1; transform: none; } }
}

/* ── Developer index and proof ───────────────────────────────────────────── */
.proof { display: grid; gap: var(--space-5); }
@media (min-width: 900px) { .proof { grid-template-columns: repeat(2, 1fr); gap: var(--space-6) var(--space-8); } }
.proof__item { padding-top: var(--space-4); border-top: 1px solid var(--line-2); }
.wall .proof__item { border-top-color: rgba(212, 175, 55, .45); }
.proof__item h3 { margin-bottom: .5rem; }
.proof__item p { color: var(--ink-2); max-width: 46ch; }
.wall .proof__item p { color: var(--on-navy-2); }
.proof__item .link-arrow { margin-top: .75rem; }

/* Types: a photographed index, not icon tiles. */
.types { display: grid; gap: var(--space-4); grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 900px) { .types { grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.type { position: relative; display: block; aspect-ratio: 4 / 5; overflow: hidden; border-radius: var(--radius-photo); text-decoration: none; color: var(--on-navy); background: var(--navy-800); }
.type img { width: 100%; height: 100%; object-fit: cover; transition: transform 700ms var(--ease); }
.type:hover img { transform: scale(1.04); }
.type__label { position: absolute; inset: auto 0 0 0; padding: 3.5rem 1rem 1rem; background: linear-gradient(to top, rgba(8, 22, 43, .92), rgba(8, 22, 43, 0)); display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-3); }
.type__label h3 { font-size: var(--step-2); }
.type__label .num { color: var(--gold); }

/* ── People ──────────────────────────────────────────────────────────────── */
.people { display: grid; gap: var(--space-5) var(--space-4); grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 700px) { .people { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1000px) { .people { gap: var(--space-5); grid-template-columns: repeat(4, minmax(0, 1fr)); } }
.person { display: block; text-decoration: none; color: inherit; }
.person img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; border-radius: var(--radius-photo); background: var(--navy-900); transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease); }
.person:hover img { transform: translateY(-3px); box-shadow: var(--shadow); }
.person h3 { font-size: 1.15rem; margin-top: .8rem; }
.person p { color: var(--gold-text); font-size: .9rem; margin-top: .15rem; }
.wall .person p { color: var(--gold); }
.wall .person h3 { color: var(--on-navy); }

/* ── Property page ───────────────────────────────────────────────────────── */
.gallery { position: relative; min-width: 0; max-width: 100%; }
.gallery__track { display: flex; gap: var(--space-3); overflow-x: auto; scroll-snap-type: x mandatory; scroll-behavior: smooth; scrollbar-width: none; border-radius: var(--radius-photo); }
.gallery__track::-webkit-scrollbar { display: none; }
.gallery__track > figure { flex: 0 0 100%; min-width: 0; scroll-snap-align: start; margin: 0; }
.gallery__track img { width: 100%; aspect-ratio: 16 / 10; object-fit: cover; border-radius: var(--radius-photo); background: var(--navy-100); }
.gallery__bar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-top: var(--space-3); }
.gallery__count { font-variant-numeric: tabular-nums; color: var(--muted); font-size: .9rem; }
.gallery__nav { display: flex; gap: .4rem; }
.icon-btn { display: inline-grid; place-items: center; width: 42px; height: 42px; border: 1px solid var(--line-2); border-radius: var(--radius); background: var(--paper); color: var(--navy-900); transition: border-color var(--dur) var(--ease), background var(--dur) var(--ease); }
.icon-btn:hover { border-color: var(--navy-900); }
.icon-btn:disabled { color: var(--muted-2); cursor: default; border-color: var(--line); }
.icon-btn svg { width: 18px; height: 18px; }
.thumbs { display: flex; gap: .5rem; margin-top: .6rem; overflow-x: auto; scrollbar-width: none; padding-bottom: 2px; }
.thumbs::-webkit-scrollbar { display: none; }
.thumbs button { flex: 0 0 auto; width: 84px; height: 64px; padding: 0; border: 2px solid transparent; border-radius: var(--radius); overflow: hidden; background: var(--navy-100); }
.thumbs button img { width: 100%; height: 100%; object-fit: cover; }
.thumbs button[aria-current="true"] { border-color: var(--gold); }
.detail { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--space-7); align-items: start; }
.detail > * { min-width: 0; }
@media (min-width: 1000px) { .detail { grid-template-columns: minmax(0, 7fr) minmax(0, 4fr); gap: var(--space-8); } .detail__aside { position: sticky; top: 92px; } }
.detail h1 { font-size: var(--step-4); }
.detail__lead { display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: space-between; gap: var(--space-4); margin-bottom: var(--space-5); }
.detail__lead .price { font-family: var(--font-text); font-weight: 500; letter-spacing: -.01em; font-size: var(--step-3); color: var(--navy-900); font-variant-numeric: tabular-nums lining-nums; white-space: nowrap; }
.detail__lead .loc { display: inline-flex; align-items: center; gap: .4rem; color: var(--muted); margin-top: .5rem; }
.detail__lead .loc svg { width: 16px; height: 16px; color: var(--gold-text); }
.prose { color: var(--ink-2); line-height: 1.7; max-width: 70ch; }
.prose p + p { margin-top: 1em; }
.features { display: grid; gap: .55rem .9rem; grid-template-columns: repeat(auto-fill, minmax(min(100%, 220px), 1fr)); }
.features li { position: relative; padding-left: 1.1rem; color: var(--ink-2); }
.features li::before { content: ""; position: absolute; left: 0; top: .62em; width: 6px; height: 6px; background: var(--gold); }
.panel { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: var(--space-5); }
.panel h2, .panel h3 { margin-bottom: var(--space-4); }
.panel--wall { background: var(--navy-900); color: var(--on-navy); border-color: var(--navy-900); }
.agent-card { display: flex; gap: var(--space-4); align-items: center; }
.agent-card img { width: 64px; height: 64px; border-radius: 50%; object-fit: cover; background: var(--navy-900); }
.agent-card strong { display: block; font-family: var(--font-display); font-weight: 400; font-size: 1.1rem; }
.agent-card span { color: var(--muted); font-size: .9rem; }
.video-frame { aspect-ratio: 16 / 9; border-radius: var(--radius-photo); overflow: hidden; background: var(--navy-950); }
.video-frame iframe, .video-frame video { width: 100%; height: 100%; border: 0; }

/* ── Media ───────────────────────────────────────────────────────────────── */
.media-card { display: flex; flex-direction: column; color: var(--ink); background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-lg); overflow: hidden; text-align: left; padding: 0; transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease); }
.media-card:hover { border-color: var(--gold); box-shadow: var(--shadow); }
.media-card__media { position: relative; aspect-ratio: 16 / 10; overflow: hidden; background: var(--navy-900); }
.media-card__media img { width: 100%; height: 100%; object-fit: cover; }
.media-card__play { position: absolute; inset: 0; display: grid; place-items: center; }
.media-card__play span { display: grid; place-items: center; width: 56px; height: 56px; border-radius: 50%; background: rgba(8, 22, 43, .78); color: var(--on-navy); border: 1px solid rgba(212, 175, 55, .8); transition: transform var(--dur) var(--ease), background var(--dur) var(--ease); }
.media-card__play svg { width: 22px; height: 22px; margin-left: 3px; }
.media-card:hover .media-card__play span { transform: scale(1.06); background: var(--navy-900); }
.media-card__body { padding: 1rem 1.1rem 1.15rem; display: flex; flex-direction: column; gap: .4rem; }
.media-card__body h3 { font-family: var(--font-text); font-size: 1rem; font-weight: 500; line-height: 1.4; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.media-card__meta { display: flex; gap: .75rem; color: var(--muted); font-size: .82rem; }
dialog.viewer { border: 0; padding: 0; background: var(--navy-950); color: var(--on-navy); width: min(1100px, 94vw); max-height: 92vh; border-radius: var(--radius-photo); box-shadow: var(--shadow-lg); }
dialog.viewer::backdrop { background: rgba(8, 22, 43, .78); backdrop-filter: blur(6px); }
dialog.viewer .viewer__head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: .8rem 1rem; }
dialog.viewer .viewer__head h2 { font-family: var(--font-text); font-size: 1rem; font-weight: 500; }
dialog.viewer .viewer__body img { max-height: 76vh; width: auto; margin: 0 auto; object-fit: contain; }
dialog.viewer .viewer__body p { padding: .9rem 1rem 1.1rem; color: var(--on-navy-2); }
dialog.viewer .icon-btn { background: transparent; color: var(--on-navy); border-color: rgba(244, 241, 232, .3); }
dialog.viewer .icon-btn:hover { border-color: var(--gold); }

/* ── Contact ─────────────────────────────────────────────────────────────── */
.contact-list > li { display: grid; grid-template-columns: 22px 1fr; gap: .9rem; padding: .9rem 0; border-top: 1px solid var(--line); }
.contact-list > li:last-child { border-bottom: 1px solid var(--line); }
.contact-list svg { width: 20px; height: 20px; color: var(--gold-text); margin-top: .1rem; }
.contact-list small { display: block; color: var(--muted); font-size: .82rem; margin-bottom: .1rem; }
.contact-list a { text-decoration: none; color: var(--ink); }
.contact-list a:hover { text-decoration: underline; }
.socials { display: flex; flex-wrap: wrap; gap: .35rem; margin: 0 0 0 -.5rem; padding: 0; list-style: none; }
.socials li, .site-footer .socials li, .footer-grid .socials li, .socials li + li { margin: 0; padding: 0; }
.socials a { display: inline-grid; place-items: center; width: 40px; height: 40px; border: 0; color: var(--ink-2); transition: color var(--dur) var(--ease); }
.socials a:hover { color: var(--navy-900); }
.socials svg { width: 22px; height: 22px; }
.wall .socials a { color: var(--on-navy-2); }
.wall .socials a:hover { color: var(--gold); }

/* ── Footer ──────────────────────────────────────────────────────────────── */
.site-footer { background: var(--navy-950); color: var(--on-navy-2); padding-block: var(--space-8) var(--space-6); font-size: .93rem; border-top: 1px solid rgba(212, 175, 55, .35); }
.footer-grid { display: grid; gap: var(--space-6); grid-template-columns: repeat(auto-fit, minmax(min(100%, 200px), 1fr)); }
.footer-grid > div:first-child { grid-column: span 1; }
@media (min-width: 900px) { .footer-grid { grid-template-columns: 1.5fr 1fr 1fr 1.3fr; } }
.site-footer h3 { font-family: var(--font-text); font-size: .8rem; letter-spacing: .14em; text-transform: uppercase; color: var(--on-navy-3); margin-bottom: 1rem; }
.site-footer ul li + li { margin-top: .5rem; }
.site-footer a { color: var(--on-navy); text-decoration: none; }
.site-footer a:hover { color: var(--gold); }
.site-footer .brand img { height: 64px; }
.site-footer .tagline { margin-top: 1rem; max-width: 34ch; color: var(--on-navy-2); }
.site-footer .qr { margin-top: 1.25rem; display: flex; align-items: center; gap: .9rem; }
.site-footer .qr img { width: 88px; height: 88px; background: #fff; padding: 6px; border-radius: var(--radius); }
.site-footer .qr span { font-size: .85rem; color: var(--on-navy-3); max-width: 16ch; }
.footer-foot { margin-top: var(--space-7); padding-top: var(--space-5); border-top: 1px solid rgba(212, 175, 55, .35); display: flex; flex-wrap: wrap; justify-content: space-between; gap: var(--space-3); font-size: .85rem; color: var(--on-navy-3); }
.footer-foot a { color: var(--on-navy-3); }
.footer-foot a:hover { color: var(--on-navy); }

/* ── WhatsApp float (kept, restyled) ─────────────────────────────────────── */
.wa-float { position: fixed; right: 1.1rem; bottom: 1.1rem; z-index: 60; display: inline-flex; align-items: center; gap: .6rem; padding: .75rem 1rem .75rem .8rem; border-radius: 999px; background: var(--whatsapp); text-decoration: none; font-weight: 600; font-size: .92rem; box-shadow: var(--shadow-lg); transition: transform var(--dur) var(--ease), background var(--dur) var(--ease); color: var(--navy-950); }
.wa-float svg { width: 24px; height: 24px; }
.wa-float:hover { transform: translateY(-2px); background: var(--whatsapp-deep); color: var(--navy-950); }
@media (max-width: 640px) { .wa-float span { display: none; } .wa-float { padding: .8rem; } }

/* ── Empty and end states ─────────────────────────────────────────────────── */
.empty { padding: var(--space-8) var(--space-5); text-align: center; color: var(--muted); border: 1px dashed var(--line-2); border-radius: var(--radius-lg); }
.empty h3 { color: var(--ink); margin-bottom: .5rem; }
.closing { text-align: center; }
.closing h2 { max-width: 22ch; margin-inline: auto; }
.closing p { color: var(--on-navy-2); margin-top: var(--space-3); max-width: 50ch; margin-inline: auto; }
.closing .row { justify-content: center; margin-top: var(--space-6); }
.notfound { min-height: 50vh; display: grid; place-items: center; text-align: center; padding: var(--space-8) var(--gutter); }
.notfound h1 { font-size: var(--step-4); margin-bottom: var(--space-3); }

/* ── Small screens ───────────────────────────────────────────────────────── */
@media (max-width: 640px) {
  .facts--cols { grid-template-columns: 1fr; }
  .sec-head { align-items: flex-start; flex-direction: column; }
  .detail__lead .price { font-size: var(--step-2); }
  .brand img { height: 46px; }
  :root { --header-h: 66px; }
}
dialog.viewer .viewer__caption { padding: .9rem 1rem 1.1rem; color: var(--on-navy-2); margin: 0; }
.site-header.is-scrolled { box-shadow: 0 6px 20px -16px rgba(11, 31, 58, .35); }
.newsletter { display: flex; flex-wrap: wrap; gap: .6rem; max-width: 520px; margin: var(--space-5) auto 0; }
.newsletter .field { flex: 1 1 240px; }
.newsletter .field input { background: var(--navy-800); border-color: rgba(244, 241, 232, .3); color: var(--on-navy); }
.newsletter .field input::placeholder { color: var(--on-navy-3); }
.newsletter .field input:focus { border-color: var(--gold); box-shadow: 0 0 0 3px rgba(212, 175, 55, .25); }

/* ── Small utilities (margins that used to be inline) ───────────────────── */
.mt-3 { margin-top: var(--space-3); } .mt-4 { margin-top: var(--space-4); } .mt-5 { margin-top: var(--space-5); } .mt-6 { margin-top: var(--space-6); } .mt-7 { margin-top: var(--space-7); }
.mb-4 { margin-bottom: var(--space-4); }
.small { font-size: .9rem; }
.sq { aspect-ratio: 1 / 1; }
section[id] { scroll-margin-top: 90px; }
.alert--center { max-width: 520px; margin: var(--space-6) auto 0; }
.panel h2 { font-size: var(--step-2); }
.detail__h { margin-top: var(--space-7); font-size: var(--step-3); }
.detail__role { color: var(--gold-text); font-size: var(--step-1); margin-top: .5rem; }
.detail__bio { font-size: var(--step-1); }
.portrait { max-width: 460px; }
.portrait img { aspect-ratio: 4 / 5; }
.closing--light h2 { color: var(--ink); }
.closing--light p { color: var(--muted); }
@media (min-width: 900px) { .contact-grid { grid-template-columns: minmax(0, 4fr) minmax(0, 7fr); } }
.mobile-nav .wrap { display: block; min-height: 0; }
@media (max-width: 639px) { .header-cta { display: none; } .brand img { height: 48px; } }

/* ── Finish-review batch: brochure grammar on every listing surface ─────── */
.card__sub { color: var(--muted); font-size: .88rem; margin-top: -.2rem; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; overflow: hidden; }
.spread--listing { margin-bottom: var(--space-7); }
.spread--listing .spread__media img { aspect-ratio: 3 / 2; }
.spread--listing .spread__loc { color: var(--muted); }
.spread--listing .spread__loc svg { color: var(--gold-text); }
.spread__title { font-size: var(--step-3); margin-top: .4rem; }
.spread__title a { text-decoration: none; color: inherit; }
.spread__title a:hover { color: var(--gold-text); }
.spread__sub { color: var(--muted); margin-top: .35rem; }
.facts--light { border-top-color: rgba(212, 175, 55, .55); }
.facts--light > div { border-bottom-color: rgba(212, 175, 55, .3); }
.price-line--light strong { color: var(--navy-900); }
.price-line--light span { color: var(--muted); font-size: .92rem; }
.detail .price-line { border-top: 0; margin-top: var(--space-2); padding-top: var(--space-3); }
.detail__sub { color: var(--muted); font-size: var(--step-1); margin-top: .35rem; }
.gallery__frame { position: relative; }
.prose__label { font-family: var(--font-text); font-weight: 600; font-size: 1rem; color: var(--ink); margin-top: 1.25em; }
.prose .features { margin-top: .6em; }
.prose .features li { color: var(--ink-2); }
.prose .features + p, .prose .features + .prose__label { margin-top: 1.25em; }
.contacts .agent-card { text-decoration: none; color: inherit; padding: .8rem 0; border-top: 1px solid var(--line); }
.contacts h2 + .agent-card { border-top: 0; padding-top: .4rem; }
.contacts .agent-card > div { flex: 1; }
.contacts .agent-card > svg { width: 18px; height: 18px; color: var(--muted-2); }
.contacts .agent-card:hover strong { color: var(--gold-text); }
.btn--paper { background: var(--on-navy); color: var(--navy-900); }
.btn--paper:hover { background: var(--paper); }
.filters__toggle { width: 100%; justify-content: space-between; }
.filters__toggle > span { display: inline-flex; align-items: center; gap: .5rem; }
.filters__toggle svg { width: 18px; height: 18px; }
.filters.is-open .filters__toggle > svg:last-child { transform: rotate(180deg); }
.filters__body { display: none; }
.filters.is-open .filters__body { display: block; margin-top: var(--space-4); }
.filters--collapsible { background: transparent; border: 0; padding: 0; }
.filters--collapsible .filters__toggle { width: auto; }
.filters--collapsible.is-open .filters__body { background: var(--paper); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: var(--space-5); }
@media (max-width: 899px) {
  .filters:not(.filters--collapsible) { padding: var(--space-3) var(--space-4); }
  .filters:not(.filters--collapsible).is-open { padding-bottom: var(--space-5); }
}
@media (min-width: 900px) {
  .filters:not(.filters--collapsible) .filters__toggle { display: none; }
  .filters:not(.filters--collapsible) .filters__body { display: block; margin-top: 0; }
}
.crumbs { flex-wrap: nowrap; min-width: 0; flex: 1 1 auto; }
.crumbs a { white-space: nowrap; }
.crumbs svg { flex: 0 0 auto; }
.crumbs [aria-current] { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.subbar .link-arrow { white-space: nowrap; flex: 0 0 auto; }
/* The share button sits opposite the breadcrumb and never shrinks or wraps. On a phone the label
   goes and the icon carries it, the same trade the WhatsApp float already makes at 640px. */
.subbar .btn { flex: 0 0 auto; }
@media (max-width: 640px) { .subbar .btn--whatsapp span { display: none; } .subbar .btn--whatsapp { padding: .55rem .7rem; } }
/* On a phone the Home crumb costs more room than it earns and the header already carries one, so
   the parent crumb leads and the listing name gets the width back. */
@media (max-width: 480px) { .crumbs > a:first-child, .crumbs > a:first-child + svg { display: none; } }
.prose__ref { color: var(--muted); font-size: .9rem; }

/* ── Dot field: every navy opening and the home closing band carry [data-dots]; site.js inserts the canvas ── */
[data-dots] { position: relative; overflow: hidden; }
[data-dots] > .wrap { position: relative; z-index: 1; }
.closing-wall { background: var(--navy-900); }
.dots { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }

/* ── Star border: a 2px gold ring (same tone as the button, so no outline shows) with two soft glows travelling its top and bottom edges (after One Legacy's StarBorder) ── */
.star-border { position: relative; display: inline-block; padding: 2px; border-radius: var(--radius-ring); background: var(--gold); overflow: hidden; vertical-align: middle; transition: background var(--dur) var(--ease); }
.star-border:hover, .star-border:has(> [aria-current="page"]) { background: var(--gold-deep); }
.star-border__glow { position: absolute; width: 300%; height: 50%; opacity: .7; border-radius: 50%; z-index: 0; pointer-events: none; background: radial-gradient(circle, var(--on-navy), transparent 10%); }
.star-border__glow--bottom { bottom: -11px; right: -250%; animation: star-movement-bottom 6s linear infinite alternate; }
.star-border__glow--top { top: -10px; left: -250%; animation: star-movement-top 6s linear infinite alternate; }
.star-border__inner { position: relative; z-index: 1; }
.star-border--block .star-border__inner { display: flex; }
.btn--gold[aria-current="page"] { background: var(--gold-deep); }
@keyframes star-movement-bottom { 0% { transform: translate(0%, 0%); opacity: 1; } 100% { transform: translate(-100%, 0%); opacity: 0; } }
@keyframes star-movement-top { 0% { transform: translate(0%, 0%); opacity: 1; } 100% { transform: translate(100%, 0%); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .star-border__glow { display: none; } }
@media (max-width: 639px) { .star-border.header-cta { display: none; } }

/* ── About page: the CEO spread, the mission and vision panels, the "why choose us" points ── */
.wall .prose { color: var(--on-navy-2); }
@media (min-width: 900px) { .spread--portrait { grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); align-items: start; } }
.signature { margin-top: var(--space-5); font-family: var(--font-display); font-size: var(--step-1); }
.signature a { text-decoration: none; color: inherit; }
.signature a:hover { color: var(--gold); }
.signature span { display: block; font-family: var(--font-text); font-size: .9rem; color: var(--on-navy-3); margin-top: .2rem; }
.panel--statement { padding: var(--space-6); }
.panel__icon { display: inline-grid; place-items: center; width: 44px; height: 44px; margin-bottom: var(--space-3); color: var(--gold-text); border: 1px solid rgba(212, 175, 55, .45); border-radius: 50%; }
.panel__icon svg { width: 24px; height: 24px; }
.proof__icon { display: block; width: 24px; height: 24px; margin-bottom: var(--space-3); color: var(--gold-text); }
.proof__icon svg { width: 24px; height: 24px; }

/* ── Developer logo wall (home) and the logo beside a developer name in a schedule ── */
/* The wall is a marquee, not a grid: the developer list grows with every launch we take on, and a grid
   turns that into an ever taller block on the home page. One set of tiles is rendered twice and the row
   slides exactly -50%, which lands on the start of the second set, so the loop has no seam. It bleeds
   past the wrap to the screen edges and fades at both, so tiles enter and leave rather than being cut.
   site.js sets --marquee-duration from the measured width so the speed is constant however many there
   are; the value here is the no-JS fallback. Hover or tab into it and it holds still. */
.marquee { --marquee-fade: 5rem; position: relative; width: 100vw; margin-inline: calc(50% - 50vw); overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 var(--marquee-fade), #000 calc(100% - var(--marquee-fade)), transparent);
          mask-image: linear-gradient(90deg, transparent, #000 var(--marquee-fade), #000 calc(100% - var(--marquee-fade)), transparent); }
/* On a phone a 5rem fade at each end eats most of the screen, so barely a tile reads clearly. */
@media (max-width: 640px) { .marquee { --marquee-fade: 1.75rem; } }
.marquee__row { display: flex; width: max-content; animation: marquee-slide var(--marquee-duration, 60s) linear infinite; }
.marquee__set { display: flex; align-items: center; gap: var(--space-3); list-style: none; margin: 0; padding: 0 0 0 var(--space-3); }
.marquee__set > li { flex: 0 0 auto; width: 200px; }
.marquee:hover .marquee__row, .marquee:focus-within .marquee__row { animation-play-state: paused; }
@keyframes marquee-slide { from { transform: translateX(0); } to { transform: translateX(-50%); } }
/* Nothing moves on its own under reduced motion: it becomes a strip you scroll yourself, and the second
   set goes, or the same logos would be there twice with no motion to explain why. */
@media (prefers-reduced-motion: reduce) {
  .marquee { overflow-x: auto; }
  .marquee__row { animation: none; }
  .marquee__set[aria-hidden] { display: none; }
}
@media print { .marquee { overflow: visible; } .marquee__row { animation: none; } .marquee__set[aria-hidden] { display: none; } }

.logos { display: grid; gap: var(--space-3); grid-template-columns: repeat(auto-fill, minmax(min(100%, 200px), 1fr)); list-style: none; margin: 0; padding: 0; }
/* No plate and no border: the logos sit straight on the ground, and the only thing that marks one out
   is its own mark coming up to full colour. The keyboard ring is the global :focus-visible outline,
   which is why the border could go without taking the focus indicator with it. */
.logo-tile { display: flex; align-items: center; justify-content: center; height: 108px; padding: 0 var(--space-4); text-decoration: none; color: var(--ink); }
.logo-tile img { max-height: 64px; max-width: 82%; width: auto; height: auto; object-fit: contain; filter: grayscale(1); transition: filter var(--dur) var(--ease); }
.logo-tile:hover img, .logo-tile:focus-visible img { filter: none; }
@media (hover: none) { .logo-tile img { filter: none; } }
.logo-tile--text { font-family: var(--font-display); font-size: var(--step-0); text-align: center; line-height: 1.2; }
.facts__dev { display: inline-flex; align-items: center; justify-content: flex-end; gap: .55rem; }
.facts__logo { height: 22px; width: auto; max-width: 90px; object-fit: contain; }

.spread__media .clip { display: block; overflow: hidden; border-radius: var(--radius-photo); box-shadow: var(--shadow-lg); }
.spread__media .clip img { border-radius: 0; box-shadow: none; }

/* ── Unit mix: a project's floor plans, set like the facts schedule ─────────────────────────── */
.table-scroll { position: relative; overflow-x: auto; max-width: 100%; }
.unit-mix { width: 100%; border-collapse: collapse; font-size: var(--step-0); }
.unit-mix th { text-align: left; font-family: var(--font-text); font-weight: 500; font-size: .8rem; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); padding: 0 var(--space-4) .7rem 0; border-bottom: 1px solid rgba(212, 175, 55, .55); white-space: nowrap; }
.unit-mix th:last-child, .unit-mix td:last-child { text-align: right; padding-right: 0; }
.unit-mix td { padding: .8rem var(--space-4) .8rem 0; border-bottom: 1px solid var(--line); color: var(--ink-2); font-variant-numeric: tabular-nums lining-nums; white-space: nowrap; }
.unit-mix tbody tr:last-child td { border-bottom: 0; }
.unit-mix td:first-child { color: var(--ink); }

/* ── Scroll choreography ───────────────────────────────────────────────────────────────────────
   JS adds .js to <html>; without it, under reduced motion, or in print, everything is simply
   visible. Three entry treatments share one observer: a block rises and fades, a heading lifts a
   line at a time from behind its own mask, a photograph wipes open from the bottom. Scroll-linked
   motion is the hero's --hp and the photograph drift on --py. Nothing pins or hijacks the scroll. */
.js [data-reveal] { opacity: 0; transform: translateY(18px); transition: opacity var(--dur-reveal) var(--ease), transform var(--dur-reveal) var(--ease); }
.js [data-reveal]:has([data-lines]) { transform: none; }                      /* the lines carry the movement */
.js [data-reveal].is-in { opacity: 1; transform: none; transition-delay: calc(var(--d, 0) * var(--stagger-step)); }
.js .card[data-reveal].is-in:hover { transform: translateY(-2px); }

.js [data-lines] .ln { display: block; overflow: hidden; padding-bottom: .04em; }
.js [data-lines] .ln__i { display: block; transform: translateY(105%); transition: transform var(--dur-reveal) var(--ease); transition-delay: calc(var(--l, 0) * var(--line-step)); }
.js [data-lines].is-in .ln__i, .js .is-in [data-lines] .ln__i { transform: none; }

.js [data-photo] { clip-path: inset(0 0 100% 0); transition: clip-path var(--dur-photo) var(--ease); }
.js [data-photo].is-in, .js .is-in [data-photo] { clip-path: inset(0 0 0 0); }
.js [data-photo] img:not([data-parallax]) { transform: scale(1.04); transition: transform calc(var(--dur-photo) + 250ms) var(--ease); }
.js [data-photo].is-in img:not([data-parallax]), .js .is-in [data-photo] img:not([data-parallax]) { transform: none; }

[data-parallax] { transform: translateY(var(--py, 0px)) scale(1.06); }
html[data-drift] [data-parallax] { will-change: transform; }                  /* only while the loop runs */

/* The inner openings move like the home hero, at a smaller amplitude: these are short bands. */
.opening[data-hero] { --hp: 0; }
.opening[data-hero] h1 { transform: translateY(calc(var(--hp) * -40px * var(--hero-amp))); opacity: clamp(0, calc(1 - var(--hp) * .85), 1); }
.opening[data-hero] > .wrap > p { transform: translateY(calc(var(--hp) * -22px * var(--hero-amp))); opacity: clamp(0, calc(1 - var(--hp) * 1.25), 1); }

@media (prefers-reduced-motion: reduce), (hover: none) { [data-parallax] { transform: none; will-change: auto; } }
@media (prefers-reduced-motion: reduce) {
  .js [data-reveal] { opacity: 1; transform: none; transition: none; }
  .js [data-lines] .ln__i, .js [data-photo] img { transform: none; transition: none; }
  .js [data-photo] { clip-path: none; transition: none; }
  .hero h1, .hero__sub, .hero__cta, .hero__art, .hero canvas.dots { transform: none; opacity: 1; }
  .opening[data-hero] h1, .opening[data-hero] > .wrap > p { transform: none; opacity: 1; }
}
/* A reveal may never leave content off the page. */
@media print {
  [data-reveal], [data-lines] .ln__i, [data-photo], [data-photo] img, [data-parallax] { opacity: 1 !important; transform: none !important; clip-path: none !important; }
}
