/* =========================================================================
   PRIVATO — Design System
   Static-first build (will be ported into Webflow once approved).
   Aesthetic: pure black + ivory, magazine-spread minimalism. W / Delano /
   Mondrian register. Typography and space carry the wow factor;
   photography fills the color story.
   ========================================================================= */

/* ---------- 1. Tokens ---------- */
:root {
  /* Color — pure black-and-white minimalism. Gray for hierarchy. */
  --ink:        #000;                /* pure black */
  --ink-soft:   #1a1a1a;
  --paper:      #121212;             /* page surface — a shade off pure black so .section--ink reads as a distinct darker band (2026-08-07). Was #000000, which made every section identical and the site read flat. */
  --ivory:      #ffffff;             /* primary background = pure white */
  --ivory-2:    #f4f4f4;             /* very subtle off-white for alt surfaces */
  --hairline:   rgba(255,255,255,0.12); /* all-black site: hairlines are light-on-dark, not a gray swatch (2026-08-07) */
  --stone:      #4a4a4a;             /* neutral cool gray */
  --stone-soft: #9b9b9b;
  --silver:     #c8c8c8;
  --wine:       #6e2a3a;             /* burgundy accent — section rules */
  /* Global image treatment — full color, with a touch of contrast/saturation for glossy print quality */
  --img-filter: contrast(1.06) saturate(1.05);

  /* Type */
  --font-display: "Italiana", "Cormorant Garamond", "Playfair Display", Georgia, serif;
  --font-serif:   "Cormorant Garamond", "EB Garamond", Georgia, serif;
  --font-sans:    "Inter", -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif;

  /* Scale (fluid)
     ---------------------------------------------------------------------
     Rebuilt 2026-08-14. The old scale ran 44.8 / 32 / 23px at the top end —
     everything sat in a narrow band, so nothing was big and nothing was small
     and the page had no dynamic range. Measured against four luxury references
     Alex sent (Mariven 88px, Bellavista 120px, Aurven ~110px, Zafron 72px);
     ours was 51px, roughly half the category standard.
     The move is not "make the headline bigger" — it is widening the DISTANCE
     between largest and smallest so hierarchy is felt rather than read. The top
     end roughly doubles; the small end tightens a notch to open the gap from
     both directions.
     Copy is untouched: this is size, tracking and leading only. */
  --fs-display:   clamp(3rem, 8.2vw, 7rem);      /* 48 → 112px */
  --fs-h1:        clamp(2.6rem, 6.6vw, 5.6rem);  /* 41.6 → 89.6px */
  --fs-h2:        clamp(1.8rem, 3.3vw, 2.9rem);  /* 28.8 → 46.4px */
  --fs-h3:        clamp(1.22rem, 1.65vw, 1.5rem);
  --fs-lede:      clamp(1.06rem, 1.2vw, 1.18rem);
  --fs-body:      1.05rem;
  --fs-small:     0.9rem;
  /* Small uppercase Inter had drifted to SIX sizes (10.56 / 10.88 / 11.52 / 11.84 /
     12 / 12.48px) for what is functionally one thing. Four of them sat within
     1.3px of each other — invisible as a distinction, but the page reads
     unresolved. Two sizes now, and the floor is raised so nothing is a squint.
     (2026-08-09)
     2026-08-14: tightened a notch as part of the scale rebuild. Dynamic range
     is a ratio, not an absolute — pushing the headline to 90px while the labels
     stay at 13px only widens the gap from one end. Floor is still above the
     squint threshold at 11.2px. */
  --fs-micro:     0.70rem;   /* 11.2px — the quietest: card indexes, proof labels, legal */
  --fs-label:     0.78rem;   /* 12.5px — every other small uppercase label */
  --fs-eyebrow:   var(--fs-label);

  /* Space scale */
  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.5rem;
  --space-4: 2.5rem;
  --space-5: 4rem;
  --space-6: 6rem;
  --space-7: 8.5rem;
  --space-8: 12rem;

  /* Layout */
  --container: 1340px;
  --container-narrow: 980px;
  --gutter: clamp(1.25rem, 4vw, 3rem);

  /* Motion */
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);
  --ease-soft: cubic-bezier(0.45, 0, 0.15, 1);
}

/* ---------- 2. Reset & base ---------- */
*, *::before, *::after { box-sizing: border-box; }
/* overflow-x safety net, 2026-08-25 — real mobile screenshots showed the page
   scrolled slightly right, clipping right-edge content (the Property Management
   h1, the contact Send button) uniformly across pages. Desktop-resized-window
   testing never reproduces this because it isn't one broken element so much as
   mobile browsers computing 100vw/scroll width slightly differently than the
   visible viewport. This is the standard, zero-visual-risk guard: it can't
   change how anything already fits, it just stops anything that doesn't fit
   from ever becoming horizontally scrollable/visible past the edge. */
html, body { overflow-x: hidden; }
html { scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  /* 2026-08-20 — was var(--paper), #121212. The whole page canvas was a shade of
     grey, not black, on every page. Every section without its own opaque
     background (edges, load flash, any gap) showed that grey through, which read
     as a light haze behind sections that were supposed to be pure black. This is
     the actual site-wide cause of it; the ledger section's grey box was one
     visible symptom, not the source. */
  background: var(--ink);
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: var(--fs-body);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  font-feature-settings: "ss01", "kern";
  text-rendering: optimizeLegibility;
}
img, picture, video { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; transition: color 0.3s var(--ease); }
button { font: inherit; cursor: pointer; background: none; border: 0; color: inherit; padding: 0; }
input, textarea, select { font: inherit; color: inherit; }
::selection { background: var(--ink); color: var(--ivory); }

/* ---------- 3. Typography ---------- */
h1, h2, h3, h4, h5 { margin: 0; font-weight: 400; line-height: 1.2; letter-spacing: -0.005em; }
h1 { font-family: var(--font-serif); font-size: var(--fs-h1); }
h2 { font-family: var(--font-serif); font-size: var(--fs-h2); line-height: 1.25; }
h3 { font-family: var(--font-serif); font-size: var(--fs-h3); line-height: 1.2; }

.display {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--fs-display);
  /* 2026-08-14: leading pulled under 1.0 and tracking taken negative. This is
     the part that actually reads as "carved" rather than "typed" — Bellavista
     runs 120px type on 108px leading with -7.2px tracking. At display size the
     optical gaps inside a line open up on their own, so the tracking that
     serves a 16px label makes a 100px headline look loose. */
  line-height: 0.94;
  letter-spacing: -0.018em;
}
.display em {
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  letter-spacing: -0.01em;
}

.eyebrow {
  font-family: var(--font-sans);
  font-size: var(--fs-eyebrow);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--stone);
  font-weight: 500;
}
.eyebrow .dot { display: inline-block; width: 4px; height: 4px; border-radius: 50%; background: currentColor; vertical-align: middle; margin: 0 0.7em 0.18em; }

/* Hero location rails sit alone under the biggest headline on the page with nothing
   near them, so they carry a step more size than a label inside a card. One tier, not
   a one-off: applied to every hero on the site so the five pages stay identical.
   0.82rem → 0.9rem. (2026-08-09) */
.hero .eyebrow,
.page-hero .eyebrow { font-size: 0.9rem; }

/* 2026-08-14 — the three-city rail (Cartagena · Medellín · Colombia) overshot a
   390px screen by only a few pixels and wrapped onto two lines. Rather than let it
   wrap, tighten the tracking and size a step at phone width so it holds one line.
   The two-city rails on index and villas already fit and are unaffected in practice;
   the rule is written for all heroes so the five pages stay one set.
   The nowrap grouping in the markup stays as the fallback below ~340px. */
@media (max-width: 430px) {
  .hero .eyebrow,
  .page-hero .eyebrow {
    font-size: 0.82rem;
    letter-spacing: 0.12em !important;
  }
}

.lede {
  font-family: var(--font-serif);
  font-size: var(--fs-lede);
  line-height: 1.55;
  color: var(--ink-soft);
  font-style: italic;
}

p { margin: 0 0 1.1em; }
p:last-child { margin-bottom: 0; }

/* ---------- 4. Layout primitives ---------- */
.container { max-width: var(--container); margin: 0 auto; padding-inline: var(--gutter); }
.container--narrow { max-width: var(--container-narrow); margin: 0 auto; padding-inline: var(--gutter); }
/* Tightened 2026-05-13 per Alex — was 8.5rem, then 4rem, now 3rem. ~6rem (1 inch) between consecutive sections. */
/* Opened 2026-08-07. Was clamp(3.4rem, 5.5vw, 5rem) — the page was packed to the
   edges, which read busier than the (already very lean) copy actually is. */
.section { padding-block: clamp(5rem, 8vw, 7.5rem); }
/* Exactly half of .section — for bands that carry little content and
   otherwise float in dead space (2026-08-09). */
.section--tight { padding-block: clamp(2.5rem, 4vw, 3.75rem); }
.section--ink { background: var(--ink); color: var(--ivory); }
.section--ink .eyebrow { color: var(--stone-soft); }
.section--ink .lede { color: var(--ivory); }
/* Card text inversion when sections flip to black bg (added 2026-05-13) */
.section--ink h2 a,
.section--ink .property-card__title,
.section--ink .service-card__title,
.section--ink .service-card__title a { color: var(--ivory); }
.section--ink .service-card__body,
.section--ink .property-card__sub { color: rgba(255,255,255,0.72); }
.section--ink .property-card__meta { color: rgba(255,255,255,0.55); }
.section--ink .property-card__tag { background: rgba(255,255,255,0.92); color: var(--ink); }
.section--ink hr.divider,
.section--ink .divider { border-color: rgba(255,255,255,0.12); }
.section--ink .section-heading p { color: rgba(255,255,255,0.7); }
.section--paper { background: var(--paper); }
.divider { border: 0; border-top: 1px solid var(--hairline); margin: 0; }
.section--ink .divider { border-color: rgba(255,255,255,0.12); }

/* ---------- 5. Buttons / links ---------- */
.btn {
  display: inline-flex; align-items: center; gap: 0.65rem;
  padding: 0.95rem 1.6rem;
  font-family: var(--font-sans); font-size: var(--fs-label); letter-spacing: 0.18em;
  text-transform: uppercase; font-weight: 500;
  border: 1px solid currentColor;
  transition: all 0.4s var(--ease);
  cursor: pointer;
}
/* One button, one hover, everywhere (2026-08-09). Previously .btn:hover filled with
   var(--ink) — black on a black site, i.e. no visible hover at all on the nav — while
   buttons inside .section--ink flipped to a solid white fill. Two behaviors, neither
   consistent. Now: a light wash and a brightened border, identical on every page. */
.btn { color: var(--ivory); border-color: rgba(255,255,255,0.55); }
.btn:hover,
.btn--invert:hover,
.section--ink .btn:hover { background: rgba(255,255,255,0.10); color: var(--ivory); border-color: var(--ivory); }
.btn--invert { background: transparent; color: var(--ivory); border-color: rgba(255,255,255,0.55); }
.section--ink .btn { color: var(--ivory); }
.btn--ghost { border-color: transparent; padding-inline: 0; }
.btn--ghost:hover { background: transparent; color: var(--ink); border-color: transparent; }

/* Fixed 2026-08-24 — the nav "Inquire" button is the .btn class above, which
   is hard-coded white-on-transparent for the dark/--ink header. Every page
   that switched to .site-header--static (white, non-moving) still used that
   same class, so the button was rendering near-white text on a near-white
   header — effectively invisible. Also doubles as "bring the CTAs out more"
   per Alex: solid dark pill instead of a thin outline, matching the weight
   of .cl-btn used in the page content below it. */
.site-header--static .nav-cta .btn {
  color: #141414; background: #fff; border-color: #fff;
  border-radius: 999px;
}
.site-header--static .nav-cta .btn:hover { background: #ececec; border-color: #ececec; color: #141414; }

.link-arrow {
  display: inline-flex; align-items: center; gap: 0.55rem;
  font-family: var(--font-sans); font-size: var(--fs-label); letter-spacing: 0.17em;
  text-transform: uppercase; font-weight: 500; color: var(--ink);
  padding-block: 0.4rem;
  border-bottom: 1px solid currentColor;
  transition: color 0.3s var(--ease), letter-spacing 0.3s var(--ease);
}
.link-arrow .arrow { transition: transform 0.4s var(--ease); display: inline-block; }
.link-arrow:hover { color: var(--silver); }
.link-arrow:hover .arrow { transform: translateX(4px); }
.section--ink .link-arrow { color: var(--ivory); }
.section--ink .link-arrow:hover { color: var(--silver); }

/* ---------- 6. Header / Navigation ---------- */
.site-header {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100;
  padding-block: 1.2rem;
  background: rgba(0,0,0, 0);
  transition: background 0.5s var(--ease), padding 0.4s var(--ease), border-color 0.5s var(--ease);
  border-bottom: 1px solid transparent;
}
/* Was cream (246,242,234) — Alex, 2026-08-24: not on the light Collection
   page. Pure white now, matching videinfra.com's header (flat white, no
   tint shift on scroll, just a hairline dividing it from content below).
   Only villas.html uses this un-inked header right now; every other page
   still uses .site-header--ink with its own separate dark scrolled color,
   so this is scoped to the Collection page in practice. */
/* Alex, 2026-08-24: "theirs doesn't move" — videinfra's header never
   animates, it's just flat white with a hairline from the first frame.
   .site-header--scrolled (below) still fades in on scroll for the --ink
   pages; this modifier instead locks the header to that same still, plain
   state permanently, no transition, no size change, matching the reference
   exactly. Only villas.html carries this class. */
.site-header--static {
  background: rgba(0,0,0, 0.97) !important;
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom-color: var(--hairline);
  transition: none;
  /* 2026-08-27 — black/white invert preview, per Alex. The header's own text
     (nav links, hamburger bars via currentColor) inherits color from body,
     which stays --ink (black) so it isn't touched globally — this header is
     now a dark panel, so it needs its own explicit light color rather than
     relying on that inherited black. */
  color: #fff;
}
.site-header--static .nav-brand img,
.site-header--static.site-header--scrolled .nav-brand img { height: 62px; }

.site-header--scrolled {
  background: rgba(0,0,0, 0.96);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  padding-block: 0.8rem;
  border-bottom-color: var(--hairline);
}
.site-header--ink {
  background: rgba(12, 11, 9, 0);
  color: var(--ivory);
}
.site-header--ink.site-header--scrolled {
  background: rgba(12, 11, 9, 0.92);
  border-bottom-color: rgba(0,0,0,0.08);
}
/* 2026-08-25, per Alex — was justify-content:space-between, which floated
   the nav links somewhere in the middle of the header with a gap before
   Inquire. Matched to Vide Infra's layout instead: logo pinned far left,
   everything else (links + Inquire) bunched together at the far right
   edge. margin-left:auto on the <nav> element pushes it and everything
   after it (nav-cta) as far right as the row allows, logo stays put. */
.nav-inner { display: flex; align-items: center; gap: 1.5rem; }
.nav-inner > nav { margin-left: auto; }
.nav-brand { display: flex; align-items: center; gap: 0.8rem; }
/* Trimmed 2026-08-27, per Alex's boho-minimal pass — a 92px logo pinned in
   the corner of every page was one of the more "in your face" fixed
   elements on the site, present on every scroll position of every page. */
.nav-brand img { height: 70px; width: auto; transition: height 0.4s var(--ease), opacity 0.4s var(--ease); }
.site-header--scrolled .nav-brand img { height: 54px; }
.nav-brand .nav-brand-light { display: none; }
.site-header--ink .nav-brand-dark { display: none; }
.site-header--ink .nav-brand-light { display: block; }
.site-header--ink.site-header--scrolled .nav-brand-dark { display: none; }
/* Swap to the white wordmark on the now-dark --static header (villas.html),
   same logic as --ink just above. 2026-08-27 fix: this used to sit right
   after .site-header--static's own block, up near line 300 — same
   specificity as the base ".nav-brand .nav-brand-light { display:none }"
   rule two lines up, but earlier in the file, so the base rule was winning
   the cascade and hiding BOTH logos (the dark one already hidden on the
   now-black header, the light one hidden by this bug) — no logo at all.
   Moved down here, after the base rule, so it actually wins. */
.site-header--static .nav-brand-dark { display: none; }
.site-header--static .nav-brand-light { display: block; }

/* 2026-08-25, per Alex — was uppercase, 0.22em tracking, .78rem: the
   boutique-hotel-menu convention. Alex: "I don't want to be like a regular
   ole travel agency... more hip and minimalistic." Matched to Vide Infra's
   plain, tightly-grouped nav voice instead: normal case (the HTML already
   reads "The Collection" etc. in Title Case, so dropping text-transform
   just lets that show), size bumped since normal case needs to be a notch
   bigger than all-caps to read at the same weight, tracking down near
   zero, gap tightened so the four links read as one close cluster. */
.nav-list {
  display: flex; align-items: center; gap: 1.8rem;
  list-style: none; margin: 0; padding: 0;
}
.nav-list a {
  font-family: var(--font-sans);
  font-size: 0.92rem;
  letter-spacing: 0.01em;
  text-transform: none;
  /* 500 → 400, per Alex — at all-caps the weight read fine, but in normal
     case medium-weight letterforms show their heaviness much more plainly.
     Regular weight matches Vide Infra's own nav and reads lighter/hipper. */
  font-weight: 400;
  color: inherit;
  padding-block: 0.5rem;
  position: relative;
}
/* 2026-08-25, per Alex — tried an underline draw-in, then a terracotta
   color shift, wanted neither: no bold, no color, just a quick blink on
   hover instead. A one-shot opacity flash (not a sustained hover state),
   so it reads as a flicker of acknowledgment, not a color/weight change. */
.nav-list a:hover { animation: navBlink 0.4s var(--ease); }
@keyframes navBlink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.3; }
}
@media (prefers-reduced-motion: reduce) {
  .nav-list a:hover { animation: none; }
}
   so nav hover speaks the same accent language as everything else instead
   of its own separate device. Considered matching Vide Infra's cloned-text
   slot-machine roll (verified live — genuinely well-built) but picked
   consistency with the site's existing accent color over adding a second,
   unrelated hover trick. */
.nav-list a:hover, .nav-list .is-active > a { color: #a9744a; }
.has-dropdown { position: relative; }
.has-dropdown > a::before {
  content: ""; display: inline-block;
  border: 4px solid transparent; border-top-color: currentColor;
  margin-right: 0.5rem; transform: translateY(2px);
  transition: transform 0.3s var(--ease);
  opacity: 0.6;
}
.has-dropdown:hover > a::before { transform: translateY(2px) rotate(180deg); }
.dropdown {
  position: absolute; top: calc(100% + 1.4rem); left: 50%; transform: translateX(-50%) translateY(8px);
  min-width: 180px;
  background: rgba(255,255,255,0.72);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  backdrop-filter: blur(14px) saturate(140%);
  border: 1px solid rgba(0,0,0,0.12);
  padding: 0.9rem 1.2rem;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity 0.35s var(--ease) 0.15s, visibility 0.35s var(--ease) 0.15s, transform 0.35s var(--ease) 0.15s;
  box-shadow: 0 12px 40px -14px rgba(255,255,255,0.5);
}
.dropdown::before {
  content: "";
  position: absolute;
  top: -1.4rem;
  left: 0;
  right: 0;
  height: 1.4rem;
  background: transparent;
}
.has-dropdown:hover .dropdown {
  opacity: 1; visibility: visible; transform: translateX(-50%) translateY(0); pointer-events: auto;
  transition-delay: 0s;
}
.dropdown-section + .dropdown-section { margin-top: 1.1rem; padding-top: 1.1rem; border-top: 1px solid rgba(0,0,0,0.14); }
.dropdown-label {
  font-family: var(--font-sans);
  font-size: var(--fs-eyebrow);
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(0,0,0,0.55);
  margin-bottom: 0.7rem;
  display: block;
}
.dropdown a {
  display: block; padding: 0.45rem 0;
  font-family: var(--font-serif); font-size: 1.08rem;
  text-transform: none; letter-spacing: 0;
  color: var(--ivory);
  text-align: center;
  transition: color 0.3s var(--ease);
}
.dropdown-label {
  text-align: center;
}
.dropdown a:hover { color: rgba(0,0,0,0.65); }
.dropdown a::after { display: none; }

.nav-cta { display: flex; align-items: center; gap: 1rem; }
.nav-cta .btn {
  padding: 0.7rem 1.2rem; font-size: var(--fs-label);
}

.nav-toggle { display: none; }
.mobile-drawer { display: none; }

@media (max-width: 960px) {
  .nav-list, .nav-cta .btn { display: none; }
  .nav-toggle {
    display: inline-flex; flex-direction: column; gap: 5px;
    width: 28px; height: 22px; justify-content: center;
  }
  .nav-toggle span { display: block; height: 1.5px; background: currentColor; transition: transform 0.4s var(--ease), opacity 0.3s var(--ease); }
  .nav-toggle.is-open span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
  .nav-toggle.is-open span:nth-child(2) { opacity: 0; }
  .nav-toggle.is-open span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }
  .mobile-drawer {
    display: block;
    position: fixed; inset: 0; z-index: 99;
    /* 2026-08-27 — black/white invert preview, per Alex. Hardcoded rather
       than swapping var(--ivory)/var(--ink) themselves, since those two
       variables are also read by the homepage's hero video treatment
       (.m-shot__title, .m-shot__name) which must stay white-on-video,
       untouched by this inversion. */
    background: #141414; color: #fff;
    padding: 6rem var(--gutter) 3rem;
    transform: translateY(-100%);
    transition: transform 0.6s var(--ease);
    overflow-y: auto;
  }
  .mobile-drawer.is-open { transform: translateY(0); }
  .mobile-drawer a {
    display: block; padding: 1rem 0;
    font-family: var(--font-serif); font-size: 1.6rem;
    border-bottom: 1px solid var(--hairline);
  }
  .mobile-drawer .dropdown-label { padding-top: 1.2rem; padding-bottom: 0; font-size: var(--fs-eyebrow); }
  .mobile-drawer .dropdown-section a {
    font-size: 1.2rem; padding-left: 0;
  }
}

/* ---------- 7. Hero (homepage) ---------- */
.hero {
  position: relative;
  min-height: 100vh; min-height: 100svh;
  display: grid; align-items: end;
  color: var(--ivory);
  overflow: hidden;
  isolation: isolate;
}
.hero__media {
  position: absolute; inset: 0; z-index: -2;
  background:
    radial-gradient(ellipse at 50% 40%, rgba(20,18,14,0.0) 0%, rgba(8,7,6,0.55) 70%, rgba(8,7,6,0.85) 100%),
    linear-gradient(180deg, rgba(8,7,6,0.25) 0%, rgba(8,7,6,0.05) 35%, rgba(8,7,6,0.85) 100%),
    #0c0b09;
}
.hero__media::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, transparent 0%, transparent 60%, rgba(8,7,6,0.4) 100%);
  z-index: -1;
}
.hero__inner {
  padding: 0 var(--gutter) clamp(3rem, 8vh, 6rem);
  max-width: var(--container);
  margin: 0 auto;
  width: 100%;
}
.hero__eyebrow {
  color: rgba(255,255,255,0.65);
  margin-bottom: 1.6rem;
  display: flex; align-items: center; gap: 0.9rem;
}
.hero__eyebrow .dot { background: currentColor; }
.hero__title { color: var(--ivory); max-width: 17ch; margin-bottom: 1.6rem; }
.hero__title em { color: var(--silver); }
.hero__body { max-width: 46ch; font-family: var(--font-serif); font-style: italic; font-size: var(--fs-lede); color: rgba(255,255,255,0.85); margin-bottom: 2rem; }
.hero__ctas { display: flex; flex-wrap: wrap; gap: 1rem; }

.hero__scroll {
  position: absolute; bottom: 1.4rem; left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 0.7rem;
  color: rgba(255,255,255,0.55);
  font-family: var(--font-sans); font-size: var(--fs-eyebrow); letter-spacing: 0.19em;
  text-transform: uppercase;
}
.hero__scroll .line { width: 1px; height: 56px; background: linear-gradient(to bottom, rgba(255,255,255,0.5), transparent); animation: drop 2.4s var(--ease) infinite; }
@keyframes drop { 0%, 100% { transform: scaleY(0.35); transform-origin: top; } 50% { transform: scaleY(1); transform-origin: top; } }

/* ---------- 8. Intro / philosophy block ---------- */
/* Left, not centre (2026-08-09). Home and the Collection page are left-aligned end
   to end; the only centered block on the site is the homepage's closing note. A
   centered statement mid-page read as a different site. */
.intro { text-align: left; }
.intro__eyebrow { margin-bottom: 2rem; }
.intro__statement {
  /* Was --font-display (Italiana). Italiana is the hero face only — on index and
     villas it appears exactly once per page, in the h1. Section statements are
     Cormorant at 32px on both finished pages, so this matches them now. */
  font-family: var(--font-serif);
  font-size: clamp(1.55rem, 2.4vw, 2.0rem);
  line-height: 1.25;
  max-width: 26ch;
  margin: 0 0 2rem;
  letter-spacing: 0.005em;
}
.intro__statement em { font-family: var(--font-serif); font-style: italic; color: var(--ink); }
.intro__body { max-width: 58ch; margin: 0 auto; color: var(--stone); font-family: var(--font-serif); font-size: 1.18rem; line-height: 1.7; }

/* ---------- 9. Two-up cards (Property Mgmt / Services) ---------- */
.two-up {
  display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.2rem, 2.4vw, 2.4rem);
}
@media (max-width: 800px) { .two-up { grid-template-columns: 1fr; } }

/* ---------- 10. Privato Collection preview ---------- */
.section-heading { display: grid; grid-template-columns: 1fr auto; gap: 2rem; align-items: end; margin-bottom: 3rem; }
.section-heading h2 { max-width: 22ch; }
.section-heading p { color: var(--stone); max-width: 36ch; font-family: var(--font-serif); font-style: italic; font-size: 1.1rem; line-height: 1.55; }
.section-heading__action { white-space: nowrap; }
@media (max-width: 720px) { .section-heading { grid-template-columns: 1fr; } .section-heading__action { margin-top: 0.5rem; } }

.collection-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1rem, 2vw, 2rem);
}
@media (max-width: 980px) { .collection-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 600px) { .collection-grid { grid-template-columns: 1fr; } }

.property-card { display: block; color: inherit; }
.property-card__img-wrap { position: relative; overflow: hidden; aspect-ratio: 4/5; background: var(--ivory-2); margin-bottom: 1.1rem; }
.property-card__img {
  position: absolute; inset: 0;
  background-size: cover; background-position: center;
  transition: transform 1.4s var(--ease);
}
.property-card:hover .property-card__img { transform: scale(1.04); }
.property-card__tag {
  position: absolute; top: 1rem; left: 1rem; z-index: 2;
  font-family: var(--font-sans); font-size: 0.7rem; letter-spacing: 0.16em; text-transform: uppercase;
  background: rgba(246,242,234,0.92); color: var(--ink);
  padding: 0.4rem 0.8rem;
}
.property-card__meta {
  display: flex; justify-content: space-between; align-items: baseline; gap: 1rem;
  font-family: var(--font-sans); font-size: var(--fs-eyebrow); letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--stone); margin-bottom: 0.4rem;
}
.property-card__title { font-family: var(--font-serif); font-size: 1.6rem; line-height: 1.15; margin-bottom: 0.4rem; }
.property-card__sub { color: var(--stone); font-family: var(--font-serif); font-style: italic; font-size: 1rem; }

/* ---------- 11. Services grid ---------- */
.service-grid {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1.4rem, 2.6vw, 2.4rem) clamp(1rem, 2vw, 2rem);
}
@media (max-width: 900px) { .service-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .service-grid { grid-template-columns: 1fr; } }
.service-card { display: block; color: inherit; }
.service-card__img-wrap { position: relative; overflow: hidden; aspect-ratio: 3/2; margin-bottom: 1rem; background: var(--ivory-2); }
.service-card__img {
  position: absolute; inset: 0; background-size: cover; background-position: center;
  transition: transform 1.6s var(--ease);
  filter: saturate(0.85);
}
.service-card:hover .service-card__img { transform: scale(1.06); filter: saturate(1); }
.service-card__title { font-family: var(--font-serif); font-size: 1.5rem; margin-bottom: 0.4rem; }
.service-card__body { color: var(--stone); font-family: var(--font-serif); font-size: 1.02rem; line-height: 1.55; margin-bottom: 0.9rem; max-width: 36ch; }

/* ---------- 12. Testimonials ---------- */
@media (max-width: 900px) { .testimonials__list { grid-template-columns: 1fr 1fr; } }
@media (max-width: 600px) { .testimonials__list { grid-template-columns: 1fr; } }

/* ---------- 13. Locations ---------- */
.locations { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.2rem, 2.4vw, 2.4rem); }
@media (max-width: 800px) { .locations { grid-template-columns: 1fr; } }

/* ---------- 15. Footer ---------- */

.newsletter {
  display: flex; border-bottom: 1px solid rgba(255,255,255,0.18);
  margin-top: 0.6rem;
}
.newsletter input {
  flex: 1; background: transparent; border: 0; padding: 0.7rem 0;
  font-family: var(--font-serif); font-size: 1rem; color: var(--ivory);
  outline: none;
}
.newsletter input::placeholder { color: rgba(255,255,255,0.4); font-style: italic; }
.newsletter button {
  font-family: var(--font-sans); font-size: var(--fs-eyebrow);
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--silver); padding-left: 1rem;
  transition: color 0.3s var(--ease);
}
.newsletter button:hover { color: var(--ivory); }

.footer-bottom {
  display: flex; justify-content: space-between; align-items: center; gap: 1.5rem; flex-wrap: wrap;
  padding-top: 2rem;
  font-family: var(--font-sans); font-size: var(--fs-eyebrow);
  letter-spacing: 0.22em; text-transform: uppercase;
  color: rgba(255,255,255,0.45);
}
.footer-bottom a:hover { color: var(--silver); }
.footer-bottom .socials { display: flex; gap: 1.4rem; }
.footer-bottom .socials a { color: rgba(255,255,255,0.7); }

/* ---------- 16. Page hero (non-home) ---------- */
.page-hero {
  position: relative;
  min-height: 70vh; min-height: 70svh;
  display: grid; align-items: end;
  color: var(--ivory);
  overflow: hidden;
}
.page-hero__media {
  position: absolute; inset: 0; z-index: -1;
  background-size: cover; background-position: center;
}
.page-hero__media::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(8,7,6,0.35) 0%, rgba(8,7,6,0.15) 40%, rgba(8,7,6,0.85) 100%);
}
.page-hero__inner { padding: 0 var(--gutter) clamp(3rem, 8vh, 5rem); max-width: var(--container); margin: 0 auto; width: 100%; }
/* 2026-08-14: matched to .display — same leading and tracking, so the four
   inner-page heroes and the homepage read as one system at the new scale.
   max-width raised 18ch → 20ch: ch scales with font-size, and at 89px the old
   cap was forcing "Property Management." to break in an awkward place. */
.page-hero h1 { font-family: var(--font-display); font-size: var(--fs-h1); line-height: 0.94; letter-spacing: -0.018em; max-width: 20ch; margin-bottom: 1.4rem; overflow-wrap: break-word; }
.page-hero h1 em { font-family: var(--font-serif); font-style: italic; color: var(--silver); }
.page-hero .lede { color: rgba(255,255,255,0.88); max-width: 50ch; font-style: italic; }

.crumbs {
  font-family: var(--font-sans); font-size: var(--fs-eyebrow);
  letter-spacing: 0.18em; text-transform: uppercase;
  color: rgba(255,255,255,0.65); margin-bottom: 1.6rem;
}
.crumbs a:hover { color: var(--ivory); }
.crumbs .sep { margin: 0 0.6em; opacity: 0.5; }

/* ---------- 17. Editorial blocks ---------- */
.two-col {
  display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem, 5vw, 5rem);
  align-items: center;
}
@media (max-width: 800px) { .two-col { grid-template-columns: 1fr; } }
.two-col__img { aspect-ratio: 4/5; background-size: cover; background-position: center; }
.two-col__copy h2 { margin-bottom: 1.4rem; max-width: 18ch; }
.two-col__copy p { color: var(--stone); font-family: var(--font-serif); font-size: 1.12rem; line-height: 1.65; }

/* Stats row */
.stats {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 2rem;
  text-align: center;
}
@media (max-width: 700px) { .stats { grid-template-columns: repeat(2, 1fr); gap: 3rem 1rem; } }

/* Contact form */
.contact-form { display: grid; grid-template-columns: 1fr 1fr; gap: 2rem 2.5rem; max-width: 720px; margin: 0 auto; }
.contact-form .full { grid-column: 1 / -1; }
@media (max-width: 600px) { .contact-form { grid-template-columns: 1fr; } }
@media (max-width: 820px) { .gt-detail-grid { grid-template-columns: 1fr !important; } }
.field { display: flex; flex-direction: column; gap: 0.3rem; }
.field label { font-family: var(--font-sans); font-size: var(--fs-eyebrow); letter-spacing: 0.16em; text-transform: uppercase; color: var(--stone-soft); }
.field input, .field textarea, .field select {
  background: transparent; border: 0; border-bottom: 1px solid var(--hairline);
  padding: 0.45rem 0; font-family: var(--font-serif); font-size: 1.08rem; color: var(--ivory);
  outline: none; transition: border-color 0.3s var(--ease);
}
.field input:focus, .field textarea:focus, .field select:focus { border-bottom-color: var(--ivory); }
.field textarea { min-height: 88px; resize: vertical; }

/* ---------- 18. Motion (entrance) ---------- */
/* 2026-08-14 — travel 24px → 44px, timing stretched. Same reasoning as the type
   scale: the old values were too small to be *felt*, so the page technically
   animated but read as static. Motion needs range for the same reason type does. */
.reveal { opacity: 0; transform: translateY(44px); transition: opacity 1.15s var(--ease-soft), transform 1.35s var(--ease-soft); }
.reveal.is-visible { opacity: 1; transform: translateY(0); }
.reveal--delay-1 { transition-delay: 0.08s; }
.reveal--delay-2 { transition-delay: 0.16s; }
.reveal--delay-3 { transition-delay: 0.24s; }

/* ---------- 18b. Line-mask reveal — removed 2026-08-25, per Alex -----------
   Was a rise-out-of-the-mask headline entrance (each line in an
   overflow-hidden box, sliding up on load). Reconnected earlier the same
   day after sitting orphaned since the class-name rebuild, then pulled
   back out immediately: overflow:hidden on a box sized to .cl-h1's tight
   0.98 line-height was clipping the descenders on any headline with a
   g/p/y — visible on "Property Management." Alex also didn't like the
   entrance itself. main.js's matching IIFE is removed too. */

/* Sequential stagger for grids — index set by JS so cards arrive in order
   instead of the two-class alternation we had. */
[data-stagger] > .reveal { transition-delay: calc(var(--i, 0) * 0.09s); }

@media (prefers-reduced-motion: reduce) {
  [data-stagger] > .reveal { transition-delay: 0s !important; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; scroll-behavior: auto !important; }
  .reveal { opacity: 1; transform: none; }
}

/* ---------- 19. Utility ---------- */
.center { text-align: center; }
.ink-section .lede, .ink-section p { color: rgba(255,255,255,0.82); }
.spacer-sm { height: 2rem; } .spacer-md { height: 4rem; } .spacer-lg { height: 6rem; }

/* ---------- 20. Image treatment (site-wide color with glossy gain) ---------- */
.hero__media,
.page-hero__media,
.feature-card__img,
.property-card__img,
.service-card__img,
.location-card__img,
.two-col__img,
.two-col > div[style*="background-image"] {
  filter: var(--img-filter);
}
/* legacy opt-out — keeps working even now that the default isn't grayscale */
.img--color { filter: none !important; }

/* ---------- 20a. Minimal service tile grid (no-photo, hairline-divider style for homepage Services) ---------- */
.service-list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: rgba(255,255,255,0.08);
  border: 1px solid rgba(255,255,255,0.08);
}
@media (max-width: 900px) { .service-list { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .service-list { grid-template-columns: 1fr; } }

.service-tile {
  background: var(--ink);
  padding: 2.2rem 1.8rem;
  display: flex; flex-direction: column;
  gap: 0.5rem;
  color: var(--ivory);
  min-height: 200px;
  transition: background 0.45s var(--ease);
}
.service-tile:hover { background: #161616; }
.service-tile__num {
  font-family: var(--font-sans);
  font-size: 0.74rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--silver);
}
.service-tile__title {
  font-family: var(--font-serif);
  font-size: 1.55rem;
  font-weight: 400;
  line-height: 1.18;
  margin: 0;
  color: var(--ivory);
}
.service-tile__body {
  font-family: var(--font-serif);
  font-size: 1.02rem;
  line-height: 1.5;
  color: rgba(255,255,255,0.6);
  margin: 0;
  max-width: 38ch;
}
.service-tile__arrow {
  margin-top: auto;
  padding-top: 1rem;
  font-family: var(--font-sans);
  font-size: 0.78rem;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--silver);
  display: inline-flex; align-items: center; gap: 0.5rem;
  transition: gap 0.3s var(--ease);
}
.service-tile:hover .service-tile__arrow { gap: 0.9rem; }

/* ---------- 20b. Listing cards (Villas/Yachts/Events — luxury real-estate-style grid, tightened 2026-05-13) ---------- */
/* 2026-08-22 per Alex — was 3-across. He'd been browsing template marketplaces
   looking for "wow factor" and landed on Colorlib's "Work" portfolio template,
   which reads as more impressive largely because of two things: only 2 tiles
   per row (each photo is bigger, so the villa reads as the subject instead of
   a thumbnail) and far more negative space between tiles. Neither of those is
   proprietary to that template — this is the same move real estate sites this
   page is already benchmarked against make (Sotheby's, Aman, Le Collectionist
   all run large 2-up grids, not 3-up). Dropped to 2 columns at desktop and
   opened up both gaps substantially. Trade-off, stated plainly: six cards at
   2-up is three rows instead of two, so the page is now noticeably longer —
   worth it for how much bigger each photo reads, but flag if it feels like
   too much scroll and this reverts in one line. */
.listing-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  column-gap: clamp(1.6rem, 3vw, 3.2rem);
  row-gap: clamp(3.5rem, 6vw, 6rem);
}
@media (max-width: 640px)  { .listing-grid { grid-template-columns: 1fr; } }

/* 9 Aug 2026 — the outer border and the fill both come off. Six bordered
   rectangles at 0.08 sat at exactly the same weight as the rule that divides one
   SECTION from the next, so nothing on the page announced a boundary. The
   photograph is the card now; the type simply sits beneath it. Sotheby's and
   Christie's list this way, and so does Airbnb — none of them draw a box.
   Hover moves to the image and the title, since there is no longer a box to light. */
.listing-card {
  display: block;
  color: inherit;
  text-decoration: none;
  background: transparent;
  border: 0;
  transition: transform 0.5s var(--ease);
}
.listing-card:hover { transform: translateY(-3px); }
.listing-card:hover .listing-card__title { color: #fff; }
.listing-card__img-wrap {
  position: relative;
  aspect-ratio: 3/2;
  overflow: hidden;
}
.listing-card__img {
  /* 2026-08-14: was a CSS background-image div — no alt text, invisible to
     Google Images. Now a real <img>; object-fit replaces background-size. */
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center;
  transition: transform 1.2s var(--ease);
}
.listing-card:hover .listing-card__img { transform: scale(1.04); }
.listing-card__tag {
  position: absolute; top: 0.7rem; left: 0.7rem; z-index: 2;
  font-family: var(--font-sans);
  font-size: 0.64rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  background: rgba(10,10,10,0.85);
  color: var(--silver);
  padding: 0.3rem 0.6rem;
  border: 1px solid rgba(255,255,255,0.12);
}
.listing-card__body {
  /* No side padding now that there is no box to pad against — the type aligns to
     the edge of its photograph, which is what makes an unboxed card read as
     deliberate rather than unfinished. (2026-08-09) */
  padding: 1.1rem 0 0;
  color: var(--ivory);
  /* Flex so the source order can be re-sequenced without editing twelve blocks of
     HTML across two pages. Checked aman.com and lecollectionist.com on 9 Aug 2026:
     both put LOCATION above the name as a quiet uppercase line, then the name. The
     markup has it below. (2026-08-09) */
  display: flex;
  flex-direction: column;
}
/* The card index is gone. "/ 01" on a card used the exact same notation as
   "/ 01 The Collection" on the section above it — one mark, two meanings, on the
   same screen. Neither reference numbers its cards. */
.listing-card__index { display: none; }
.listing-card__location { order: 1; }
.listing-card__title    { order: 2; }
.listing-card__specs    { order: 3; }
.listing-card__desc     { order: 4; }
.listing-card__cta      { order: 5; }
.listing-card__index {
  font-family: var(--font-sans);
  font-size: var(--fs-micro);
  letter-spacing: 0.19em;
  text-transform: uppercase;
  color: var(--silver);
  margin-bottom: 0.4rem;
}
.listing-card__title {
  font-family: var(--font-serif);
  font-size: 1.65rem;
  line-height: 1.12;
  margin: 0 0 0.5rem;
  color: var(--ivory);
  transition: color 0.3s var(--ease);
}
.listing-card__location {
  font-family: var(--font-sans);
  font-size: var(--fs-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.5);
  margin-bottom: 0.45rem;
}
.listing-card__desc {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 1.3rem;
  line-height: 1.45;
  color: rgba(255,255,255,0.82);
  margin: 0 0 0.8rem;
  min-height: 2.4em;
}
/* Specs are now one quiet inline line — no rule above, no rule below, no
   oversized numerals. This is how Le Collectionist writes them
   ("10 guests · 5 bedrooms · 4 bathrooms"), and it means a card contains ZERO
   horizontal rules. Nothing inside a card competes with a section boundary now.
   (2026-08-09) */
.listing-card__specs {
  display: flex;
  flex-wrap: wrap;
  gap: 0 0.5rem;
  padding: 0;
  border: 0;
  margin-bottom: 0.9rem;
  font-family: var(--font-serif);
  font-size: 1.02rem;
  color: rgba(255,255,255,0.62);
}
/* 2026-08-19: the line-icons ahead of each stat (guests/bed/bath glyphs) are
   pulled per Alex — back to the plain middot-joined line. */
.listing-card__specs span + span::before {
  content: "\00B7";
  margin-right: 0.5rem;
  color: rgba(255,255,255,0.3);
}
.listing-card__specs strong {
  font-weight: 400;
  color: rgba(255,255,255,0.62);
  font-size: inherit;
  margin-right: 0.28em;
}
.listing-card__cta {
  font-family: var(--font-sans);
  font-size: var(--fs-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ivory);
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  transition: gap 0.3s var(--ease);
}
.listing-card:hover .listing-card__cta { gap: 0.7rem; }

/* =======================================================================
   MERIDIAN LAYER (2026-08-23)
   -----------------------------------------------------------------------
   Built after Alex chose the Meridian reference over Noema. Measured from the
   live page rather than eyeballed: section rhythm 160px, hairline #2a2a30,
   h2 64/1.05 at -1.6px tracking, marquee 28px serif italic between two rules,
   work rows on a 1fr 1fr grid with 72px gutter and a 4:3 image.
   Three deliberate departures, all for reasons this site has already settled:
     1. Fonts stay ours. Cormorant Garamond and Inter, not Fraunces and Manrope.
        Only the mono is new, because that label treatment is the actual idea.
     2. Meridian's tag chips are rounded pills. Ours are a middot-joined line —
        bordered pills have been pulled from this site every time they appear.
     3. Scoped to .meridian so nothing here can leak into villas.html or the
        other pages until Alex decides he wants it there too.
   ======================================================================= */
.meridian {
  --m-hair: rgba(255,255,255,0.14);
  --m-dim:  rgba(255,255,255,0.42);
  --m-mut:  rgba(255,255,255,0.66);
  --m-sand: #c8a882;
  --m-mono: "JetBrains Mono", "SF Mono", Menlo, Consolas, monospace;
}

/* --- the mono label, used for eyebrows and section indexes --- */
.meridian .m-eyebrow,
.meridian .m-index {
  display: block;
  font-family: var(--m-mono);
  font-size: 0.82rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  margin: 0 0 1.4rem;
}
.meridian .m-eyebrow { color: var(--m-sand); }
.meridian .m-index   { color: var(--m-dim); }

/* --- section shell. 160px at full size, scaling down on narrow screens --- */
.m-section { padding-block: clamp(4.5rem, 11vw, 10rem); }
.m-section--tight { padding-block: clamp(3rem, 6vw, 5rem); }
.m-rule { border: 0; border-top: 1px solid var(--m-hair); margin: 0; }

/* Heading block left, supporting note right — Meridian's section-head pattern.
   The note is what stops a bare headline sitting alone above a list. */
.m-head {
  display: grid;
  grid-template-columns: 1.35fr 1fr;
  gap: clamp(2rem, 6vw, 6rem);
  align-items: end;
  margin-bottom: clamp(2.5rem, 5vw, 4.5rem);
}
.m-head h2 {
  font-family: var(--font-serif);
  font-size: clamp(2.4rem, 5.2vw, 4rem);
  line-height: 1.05;
  letter-spacing: -0.025em;
  margin: 0;
  color: var(--ivory);
}
.m-head h2 em { font-style: italic; color: var(--m-sand); }
.m-aside {
  font-family: var(--font-serif);
  font-size: 1.15rem;
  line-height: 1.6;
  color: var(--m-mut);
  margin: 0;
  max-width: 42ch;
}
@media (max-width: 860px) {
  .m-head { grid-template-columns: 1fr; align-items: start; gap: 1.4rem; }
}

/* --- HERO ---------------------------------------------------------------
   Headline left, tagline right, a rail of service words beneath. The black
   field is kept: the photo was taken out of this hero on 2026-08-20 and that
   decision stands. */
.m-hero-grid {
  display: grid;
  grid-template-columns: 1.5fr 1fr;
  gap: clamp(2rem, 6vw, 5rem);
  align-items: end;
}
.m-hero-tagline {
  font-family: var(--font-serif);
  font-size: clamp(1.05rem, 1.4vw, 1.28rem);
  line-height: 1.62;
  color: var(--m-mut);
  margin: 0 0 0.6rem;
  max-width: 40ch;
}
.m-hero-rail {
  display: flex;
  flex-wrap: wrap;
  gap: 0 2.6rem;
  /* 2026-08-28, per Alex — the hero read as "fragmented," and this was the
     real cause: 1.6rem margin + 1.6rem padding (3.2rem total) below the
     locale line, nearly 3x the 1.2rem gap between the headline and the
     locale line above it, so the rail visually broke away from the
     headline group instead of reading as part of the same block. Tightened
     to sit closer to that same rhythm; hairline stays as the one deliberate
     divider between "the headline" and "the three services." */
  margin-top: 1.1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--m-hair);
}
/* Size + color bumped 2026-08-24 — Alex: "the words underneath Personally
   hosted I can barely see." Was 0.72rem at var(--m-dim), 42% white — nearly
   unreadable over a busy video. This is the only place on the site that
   used --m-dim for primary-reading text rather than a true secondary label,
   so it gets its own brighter value instead of changing --m-dim globally
   and affecting other dark-theme elements that were fine as-is.
   Bumped a second notch same day, per Alex, larger + brighter still. */
.m-hero-rail span {
  font-family: var(--m-mono);
  font-size: 0.9rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.97);
  position: relative;
  padding-left: 1rem;
}
.m-hero-rail span::before {
  content: "";
  position: absolute; left: 0; top: 0.42em;
  width: 4px; height: 4px; border-radius: 50%;
  /* 2026-08-25, per Alex — one accent gold site-wide. Was var(--m-sand)
     (#c8a882), the dark-system value; now #a9744a, same as every dot,
     em, and eyebrow on the light .cl- pages. */
  background: #a9744a;
}
@media (max-width: 860px) {
  .m-hero-grid { grid-template-columns: 1fr; }
  .m-hero-rail { gap: 0.55rem 1.6rem; }
}

/* --- PHOTOGRAPH-FIRST (2026-08-23) --------------------------------------
   The change Alex was actually asking for all evening. Every template he
   responded to — Qrest, Nabulé, Meridian — opens with a photograph filling the
   screen and sets type on top of it. This site opened with a black field and
   put its photographs inside boxes further down, which is why a new type system
   still read as "the same website".
   The hero photo was removed on 2026-08-20 because a legibility gradient over
   it looked washed out. That was a treatment problem, not a photo problem, so
   it is solved here rather than avoided: a hard bottom-weighted scrim that is
   fully transparent across the top two-thirds and near-solid where the type
   sits, instead of the flat 50% wash that greyed the whole frame before. */
.m-shot {
  position: relative;
  min-height: 100vh; min-height: 100svh;
  display: flex;
  align-items: flex-end;
  overflow: hidden;
  isolation: isolate;
}
/* 2026-08-25, per Alex — on his phone "Private hospitality." sat flush
   against the fixed white nav with no breathing room, because the headline
   block is bottom-anchored (align-items:flex-end above) with zero top
   padding — on a short mobile viewport there's nothing stopping its top
   edge from landing right at the nav's bottom edge. padding-top on the flex
   CONTAINER (not the text block itself) reserves genuine dead space the
   bottom-anchored content can never encroach into, so there's always
   guaranteed clearance under the nav regardless of viewport height. */
@media (max-width: 700px) {
  .m-shot { padding-top: clamp(6rem, 22vh, 8.5rem); }
}
.m-shot--tall { min-height: 78vh; min-height: 78svh; }
/* --- CARD — two photos side by side instead of three stacked full-bleed
   panels. Added 2026-08-24: the Collection section was reading as if it took
   over the whole page (3 x 78vh of stacked photographs). This halves that to
   one row. m-shot__name still uses vw-based sizing meant for a full-width
   panel, so it gets its own smaller clamp here or it overruns a half column. */
.m-collection-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2px;
  background: var(--ink);
}
.m-shot--card { min-height: 58vh; min-height: 58svh; }
.m-shot--card .m-shot__name { font-size: clamp(1.6rem, 3.4vw, 2.6rem); }
.m-shot--card .m-shot__inner { padding-bottom: clamp(2rem, 5vh, 3.5rem); }
@media (max-width: 860px) {
  .m-collection-grid { grid-template-columns: 1fr; gap: 2px; }
  .m-shot--card { min-height: 62vh; min-height: 62svh; }
}
.m-shot__img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center;
  filter: contrast(1.08) saturate(1.04);
  z-index: -2;
}
/* Transparent until 45%, then falls away hard. The type sits in real black,
   the photograph keeps its colour everywhere else. */
.m-shot::after {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(180deg,
    rgba(0,0,0,0.55) 0%,
    rgba(0,0,0,0.10) 22%,
    rgba(0,0,0,0.00) 45%,
    rgba(0,0,0,0.62) 78%,
    rgba(0,0,0,0.92) 100%);
}
/* Homepage hero only, lightened 2026-08-24 — Alex wants the cathedral
   footage's actual color and light visible, not buried under the darker
   base scrim above. Title/eyebrow keep their own text-shadow (see
   .m-shot__title, .m-eyebrow) so legibility doesn't depend on this being
   dark; only the .m-hero-rail row at the very bottom needed the deeper
   tail kept in to stay readable. */
.m-shot.meridian::after {
  background: linear-gradient(180deg,
    rgba(0,0,0,0.28) 0%,
    rgba(0,0,0,0.04) 22%,
    rgba(0,0,0,0.00) 45%,
    rgba(0,0,0,0.38) 78%,
    rgba(0,0,0,0.60) 100%);
}
.m-shot__inner {
  position: relative;
  width: 100%;
  max-width: var(--container);
  margin: 0 auto;
  padding: 0 var(--gutter) clamp(3rem, 8vh, 6rem);
}
/* 2026-08-25, per Alex — the homepage hero was the one section on the site
   still speaking the old dark/Meridian voice (serif headline, --sand gold
   #c8a882) while every other page had moved to the light .cl- system's
   voice (bold sans h1, #a9744a accent). Video stays — this only changes
   the type/color to match .cl-h1 and .cl-h1 em exactly, so the hero reads
   as the same site as everything below it, just full-bleed and on dark. */
.m-shot__title {
  font-family: var(--font-sans);
  font-weight: 600;
  /* 2026-08-25, per Alex — matched exactly to .cl-h1's size (was its own
     larger clamp, 7.5vw/6.4rem, sized for the old full-bleed treatment).
     Now identical to every inner-page headline. */
  font-size: clamp(2.3rem, 5.2vw, 4.3rem);
  line-height: 0.98;
  letter-spacing: -0.02em;
  margin: 0;
  color: var(--ivory);
  text-shadow: 0 2px 40px rgba(0,0,0,0.5);
  max-width: 100%; overflow-wrap: break-word;
}
@media (max-width: 420px) {
  .m-shot__title { font-size: clamp(1.8rem, 8vw, 4rem); }
}
/* 2026-08-28, per Alex — the two headline lines read as double-spaced.
   The old markup was a <br/> + inline <em> at 0.75em; mixing two different
   font-sizes (and a serif/sans switch) on the same line-height:0.98 relies
   on the browser's own leading math for each run, which isn't reliable
   across the size/font jump. Replaced with two explicit block-level
   spans so the gap between lines is a real, controlled value instead of
   inherited line-height math. */
.m-shot__title-line { display: block; }
.m-shot__title-line--accent {
  font-family: var(--font-serif); font-style: italic; font-weight: 400;
  font-size: 0.75em; color: #a9744a; margin-top: -0.08em;
}
/* Locale line under the hero title, 2026-08-24 — replaces the old faint
   eyebrow. "Colombia" stays white/full-opacity so it reads as part of the
   headline; the cities sit in the hero's own sand/taupe accent, same color
   as "Personally hosted." above it. */
/* Restyled 2026-08-25, per Alex, to match .cl-eyebrow — the same quiet
   mono-caps location tag every inner-page hero already uses (villas.html,
   group-travel.html, property-management.html all read "City · City ·
   Colombia" in this exact voice). Was serif italic sentence-case with a
   white/gold split between "Colombia" and the cities — the one hero-only
   treatment left on the site. Now one flat muted tone, same as every
   other page's location line, just white-on-video instead of black-on-white. */
.m-hero-locale {
  font-family: "JetBrains Mono", "SF Mono", Menlo, Consolas, monospace;
  /* Sized and brightened up a step, 2026-08-25, per Alex — wanted this to
     stick out on the video, not sit as a quiet caption the way the same
     line reads set against white on the inner pages. */
  font-size: 1.05rem; letter-spacing: 0.18em; text-transform: uppercase;
  margin: 1.2rem 0 0; color: rgba(255,255,255,0.9);
  text-shadow: 0 2px 20px rgba(0,0,0,0.4);
}
/* 2026-08-25, per Alex — tried terracotta, then plain; settled on bold
   white. Stays part of the headline's own white rather than pulling in
   the accent color, weight alone does the emphasis. */
.m-hero-locale__accent { color: inherit; font-weight: 700; }

/* A villa panel: index and name low-left, spec line and link low-right. */
.m-shot__row {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: clamp(1rem, 4vw, 3rem);
  flex-wrap: wrap;
}
.m-shot__name {
  font-family: var(--font-serif);
  font-size: clamp(2.2rem, 6vw, 4.6rem);
  line-height: 1;
  margin: 0;
  color: var(--ivory);
  text-shadow: 0 2px 40px rgba(0,0,0,0.5);
}
.m-shot__meta {
  font-family: var(--m-mono, "JetBrains Mono", monospace);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.82);
  margin: 0 0 0.6rem;
}
.m-shot__meta span + span::before {
  content: "\00B7"; margin: 0 0.6rem; color: var(--sand);
}
a.m-shot { text-decoration: none; color: inherit; }
a.m-shot .m-shot__img { transition: transform 1.6s var(--ease); }
a.m-shot:hover .m-shot__img { transform: scale(1.035); }
@media (max-width: 700px) {
  .m-shot__row { flex-direction: column; align-items: flex-start; gap: 0.8rem; }
}
@media (prefers-reduced-motion: reduce) {
  a.m-shot .m-shot__img, a.m-shot:hover .m-shot__img { transition: none; transform: none; }
}

/* --- WORK ROWS (the villa list) ----------------------------------------- */
.m-rows { border-top: 1px solid var(--m-hair); }
.m-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(1.6rem, 4.5vw, 4.5rem);
  align-items: center;
  padding-block: clamp(2.2rem, 4vw, 4rem);
  border-bottom: 1px solid var(--m-hair);
  text-decoration: none;
  color: inherit;
}
.m-row__media { position: relative; aspect-ratio: 4/3; overflow: hidden; }
.m-row__media img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  filter: var(--img-filter);
  transition: transform 1.2s var(--ease);
}
.m-row:hover .m-row__media img { transform: scale(1.045); }
.m-row__meta {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem;
  font-family: var(--m-mono);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--m-dim);
  margin-bottom: 1rem;
}
.m-row__meta .dot {
  width: 3px; height: 3px; border-radius: 50%;
  background: var(--m-sand); display: inline-block;
}
.m-row__title {
  font-family: var(--font-serif);
  font-size: clamp(1.9rem, 3.4vw, 2.7rem);
  line-height: 1.08;
  margin: 0 0 0.7rem;
  color: var(--ivory);
}
.m-row__desc {
  font-family: var(--font-serif);
  font-size: 1.12rem;
  line-height: 1.6;
  color: var(--m-mut);
  margin: 0 0 1.1rem;
  max-width: 40ch;
}
/* Meridian sets these as bordered pills. Here they are one quiet middot line,
   matching the villa specs on villas.html — no boxes anywhere on this site. */
.m-row__tags {
  font-family: var(--m-mono);
  font-size: 0.7rem;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--m-dim);
  margin: 0 0 1.2rem;
}
.m-row__tags span + span::before {
  content: "\00B7"; margin: 0 0.6rem; color: rgba(255,255,255,0.25);
}
.m-link {
  font-family: var(--m-mono);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ivory);
  display: inline-flex; align-items: center; gap: 0.45rem;
  transition: gap 0.3s var(--ease);
  text-decoration: none;
}
.m-row:hover .m-link, .m-link:hover { gap: 0.85rem; }
@media (max-width: 860px) {
  .m-row { grid-template-columns: 1fr; gap: 1.4rem; }
}

/* --- CARD GRID (2026-08-24) ----------------------------------------------
   villas.html, per Alex: he liked videinfra.com/work's grid of project
   cards and wants The Collection laid out the same way — photograph, small
   label, name, nothing else at rest. This is the idea (a grid of cards),
   not their code. Reuses .m-row__media / .m-row__meta / .m-row__title /
   .m-link — the same parts the stacked rows used — so the dark-section
   color overrides further down (".section .m-row__meta", etc.) keep
   applying with no new exemptions needed. Description and bed/bath tags are
   dropped from this view rather than hidden — they still live in the JSON-LD
   and on each Hostaway listing page, so nothing is actually lost, the grid
   just stops repeating it. The CTA now only shows on hover/focus, since a
   whole row of "Check Availability" links under six photographs is exactly
   the clutter this replaces the rows to get away from. */
.m-cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(2rem, 4vw, 3.2rem) clamp(1.6rem, 3vw, 2.4rem);
  border-top: 1px solid var(--m-hair);
  padding-top: clamp(2.2rem, 4vw, 3.5rem);
}
.m-card { display: block; text-decoration: none; color: inherit; }
.m-card .m-row__media { aspect-ratio: 3/4; margin-bottom: 1.1rem; }
.m-card:hover .m-row__media img { transform: scale(1.045); }
.m-card .m-row__meta { margin-bottom: 0.7rem; }
.m-card .m-row__title { font-size: clamp(1.4rem, 1.9vw, 1.85rem); margin-bottom: 0.5rem; }
.m-card .m-link { opacity: 0; transition: opacity 0.3s var(--ease), gap 0.3s var(--ease); }
.m-card:hover .m-link, .m-card:focus-visible .m-link { opacity: 1; }
@media (hover: none) {
  .m-card .m-link { opacity: 1; }
}
@media (max-width: 860px) {
  .m-cards { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 560px) {
  .m-cards { grid-template-columns: 1fr; }
}
@media (prefers-reduced-motion: reduce) {
  .m-card:hover .m-row__media img { transform: none; }
}

/* --- THE WALK (2026-08-23) ----------------------------------------------
   A villa shown in the order you'd actually move through it — street door,
   courtyard, water, roof — instead of a grid of thumbnails in no order at all.
   Every listing site on earth does the grid; none of them teach you the
   building. These houses are colonial courtyard architecture, where the whole
   drama is the sequence, so the sequence is the thing worth selling.
   Deliberately unfolds INSIDE the villa row rather than on a separate page:
   Hostaway already serves a page per property, and a second one here would
   compete with it for the same search and duplicate the same specs.
   Only opens on the villas that genuinely have the frames for it. A walk built
   from one photograph repeated is worse than no walk. */
.m-walk {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(0.6rem, 1.2vw, 1rem);
  margin-top: clamp(1.6rem, 3vw, 2.4rem);
}
/* The opening frame runs the full width — you arrive before you look around. */
.m-walk__frame--wide { grid-column: 1 / -1; }
.m-walk__frame {
  position: relative;
  aspect-ratio: 3/2;
  overflow: hidden;
  display: block;
}
.m-walk__frame--wide { aspect-ratio: 16/9; }
.m-walk__frame img {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover;
  filter: var(--img-filter);
  transition: transform 1.3s var(--ease);
}
.m-row:hover .m-walk__frame img { transform: scale(1.03); }
.m-walk__cap {
  position: absolute;
  left: 0.9rem; bottom: 0.75rem;
  font-family: var(--m-mono, "JetBrains Mono", monospace);
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.92);
  text-shadow: 0 1px 12px rgba(0,0,0,0.6);
  margin: 0;
}
@media (max-width: 640px) {
  .m-walk { grid-template-columns: 1fr; }
  .m-walk__frame { aspect-ratio: 4/3; }
}
@media (prefers-reduced-motion: reduce) {
  .m-walk__frame img, .m-row:hover .m-walk__frame img { transition: none; transform: none; }
}

/* --- LEDGER BAND (2004 / 2014 / 2018 / Whom) ---------------------------- */
.m-ledger {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(1.6rem, 4vw, 3.5rem);
  padding-block: clamp(3rem, 6vw, 5rem);
  border-top: 1px solid var(--m-hair);
  border-bottom: 1px solid var(--m-hair);
}
.m-ledger__num {
  display: block;
  font-family: var(--font-serif);
  font-size: clamp(2.6rem, 5vw, 4.2rem);
  line-height: 1;
  color: var(--ivory);
  margin-bottom: 0.7rem;
}
.m-ledger__label {
  display: block;
  font-family: var(--m-mono);
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--m-dim);
  line-height: 1.9;
}
@media (max-width: 900px) { .m-ledger { grid-template-columns: repeat(2, 1fr); row-gap: 2.4rem; } }
@media (max-width: 520px) { .m-ledger { grid-template-columns: 1fr; } }

/* --- SERVICE ROWS ------------------------------------------------------- */
.m-svc { border-top: 1px solid var(--m-hair); }
.m-svc-row {
  display: grid;
  grid-template-columns: 5rem 1.1fr 1.6fr 3rem;
  gap: clamp(1rem, 3vw, 2.5rem);
  align-items: baseline;
  padding-block: clamp(1.8rem, 3.2vw, 2.8rem);
  border-bottom: 1px solid var(--m-hair);
  text-decoration: none;
  color: inherit;
  transition: padding-left 0.4s var(--ease);
}
.m-svc-row:hover { padding-left: 0.9rem; }
.m-svc-row__num {
  font-family: var(--m-mono);
  font-size: 0.72rem;
  letter-spacing: 0.14em;
  color: var(--m-dim);
}
.m-svc-row__title {
  font-family: var(--font-serif);
  font-size: clamp(1.55rem, 2.6vw, 2.1rem);
  line-height: 1.1;
  margin: 0;
  color: var(--ivory);
}
.m-svc-row__title em { font-style: italic; color: var(--m-sand); }
.m-svc-row__desc {
  font-family: var(--font-serif);
  font-size: 1.08rem;
  line-height: 1.6;
  color: var(--m-mut);
  margin: 0;
}
.m-svc-row__arrow {
  font-size: 1.1rem;
  color: var(--m-dim);
  justify-self: end;
  transition: transform 0.4s var(--ease), color 0.3s var(--ease);
}
.m-svc-row:hover .m-svc-row__arrow { transform: translateX(6px); color: var(--ivory); }
@media (max-width: 900px) {
  .m-svc-row { grid-template-columns: 4rem 1fr 2rem; }
  .m-svc-row__desc { grid-column: 2 / -1; margin-top: 0.6rem; }
}

/* --- CTA STRIP ----------------------------------------------------------
   The one inverted band on the page. Not a box: full bleed, edge to edge,
   no border, no radius. Its job is to break 100vh of black right before the
   footer so the close lands rather than fades. */
.m-cta {
  background: var(--ivory);
  color: var(--ink);
  padding-block: clamp(4rem, 9vw, 8rem);
}
.m-cta h2 {
  font-family: var(--font-serif);
  font-size: clamp(2.4rem, 5.5vw, 4.2rem);
  line-height: 1.05;
  letter-spacing: -0.025em;
  margin: 0 0 1.4rem;
  color: var(--ink) !important;
}
.m-cta h2 em { font-style: italic; color: #8a7355; }
.m-cta p {
  font-family: var(--font-serif);
  font-size: 1.2rem;
  line-height: 1.6;
  color: #4a4a4a !important;
  margin: 0 0 2.2rem;
  max-width: 46ch;
}
.m-cta .m-link { color: var(--ink); }

/* ---------- 21. Hero settle (simulates the moving-yacht feel until real video is dropped in) ---------- */
/* 2026-08-19, third pass — the ambient kenBurnsDrift loop is killed per Alex,
   keeping only heroSettle: the one-time, fast, obviously-visible zoom-down on
   load, same idea as .listing-card's is-visible settle. No ongoing motion
   after it lands. */
@keyframes heroSettle {
  0%   { transform: scale(1.12) translate3d(0.5%, 0.35%, 0); }
  100% { transform: scale(1.0)  translate3d(0, 0, 0); }
}
.hero--kenburns .hero__media {
  animation: heroSettle 1.3s ease-out forwards;
  transform-origin: center;
  will-change: transform;
}
@media (prefers-reduced-motion: reduce) {
  .hero--kenburns .hero__media { animation: none; }
}
/* Same treatment, applied to the four inner-page heroes (2026-08-19). Both
   .hero and .page-hero are overflow:hidden with an absolutely-positioned
   media layer, so the same keyframe is safe at either size — no visible
   edge, no scrollbar. */
.page-hero--kenburns .page-hero__media {
  animation: heroSettle 1.3s ease-out forwards;
  transform-origin: center;
  will-change: transform;
}
@media (prefers-reduced-motion: reduce) {
  .page-hero--kenburns .page-hero__media { animation: none; }
}

/* ---------- Mobile fixes for new footer and contact form (added 2026-06-22) ---------- */
@media (max-width: 720px) {
  .footer-row {
    justify-content: center !important;
    align-items: center !important;
    text-align: center !important;
  }
  .footer-row > div {
    align-items: center !important;
    justify-content: center !important;
    text-align: center !important;
  }
}
@media (max-width: 640px) {
  .contact-grid {
    grid-template-columns: 1fr !important;
  }
}

/* ---------- 22. Wow layer — smooth scroll (Lenis), film grain, gallery reveal (added 2026-07-25) ---------- */

/* Lenis smooth-scroll: rules apply only when main.js adds .lenis to <html>.
   When Lenis is off (no JS / reduced motion), the native html{scroll-behavior:smooth} above stays in force. */
html.lenis, html.lenis body { height: auto; }
.lenis.lenis-smooth { scroll-behavior: auto !important; }
.lenis.lenis-smooth [data-lenis-prevent] { overscroll-behavior: contain; }
.lenis.lenis-stopped { overflow: hidden; }
.lenis.lenis-smooth iframe { pointer-events: none; }

/* Film grain: a fixed, non-interactive filmic texture sitting under the nav (z 60 < header z 100). */
body::after {
  content: "";
  position: fixed;
  top: -50%; left: -50%;
  width: 200%; height: 200%;
  pointer-events: none;
  z-index: 60;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.82' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  background-repeat: repeat;
  opacity: 0.045;
  will-change: transform;
  animation: grainDrift 0.5s steps(5) infinite;
}
@keyframes grainDrift {
  0%   { transform: translate(0, 0); }
  20%  { transform: translate(-2%, -3%); }
  40%  { transform: translate(-4%, 2%); }
  60%  { transform: translate(3%, -2%); }
  80%  { transform: translate(-1%, 3%); }
  100% { transform: translate(2%, -1%); }
}

/* Gallery reveal: villa-card image settles out of a soft zoom as the card scrolls into view.
   Re-declares hover AFTER .is-visible so the hover zoom keeps precedence. */
.listing-card__img {
  transform: scale(1.1);
  transition: transform 1.5s var(--ease-soft), filter 1.5s var(--ease-soft);
}
.listing-card.is-visible .listing-card__img { transform: scale(1); }
.listing-card:hover .listing-card__img { transform: scale(1.04); }

@media (prefers-reduced-motion: reduce) {
  body::after { animation: none; }
  .listing-card__img,
  .listing-card.is-visible .listing-card__img { transform: none; }
}

/* ---------- 24. Softer surfaces — sections flow on tone alone, no hard rules (added 2026-07-25) ---------- */

/* ---------- 25. Printed-matter — matte paper grain on light sections (2026-07-25) ---------- */
body, .section--paper {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='pp'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23pp)' opacity='0.05'/%3E%3C/svg%3E");
  background-repeat: repeat;
  background-position: center;
}

/* ---------- 26. All-dark: every section carries light text on charcoal/black (2026-07-25) ---------- */
.section { color: var(--ivory); }
.section h1, .section h2, .section h3, .section h4,
.section .display, .section strong { color: var(--ivory) !important; }
.section p, .section li, .section .lede, .section .intro__body { color: rgba(255,255,255,0.74) !important; }
.section em { color: var(--silver) !important; }
.section .eyebrow, .section .eyebrow span { color: var(--stone-soft) !important; }
.section .divider { border-color: rgba(255,255,255,0.12) !important; }
/* keep the villa cards' own tuned light tones */
.section .listing-card__desc { color: rgba(255,255,255,0.82) !important; }
/* Ivory, not silver (2026-08-09). It is the only action on a card and it now has to
   carry that on its own — the border that used to frame it is gone. Horizon's "In
   development" overrides this inline, since that one is a state, not an action. */
.section .listing-card__cta, .section .listing-card__cta * { color: var(--ivory) !important; }

/* =======================================================================
   THE BRIDGE (2026-08-23)
   -----------------------------------------------------------------------
   Home and the Collection were rebuilt on the Meridian layer; Our Story,
   Group Travel, Property Management and Inquire were not. Rather than rewrite
   four pages of working markup, these rules pull the components those pages
   ALREADY use onto the same system, so the whole site speaks once.
   Three changes, applied everywhere:
     1. .sec-num and .eyebrow become the mono label. That single typographic
        move is what makes an interior page read as part of this site.
     2. The italic second beat becomes sand instead of silver — the accent is
        now consistent from the homepage headline to the last page's closing
        line. This is the one genuinely global change; --sand is a single
        variable if it ever needs pulling back.
     3. The old rule that drew a 2.2rem dash before .sec-num is dropped. The
        mono slash notation ("/ 01 —") carries that job now, and the two
        together read as one device too many.
   ======================================================================= */
:root { --sand: #c8a882; }

.sec-num,
.eyebrow,
.eyebrow span {
  font-family: "JetBrains Mono", "SF Mono", Menlo, Consolas, monospace !important;
  font-size: 0.75rem !important;
  letter-spacing: 0.2em !important;
  font-weight: 400 !important;
  text-transform: uppercase;
}
.sec-num { color: rgba(255,255,255,0.42) !important; }
.sec-num::before { display: none !important; }
/* .section .eyebrow already exists earlier in this file at (0,2,0) and would
   outrank a bare .eyebrow no matter where it sits, so the sand has to be
   declared at matching specificity. Verified by rendering both selectors
   against each other rather than assuming source order would settle it. */
.eyebrow, .eyebrow span,
.section .eyebrow, .section .eyebrow span,
.page-hero .eyebrow, .page-hero .eyebrow span { color: var(--sand) !important; }

/* The italic beat, everywhere it appears. */
.section em,
.statement em,
.page-hero h1 em,
.hero__title em,
.band__line em,
.intro-statement em,
.split__lead em            { color: var(--sand) !important; font-style: italic; }
/* The closing band is on ivory, so its italic needs the darker relative. */
.m-cta h2 em               { color: #8a7355 !important; }

/* --- Meridian layer exemptions (2026-08-23) ---------------------------------
   Caught on the real page, not in isolation: the Meridian sections sit inside
   .section, so the blanket rules above were winning. `.section p` was flattening
   every muted tone to a single 0.74, and `.section em` was repainting the sand
   italics silver — which would have quietly removed the accent that gives this
   layer its warmth. The values below are the ones the components were designed
   with; the !important is only here to answer the !important above it. */
.section .m-aside,
.section .m-row__desc,
.section .m-svc-row__desc     { color: rgba(255,255,255,0.66) !important; }
.section .m-row__tags,
.section .m-index             { color: rgba(255,255,255,0.42) !important; }
.section .m-head h2 em,
.section .m-svc-row__title em,
.section .m-row__title em     { color: #c8a882 !important; font-style: italic; }
.section .m-link,
.section .m-link *            { color: var(--ivory) !important; }
.section .m-ledger__num       { color: var(--ivory) !important; }
.section .m-ledger__label     { color: rgba(255,255,255,0.42) !important; }
.section .m-row__meta,
.section .m-row__meta span    { color: rgba(255,255,255,0.42) !important; }
.section .m-row__meta .dot    { background: #c8a882 !important; }

/* ---------- 27. All black — sections separated by hairline + air, not tone (2026-07-26) ----------
   Same system already used by the homepage service tiles: black fields, 1px white-at-8% rules,
   gray reserved for cards and hover states only. */
/* THE BOUNDARY TIER (2026-08-09). Three weights, and they must stay distinct:
     0     — inside a card, no rule at all
     0.10  — a rule INSIDE a section, always contained by the container
     0.18  — a SECTION boundary, always full-bleed edge to edge
   Before this, section boundaries were 0.08 and card borders were 0.08, so a major
   division looked exactly like the edge of a thumbnail. That is what made the
   bottom of the homepage run together. Do not raise contained rules past 0.12 or
   this collapses again. */
.section + .section,
.page-hero + .section,
.section + .footer,
.section + footer { border-top: 1px solid rgba(255,255,255,0.18); }

/* gray stays an accent, never a field */
.service-tile:hover { background: #171717; }

/* ---------- 28a. View transitions — pages morph instead of white-flashing ---------- */
@view-transition { navigation: auto; }

::view-transition-old(root) {
  animation: vtFadeOut 0.28s cubic-bezier(0.4, 0, 0.2, 1) both;
}
::view-transition-new(root) {
  animation: vtFadeIn 0.45s cubic-bezier(0.16, 1, 0.3, 1) both;
}
@keyframes vtFadeOut { to { opacity: 0; } }
@keyframes vtFadeIn  { from { opacity: 0; transform: translateY(14px); } }

@media (prefers-reduced-motion: reduce) {
  ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
}

/* ---------- 28b. Editorial section numbering ---------- */
.section { position: relative; }

.sec-num {
  display: block;
  font-family: var(--font-sans);
  font-size: var(--fs-label);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: rgba(255,255,255,0.48);
  margin: 0 0 2.2rem;
}
@media (min-width: 1180px) {
  .sec-num {
    position: absolute;
    top: clamp(3.4rem, 5.5vw, 5rem);
    left: clamp(1.4rem, 3vw, 3rem);
    margin: 0;
    writing-mode: vertical-rl;
    letter-spacing: 0.4em;
  }
}

/* ---------- 28c. Full-screen overlay menu (all breakpoints) ---------- */
.nav-list { display: none; }

.nav-toggle {
  display: inline-flex; flex-direction: column; gap: 5px;
  width: 28px; height: 22px; justify-content: center;
  background: none; border: 0; padding: 0; cursor: pointer;
  color: currentColor;
}
.nav-toggle span {
  display: block; height: 1.5px; background: currentColor;
  transition: transform 0.4s var(--ease), opacity 0.3s var(--ease);
}
.nav-toggle.is-open span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.nav-toggle.is-open span:nth-child(2) { opacity: 0; }
.nav-toggle.is-open span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }
.nav-toggle.is-open { color: var(--ivory); position: relative; z-index: 101; }

.mobile-drawer {
  display: flex; flex-direction: column; justify-content: center;
  position: fixed; inset: 0; z-index: 99;
  background: #000; color: var(--ivory);
  padding: 7rem var(--gutter) 3rem;
  overflow-y: auto;
  opacity: 0; visibility: hidden;
  transition: opacity 0.5s var(--ease), visibility 0s linear 0.5s;
}
.mobile-drawer.is-open {
  opacity: 1; visibility: visible;
  transition: opacity 0.5s var(--ease), visibility 0s;
}
.mobile-drawer::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(ellipse at 50% 40%, #141414 0%, #050505 55%, #000 100%);
  z-index: -1;
}
/* Was Italiana at 32px. Italiana is the display face — it is only ever allowed to
   be the largest thing on a page, never navigation. On a phone this drawer IS the
   nav, so it now matches the desktop header exactly: Inter, uppercase, wide
   tracking — just scaled up for a thumb. (2026-08-09) */
.mobile-drawer a {
  display: block;
  font-family: var(--font-sans);
  font-size: clamp(1rem, 2.6vw, 1.15rem);
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ivory);
  text-decoration: none;
  padding: 0.42em 0;
  border-bottom: 1px solid rgba(255,255,255,0.08);
  opacity: 0;
  transform: translateY(18px);
  transition: color 0.35s var(--ease), opacity 0.6s var(--ease), transform 0.6s var(--ease);
}
.mobile-drawer a:hover { color: var(--stone-soft); }
.mobile-drawer.is-open a { opacity: 1; transform: none; }
.mobile-drawer.is-open a:nth-child(1) { transition-delay: 0.10s; }
.mobile-drawer.is-open a:nth-child(2) { transition-delay: 0.16s; }
.mobile-drawer.is-open a:nth-child(3) { transition-delay: 0.22s; }
.mobile-drawer.is-open a:nth-child(4) { transition-delay: 0.28s; }
.mobile-drawer.is-open a:nth-child(5) { transition-delay: 0.34s; }

.drawer-meta {
  margin-top: clamp(2rem, 5vh, 3.4rem);
  display: flex; flex-wrap: wrap; gap: 0.5rem 1.6rem;
  font-family: var(--font-sans); font-size: var(--fs-micro);
  letter-spacing: 0.16em; text-transform: uppercase;
  color: var(--stone-soft);
  opacity: 0; transition: opacity 0.6s var(--ease) 0.4s;
}
.mobile-drawer.is-open .drawer-meta { opacity: 1; }
.drawer-meta a {
  font-family: inherit; font-size: inherit; letter-spacing: inherit;
  padding: 0; border: 0; color: var(--stone-soft);
  opacity: 1; transform: none; display: inline;
}
.drawer-meta a:hover { color: var(--ivory); }

@media (prefers-reduced-motion: reduce) {
  .mobile-drawer a, .drawer-meta { transition: none; opacity: 1; transform: none; }
}

/* ---------- 28d. Proof band — facts, not testimonials ---------- */
.proof-band {
  display: grid;
  /* 3 cells. Was 5 — "Private residences" and "Cities" dropped 3 Aug (both already
     stated elsewhere on the page). A 4th guest-rating cell was tried and removed 7 Aug. */
  grid-template-columns: repeat(3, 1fr);
  border-top: 1px solid rgba(255,255,255,0.08);
  border-bottom: 1px solid rgba(255,255,255,0.08);
}
.proof-cell {
  padding: clamp(1.8rem, 3.2vw, 2.8rem) clamp(1rem, 2vw, 1.6rem);
  text-align: center;
  border-right: 1px solid rgba(255,255,255,0.08);
}
.proof-cell:last-child { border-right: 0; }
/* Was Italiana — hairline-thin numerals, near-illegible at this size. Now the same
   face as "Personally hosted." in the hero: Cormorant Garamond italic, which has
   real stroke weight. Silver rather than white so the band reads as quiet fact,
   a step above the label beneath it without being the loudest thing on the page. */
.proof-num {
  display: block;
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: 400;
  font-size: clamp(1.8rem, 2.8vw, 2.4rem);
  line-height: 1;
  /* Silver → ivory 2026-08-09. With the labels beneath staying gray, the contrast
     between the two does the ranking, so the numerals can carry full white without
     the row getting loud. */
  color: var(--ivory);
  margin-bottom: 0.7rem;
}
.proof-label {
  display: block;
  font-family: var(--font-sans);
  font-size: var(--fs-micro);
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--stone-soft);
  line-height: 1.7;
}
/* 3-cell band: three across above mobile, stacked below. The original rules were
   written for 5 cells and left doubled hairlines once cells were removed. */
@media (max-width: 560px) {
  .proof-band { grid-template-columns: 1fr; }
  .proof-cell { border-right: 0; border-bottom: 1px solid rgba(255,255,255,0.08); }
  .proof-cell:last-child { border-bottom: 0; }
}

/* ---------- 28e. Statement — one sentence, one screen ---------- */
/* No flex here. It was `display:flex; align-items:center`, which made .sec-num and
   .container siblings in a ROW — the label sat at 175px and the statement at 781px
   while every other page starts at the container edge.
   Switching to flex-column did not fix it either: .container and .sec-num both carry
   `margin: 0 auto`, and auto margins on the cross axis stop a flex item stretching,
   so they shrink-wrapped and centered instead. Plain block layout is what every other
   section on the site uses, and the padding already does the spacing. (2026-08-09) */
.statement-section {
  min-height: 82vh;
}
.statement {
  font-family: var(--font-serif);
  font-size: var(--fs-h2);
  line-height: 1.02;
  letter-spacing: -0.025em;
  color: var(--ivory) !important;
  margin: 0;
  max-width: 16ch;
}
.statement em {
  font-family: var(--font-serif);
  font-style: italic;
  letter-spacing: -0.01em;
  /* --silver, not --stone-soft (2026-08-09). Every italic second beat on the site
     is silver; these two rules were forcing 155 gray against everything else's 200,
     so two statements on the same page sat 45 points apart. */
  color: var(--silver) !important;
}

/* ---------- 28f. Asymmetric split — statement left, support right ---------- */
.split {
  display: grid;
  grid-template-columns: 1.05fr 1fr;
  gap: clamp(2rem, 6vw, 6rem);
  align-items: center;
}
.split__lead {
  /* Cormorant, not Italiana — same reasoning as .intro__statement. (2026-08-09) */
  font-family: var(--font-serif);
  font-size: clamp(1.5rem, 2.4vw, 2.0rem);
  line-height: 1.12;
  letter-spacing: -0.015em;
  color: var(--ivory) !important;
  margin: 0;
}
.split__lead em {
  font-family: var(--font-serif); font-style: italic;
  color: var(--silver) !important;
}
.split__body { padding-top: 0.6rem; }
.split__body p {
  font-family: var(--font-serif);
  /* 1.12rem (17.92px) was an orphan — no such size on index or villas, where all
     body copy is 1.3rem / 20.8px. (2026-08-09) */
  font-size: 1.3rem;
  line-height: 1.6;
  max-width: 46ch;
  margin: 0 0 1.3rem;
}
.split__body p:last-child { margin-bottom: 0; }
@media (max-width: 880px) {
  .split { grid-template-columns: 1fr; gap: 1.8rem; }
}

/* ---------- 28g. Hairline map ---------- */
.map-figure svg {
  width: 100%;
  max-width: 300px;
  height: auto;
  overflow: visible;
}

/* proof band sits flush under the hero — no doubled hairlines */
.proof-section { padding-block: 0 !important; }
.proof-section + .section { border-top: 0; }

/* section numbers on light fields */
.section--paper .sec-num { color: rgba(0,0,0,0.52); }

/* ---------- 28c-fix. Overlay menu: clear the fixed header ----------
   The logo sits at z-index 100, above the drawer, so any link that rode up
   under it was unclickable. Start the list below the header instead of
   centring it, and bring the type down a size so five links + the meta row
   fit a laptop viewport without overflowing upward. (2026-07-26) */
.mobile-drawer {
  justify-content: flex-start;
  padding: clamp(9.5rem, 21vh, 12.5rem) var(--gutter) clamp(2.5rem, 6vh, 4rem);
}
.mobile-drawer > a {
  font-size: clamp(1rem, 2.6vw, 1.15rem);
  padding: 0.34em 0;
}

/* ---------- 28c-fix2. Desktop nav back on the top line ----------
   Block 28c hid .nav-list at every width and put everything behind the
   overlay. Alex wants the links visible on desktop, so above the original
   960px breakpoint the horizontal nav returns and the hamburger goes away.
   Below 960px the full-screen overlay still runs. (2026-07-26) */
@media (min-width: 961px) {
  .nav-list { display: flex; }
  .nav-toggle { display: none; }
  .mobile-drawer { visibility: hidden; opacity: 0; }
}

/* ---------- 28e-fix. The deck under a statement ----------
   1.12rem body copy hung straight off a 7rem display line with nothing
   between them. A hairline bridges the jump and the deck gets a real
   size of its own, indented so it reads as a second voice. (2026-07-26) */
.statement-deck {
  display: grid;
  grid-template-columns: clamp(2.5rem, 7vw, 7rem) 1fr;
  align-items: start;
  gap: clamp(1.2rem, 2.5vw, 2.2rem);
  margin-top: clamp(2rem, 4vh, 3.2rem);
  max-width: 46rem;
}
.statement-deck__rule {
  display: block;
  height: 1px;
  background: rgba(255,255,255,0.28);
  margin-top: 1.05em;
}
.statement-deck p {
  font-family: var(--font-serif);
  font-style: italic;
  font-size: 1.3rem;
  line-height: 1.6;
  letter-spacing: -0.005em;
  color: var(--silver) !important;
  max-width: 34ch;
  margin: 0;
}
@media (max-width: 640px) {
  .statement-deck { grid-template-columns: 1fr; gap: 1.1rem; }
  .statement-deck__rule { width: 3.5rem; margin-top: 0; }
}

/* ---------- 29. Spacing pass: cap the black, kill the dead air ----------
   Interior heroes were 70vh, which on a tall monitor is 700px+ of gradient
   holding three lines of type at the very bottom. Two pages had ad-hoc inline
   overrides (52vh, 46vh) so no two heroes matched. One capped rule now runs
   every interior page: it never goes below 24rem on a phone, never above
   33rem on a large display, and grows past the cap only if the type itself
   needs the room. The top padding guarantees the headline always clears the
   fixed logo. (2026-07-26) */
/* Matched to the homepage hero 2026-08-09. The home hero runs 64vh with roughly
   11vh of air beneath the headline; the interior heroes were 52vh with 5.5vh, so
   they landed ~70px shorter and felt cramped by comparison. Same proportions now,
   so moving from the homepage to any interior page is not a change in register. */
/* 2026-08-14: raised with the type scale. The 40rem ceiling was set against a
   45px headline; at 90px the four inner heroes were as cramped as the homepage
   was. Ceiling 40rem → 52rem and the floor lifts to match, so a two-line
   headline like "The Privato Collection." has somewhere to sit. */
.page-hero {
  min-height: clamp(34rem, 76vh, 52rem);
  min-height: clamp(34rem, 76svh, 52rem);
}
.page-hero__inner {
  padding-top: clamp(10rem, 19vh, 13rem);
  padding-bottom: clamp(4.5rem, 12vh, 8rem);
}

/* the statement was flex-centered inside 82vh, so a single sentence sat in a
   half-empty screen with the section's own 5rem padding on top of that */
.statement-section {
  min-height: clamp(17rem, 42vh, 25rem);
  min-height: clamp(17rem, 42svh, 25rem);
}
@media (max-width: 880px) {
  .statement-section { min-height: 0; }
}

/* ---------- 30. Section numbers: readable, and out of the text's way ----------
   Two separate problems. First, 0.68rem rotated type at 48% white on black is
   roughly 11px of low-contrast vertical text, which is not readable, it's
   texture. Second, the vertical treatment kicked in at 1180px while the
   container is 1340px wide, so between 1180 and about 1440 the label was
   sitting right on the edge of the body copy with no margin at all. That
   reads as clutter no matter how it's styled.

   Now: heavier and brighter at every width, and the vertical version only
   appears when there is real margin to put it in, positioned off the
   container edge rather than the viewport edge so the gap stays constant
   as the screen grows. Below that, it sits above the section, horizontal,
   with a short rule so it still reads as a marker. (2026-07-26) */
.sec-num {
  font-size: var(--fs-label);
  font-weight: 500;
  letter-spacing: 0.18em;
  color: rgba(255,255,255,0.72);
}
.sec-num::before {
  content: "";
  display: inline-block;
  width: 2.2rem;
  height: 1px;
  background: rgba(255,255,255,0.4);
  vertical-align: middle;
  margin: 0 1rem 0.18em 0;
}
.section--paper .sec-num { color: rgba(0,0,0,0.7); }
.section--paper .sec-num::before { background: rgba(0,0,0,0.32); }

/* the horizontal label tracks the container exactly, so it starts on the same
   vertical line as the copy underneath it at every width */
.sec-num {
  max-width: var(--container);
  margin: 0 auto 2rem;
  padding-inline: var(--gutter);
}

@media (min-width: 1180px) {
  .sec-num { position: static; writing-mode: horizontal-tb; margin: 0 auto 2rem; }
}

@media (min-width: 1500px) {
  .sec-num {
    position: absolute;
    top: clamp(3.4rem, 5.5vw, 5rem);
    left: max(1.5rem, calc((100% - 1340px) / 2 - 3.4rem));
    margin: 0;
    padding-inline: 0;
    writing-mode: vertical-rl;
    letter-spacing: 0.2em;
    font-size: var(--fs-label);
  }
  .sec-num::before { display: none; }
}

/* ===== ROSTER — "Whom We Host" register. Moved out of about.html 2026-08-03
   when the roster relocated to group-travel.html; shared so any page can use it. ===== */
  /* the roster is a register, not a second set of headlines */
  .roster { list-style:none; margin:0; padding:0; border-top:1px solid rgba(255,255,255,0.10); max-width:34rem; }
  .roster li {
    font-family:var(--font-serif);
    font-size:clamp(1.02rem,1.5vw,1.3rem);
    letter-spacing:0.09em;
    line-height:1.2;
    color:rgba(255,255,255,0.9);
    padding:1.05rem 0;
    border-bottom:1px solid rgba(255,255,255,0.10);
  }

  /* the payoff line, and the only white serif on the page below the statement */
  .roster-note {
    font-family:var(--font-serif);
    font-style:italic;
    font-size:1.3rem;
    line-height:1.35;
    color:var(--ivory) !important;
    max-width:26ch;
    margin:clamp(2rem,4vh,2.8rem) 0 0;
  }

/* ---------- Panel — a delineated tile, not an upholstered one (2026-08-09) ----------
   The homepage two-up used solid var(--ink) fills on the #121212 page, so the two
   blocks read as heavy slabs with the page showing between them. A hairline on
   transparent gives the same grouping with none of the weight. Hover matches the
   button language: a faint wash and a brighter edge. */
.panel {
  display: flex;
  flex-direction: column;
  padding: clamp(1.8rem, 2.4vw, 2.2rem);
  background: var(--ink);
  border: 1px solid rgba(255,255,255,0.06);
  color: inherit;
  text-decoration: none;
  transition: background 0.4s var(--ease), border-color 0.4s var(--ease);
}
.panel:hover { background: #161616; border-color: rgba(255,255,255,0.16); }

/* 2026-08-09 — Alex: "drop those boxes in the group, it's too many boxes."
   The fill and the outline both come off. What's left is two columns divided by a
   single vertical hairline, on the same black as the rest of the page. The
   link-arrow underneath is what says "clickable" — the box was never doing that
   job, it was just adding weight. Hover now lifts the type instead of the box. */
.panel {
  background: transparent;
  border: 0;
  padding: 0;
}
.panel + .panel {
  border-left: 1px solid rgba(255,255,255,0.10);
  padding-left: clamp(1.6rem, 3vw, 3rem);
}
/* Hairline-divided columns of .panel. Was removed when the homepage's three doors
   collapsed to one closing note; restored 2026-08-09 because group-travel.html now
   uses it for Leisure / Business. Column count is set per-page inline. */
.doors {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(1.6rem, 3vw, 3rem);
  align-items: stretch;
}
@media (max-width: 900px) {
  .doors { grid-template-columns: 1fr !important; gap: 0; }
  .doors .panel + .panel {
    border-left: 0;
    border-top: 1px solid rgba(255,255,255,0.10);
    padding-left: 0;
    padding-top: 2rem;
    margin-top: 2rem;
  }
}

/* ===== TRIP INDEX — 2026-08-17. Replaces the bulleted Leisure/Business lists.
   Alex saw a reference site's retreat list (photo, name, price, hairline row —
   no cards) and asked for the same register here, in our own type and photography.
   One header photo per column, then the five types as plain hairline rows —
   number, name, description, nothing boxed. The name shifts right on hover, same
   gesture as the villa cards and the panel links it replaces. ===== */
.trip-index {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(2rem, 4vw, 4rem);
}
.trip-index__col {
  display: flex;
  flex-direction: column;
  text-decoration: none;
}
.trip-index__media {
  width: 100%;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  margin-bottom: clamp(1.5rem, 3vw, 2.2rem);
}
.trip-index__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  filter: var(--img-filter);
  transform: scale(1.04);
  transition: transform 0.8s var(--ease);
}
.trip-index__col:hover .trip-index__media img { transform: scale(1); }
.trip-index__list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.trip-index__row {
  display: flex;
  align-items: baseline;
  gap: clamp(0.9rem, 2vw, 1.5rem);
  padding: 1.05rem 0;
  border-top: 1px solid rgba(255,255,255,0.10);
}
.trip-index__row:last-child { border-bottom: 1px solid rgba(255,255,255,0.10); }
.trip-index__num {
  font-family: var(--font-serif);
  font-size: 0.9rem;
  color: var(--stone-soft);
  min-width: 1.5rem;
}
.trip-index__name {
  font-family: var(--font-serif);
  font-size: 1.25rem;
  color: var(--ivory);
  white-space: nowrap;
  transition: transform 0.4s var(--ease);
}
.trip-index__desc {
  font-family: var(--font-serif);
  font-size: 1.02rem;
  color: rgba(255,255,255,0.55);
  flex: 1;
}
.trip-index__col:hover .trip-index__name,
.trip-index__row:hover ~ .trip-index__row .trip-index__name { transform: none; }
.trip-index__row:hover .trip-index__name { transform: translateX(6px); }
.trip-index__row:hover .trip-index__desc { color: rgba(255,255,255,0.72); }
@media (max-width: 900px) {
  .trip-index { grid-template-columns: 1fr; gap: 3rem; }
}
@media (max-width: 560px) {
  .trip-index__row { flex-wrap: wrap; }
  .trip-index__desc { flex-basis: 100%; padding-left: calc(1.5rem + 0.9rem); }
}

/* ===== MEDIA BAND — full-bleed photography between sections (2026-08-09).
   Group Travel was the only page on the site with zero images while selling the
   one thing that is purely visual. Edge to edge, no container, no caption: the
   photograph is the argument.
   The background-color is a deliberate fallback so the band reads as intentional
   dark space rather than a broken image if a file is missing. ===== */
.media-band {
  width: 100%;
  aspect-ratio: 21 / 9;
  background: #0d0d0d center/cover no-repeat;
  filter: var(--img-filter);
}
.media-pair {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(1rem, 1.8vw, 1.6rem);
}
.media-pair > div {
  aspect-ratio: 4 / 3;
  background: #0d0d0d center/cover no-repeat;
  filter: var(--img-filter);
}
@media (max-width: 760px) {
  .media-band { aspect-ratio: 16 / 10; }
  .media-pair { grid-template-columns: 1fr; }
}

/* The page's closing note. Centered — and it is the ONLY centered block on the site,
   which is precisely why it reads as an ending rather than another section. The
   inline-flex on the link keeps its underline the width of the text instead of the
   width of the column. (2026-08-09) */
.closing-note {
  text-align: center;
  max-width: 46rem;
  margin-inline: auto;
}
.closing-note .eyebrow { justify-content: center; }
.closing-note .link-arrow { display: inline-flex; }
.panel:hover { background: transparent; }
/* The name IS the link now, so the hover has to live on the name. Arrow slides,
   arrowhead brightens — the same gesture the villa cards use. (2026-08-09) */
.panel .arrow { display: inline-block; transition: transform 0.4s var(--ease), color 0.3s var(--ease); }
.panel:hover .arrow { transform: translateX(5px); color: var(--ivory) !important; }

/* ===== LEDGER — the years and the two credibility notes, one block (2026-08-09).
   Replaces .proof-band + .note-pair, which were two visual languages stacked in
   the same gray field: centered text in bordered cells on top, outlined boxes
   underneath. Alex: "too boxy, it doesn't flow."
   The fix is subtraction. No cell borders, no box fills, no outlines — one grid,
   one left-hand alignment shared with every other section on the site, and a
   single hairline separating the two rows. The columns line up between the rows,
   so the years sit directly above the notes and the whole thing reads as one
   register rather than two stacked bands. ===== */
.ledger-years {
  display: grid;
  /* Four cells: three years and the roster. align-items:start so the taller
     fourth column does not drag the years down to its centre. (2026-08-09)
     2026-08-14: equal quarters left Whom's two paired lines too narrow to fit —
     "Corporate Retreats" wrapped to its own line. A year cell only needs a
     four-digit number and a six-word caption; Whom gets the width instead. */
  /* 2026-08-19: was 0.72fr/0.72fr/0.72fr/1.84fr — a 2.56:1 ratio that bunched
     the three years tight on the left and left Whom sitting alone in a much
     wider column, which read as lopsided rather than centering was actually
     needed (per Alex — pushed back on centering, this was the real fix).
     Narrowed the gap to 1.7:1. Whom still needs more room than a year cell —
     "Group Celebrations · Corporate Retreats" is real text, not a numeral —
     so it isn't equal quarters, but the row should now read as one balanced
     line instead of three tight cells plus a wide fourth. Check after this
     that "Corporate Retreats" still holds its line; the label-dot margin
     below was tightened slightly as a buffer against it wrapping. */
  grid-template-columns: repeat(3, 0.85fr) 1.45fr;
  align-items: start;
  gap: clamp(1.5rem, 3vw, 3rem);
}
/* The years were the only centered text on the site. Now left, like everything else. */
.ledger-years > div { text-align: left; }
/* The roster stacks under "Whom" tighter than a year's single label needs to.
   2026-08-14: was four separate lines, one per name — that column ran taller
   than the year cells beside it and read as an outlier. Paired to two lines,
   middot-joined like the villa spec line, to bring the height back in line. */
.ledger-whom .proof-label { line-height: 2.1; }
/* 2026-08-20 per Alex — was a middot character (&middot;) at 30% opacity, a faint
   typographic mark. Now a real drawn dot, same construction as .eyebrow .dot
   elsewhere on the site (round, currentColor), sized to sit quietly between the
   client-type words rather than reading as punctuation. */
.ledger-whom .label-dot { display: inline-block; width: 4px; height: 4px; border-radius: 50%; background: var(--stone-soft); vertical-align: middle; margin: 0 0.6em 0.15em; }
@media (max-width: 900px) {
  .ledger-years { grid-template-columns: repeat(2, 1fr); row-gap: 2.4rem; }
}
@media (max-width: 560px) {
  .ledger-years { grid-template-columns: 1fr; gap: 2rem; }
}

/* ---------- Footer — two zones (2026-08-09) --------------------------------
   Was a single flex row with space-between: three clusters shoved to the edges,
   a hole in the middle, four type treatments and the copyright sitting in the
   optical centre. Now content columns on a grid, a hairline, then a quiet legal
   strip — the pattern Aman and Mondrian both use. */
/* Footer is a section boundary, so it takes the boundary weight (0.18), not the
   contained weight. It also needs air above the logo or the doors row collides
   straight into it. (2026-08-09) */
.site-footer { background: var(--ink); border-top: 1px solid rgba(255,255,255,0.18); padding-top: clamp(0.6rem, 1.2vw, 1rem); }
.footer-grid {
  display: grid;
  grid-template-columns: auto 1fr auto auto;
  align-items: center;
  /* Row gap and column gap are NOT the same job here. The columns want air
     between them; the legal line below wants almost none, or it reads as a
     black band under the logo. Shorthand `gap` was giving both 54px. (2026-08-09) */
  column-gap: clamp(1.6rem, 3vw, 3.4rem);
  row-gap: 0;
  /* Less at the bottom than the top: the legal line closes the page, it does not
     need matching air beneath it. (2026-08-09) */
  padding-block: clamp(1.2rem, 1.8vw, 1.6rem) clamp(0.8rem, 1.2vw, 1.05rem);
}
/* Logo anchors left, an empty spacer column absorbs the middle, Explore and
   Contact cluster on the right. (2026-08-09) */
.footer-grid > *:nth-child(1) { text-align: left; }
.footer-grid > *:nth-child(2) { text-align: center; }
.footer-grid > *:nth-child(3),
.footer-grid > *:nth-child(4) { text-align: right; }
/* display:block matters — an inline img sits on the text baseline and carries a
   few px of descender space under it, which reads as dead black. (2026-08-09) */
.footer-brand img { display: block; height: 132px; width: auto; opacity: 1; margin-inline: 0; }
.footer-col h3 {
  /* Dropped to micro so the heading still outranks the links beneath it once
     those links came down to nav size. Both uppercase at 13.12px would make the
     heading and its list indistinguishable. (2026-08-09) */
  font-family: var(--font-sans); font-size: var(--fs-micro); letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--stone-soft);
  font-weight: 500; margin: 0 0 0.65rem;
}
.footer-col a {
  /* Was 0.92rem (14.72px) against the nav's 13.12px. Same job, same size now. */
  display: block; font-family: var(--font-sans); font-size: var(--fs-label);
  letter-spacing: 0.02em;
  color: rgba(255,255,255,0.82); padding-block: 0.16rem;
  transition: color 0.3s var(--ease);
}
.footer-col a:hover { color: var(--ivory); }
/* Explore has four links, Contact three. Centring each one independently left
   their headings on different lines, which reads as a mistake. Top-align both
   so EXPLORE and CONTACT share a baseline. (2026-08-09) */
.footer-col { align-self: start; padding-top: 0.35rem; }
.footer-legal {
  grid-column: 1 / -1;
  display: flex; flex-wrap: wrap; gap: 0.3rem 0.9rem;
  align-items: center; justify-content: center;
  margin-top: clamp(0.5rem, 0.9vw, 0.8rem);
  font-family: var(--font-sans); font-size: var(--fs-micro);
  /* Small print — the quietest text on the page. (2026-08-09) */
  color: rgba(255,255,255,0.42);
}
.footer-legal a { color: inherit; transition: color 0.3s var(--ease); }
.footer-legal a:hover { color: rgba(255,255,255,0.75); }
.footer-legal .sep { color: rgba(255,255,255,0.22); }
@media (max-width: 760px) {
  .footer-grid { grid-template-columns: 1fr; gap: 2.4rem; }
  /* Stacked on a phone, three different alignments read as a mistake.
     The whole closing zone is centered, so the columns centre with it. */
  .footer-grid > *:nth-child(1),
  .footer-grid > *:nth-child(2),
  .footer-grid > *:nth-child(3) { text-align: center; }
  .footer-brand img { margin-inline: auto; }
}

/* Closing address sits inside the footer row now — centre column, to the right of
   the logo. Deliberately quiet: Inquire already lives in the nav on every page, so
   this is a reminder rather than a second pitch. (2026-08-09) */
.footer-cta {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: 1rem;
}
.footer-cta h2 {
  font-family: var(--font-serif); font-size: var(--fs-h3);
  color: rgba(255,255,255,0.88); font-weight: 400; margin: 0;
}
.footer-cta .btn-row { display: flex; gap: 0.7rem; flex-wrap: wrap; justify-content: center; }


/* ---------- 30. Editorial photo bands (2026-08-14) --------------------------
   Added after Alex sent four luxury references (Mariven, Bellavista, Aurven,
   Zafron) and said the site was "nothing like" them. The measured difference
   was not type or colour — it was that those pages are CONTINUOUS IMAGERY
   (36-53 photographs, 10,000-13,000px long) while this one was a header image
   followed by text on black. Bigger type on a text page does not close that
   gap; the page has to be built around pictures instead of around paragraphs.

   Three primitives, all full-bleed, all reusable on any page:
     .band          — edge-to-edge photograph, type optional, sits between sections
     .band__inner   — the type layer, constrained back to the container width
     .duo           — two frames offset against each other, magazine style
   Full-bleed is done with 100vw + the negative-margin trick rather than moving
   these outside .container, so the existing page structure is untouched. */

.band {
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  min-height: clamp(26rem, 68vh, 44rem);
  display: grid;
  align-items: end;
  overflow: hidden;
  isolation: isolate;
}
.band__media {
  position: absolute; inset: 0; z-index: -1;
  background-size: cover;
  background-position: center;
  transform: scale(1.06);
  transition: transform 1.6s var(--ease-soft);
}
.band.is-visible .band__media { transform: scale(1); }
/* Wash so type always has something to sit on, regardless of the frame behind it */
/* 2026-08-17: wash strengthened after looking at it in the page. The first
   values were tuned against a dark frame; on the lighter interiors the headline
   lost contrast at the bottom-left where it actually sits. Two layers now — a
   vertical fade for the floor, plus a left-weighted one under the type. */
.band::after {
  content: "";
  position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(90deg, rgba(0,0,0,0.72) 0%, rgba(0,0,0,0.30) 42%, rgba(0,0,0,0) 68%),
    linear-gradient(180deg, rgba(0,0,0,0.45) 0%, rgba(0,0,0,0.12) 40%, rgba(0,0,0,0.85) 100%);
}
.band__inner {
  max-width: var(--container);
  margin: 0 auto;
  width: 100%;
  padding: 0 var(--gutter) clamp(2.6rem, 6vh, 4.5rem);
}
.band__line {
  font-family: var(--font-serif);
  font-size: var(--fs-h2);
  line-height: 1.25;
  color: var(--ivory);
  margin: 0;
  max-width: 26ch;
}
.band__line em { font-style: italic; color: var(--silver); }

/* Offset pair — the magazine device on every reference site: two frames at
   different heights so the eye travels diagonally instead of straight across. */
.duo {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(1rem, 2.4vw, 2.2rem);
  align-items: start;
}
.duo__fig { margin: 0; }
.duo__fig img {
  display: block;
  width: 100%;
  height: clamp(20rem, 46vh, 34rem);
  object-fit: cover;
}
.duo__fig:last-child { margin-top: clamp(2.5rem, 7vw, 6rem); }
.duo__cap {
  font-family: var(--font-sans);
  font-size: var(--fs-micro);
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--stone-soft);
  margin-top: 0.9rem;
}
@media (max-width: 760px) {
  .duo { grid-template-columns: 1fr; }
  .duo__fig:last-child { margin-top: 0; }
  .band { min-height: clamp(20rem, 52vh, 30rem); }
}

/* ---------- 31. Homepage rebuild pieces (2026-08-17) ------------------------
   Three small additions supporting the villa-dominant homepage: the scroll cue
   under the full-screen hero, the one-sentence positioning statement, and the
   band link spacing. Kept here rather than inline so the other pages can use
   the same pieces when they get rebuilt. */

/* Scroll cue — a hairline that breathes, rather than an arrow or a word.
   Matches the site's hairline language instead of introducing an icon. */
.hero__cue {
  position: absolute;
  bottom: clamp(1.4rem, 3vh, 2.4rem);
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
}
.hero__cue-line {
  display: block;
  width: 1px;
  height: clamp(2.2rem, 5vh, 3.4rem);
  background: linear-gradient(180deg, rgba(255,255,255,0) 0%, rgba(255,255,255,0.65) 100%);
  animation: cueDrift 2.8s var(--ease-soft) infinite;
  transform-origin: top;
}
@keyframes cueDrift {
  0%   { transform: scaleY(0.35); opacity: 0.15; }
  45%  { transform: scaleY(1);    opacity: 0.8;  }
  100% { transform: scaleY(0.35); opacity: 0.15; }
}

/* The one sentence that says what the company is. Sized between a headline and
   body — it is a statement, not a heading, so it should not compete with the
   section titles below it. */
.intro-statement {
  font-family: var(--font-serif);
  font-size: clamp(1.5rem, 2.7vw, 2.4rem);
  line-height: 1.35;
  color: var(--ivory);
  margin: 0;
  max-width: 30ch;
}
.intro-statement em { font-style: italic; color: var(--silver); }

/* ===== CROP DISPLAY — 2026-08-17. A word sized bigger than the section that
   holds it, clipped by a fixed-height wrapper so only its top half shows before
   the next block starts. Original markup and sizing; not lifted from any
   reference. Fails safe: with no wrapper height set it just reads as a big
   oversized headline, never blank. ===== */
/* 2026-08-17, corrected same day: the overflow:hidden + negative-margin crop
   overlapped the heading straight onto the text below it — dropped the
   clipping trick entirely. Now a big, confident headline with normal spacing. */
/* 2026-08-19, corrected again — per Alex, and this one wasn't a taste call:
   this was capping at 6.4rem, which is BIGGER than the site's own --fs-h1
   (5.6rem, the hero headline). A section label was outranking the page's
   actual H1 — a real hierarchy break, not just "too loud." Brought well under
   --fs-h1 so it still reads as a moment but never competes with the headline
   that's supposed to be the loudest thing on the page. */
.crop-display-wrap {
  margin-bottom: clamp(1.6rem, 3vw, 2.4rem);
}
.crop-display {
  font-family: var(--font-display);
  font-size: clamp(2.2rem, 4.6vw, 3.6rem);
  line-height: 1;
  letter-spacing: -0.015em;
  color: var(--ivory);
  margin: 0;
}
@media (max-width: 760px) {
  .crop-display { font-size: clamp(1.7rem, 7vw, 2.4rem); }
}

/* ===== PHOTO BOX — 2026-08-17. A plain rectangular photograph used as a layout
   element: no border, no shadow, no radius, no fill behind it. The edge of the
   image IS the edge of the box. Alex's call after seeing the reference site's
   image tiles — he wants that device usable anywhere, so this is a generic
   utility rather than a one-off. Pairs with .split, bands, or on its own. */
.photo-box {
  display: block;
  width: 100%;
  overflow: hidden;
}
.photo-box img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  filter: var(--img-filter);
}
.photo-box--portrait { aspect-ratio: 4 / 5; }
.photo-box--square { aspect-ratio: 1 / 1; }
.photo-box--wide { aspect-ratio: 4 / 3; }

@media (prefers-reduced-motion: reduce) {
  .hero__cue-line { animation: none; opacity: 0.5; }
}

/* =========================================================================
   THE COLLECTION — LIGHT (2026-08-24)
   -----------------------------------------------------------------------
   villas.html only, at Alex's request after videinfra.com/work: their idea
   of a grid page (giant headline, filter pills, photo + name, nothing else
   at rest) rebuilt white for The Collection — not their code, none of it
   copied. A dedicated .cl- namespace on purpose: this stylesheet forces
   white text on every .section, everywhere, on the working assumption that
   every section sits on black (see "27. All black" and the Meridian layer
   exemptions above — both are !important and both assume a dark canvas).
   A real white page fighting that per-selector would be fragile forever;
   a clean namespace with its own colors, defined once, is not. Nothing
   here touches .section/.meridian/.m-row, so no other page is affected.
   This is a preview of ONE page — everything else on the site stays the
   black-field Meridian look until/unless Alex says otherwise.
   ========================================================================= */
.cl-page { background: var(--ink); color: #fff; } /* was #141414 (dark grey) — didn't match the nav's near-pure black; fixed 2026-08-27 */

.cl-hero { padding: clamp(6rem,11vw,8.5rem) 0 clamp(2.2rem,4.5vw,3.4rem); }
.cl-crumbs {
  font-family: "JetBrains Mono", "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: rgba(255,255,255,0.42); margin-bottom: 2.2rem;
}
.cl-crumbs a { color: rgba(255,255,255,0.42); text-decoration: none; }
.cl-crumbs a:hover { color: #fff; }
.cl-crumbs .sep { margin: 0 0.5em; opacity: 0.5; }
/* Toned down + spaced out, 2026-08-24 — Alex: theirs isn't that big, and the
   gap between "Work" and the pills below it is huge. Was 7.2rem max with a
   1.6rem margin; sized down and the gap opened up to match. */
.cl-h1 {
  font-family: var(--font-sans); font-weight: 600;
  /* 2026-08-27 — notched down twice now. First pass (irradiation — light
     text reads larger/heavier on dark than the same size on light) trimmed
     ~7% off the top end after the black/white invert. Second pass, same
     day: Alex's brand direction is "boho chic meets minimalist, subtle, not
     in-your-face" — a giant sans-serif headline is a loud, corporate-agency
     gesture (borrowed from videinfra.com) that fights that voice regardless
     of the irradiation fix. Cut further, general site-wide "make it smaller,
     more subtle" pass — see the matching note on .m-shot__title, .cl-h2,
     .cl-card__title, .cl-row__title, all trimmed together for one consistent
     quieter scale rather than one page reading small next to another. */
  font-size: clamp(2.3rem, 5vw, 4.2rem); line-height: 0.98; letter-spacing: -0.02em;
  margin: 0 0 clamp(3.4rem, 7vw, 5.4rem); color: #fff;
  /* 2026-08-25, per Alex — "Property Management." was clipping its last
     letter off the right edge on his real phone (font renders wider there
     than in any desktop test — likely his device's own text-size setting).
     First attempt added word-break:break-word alongside overflow-wrap,
     which was wrong: word-break is the aggressive one and chopped
     "Management" mid-word ("Managemen" / "t.") instead of moving the whole
     word down. overflow-wrap alone only breaks a word if it truly can't
     fit even by itself on its own line — much rarer, and the lowered floor
     below (see the max-width:420px rule) means it usually won't need to. */
  max-width: 100%; overflow-wrap: break-word;
}
@media (max-width: 420px) {
  .cl-h1 { font-size: clamp(1.8rem, 7.5vw, 4.2rem); }
}
/* Size + color bumped 2026-08-24 — Alex: the copy under every hero sitewide
   reads too small and too faint. Was clamp(1.1,1.6vw,1.35) at 60% black. */
.cl-lede {
  font-family: var(--font-serif); font-style: italic;
  font-size: clamp(1.05rem, 1.4vw, 1.28rem); line-height: 1.6;
  color: rgba(255,255,255,0.72); max-width: 46ch; margin: 0 0 2.6rem;
}

/* --- Hero with a portrait alongside the headline — about.html, 2026-08-24.
   Alex: put Melissa to the right of "Our Story." Text column stays exactly
   like every other .cl-hero; the photo is a fixed-width portrait column
   that sits bottom-aligned with the headline, name/role set underneath in
   the same small-caps mono used for .cl-crumbs elsewhere on the page. */
/* Tightened 2026-08-27, per Alex ("too wide") — align-items was "end", which
   pinned the short two-line heading to the bottom of the row and left a big
   empty gap above it, since the portrait photo was taller than the text.
   Switched to "center" so heading and photo sit level, and shrank the photo
   itself so the whole row reads as one compact unit instead of a tall,
   sparse one. */
.cl-hero-split { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: clamp(2rem,5vw,4rem); }
.cl-hero-split__photo { width: clamp(140px,13vw,190px); }
.cl-hero-split__photo img {
  display: block; width: 100%; aspect-ratio: 3/4; object-fit: cover;
  background: #1a1a1a;
  /* Soft lift instead of a frame, 2026-08-24 — no border line, just depth,
     so it stays inside the site's no-boxes rule while still separating
     the photo from the white page. */
  box-shadow: 0 30px 50px -20px rgba(20,20,20,0.35), 0 10px 20px rgba(20,20,20,0.08);
}
.cl-hero-split__name {
  font-family: var(--font-sans); font-weight: 600; font-size: 0.95rem;
  color: #fff; margin: 1rem 0 0.15rem;
}
.cl-hero-split__role {
  font-family: "JetBrains Mono", "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.68rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: rgba(255,255,255,0.5); margin: 0;
}
@media (max-width: 780px) {
  .cl-hero-split { grid-template-columns: 1fr; }
  .cl-hero-split__photo { width: 150px; }
}

/* #origin (about.html) — 2026-08-28, per Alex: after several passes that
   only nudged individual values without fixing why the section kept
   reading as thin/scattered/inconsistent, #origin now reuses
   .cl-yacht-split verbatim (see markup in about.html and .cl-yacht-split__*
   above) — same grid, same spacing, same text-beat pattern as
   group-travel's Yachts/Host section, so the two "photo-forward pairing"
   sections on the site are the same component, not two builds of the same
   idea. This is the ONE real difference: Melissa's photo is a portrait
   headshot, the yacht photo is landscape, so the img's aspect-ratio and
   max-width are overridden here instead of force-cropping a portrait into
   the yacht's 3:2 frame. Nothing else about .cl-yacht-split is touched. */
/* 2026-08-28, per Alex — stopped trying to make Melissa's photo match the
   yacht photo's footprint at all: "can be whatever size it needs to,
   smaller I sincerely hope." Different shape, different job (portrait
   headshot vs. landscape establishing shot) — sized here as its own normal
   photo instead of stretched to fill a footprint built for a different
   kind of image. */
#origin .cl-yacht-split__photo img {
  aspect-ratio: 3/4; max-width: clamp(220px,20vw,280px);
}
/* The base .cl-yacht-split__photo img rule right-aligns the image itself
   (margin-left:auto, since the grid column is much wider than the capped
   image). The figcaption (Melissa / Director of Operations) is a separate
   full-width block inside the same figure, so without this it sits
   left-aligned under nothing — visually detached from the photo it's
   captioning. Flexing the figure to the right edge keeps image + name +
   title as one aligned unit. */
#origin .cl-yacht-split__photo {
  display: flex; flex-direction: column; align-items: flex-end;
}
#origin .cl-yacht-split__photo figcaption { text-align: right; }
/* Mobile bug found + fixed 2026-08-28: the right-alignment above is a
   desktop-only composition choice (to echo the yacht photo's right-hugging
   position next to a wide text column). On mobile, .cl-yacht-split__grid
   collapses to one full-width column and the photo moves above the text
   (order:-1) — right-pinning a capped-width portrait there just leaves it
   floating off to one side with dead space on the left, which isn't how
   any other mobile photo on the site behaves. Centered here instead, only
   under the same 860px breakpoint the rest of .cl-yacht-split already
   uses. */
@media (max-width: 860px) {
  #origin .cl-yacht-split__photo { align-items: center; }
  #origin .cl-yacht-split__photo figcaption { text-align: center; }
}

/* --- filter pills — the one place this page uses a bordered shape on
   purpose. Alex specifically asked to match this reference, pills included;
   the rest of the site's "no boxes" rule stays in force everywhere else. */
.cl-pills { display: flex; flex-wrap: wrap; gap: 0.6rem; }
.cl-pill {
  font-family: var(--font-sans); font-size: 0.85rem; font-weight: 500;
  padding: 0.65rem 1.3rem; border-radius: 999px; border: 1px solid rgba(255,255,255,0.14);
  background: rgba(255,255,255,0.04); color: #fff; cursor: pointer;
  transition: background 0.25s var(--ease), color 0.25s var(--ease), border-color 0.25s var(--ease);
}
.cl-pill:hover { border-color: rgba(255,255,255,0.32); }
.cl-pill.is-active { background: #fff; border-color: #fff; color: #141414; }

.cl-section { padding-block: clamp(3.5rem,7vw,6rem); border-top: 1px solid rgba(255,255,255,0.08); }

.cl-head { margin-bottom: clamp(2rem,4vw,3rem); }
.cl-index {
  display: block;
  font-family: "JetBrains Mono", "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.75rem; letter-spacing: 0.2em; text-transform: uppercase;
  color: rgba(255,255,255,0.42); margin: 0 0 1rem;
}
.cl-head h2 {
  font-family: var(--font-serif); font-size: clamp(2rem,4vw,2.8rem); line-height: 1.1;
  margin: 0; color: #fff;
}
.cl-head h2 em { font-style: italic; color: #a9744a; }

/* Grid + card shape matched to videinfra's, 2026-08-24 — Alex: "same size
   as theirs." Their work cards are two per row, wide landscape frames
   (roughly 2:1), not three per row portrait. Dropped to 2 columns / 2:1
   here to match; six villas now read as three rows of two, same as their
   grid read as three rows of two project cards. */
.cl-grid {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: clamp(2rem,4vw,3.2rem) clamp(1.6rem,3vw,2.4rem);
}
.cl-card { display: block; text-decoration: none; color: inherit; }
.cl-card__media {
  display: block; position: relative; aspect-ratio: 2/1; overflow: hidden;
  margin-bottom: 1.1rem; background: #1a1a1a;
}
.cl-card__media img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  transition: transform 1.2s var(--ease);
}
.cl-card:hover .cl-card__media img { transform: scale(1.045); }
.cl-card__meta {
  display: flex; align-items: center; flex-wrap: wrap; gap: 0.5rem;
  font-family: "JetBrains Mono", "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.76rem; letter-spacing: 0.13em; text-transform: uppercase;
  color: rgba(255,255,255,0.56); margin: 0 0 0.6rem;
}
.cl-card__meta .dot { width: 3px; height: 3px; border-radius: 50%; background: #a9744a; display: inline-block; }
.cl-card__title {
  font-family: var(--font-serif); font-size: clamp(1.2rem,1.6vw,1.55rem); line-height: 1.15;
  margin: 0 0 0.5rem; color: #fff;
}
/* Always visible, 2026-08-24 — was opacity:0 by default with a hover/focus
   reveal, so "Check Availability" and "Opening 2027" were invisible until
   you hovered the card. Alex wants those static, not hover-revealed. */
/* Font switched off JetBrains Mono 2026-08-27, per Alex — bold mono at
   0.72rem with 0.16em tracking was reading blurry/hard to read (bold
   weight + wide letter-spacing pushes a small monospace face past where
   it stays crisp). Inter (the site's sans, already used for .cl-btn and
   body copy) holds up much better at a bold weight and small size — sized
   up slightly and tracking pulled in so it doesn't feel loose. */
.cl-card__link {
  font-family: var(--font-sans);
  font-size: 0.82rem; letter-spacing: 0.06em; text-transform: uppercase;
  font-weight: 600;
  color: #fff; display: inline-flex; align-items: center; gap: 0.45rem;
  transition: color 0.3s var(--ease);
}
/* 2026-08-27, per Alex — the .cl-btn pill on villa cards ("just make them a
   bold Check Availability and blink when hover") was one iteration too
   far. Back to plain text, bold instead of the pill, color-shift on hover
   instead of an underline or the pill's background swap — same "blink"
   device already used for the homepage's What We Do row titles
   (.cl-rows--split .cl-row:hover .cl-row__title). Scoped to an actual .cl-card
   link (not Horizon's muted "Opening 2027", which isn't a link at all —
   that div has no :hover to trigger this). */
.cl-card:hover .cl-card__link { color: #a9744a; }

/* Cut to a single line, 2026-08-24 — .cl-note IS the <p> now (no eyebrow,
   no separate sentence, no <em>), the link sits inline at the end of it. */
/* Size + color bumped 2026-08-24 alongside .cl-lede, same reason. */
.cl-note {
  font-family: var(--font-serif); font-style: italic;
  font-size: clamp(1.12rem,1.7vw,1.35rem); line-height: 1.55;
  color: rgba(255,255,255,0.72); margin: 0;
}
.cl-note a {
  font-family: var(--font-serif); font-style: italic; font-weight: 500;
  font-size: inherit; color: #fff; text-decoration: none;
  display: inline-flex; align-items: center; gap: 0.35rem;
  transition: gap 0.3s var(--ease);
}
.cl-note a:hover { gap: 0.7rem; }
.cl-note .arrow { transition: transform 0.4s var(--ease); display: inline-block; }

@media (max-width: 700px) {
  .cl-grid { grid-template-columns: 1fr; }
  .cl-pills { gap: 0.5rem; }
}
@media (prefers-reduced-motion: reduce) {
  .cl-card:hover .cl-card__media img { transition: none; transform: none; }
}

/* --- VILLA GALLERY — PHOTO-FIRST CARDS (2026-08-27, per Alex) -----------
   villas.html's grid was "a competent but generic card grid" — photo, then
   caption below it. This modifier (added onto .cl-grid/.cl-card, not
   replacing them — the homepage's Collection preview uses its own
   .cl-grid--journal variant below, untouched) moves name/meta/link onto a
   bottom scrim over the photo itself, same photograph-first language as
   .cl-band and the homepage hero. Markup: each .cl-card gets .cl-card--bleed
   and its meta/title/link move inside a new .cl-card__body wrapper.
   2026-08-27, round two — first pass broke the grid out of .container to
   full viewport width with a 2px gap; Alex: the photos crammed into each
   other, six different color palettes with no separation. Pulled it back
   inside .container (like every other section on this page) and opened the
   gap up to a real gutter. See villas.html. */
/* Narrowed 2026-08-27, per Alex ("just a notch or two smaller... too in your
   face") — Lotus's feature panel and the grid below it were running the
   site's full 1340px container width, same as every other section, which
   made the photos read larger/louder than the rest of the page. Scoped to
   #villas only (see villas.html) so no other section's width changes. */
#villas.cl-section > .container { max-width: 1160px; }

.cl-grid--bleed {
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(1.4rem, 3vw, 2.4rem);
}
.cl-card--bleed {
  position: relative;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  isolation: isolate;
}
/* Media span overscans its card by 6% top and bottom so the scroll parallax
   (js/main.js) has room to shift the image without ever exposing an edge. */
.cl-card--bleed .cl-card__media {
  position: absolute; inset: -6% 0; margin: 0; aspect-ratio: auto; background: #1a1a1a;
}
.cl-card--bleed::after {
  content: "";
  position: absolute; inset: 0; z-index: 1;
  /* Lightened 2026-08-27, per Alex — the photos were reading darker than
     they needed to; this only exists so the overlaid name/meta stay
     legible, not to mute the photo itself. Transparent further down (58%
     vs. 45%) and capped lower (0.72 vs. 0.88) so more of each photo's own
     color and light comes through, text still sits on enough black to read. */
  background: linear-gradient(180deg,
    rgba(0,0,0,0) 58%,
    rgba(0,0,0,0.4) 82%,
    rgba(0,0,0,0.72) 100%);
  pointer-events: none;
}
.cl-card__body {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 2;
  padding: clamp(1.2rem, 3vw, 1.9rem);
}
.cl-card--bleed .cl-card__meta { color: rgba(255,255,255,0.78); margin: 0 0 0.5rem; }
.cl-card--bleed .cl-card__title { color: #fff; text-shadow: 0 2px 24px rgba(0,0,0,0.45); margin: 0 0 0.6rem; }
@media (max-width: 700px) {
  .cl-grid--bleed { grid-template-columns: 1fr; }
  .cl-card--bleed { aspect-ratio: 4 / 5; }
}
@media (prefers-reduced-motion: reduce) {
  .cl-card--bleed .cl-card__media { transform: none !important; }
}

/* --- COLLECTION GRID NOTE CELL (2026-08-27, per Alex) --------------------
   Six villas in a 2-up grid leaves Horizon alone on the last row with an
   empty cell beside it — read as a blank black hole next to a photo. Alex's
   fix: put the "Every Villa. Fully Staffed..." line in that empty cell
   instead of as a separate paragraph under the grid. This is the one
   deliberate exception to the site's no-boxes rule — Alex asked for a box
   here specifically, to fill a real empty slot in a photo grid, not as a
   general card treatment — so it's a single hairline border (matching the
   weight already used for .cl-section dividers, not a heavy card outline),
   sized to match the photo cells exactly so the row reads even. */
.cl-card--note {
  aspect-ratio: 4 / 3;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center;
  padding: clamp(1.6rem, 3vw, 2.4rem);
  border: 1px solid rgba(255,255,255,0.14);
}
.cl-card--note .cl-eyebrow { margin: 0 0 1rem; }
.cl-card--note .cl-card__title { margin: 0 0 0.8rem; }
.cl-card--note p { margin: 0; max-width: 26ch; font-family: var(--font-sans); font-size: 0.98rem; line-height: 1.55; color: rgba(255,255,255,0.65); }
.cl-card--note strong { font-weight: 600; color: #fff; }
@media (max-width: 700px) {
  .cl-card--note { aspect-ratio: 4 / 5; }
}

/* --- FEATURED VILLA (2026-08-27) — Casa Lotus gets its own full-width panel
   above the grid, per Alex comparing full-bleed vs. contained grid mockups:
   neither gave the page a focal point on its own — every villa read as
   equal weight, which flattens the Collection's actual flagship into just
   another tile. One feature panel, then the smaller grid for the rest —
   same "photo, then everything else" device .cl-band already uses on
   property-management.html. Built on .cl-card--bleed, just taller and with
   a bigger title. */
/* Switched to a fixed aspect-ratio 2026-08-27, per Alex — the vh-based
   min-height (previous fix) still cropped a lot of the photo vertically on
   any normal-height viewport: 66vh at a typical 900px-tall laptop screen is
   only ~594px, well short of the ~753px this panel's width actually needs
   to show collection-lotus-tall.jpg (1596x897, ratio 1.78) uncropped. A
   vh-based height can never reliably match a target tied to the panel's
   WIDTH, which is what actually determines the crop. Locking the box to the
   photo's own ratio instead guarantees the full frame shows, at any
   viewport, with zero vertical cropping — this is specific to this one
   photo's proportions; if the featured image changes, this ratio should
   change with it. */
/* Reworked 2026-08-27, per Alex — the photo-first .cl-card--bleed treatment
   (name/meta/link overlaid on the photo itself) is gone from villas.html.
   Alex didn't like the info sitting on top of the image, and the CTA read
   as plain white text when every other CTA on the site (.cl-btn) is a
   white pill with dark text — inconsistent, and easy to mistake for a
   styling bug. Villa cards are back to the original shape: photo on top
   (plain .cl-card__media, normal flow, not absolute/overlaid), then meta,
   title, and a real .cl-btn pill in the black page space below it — same
   pattern the rest of the site already uses for a link. .cl-card--feature
   now only sizes Lotus's media box (not the whole card), so it keeps its
   own bigger, uncropped panel while the info below behaves like every
   other card. */
.cl-card--feature .cl-card__media { aspect-ratio: 2560 / 1340; }
.cl-card--feature .cl-card__title { font-size: clamp(1.7rem, 3vw, 2.3rem); }
/* Bug, 2026-08-27 — the rework above dropped the margin-bottom that used
   to live on .cl-card--feature itself (back when the whole card was
   locked to the photo's aspect-ratio). With that gone, Lotus's "Check
   Availability" sat almost flush against the grid row below it — Alex:
   "almost into the next pic." Restored here, now scoped correctly since
   the aspect-ratio moved to .cl-card__media above. This is what actually
   separates the Lotus block from the 2-up grid; the grid's own five cards
   are already evenly spaced by .cl-grid's gap. */
.cl-card--feature { margin-bottom: clamp(1.6rem, 3vw, 2.2rem); }
/* Compact pill sizing so .cl-btn fits a card's caption block instead of
   the larger CTA rows it's normally used in. Unused since "Check
   Availability" reverted to plain text below, kept in case a card ever
   needs a real pill CTA again. */
.cl-card .cl-btn { margin-top: 0.3rem; padding: 0.6rem 1.3rem; font-size: 0.68rem; }

/* --- HOMEPAGE COLLECTION PREVIEW — "journal" grid (2026-08-27), per Alex,
   after seeing videinfra.com/blog: same idea (small quiet photo, name, one
   caption line, lots of space, no card box) adapted to this site's system —
   still plain .cl-card, no border, on black — just three per row instead of
   two, so the homepage's preview reads as a quick index rather than a
   repeat of the Collection page's own (now feature + grid) treatment. Scoped
   to the homepage only — villas.html keeps .cl-grid--bleed. */
.cl-grid--journal { grid-template-columns: repeat(3, 1fr); gap: clamp(2.2rem,3.5vw,3rem) clamp(1.4rem,2.5vw,2rem); }
.cl-grid--journal .cl-card__media { aspect-ratio: 4/3; }
@media (max-width: 900px) {
  .cl-grid--journal { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 700px) {
  .cl-grid--journal { grid-template-columns: 1fr; }
}

/* --- FOOTER — matched to videinfra.com, 2026-08-24: brand / link list /
   pill CTA on one row, a tall quiet gap, copyright + legal along the
   bottom. --- */
.cl-footer { background: var(--ink); border-top: 1px solid rgba(255,255,255,0.08); padding: clamp(2.6rem,5vw,4rem) 0 clamp(1.8rem,3vw,2.4rem); } /* was #141414, same mismatch as .cl-page — fixed 2026-08-27 */
.cl-footer__top {
  display: flex; align-items: flex-start; justify-content: space-between;
  flex-wrap: wrap; gap: 2.5rem;
  margin-bottom: clamp(2.6rem,5vw,4rem);
}
.cl-footer__brand { font-family: var(--font-sans); font-weight: 700; font-size: 1.3rem; color: #fff; }
/* Cities line under the footer brand, 2026-08-24 — same small-caption
   language as .cl-card__meta (JetBrains Mono, uppercase, muted) rather than
   the dark-theme .drawer-meta, since the light .cl-footer sits on white. */
.cl-footer__cities {
  display: block; margin-top: 0.35rem;
  font-family: "JetBrains Mono", "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.72rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: rgba(255,255,255,0.5); font-weight: 400;
}
.cl-footer__links { display: flex; flex-direction: column; gap: 0.5rem; }
.cl-footer__links a { font-family: var(--font-sans); font-size: 1rem; color: #fff; text-decoration: none; }
.cl-footer__links a:hover { color: rgba(255,255,255,0.5); }
.cl-footer__cta {
  font-family: var(--font-sans); font-size: 0.95rem; font-weight: 600;
  background: #fff; color: #141414; text-decoration: none;
  padding: 0.95rem 1.9rem; border-radius: 999px; white-space: nowrap;
  transition: background 0.25s var(--ease);
}
.cl-footer__cta:hover { background: #ececec; }
.cl-footer__bottom {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 1rem;
  font-family: var(--font-sans); font-size: 0.85rem; color: rgba(255,255,255,0.45);
}
.cl-footer__bottom a { color: rgba(255,255,255,0.5); text-decoration: none; }
.cl-footer__bottom a:hover { color: #fff; }
.cl-footer__bottom .sep { margin: 0 0.5em; opacity: 0.5; }
@media (max-width: 640px) {
  .cl-footer__top { flex-direction: column; gap: 1.6rem; }
  .cl-footer__cta { align-self: flex-start; }
  .cl-footer__bottom { flex-direction: column; align-items: flex-start; gap: 0.6rem; }
}

/* --- NEIGHBORHOODS — villas.html, 2026-08-24. Upright serif headings over
   plain sans body copy, deliberately NOT italic — this is the block that
   needed to read differently from both the italic "We can source it" line
   above it and the mono-caps spec list below it. --- */
.cl-locale-grid {
  display: grid; grid-template-columns: repeat(auto-fit,minmax(min(100%,20rem),1fr));
  gap: clamp(1.6rem,3vw,3rem); margin-top: 1.4rem;
}
.cl-locale-grid__name {
  font-family: var(--font-serif); font-style: normal; font-weight: 500;
  font-size: clamp(1.2rem,2vw,1.5rem); color: #fff; margin: 0 0 0.5rem;
}
.cl-locale-grid__body {
  font-family: var(--font-sans); font-style: normal; font-size: 1rem;
  line-height: 1.55; color: rgba(255,255,255,0.6); margin: 0;
}
.cl-locale-grid__body em { font-style: italic; color: #a9744a; }

/* =========================================================================
   THE LIGHT SYSTEM — extended to index.html (2026-08-24)
   -----------------------------------------------------------------------
   Same .cl- namespace as villas.html, extended with the pieces the
   homepage needs that the Collection page didn't: a two-tone headline, a
   photo/video band, a ledger row, and a plain link-row list. Sizing follows
   the correction Alex gave on villas.html — their headlines aren't as huge
   as a first pass suggests, and the gap under them is bigger than it looks
   — applied here from the start rather than repeating that pass. ========= */
.cl-eyebrow {
  display: block;
  font-family: "JetBrains Mono", "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.8rem; letter-spacing: 0.18em; text-transform: uppercase;
  color: #a9744a; margin: 0 0 1.4rem;
}
/* Was bold sans + full-size gold — the one place on the site that broke
   from the italic-serif-accent convention (.cl-h2 em, .m-row__title em,
   etc). Matched to it here, 2026-08-24: smaller, italic, serif. */
.cl-h1 .accent, .cl-h1 em { font-family: var(--font-serif); font-style: italic; font-weight: 400; font-size: 0.6em; color: #a9744a; }

.cl-hero-row {
  display: grid; grid-template-columns: 1fr 1.3fr;
  gap: clamp(2rem,5vw,4rem); align-items: end;
  margin-top: clamp(2.4rem,5vw,4rem);
  padding-top: clamp(1.6rem,3vw,2.4rem);
  border-top: 1px solid rgba(255,255,255,0.08);
}
.cl-hero-rail { display: flex; flex-wrap: wrap; gap: 0.5rem 2rem; }
.cl-hero-rail span {
  font-family: "JetBrains Mono", "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.72rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: rgba(255,255,255,0.55); position: relative; padding-left: 1rem;
}
.cl-hero-rail span::before {
  content: ""; position: absolute; left: 0; top: 0.42em;
  width: 4px; height: 4px; border-radius: 50%; background: #a9744a;
}
@media (max-width: 860px) { .cl-hero-row { grid-template-columns: 1fr; } }

/* A quiet photo/video strip, not a full-screen hero — the headline above
   carries the page opening now, this is closer to the aerial photo band
   videinfra runs under theirs. group-travel.html no longer uses this (see
   .cl-yacht-split below) but it's still the pattern for any future band
   photo elsewhere on the site, so kept rather than deleted. */
.cl-band { position: relative; height: clamp(220px,32vw,400px); overflow: hidden; background: #1a1a1a; }
.cl-band__media { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* --- YACHTS SPLIT PANEL (2026-08-27) — group-travel.html only, per Alex.
   Photo-forward: the image column is the dominant 1fr track, text sits in
   a narrower fixed column beside it, opposite the usual text-dominant
   .cl-hero-split ratio (about.html) — here the photo IS the point, not an
   accent next to copy. aspect-ratio locked to the source image (2200x1467)
   so it always renders uncropped, same convention as villas.html's Casa
   Lotus panel. No box/border on the photo — it's a plain image, not a
   card; the site's no-boxes rule is about UI chrome, not photography. */
.cl-yacht-split__grid {
  display: grid; grid-template-columns: minmax(0,22rem) 1fr;
  gap: clamp(2.5rem,5vw,4.5rem); align-items: center;
}
.cl-yacht-split__text .cl-h2 { margin: 0.6rem 0 1rem; }
.cl-yacht-split__photo { margin: 0; }
/* 2026-08-28, per Alex: "make the yacht pic smaller if you need to" — at
   full 1fr width (roughly 1000px on desktop, ~667px tall at 3:2) the photo
   dominated the panel so much that The Host below read as its own section
   rather than a continuation. Capping the image itself (not the grid
   column) keeps the two-column layout but shrinks the photo's footprint
   and, with it, the panel's total height. */
.cl-yacht-split__photo img {
  display: block; width: 100%; max-width: 30rem; margin-left: auto;
  aspect-ratio: 3 / 2; object-fit: cover;
}
@media (max-width: 860px) {
  .cl-yacht-split__grid { grid-template-columns: 1fr; gap: 1.8rem; }
  .cl-yacht-split__photo { order: -1; }
  .cl-yacht-split__photo img { max-width: 100%; margin-left: 0; }
}
/* .cl-yacht-split__host removed 2026-08-28, per Alex — putting Bilingual
   Host in its own full-width centered block with a hairline over it read
   as a second section, not a continuation. Bilingual Host now lives
   stacked inside .cl-yacht-split__text itself (see group-travel.html),
   same column, same photo, one section. The leftover ".cl-yacht-split__host
   .cl-h2" rule (dead — not referenced in any HTML) was cleaned up
   2026-08-28 during a full pass for orphaned CSS. */

.cl-ledger {
  display: grid; grid-template-columns: repeat(4,1fr);
  gap: clamp(1.6rem,4vw,3.5rem);
}
/* 2026-08-28, per Alex — bumped up. This ledger (years + Whom, about.html)
   is the entire content of "Our Story" beyond the h1, and at the old sizes
   it read as fine print, not the page's one statement. Numerals a notch
   bigger, labels a notch bigger and noticeably whiter (0.58 → 0.82 opacity)
   so the whole block carries actual weight instead of fading into the
   black field around it. */
.cl-ledger__num {
  display: block; font-family: var(--font-serif);
  font-size: clamp(2.1rem,4vw,2.9rem); color: #fff; margin-bottom: 0.5rem;
}
.cl-ledger__label {
  display: block; font-family: "JetBrains Mono", "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.82rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: rgba(255,255,255,0.82);
}
/* .cl-ledger__label--split (the Whom cell's center-dot treatment) removed
   2026-08-25, per Alex — it right-aligned the first line so it didn't start
   flush under "Whom" the way every other cell's label starts flush under
   its number. Whom's two lines now use plain .cl-ledger__label, unchanged
   from every other cell. Markup updated in index.html to match. */
@media (max-width: 700px) { .cl-ledger { grid-template-columns: repeat(2,1fr); } }

/* .cl-hero-meta / .cl-hero-meta__whom / .cl-hero-meta__note removed
   2026-08-28, per Alex — the side-by-side-with-a-hairline layout never
   read well, and reusing .cl-ledger__num's number style on the word
   "Whom" made it look like a fourth stat cell instead of its own section
   beat. Replaced with the eyebrow/h2/lede pattern below, matching
   group-travel.html's Yachts/Host block (which Alex pointed to directly
   as the model), plus .cl-whom-grid for the roster itself. No longer used
   anywhere on the site — about.html was the only page that referenced
   these three classes. */

/* .cl-whom-grid removed 2026-08-28, per Alex — the Whom beat on about.html
   is now one plain .cl-lede sentence, same as every other beat on the
   site (Yachts/Host), not a grid. No longer referenced anywhere. */

/* No border-top here, 2026-08-24 — .cl-section already draws the section
   boundary hairline directly above .cl-rows. Adding a second one here put
   two hairlines a few rem apart (the section's own top padding sitting
   between them), which read as two empty banded sections instead of one
   normal gap. Same class of bug this project already fixed once on
   villas.html's "Beyond the Collection" note — recurring here because this
   is a different component, not a copy-paste of that one. */
.cl-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1.5rem;
  padding-block: clamp(1.8rem,3.5vw,2.8rem);
  border-bottom: 1px solid rgba(255,255,255,0.08);
  text-decoration: none; color: inherit;
}
/* .cl-row__text wraps title + desc in their own column, 2026-08-24 — before
   this, title/desc/arrow all sat in one flex row with wrap:wrap, so
   whichever description happened to be short enough stayed on the title's
   line while a longer one (Group Travel's) wrapped underneath — the two
   rows on index.html looked structurally different from each other purely
   by text length. Stacking them in a fixed column makes every row's desc
   sit directly under its title the same way, regardless of sentence length. */
.cl-row__text { display: flex; flex-direction: column; gap: 0.4rem; }
.cl-row__title { font-family: var(--font-serif); font-size: clamp(1.2rem,1.9vw,1.55rem); color: #fff; margin: 0; }
.cl-row__desc { font-family: var(--font-serif); font-style: italic; font-size: 1.08rem; color: rgba(255,255,255,0.68); margin: 0; }
.cl-row .arrow { font-size: 1.2rem; color: #fff; transition: transform 0.3s var(--ease); display: inline-block; }
.cl-row:hover .arrow { transform: translateX(4px); }

/* --- HOMEPAGE ROWS → THREE PLAIN COLUMNS (2026-08-27, per Alex) ----------
   Third pass on #what-we-do: no boxes (confirmed off-limits everywhere on
   this site), one section, Collection/Group Travel/Property Management
   side by side instead of stacked, arrows removed — the title itself
   carries the link now, hover does the arrow's old job. Overrides .cl-row's
   flex/border/padding, which were built for the stacked version; .cl-row is
   only used here on index.html (checked — property-management.html and
   group-travel.html only reuse .cl-row__title's type, not the row/link
   component), so this is safe to change without touching those pages. */
.cl-rows--split { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(2.2rem, 5vw, 4rem); }
.cl-rows--split .cl-row {
  display: block; padding-block: 0; border-bottom: none;
}
.cl-rows--split .cl-row__title {
  transition: color 0.3s var(--ease);
}
.cl-rows--split .cl-row:hover .cl-row__title,
.cl-rows--split .cl-row:focus-visible .cl-row__title {
  color: #a9744a;
}
@media (max-width: 860px) {
  .cl-rows--split { grid-template-columns: 1fr; gap: clamp(2rem,5vw,2.6rem); }
  .cl-rows--split .cl-row { padding-block: 0.4rem; border-bottom: 1px solid rgba(255,255,255,0.08); padding-bottom: 1.6rem; }
  .cl-rows--split .cl-row:last-child { border-bottom: none; }
}

.cl-h2 { font-family: var(--font-serif); font-size: clamp(1.7rem,3.2vw,2.3rem); line-height: 1.15; margin: 0 0 1.2rem; color: #fff; overflow-wrap: break-word; }
.cl-h2 em { font-style: italic; color: #a9744a; }

/* Bumped 2026-08-24 per Alex — "bring out the CTAs a bit": a notch bigger,
   a notch bolder, and a soft lift on hover instead of just a color swap.
   2026-08-27 — softened back down, per Alex's boho-minimal brand direction:
   a solid white pill with a heavy drop shadow reads like a SaaS landing
   page, not "subtle." Kept the pill shape and the hover lift (still useful,
   still quiet) but pulled the shadow and padding in a notch so it doesn't
   compete with everything else on the page. */
.cl-btn {
  /* Typography matched to the nav "Inquire" pill (.site-header--static .nav-cta .btn),
     2026-08-25 per Alex — every CTA on the site reads as one family now. */
  display: inline-flex; align-items: center; gap: 0.55rem;
  font-family: var(--font-sans); font-size: var(--fs-label); letter-spacing: 0.16em;
  text-transform: uppercase; font-weight: 500;
  background: #fff; color: #141414; text-decoration: none;
  padding: 0.85rem 1.7rem; border-radius: 999px;
  box-shadow: 0 3px 10px rgba(20,20,20,0.10);
  transition: background 0.25s var(--ease), gap 0.25s var(--ease), box-shadow 0.25s var(--ease), transform 0.25s var(--ease);
}
.cl-btn:hover { background: #ececec; gap: 0.75rem; box-shadow: 0 5px 14px rgba(20,20,20,0.14); transform: translateY(-1px); }
.cl-btn[disabled] { opacity: 0.5; cursor: default; box-shadow: none; }
@media (prefers-reduced-motion: reduce) { .cl-btn:hover { transform: none; } }

/* contact.html's inquiry form, light-themed. Scoped under .cl-page so the
   shared .field/.contact-grid classes elsewhere are untouched — right now
   no other live page uses them, but this keeps it that way on purpose.
   The form's name/method/data-netlify/onsubmit/field names are untouched
   in the markup; only these colors changed. */
.cl-page .field label {
  color: rgba(255,255,255,0.5);
}
.cl-page .field input,
.cl-page .field select,
.cl-page .field textarea {
  color: #fff; background: transparent;
  border-bottom-color: rgba(255,255,255,0.2);
  font-size: 1rem; font-style: normal;
}
.cl-page .field input:focus,
.cl-page .field select:focus,
.cl-page .field textarea:focus { border-bottom-color: #fff; }
.cl-page .field select { background: var(--ink); }
.cl-page .field option { color: #fff; background: var(--ink); }
/* 2026-08-25, per Alex — the Send button was riding off the right edge of
   the screen on his phone (Firefox Focus, a different rendering engine than
   anything tested here). flex-wrap:wrap on the row *should* have dropped it
   to its own line once the row got tight, but rather than trust that on an
   engine/font combination this site hasn't been tested against, force the
   stack explicitly below phone width so it can't depend on that calculation
   going right. */
@media (max-width: 480px) {
  .cl-form-foot { flex-direction: column !important; align-items: flex-start !important; }
}

/* group-travel.html's Leisure/Business typology — two hairline-row lists
   instead of the old bordered/filled cards (already dropped site-wide
   before this pass; kept dropped here). */
.cl-trip { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem,5vw,4rem); }
.cl-trip-col { display: block; text-decoration: none; color: inherit; }
.cl-trip-list { list-style: none; margin: 0; padding: 0; border-top: 1px solid rgba(255,255,255,0.08); }
.cl-trip-list li {
  display: flex; justify-content: space-between; align-items: baseline; gap: 1rem;
  padding-block: 0.85rem; border-bottom: 1px solid rgba(255,255,255,0.08);
}
.cl-trip-name { font-family: var(--font-serif); font-size: 1.2rem; color: #fff; }
.cl-trip-desc { font-family: var(--font-serif); font-style: italic; font-size: 1.2rem; color: rgba(255,255,255,0.72); text-align: right; }
/* Hover color-shift removed 2026-08-27, per Alex — every bullet in both
   Leisure and Business lit up gold on hover since the whole column is one
   .cl-trip-col link, which read as a CTA repeated ten times over. The
   page already has one real CTA at the bottom ("Plan your trip."); these
   lists don't need to double as another. */
@media (max-width: 700px) {
  .cl-trip { grid-template-columns: 1fr; gap: 2.6rem; }
  .cl-trip-list li { flex-direction: column; gap: 0.15rem; }
  .cl-trip-desc { text-align: left; }
}

/* --- SPLIT — small label left, content right. videinfra's repeating module
   (Company's "Inspiring with design." pair, eCommerce's "Overview" row):
   used for property-management.html's Overview / Who We Work With / Track
   Record, 2026-08-24. --- */
.cl-split { display: grid; grid-template-columns: 1fr 2.2fr; gap: clamp(2rem,5vw,4rem); align-items: start; }
.cl-split__label {
  font-family: var(--font-sans); font-size: 0.95rem; color: rgba(255,255,255,0.5);
}
.cl-split__body { font-family: var(--font-serif); font-size: clamp(1.05rem,1.6vw,1.3rem); line-height: 1.6; color: #fff; }
.cl-split__body em { font-style: italic; color: #a9744a; }
.cl-split + .cl-split { margin-top: clamp(2.4rem,5vw,4rem); padding-top: clamp(2.4rem,5vw,4rem); border-top: 1px solid rgba(255,255,255,0.08); }
@media (max-width: 780px) {
  .cl-split { grid-template-columns: 1fr; gap: 1rem; }
}

/* --- LEGAL — privacy.html/terms.html, light, 2026-08-24. Long-form body
   copy: serif paragraphs, dark ink, no per-element inline styles needed. --- */
.cl-legal__note { font-family: var(--font-serif); font-style: italic; color: rgba(255,255,255,0.5); margin-bottom: 2.5rem; }
.cl-legal h2 { font-family: var(--font-serif); font-size: clamp(1.3rem,2.2vw,1.6rem); margin: 2.5rem 0 1rem; color: #fff; }
.cl-legal p { font-family: var(--font-serif); font-size: 1.05rem; line-height: 1.65; color: rgba(255,255,255,0.72); margin-bottom: 1.2rem; }
.cl-legal a { color: #fff; border-bottom: 1px solid #fff; text-decoration: none; }

/* --- 404 / thanks — light, 2026-08-24. Reuses .cl-h1/.cl-lede/.cl-btn. --- */
.cl-statement { min-height: 62vh; display: flex; flex-direction: column; justify-content: center; }

/* --- SCROLL-SYNCED LABEL BAR — index.html only, 2026-08-24. Fixed strip,
   hidden below the viewport until the hero scrolls out, then a quiet
   hairline-topped bar with a mono label that swaps as each section takes
   over — see the IntersectionObserver in index.html. Sits under the
   header's z-index (100) so it never fights the nav on short screens. */
.cl-scrollbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 90;
  display: flex; align-items: center; justify-content: space-between;
  padding: 1rem var(--gutter);
  background: rgba(0,0,0,0.94);
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  border-top: 1px solid rgba(255,255,255,0.08);
  transform: translateY(100%);
  transition: transform 0.45s var(--ease);
}
.cl-scrollbar.is-visible { transform: translateY(0); }
.cl-scrollbar__label {
  font-family: "JetBrains Mono", "SF Mono", Menlo, Consolas, monospace;
  font-size: 0.78rem; letter-spacing: 0.14em; text-transform: uppercase;
  color: #fff;
}
.cl-scrollbar__arrow { color: rgba(255,255,255,0.4); font-size: 0.9rem; }
@media (prefers-reduced-motion: reduce) { .cl-scrollbar { transition: none; } }

/* --- PINNED PHOTO ROW — "What We Do" on index.html, 2026-08-24. Native
   position:sticky (not a scroll-jacked/transform pin) so it can't fight
   Lenis — Lenis smooths the real document scroll here rather than
   transforming a wrapper, so sticky positioning tracks normally. Rows get
   extra padding (.cl-rows--pinned) so there's enough scroll distance for
   the sticky image to actually hold in place before the section ends. --- */
.cl-pin-row { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(2rem,5vw,4rem); align-items: start; }
.cl-pin-row__sticky { position: sticky; top: 6.5rem; align-self: start; }
.cl-pin-row__media { position: relative; width: 100%; height: 62vh; min-height: 320px; max-height: 560px; overflow: hidden; background: #1a1a1a; }
.cl-pin-row__media img {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover;
  opacity: 0; transition: opacity 0.7s var(--ease);
}
.cl-pin-row__media img.is-active { opacity: 1; }
.cl-rows--pinned .cl-row { padding-block: clamp(3.2rem,7vw,5.5rem); }
@media (max-width: 860px) {
  .cl-pin-row { grid-template-columns: 1fr; }
  .cl-pin-row__sticky { position: static; margin-bottom: 1rem; }
  .cl-pin-row__media { height: 46vh; min-height: 240px; }
  .cl-pin-row__media img { opacity: 1 !important; position: relative; }
  .cl-pin-row__media img:not(:first-child) { display: none; }
  .cl-rows--pinned .cl-row { padding-block: clamp(1.8rem,3.5vw,2.8rem); }
}
@media (prefers-reduced-motion: reduce) { .cl-pin-row__media img { transition: none; } }
