/* =============================================================================
   Villa Laura — styles.css
   Shared design system for every page. Palette lives here as CSS custom
   properties; no hard-coded colour exists outside :root. Adapts the Rolls-Royce
   posture — quiet, cinematic, near-monochrome — to a single luxury residence.
   Typeface: Jost only (200 / 300 / 400). No serif anywhere.
   ============================================================================= */

:root {
  /* ---- Palette (image-led, near-monochrome) -------------------------------
     Provisional neutral base from CLAUDE.md. --accent is sampled from the
     photography per the constitution: a warm sand-bronze pulled from the
     evening light on the villa's stone (hero lamplight, terrace + aerial sand).
     One accent only — used sparingly for rules, small marks and hovers. */
  --ink:        #16140F;   /* near-black — primary text & solid nav   */
  --ink-soft:   #211E18;   /* ~5% lighter than ink — Explore Further sits just above the footer */
  --bone:       #F6F3EE;   /* off-white  — primary background & text-on-image */
  --mute:       #8C857A;   /* neutral mid — secondary text, hairlines */
  --accent:     #A98B63;   /* PROVISIONAL — sampled from the imagery  */

  /* RGB channels so scrims/shadows/marks derive from the same palette */
  --ink-rgb:    22, 20, 15;
  --scrim-rgb:  12, 11, 8;   /* neutral near-black for image scrims    */
  --accent-rgb: 169, 139, 99;
  --bone-rgb:   246, 243, 238;

  --hairline:   rgba(var(--ink-rgb), 0.14);
  --hairline-light: rgba(var(--bone-rgb), 0.18);
  --accent-soft: rgba(var(--accent-rgb), 0.55);

  /* ---- Type --------------------------------------------------------------- */
  --font: 'Jost', system-ui, -apple-system, 'Segoe UI', sans-serif;
  /* Body size — eyebrows, sub-heads, support lines and CTAs all share this size,
     set apart from body by caps + tracking, never by size. */
  --t-body: clamp(0.95rem, 0.9rem + 0.25vw, 1.05rem);
  --t-h1:   clamp(2rem, 9.5vw, 6.5rem);             /* hero only — sized to fit one line */
  --t-h2:   clamp(2rem, 1.2rem + 3.6vw, 4.25rem);   /* section headlines */
  --t-menu: clamp(1.55rem, 0.9rem + 3vw, 2.85rem);  /* overlay menu links */

  /* tracking */
  --tr-h1: 0.14em;
  --tr-h2: 0.13em;
  --tr-eyebrow: 0.28em;
  --tr-support: 0.2em;
  --tr-link: 0.2em;

  /* ---- Motion ------------------------------------------------------------- */
  --ease: cubic-bezier(0.22, 0.61, 0.36, 1);   /* long, gentle ease-out */
  --slow: 0.8s;
  --slower: 1.2s;

  /* ---- Layout ------------------------------------------------------------- */
  --pad-x: clamp(1.15rem, 3.2vw, 2.6rem);
  --section-y: clamp(4.5rem, 9vw, 8rem);   /* one vertical rhythm for every content section */

  /* ---- Clean twilight gradient field — for the floating moments + facts block */
  --field-twilight: linear-gradient(165deg, #1b2740 0%, #1a1d2b 46%, var(--ink) 100%);
  /* ---- Soft sky field — the inset feature images float on this */
  --field-sky-top: #ccd7e1;
  --field-sky: linear-gradient(180deg, var(--field-sky-top) 0%, #e7e6dd 52%, var(--bone) 100%);
}

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  /* dark canvas behind the page: the overscroll / rubber-band area reads black
     (no white strip above the hero) and matches the ink footer at the bottom */
  background: var(--ink);
}

body {
  margin: 0;
  background: var(--bone);
  color: var(--ink);
  font-family: var(--font);
  font-weight: 400;
  font-size: var(--t-body);
  line-height: 1.7;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { display: block; max-width: 100%; height: auto; }
a { color: inherit; text-decoration: none; }
h1, h2, h3, p, figure { margin: 0; }
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 4px;
}

/* Skip link */
.skip-link {
  /* fixed (not absolute) so the iOS rubber-band over-scroll can't drag it into view */
  position: fixed;
  left: 0; top: 0;
  transform: translateY(-130%);
  z-index: 300;
  margin: 0.6rem;
  padding: 0.7rem 1.1rem;
  background: var(--ink);
  color: var(--bone);
  letter-spacing: var(--tr-link);
  text-transform: uppercase;
  font-size: 0.8rem;
  transition: transform var(--slow) var(--ease);
}
.skip-link:focus { transform: none; }

/* =============================================================================
   Shared type utilities
   ============================================================================= */
.eyebrow {
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: var(--tr-eyebrow);
  font-size: 16px;
  line-height: 1.4;
}

.support {
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: var(--tr-support);
  font-size: 22px;
  line-height: 1.5;
}
/* Home panel sublines read as warm sentences, not letter-spaced taglines. */
.panel .support {
  text-transform: none;
  letter-spacing: 0.005em;
  font-weight: 300;
  font-size: clamp(1.05rem, 0.95rem + 0.55vw, 1.35rem);
  line-height: 1.55;
  max-width: 33rem;
  margin-inline: auto;
}

/* Text-only CTA — a quiet underlined link; colour inherits (ink on light,
   off-white over images), so it reads on any background */
.btn-quiet {
  display: inline-block;
  align-self: center;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: var(--tr-link);
  font-size: 16px;
  color: inherit;
  /* pure glass — heavy blur, no keyline; lightens slightly on hover */
  padding: 5px 15px;
  border-radius: 100px;
  background: rgba(var(--bone-rgb), 0.1);
  -webkit-backdrop-filter: blur(18px) saturate(125%);
  backdrop-filter: blur(18px) saturate(125%);
  cursor: pointer;
  transition: background var(--slow) var(--ease), transform 0.24s var(--ease);
}
.btn-quiet:hover,
.btn-quiet:focus-visible {
  background: rgba(var(--bone-rgb), 0.2);
}
/* On flat light interludes (off the dark band) the glass pill is bone-on-bone and
   vanishes — render the CTA as a quiet outlined pill so it clearly reads as a button.
   Dark-band and on-band-dark interludes keep the light glass pill: they have contrast. */
main > .dp-interlude:not(.on-band-dark) .btn-quiet {
  background: transparent;
  border: 1px solid rgba(var(--ink-rgb), 0.34);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  transition: background var(--slow) var(--ease), border-color var(--slow) var(--ease), transform 0.24s var(--ease);
}
main > .dp-interlude:not(.on-band-dark) .btn-quiet:hover,
main > .dp-interlude:not(.on-band-dark) .btn-quiet:focus-visible {
  background: rgba(var(--ink-rgb), 0.06);
  border-color: rgba(var(--ink-rgb), 0.62);
}

/* =============================================================================
   Header / sticky resizing nav
   Transparent over the hero; settles to solid ink, slimmer, once scrolled.
   ============================================================================= */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: 1rem;
  padding: clamp(1.15rem, 2.4vw, 1.9rem) var(--pad-x);
  color: var(--bone);
  transition: background var(--slow) var(--ease),
              padding var(--slow) var(--ease),
              color var(--slow) var(--ease);
}
/* top scrim so nav stays legible over the image; fades when solid */
.site-header::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(180deg, rgba(var(--scrim-rgb), 0.5), rgba(var(--scrim-rgb), 0));
  transition: opacity var(--slow) var(--ease);
  pointer-events: none;
}
.site-header.is-solid {
  background: rgba(var(--ink-rgb), 0.6);
  -webkit-backdrop-filter: blur(16px) saturate(120%);
  backdrop-filter: blur(16px) saturate(120%);
  padding-top: clamp(0.75rem, 1.4vw, 1.1rem);
  padding-bottom: clamp(0.75rem, 1.4vw, 1.1rem);
}
.site-header.is-solid::before { opacity: 0; }

.nav-menu  { justify-self: start; }
.nav-cta   { justify-self: end; }

.nav-link {
  font-weight: 300;
  text-transform: uppercase;
  letter-spacing: var(--tr-link);
  font-size: 18px;
  padding-bottom: 0.25rem;
  border-bottom: 1px solid transparent;
  transition: border-color var(--slow) var(--ease);
  white-space: nowrap;
}
.nav-link:hover,
.nav-link:focus-visible { border-bottom-color: var(--accent); }

/* centre wordmark — "settles gently into place" when the bar shrinks */
.wordmark {
  grid-column: 2;
  justify-self: center;
  font-weight: 300;
  text-transform: uppercase;
  letter-spacing: 0.34em;
  font-size: clamp(1rem, 0.7rem + 1.1vw, 1.4rem);
  white-space: nowrap;
  /* offset the letter-spacing so the wordmark stays optically centred */
  padding-left: 0.34em;
  transition: font-size var(--slow) var(--ease),
              letter-spacing var(--slow) var(--ease);
}
.site-header.is-solid .wordmark {
  font-size: clamp(0.95rem, 0.8rem + 0.7vw, 1.12rem);
  letter-spacing: 0.3em;
  padding-left: 0.3em;
}

/* =============================================================================
   Panels — five full-bleed image + headline views
   ============================================================================= */
.panel {
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  align-content: center;     /* copy centred vertically in the panel */
  justify-items: center;
  overflow: clip;
  isolation: isolate;
  padding: 7rem var(--pad-x) clamp(5.5rem, 15vh, 10rem);
}

.panel__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: -2;
  /* zoom via the individual `scale` property so JS parallax can drive
     `translate` independently without the two transforms fighting */
  scale: 1.18;
  transition: scale var(--slower) var(--ease);
  will-change: transform;
}

/* Per-image focal points for the cover crop */
.panel--hero      .panel__img { object-position: center 42%; }
.panel--detail    .panel__img { object-position: center center; }
.panel--world     .panel__img { object-position: 20% center; }
.panel--cabos     .panel__img { object-position: 58% center; }

/* Scrim: a slight, even darkening across the WHOLE panel so the centred copy
   reads on any frame, with a touch more at the top (nav) and bottom to ground
   it. A flat wash + soft edge gradient — never a box. */
.panel__scrim {
  position: absolute;
  inset: 0;
  z-index: -1;
  background:
    linear-gradient(180deg,
      rgba(var(--scrim-rgb), 0.34) 0%,
      rgba(var(--scrim-rgb), 0) 22%,
      rgba(var(--scrim-rgb), 0) 76%,
      rgba(var(--scrim-rgb), 0.5) 100%),
    rgba(var(--scrim-rgb), 0.34);
}

.panel__content {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(1rem, 2.2vw, 1.6rem);
  max-width: min(92vw, 48rem);
  text-align: center;
  color: var(--bone);
}

.panel__title {
  font-weight: 200;
  text-transform: uppercase;
  line-height: 1.02;
}
h1.panel__title { font-size: var(--t-h1); letter-spacing: var(--tr-h1); white-space: nowrap; }
h2.panel__title { font-size: var(--t-h2); letter-spacing: var(--tr-h2); }

/* the hero wordmark runs wide on one line — give it room and let the halo follow */
.panel--hero .panel__content { max-width: min(94vw, 58rem); }

/* hero eyebrow/support a touch brighter against the busy evening frame */
.panel--hero .eyebrow,
.panel--hero .support { opacity: 0.95; }

/* scroll cue beneath the hero copy */
.scroll-cue {
  position: absolute;
  left: 50%;
  bottom: clamp(1.6rem, 4vh, 3rem);
  transform: translateX(-50%);
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.7rem;
  color: var(--bone);
}
.scroll-cue span {
  font-weight: 300;
  text-transform: uppercase;
  letter-spacing: 0.3em;
  font-size: 0.66rem;
  opacity: 0.8;
  padding-left: 0.3em;
}
.scroll-cue i {
  width: 1px;
  height: 46px;
  background: linear-gradient(180deg, rgba(var(--bone-rgb), 0.7), rgba(var(--bone-rgb), 0));
  transform-origin: top;
  animation: cue 2.6s var(--ease) infinite;
}
@keyframes cue {
  0%   { transform: scaleY(0.2); opacity: 0; }
  35%  { opacity: 1; }
  100% { transform: scaleY(1); opacity: 0; }
}

/* =============================================================================
   Scroll reveal — fade-and-rise (only applied once .js is present)
   ============================================================================= */
.js .panel__content > * {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
}
.js .panel.is-visible .panel__content > * { opacity: 1; transform: none; }
.panel.is-visible .panel__img { scale: 1.1; }  /* settles to a slight zoom — leaves headroom for parallax drift */

/* Discover hero — a slow Ken Burns drives `scale` for depth the moment you land;
   JS drives `translate` for the scroll drift. Separate properties, so the zoom
   and the parallax layer cleanly. The (filling) animation overrides the reveal
   scale above, keeping ~8%+ headroom for the translate at all times. */
@media (prefers-reduced-motion: no-preference) {
  .hero-parallax { animation: heroLand 20s var(--ease) forwards; }
}
@keyframes heroLand {
  from { scale: 1.16; }
  to   { scale: 1.26; }
}

/* gentle stagger */
.panel.is-visible .panel__content > *:nth-child(1) { transition-delay: 0.05s; }
.panel.is-visible .panel__content > *:nth-child(2) { transition-delay: 0.15s; }
.panel.is-visible .panel__content > *:nth-child(3) { transition-delay: 0.25s; }
.panel.is-visible .panel__content > *:nth-child(4) { transition-delay: 0.35s; }

.js .scroll-cue { opacity: 0; transition: opacity var(--slower) var(--ease); }
.js .panel--hero.is-visible .scroll-cue { opacity: 1; transition-delay: 0.8s; }

/* =============================================================================
   Footer
   ============================================================================= */
.site-footer {
  background: var(--ink);
  color: var(--bone);
  padding: clamp(3.5rem, 7vw, 6rem) var(--pad-x) 2.5rem;
  /* iOS paints the bottom rubber-band over-scroll with the body (bone) background,
     showing a white strip below the footer. This ink box-shadow sits only below the
     footer (offset == spread, so no upward bleed) and keeps that area dark. */
  box-shadow: 0 100vh 0 100vh var(--ink);
}
.footer-inner { max-width: 72rem; margin: 0 auto; }

.footer-cols {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 10.5rem), 1fr));
  gap: clamp(1.6rem, 4vw, 3.4rem);
}
.footer-col h2 {
  font-weight: 300;
  text-transform: uppercase;
  letter-spacing: var(--tr-eyebrow);
  font-size: var(--t-body);
  color: var(--mute);
  margin-bottom: 1.2rem;
}
.footer-col a {
  display: inline-block;
  padding: 0.4rem 0;
  color: rgba(var(--bone-rgb), 0.82);
  letter-spacing: 0.04em;
  border-bottom: 1px solid transparent;
  transition: color var(--slow) var(--ease), border-color var(--slow) var(--ease);
}
.footer-col a:hover,
.footer-col a:focus-visible { color: var(--bone); border-bottom-color: var(--accent); }

.footer-base {
  display: grid;
  grid-template-columns: 1fr auto;
  column-gap: 1.5rem;
  row-gap: 0.7rem;
  align-items: baseline;
  margin-top: clamp(2.5rem, 6vw, 4.5rem);
  padding-top: 2rem;
  border-top: 1px solid var(--hairline-light);
}
/* Row 1: address line (left) + private-sale statement (right), matched styling. */
.footer-line {
  grid-column: 1; grid-row: 1; justify-self: start;
  color: var(--mute);
  font-size: 0.82rem;
  letter-spacing: 0.05em;
}
.footer-statement {
  grid-column: 2; grid-row: 1; justify-self: end; text-align: right;
  color: var(--mute);
  font-size: 0.82rem;
  letter-spacing: 0.05em;
}
/* Row 2: legal (left) + language switch (right). */
.footer-base .footer-legal { grid-column: 1; grid-row: 2; justify-self: start; margin-top: 0; }
.footer-base .lang-switch { grid-column: 2; grid-row: 2; justify-self: end; }

/* Language switch */
.lang-switch {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
}
.lang-switch a, .lang-switch span { color: var(--mute); transition: color var(--slow) var(--ease); }
.lang-switch a:hover, .lang-switch a:focus-visible { color: var(--bone); }
.lang-switch [aria-current="true"] { color: var(--bone); }
.lang-switch .sep { opacity: 0.5; }

/* =============================================================================
   Menu overlay
   ============================================================================= */
.menu-overlay {
  position: fixed;
  inset: 0;
  z-index: 200;
  background: rgba(var(--ink-rgb), 0.6);
  -webkit-backdrop-filter: blur(28px) saturate(115%);
  backdrop-filter: blur(28px) saturate(115%);
  color: var(--bone);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: clamp(0.4rem, 1.4vh, 1rem);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--slow) var(--ease), visibility var(--slow) var(--ease);
}
.menu-overlay.is-open { opacity: 1; visibility: visible; }

/* Glass fallbacks: stay legible without backdrop-filter, and honour a
   reduced-transparency preference. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .menu-overlay { background: rgba(var(--ink-rgb), 0.95); }
  .site-header.is-solid { background: var(--ink); }
  .btn-quiet { background: rgba(var(--ink-rgb), 0.4); }   /* readable pill without blur */
}
@media (prefers-reduced-transparency: reduce) {
  .menu-overlay,
  .site-header.is-solid,
  .btn-quiet {
    background: var(--ink);
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  .btn-quiet { background: rgba(var(--ink-rgb), 0.55); }
}

.menu-overlay nav {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(0.4rem, 1.4vh, 1rem);
}
.menu-overlay nav a {
  font-weight: 200;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  font-size: var(--t-menu);
  line-height: 1.25;
  color: rgba(var(--bone-rgb), 0.88);
  transition: color var(--slow) var(--ease);
}
.menu-overlay nav a:hover,
.menu-overlay nav a:focus-visible { color: var(--accent); }

.menu-close {
  position: absolute;
  top: clamp(1.1rem, 2.4vw, 1.9rem);
  right: var(--pad-x);
  text-transform: uppercase;
  letter-spacing: var(--tr-link);
  font-size: 0.8rem;
  font-weight: 300;
  padding-bottom: 0.25rem;
  border-bottom: 1px solid transparent;
  transition: border-color var(--slow) var(--ease);
}
.menu-close:hover,
.menu-close:focus-visible { border-bottom-color: var(--accent); }

.menu-overlay .lang-switch {
  margin-top: clamp(1.6rem, 4vh, 3rem);
}

/* =============================================================================
   Responsive
   ============================================================================= */
@media (max-width: 640px) {
  .footer-cols { grid-template-columns: 1fr; gap: 2.2rem; }
  .footer-base { grid-template-columns: 1fr; row-gap: 0.55rem; }
  .footer-line { grid-row: 1; }
  .footer-statement { grid-column: 1; grid-row: 2; justify-self: start; text-align: left; }
  .footer-base .footer-legal { grid-row: 3; }
  .footer-base .lang-switch { grid-column: 1; grid-row: 4; justify-self: start; }
  /* tighten the bar so MENU · wordmark · Request all sit on one line */
  .site-header { gap: 0.5rem; padding-left: 1rem; padding-right: 1rem; }
  .nav-link { font-size: 0.66rem; letter-spacing: 0.13em; }
  .wordmark { font-size: 0.98rem; letter-spacing: 0.16em; padding-left: 0.16em; }
}

/* "Visit" is short enough to keep on every screen size */

/* =============================================================================
   Reduced motion — honour the user's preference
   ============================================================================= */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
  }
  .panel__img { scale: 1 !important; translate: none !important; }
  .js .panel__content > * { opacity: 1 !important; transform: none !important; }
  .js .scroll-cue { opacity: 1 !important; }
  .scroll-cue i { animation: none; }
}

/* =============================================================================
   Content pages (Discover) — built on the same system as the home panels
   ============================================================================= */

/* Generic scroll reveal for content sections (the home panels have their own) */
.js .reveal { opacity: 0; transform: translateY(28px); transition: opacity 0.9s var(--ease), transform 0.9s var(--ease); }
.js .reveal.is-visible { opacity: 1; transform: none; }

/* Body copy — sentence case, comfortable measure */
.dp-body { font-weight: 400; font-size: clamp(1rem, 0.97rem + 0.3vw, 1.12rem); line-height: 1.4; }
.panel__content .dp-body { max-width: 34rem; color: var(--bone); }  /* over-image feature body */

/* On-bone section headline (splits + interludes) */
.dp-title {
  font-weight: 200;
  text-transform: uppercase;
  letter-spacing: var(--tr-h2);
  line-height: 1.08;
  font-size: clamp(1.8rem, 1.15rem + 2.6vw, 3.25rem);
}

/* Content features reuse .panel but sit a touch under full-height (not the hero) */
.panel--feature { min-height: 86svh; }
.panel--hero-sub { min-height: 75vh; min-height: 75svh; }   /* sub-page heroes: 75% of the viewport */

/* (An earlier .dp-split prototype lived here — removed; the content-page .dp-split
   further down is the one in use, with .dp-split__inner as the grid.) */

/* ---- Interlude: centred text on the bone field ------------------------ */
.dp-interlude { padding: var(--section-y) var(--pad-x); }
.dp-interlude__inner {
  max-width: 46rem;
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 30px;
}
.dp-interlude .dp-body { max-width: 40rem; }

/* "One of Their Own" — a standout statement: generous space + a larger headline */
.dp-statement { padding-block: clamp(7rem, 14vw, 13rem); }
.dp-statement .dp-interlude__inner { max-width: 54rem; }
.dp-statement .dp-title { font-size: clamp(2.4rem, 1.5rem + 3.6vw, 4.5rem); text-wrap: balance; }
.dp-statement .dp-body { font-size: clamp(1.1rem, 1rem + 0.7vw, 1.45rem); max-width: 52rem; margin-inline: auto; text-wrap: balance; }

/* ---- At a Glance: the facts, on ink ----------------------------------- */
.dp-glance { background: transparent; color: var(--bone); padding-bottom: calc(var(--section-y) * 2); }   /* match the space above (the video adds its bottom gap too) */   /* white text on the band */
.dp-glance .eyebrow { color: var(--bone); }
.dp-price { font-weight: 200; font-size: clamp(2.2rem, 1.4rem + 3.2vw, 3.75rem); letter-spacing: 0.04em; line-height: 1.1; }
.dp-price span { display: block; font-size: var(--t-body); letter-spacing: var(--tr-support); text-transform: uppercase; font-weight: 300; margin-top: 1rem; color: rgba(var(--bone-rgb), 0.82); }
.dp-specs { font-weight: 300; text-transform: uppercase; letter-spacing: 0.14em; font-size: var(--t-body); line-height: 2.1; color: rgba(var(--bone-rgb), 0.85); }
.dp-note { color: var(--mute); font-size: 0.88rem; letter-spacing: 0.04em; }
.dp-note a { border-bottom: 1px solid var(--accent-soft); }
.dp-note a:hover { border-bottom-color: var(--bone); }

/* ---- Explore Further: cross-link cards -------------------------------- */
/* Explore Further — rides the same dark ground as the footer, reading as its top. */
.dp-explore { background: var(--ink-soft); color: var(--bone); padding: clamp(4.5rem, 10vw, 8rem) var(--pad-x) clamp(2.5rem, 5vw, 3.5rem); text-align: center; }
.dp-explore .dp-title { color: var(--bone); }
.dp-explore__head { margin: 0 auto clamp(2.5rem, 5vw, 4rem); }
.dp-explore__grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(1.6rem, 3vw, 2.6rem); max-width: 78rem; margin-inline: auto; }
.dp-explore__grid--two { grid-template-columns: repeat(2, 1fr); max-width: 52rem; }   /* the details page links to just the two world pages */
.dp-explore__card { display: block; color: inherit; text-align: left; }
.dp-explore__media { aspect-ratio: 3 / 2; overflow: hidden; margin-bottom: 1.25rem; }
.dp-explore__media img { width: 100%; height: 100%; object-fit: cover; display: block; scale: 1; transition: scale 1.3s var(--ease); }
.dp-explore__card:hover .dp-explore__media img,
.dp-explore__card:focus-visible .dp-explore__media img { scale: 1.05; }
.dp-explore__title { color: var(--bone); font-weight: 200; text-transform: uppercase; letter-spacing: 0.12em; font-size: clamp(1.15rem, 1rem + 0.6vw, 1.45rem); }
.dp-explore__line { color: rgba(var(--bone-rgb), 0.55); text-transform: uppercase; letter-spacing: 0.2em; font-size: 0.78rem; margin-top: 0.5rem; }
.dp-explore__card:hover .dp-explore__title { color: var(--accent); transition: color var(--slow) var(--ease); }
@media (max-width: 820px) { .dp-explore__grid { grid-template-columns: 1fr; max-width: 30rem; } }

@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1 !important; transform: none !important; }
  .dp-explore__media img { transition: none; }
}

/* The carousel section sits on its own solid field */
.spaces { background: transparent; }   /* sits on the gradient band */

/* =============================================================================
   Panel scroll — one panel per gesture. On a mouse/trackpad, main.js glides to the
   next/previous panel per wheel notch or arrow key (one gesture = one panel) — no
   snap-back under 50%, no jump over it. On touch we keep a gentle native proximity
   snap rather than hijacking the finger.
   ============================================================================= */
@media (hover: none) and (pointer: coarse) {
  html:has(.stack) { scroll-snap-type: y proximity; }
  .stack .panel, html:has(.stack) .site-footer { scroll-snap-align: start; }
}

/* =============================================================================
   One of Their Own — ONE continuous field (never two sections).
   A pale-blue → peach gradient (Gradient 1 → Gradient 2) fills the top and carries
   the heading and the four floating "moments". At the foot, the full Cabo image
   fades up out of the peach and holds the glass viewing card. The montage and the
   invite are a single piece: the gradient melts into the image, the last montage
   image overlapping the seam.
   ============================================================================= */
.field {
  position: relative;
  isolation: isolate;
  overflow: clip;
  background: linear-gradient(180deg, #e5eaf5 0%, #fed9c6 50%, #fed9c6 100%);
}
/* The full image — anchored at the foot of the field; its top fades up into the peach. */
.field__photo {
  position: absolute;
  left: 0; right: 0; bottom: -6%;   /* slight overflow so an upward drift never reveals an edge */
  height: clamp(40rem, 70vh, 60rem);
  z-index: 0;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 30%);
          mask-image: linear-gradient(180deg, transparent 0, #000 30%);   /* melt the photo's top into the gradient */
  will-change: transform;
}
.field__photo img {
  width: 100%; height: 100%;
  object-fit: cover; object-position: center 80%;   /* the rock formations + deep-blue sea */
  display: block;
}
/* Provenance — the section's title, over the gradient. */
.field__intro {
  position: relative;
  z-index: 3;
  max-width: 54rem;
  margin-inline: auto;
  text-align: center;
  padding: clamp(3.5rem, 7vw, 6rem) var(--pad-x) clamp(0.5rem, 1.5vw, 1rem);
}
.field__intro .dp-body { max-width: 52rem; margin: 30px auto 0; text-wrap: balance; }
/* The floating montage — four scattered moments drifting over the gradient. */
.float__stage {
  position: relative;
  z-index: 2;
  max-width: 80rem;
  margin-inline: auto;
  height: clamp(56rem, 104vw, 86rem);   /* tall canvas — the moments breathe instead of crushing together */
}
.float__item {
  position: absolute;
  overflow: hidden;
  box-shadow: 0 26px 60px rgba(var(--scrim-rgb), 0.22);   /* soft lift on the light field */
  will-change: transform;
}
.float__item img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Opened up: a alone at the top; b (right) and c (left) sit below it with gradient
   between them; d anchors low over the photo's fade. Only light corner overlaps. */
.float__item--a { width: 82%; aspect-ratio: 5 / 3; left: 5%;   top: 0%;    z-index: 1; }
.float__item--b { width: 39%; aspect-ratio: 4 / 5; right: 3%;  top: 40%;   z-index: 2; }
.float__item--c { width: 39%; aspect-ratio: 1 / 1; left: 3%;   top: 54%;   z-index: 3; }
.float__item--d { width: 41%; aspect-ratio: 3 / 2; left: 30%;  top: 78%;   z-index: 4; }   /* overlaps the photo's fade — joins gradient to image */
/* Request a Viewing — the glass card, over the full image at the foot. */
.field__invite {
  position: relative;
  z-index: 3;
  display: grid;
  place-items: center;
  min-height: clamp(26rem, 40vw, 34rem);
  padding: clamp(2rem, 4vw, 3rem) var(--pad-x) clamp(4rem, 8vw, 6.5rem);
}

/* =============================================================================
   An Invitation — the closing scene on the content pages (Details · Del Mar ·
   Cabos): a full-bleed image with a centred smoked-glass card. The image drifts
   and the card slides up on scroll, echoing Discover's closing field.
   ============================================================================= */
.invite-hero {
  position: relative;
  overflow: clip;
  isolation: isolate;
  display: grid;
  place-items: center;
  padding: clamp(4.5rem, 9vw, 8rem) var(--pad-x);
  min-height: clamp(34rem, 56vw, 50rem);
}
.invite-hero__bg {
  position: absolute;
  left: 0; right: 0; top: -12%; bottom: -12%;   /* oversized so the drift never shows an edge */
  z-index: -2;
  will-change: transform;
}
.invite-hero__bg img { width: 100%; height: 100%; object-fit: cover; object-position: center; display: block; }
.invite-hero::after {                            /* a soft scrim grounds the card and deepens the scene */
  content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(180deg, rgba(var(--scrim-rgb), 0.20) 0%, rgba(var(--scrim-rgb), 0.42) 100%);
}
.invite-hero .eyebrow { color: rgba(var(--bone-rgb), 0.82); }
.invite-hero .btn-quiet {
  background: rgba(var(--bone-rgb), 0.16);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
.invite-hero .btn-quiet:hover,
.invite-hero .btn-quiet:focus-visible { background: rgba(var(--bone-rgb), 0.28); }
.invite-hero__box {
  width: min(56rem, 100%);     /* hugs its content — no dead space */
  display: grid;
  place-items: center;
  padding: clamp(2.8rem, 6vw, 4.5rem) clamp(2rem, 5vw, 4rem);
  background: rgba(var(--scrim-rgb), 0.30);     /* smoked glass over the image */
  -webkit-backdrop-filter: blur(22px) saturate(125%);
  backdrop-filter: blur(22px) saturate(125%);
  will-change: transform;
}
.invite-hero__inner {
  display: flex; flex-direction: column; align-items: center; text-align: center;
  gap: 30px;
  max-width: 34rem;
  color: var(--bone);
}
.invite-hero__title {
  font-weight: 200; text-transform: uppercase; letter-spacing: var(--tr-h2);
  font-size: clamp(1.7rem, 1.2rem + 1.8vw, 2.6rem); line-height: 1.1;
}
.invite-hero__body {
  font-weight: 400; font-size: clamp(1.05rem, 1rem + 0.4vw, 1.25rem);
  line-height: 1.4; color: rgba(var(--bone-rgb), 0.9); text-wrap: balance;
}
/* Details closer — the gradient band melts into this image. Its top row is #4b88b2,
   the band's foot, and the section carries the same blue, so the seam is invisible. The
   scene anchors to the bottom; the top scrim is lifted so the sky reads as the gradient
   continuing. Reuses the .invite-hero parallax (image drifts, card slides) untouched. */
.invite-hero--closer {
  background: #4b88b2;                                  /* same as the band's foot — seamless seam */
  min-height: clamp(40rem, 92vh, 62rem);
}
.invite-hero--closer .invite-hero__bg img { object-position: center bottom; }  /* anchor the scene low */
/* Lift the scrim off the top half so the #4b88b2 sky stays true; keep a faint wash low. */
.invite-hero--closer::after {
  background: linear-gradient(180deg, rgba(var(--scrim-rgb), 0) 0%, rgba(var(--scrim-rgb), 0) 50%, rgba(var(--scrim-rgb), 0.30) 100%);
}
/* A short cap of the exact band colour over the very top guarantees a banding-free seam. */
.invite-hero--closer::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 14%;
  z-index: -1; pointer-events: none;
  background: linear-gradient(180deg, #4b88b2 0%, rgba(75, 136, 178, 0) 100%);
}
/* Los Cabos foot — a tinted band (#e5eaf5 → #bacce7) runs behind Access, The Quiet Side and
   Peace of Mind, then the closing image (its top row is #bacce7) anchors to the foot. Same
   machinery as the Details band + closer above: the band's foot, the section, the image top
   and the cap are all #bacce7, so the gradient melts straight into the image. */
.band-coast-foot { background: linear-gradient(180deg, #e5eaf5 0%, #bacce7 100%); }
.band-coast-foot .dp-split { background: transparent; }
.invite-hero--closer-cabos { background: #bacce7; }
.invite-hero--closer-cabos::before {
  background: linear-gradient(180deg, #bacce7 0%, rgba(186, 204, 231, 0) 100%);
}
/* Villas Del Mar foot — a #212f4a → #315393 band runs behind the closing wellness sections, then the
   closing image (its top row is #315393) anchors to the foot. Same machinery as the Details band. */
.band-delmar-foot { background: linear-gradient(180deg, #212f4a 0%, #315393 100%); }
.band-delmar-foot .dp-split { background: transparent; }
.band-delmar-foot .dp-title { color: var(--bone); }
.band-delmar-foot .dp-body { color: rgba(var(--bone-rgb), 0.86); }
.invite-hero--closer-delmar { background: #315393; }
.invite-hero--closer-delmar::before { background: linear-gradient(180deg, #315393 0%, rgba(49, 83, 147, 0) 100%); }
/* The card frosts the image; a nested backdrop-filter renders muddy, so the pill reads via tint alone. */
.field .btn-quiet {
  background: rgba(var(--bone-rgb), 0.16);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
.field .btn-quiet:hover,
.field .btn-quiet:focus-visible { background: rgba(var(--bone-rgb), 0.28); }
@media (max-width: 760px) {
  .field__intro { padding-bottom: clamp(1.5rem, 5vw, 2.5rem); }
  .float__stage { height: auto; display: flex; flex-direction: column; gap: 1.4rem; }
  .float__item { position: relative; z-index: 2; width: 100%; aspect-ratio: 3 / 2; box-shadow: 0 16px 40px rgba(var(--scrim-rgb), 0.28); }
  .float__item--b { aspect-ratio: 4 / 5; }
  .float__item--c { aspect-ratio: 1 / 1; }
  .float__item img { transform: none !important; }
  .field__photo { height: 34rem; }
  .invite-hero__box { width: 100%; padding: clamp(2.5rem, 9vw, 3.5rem) 1.5rem; }
}

/* =============================================================================
   Feature "show" — inset image floating on a soft field; text centred below.
   No text over the image (the RR pattern).
   ============================================================================= */
.dp-show {
  background: var(--field-sky);
  padding: var(--section-y) var(--pad-x);
}
.dp-show__media {
  max-width: 66rem;
  margin: 0 auto;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  box-shadow: 0 40px 90px rgba(var(--scrim-rgb), 0.22);
}
/* The captioned dining feature video widens to match the split module (78rem) below it. */
.dp-show__media--caption { max-width: 78rem; }
/* Subtle photo credit anchored to a split image's lower corner. */
.dp-split__media { position: relative; }
.img-credit {
  position: absolute; bottom: 0.5rem; right: 0.7rem; z-index: 2;
  font-size: 0.6rem; letter-spacing: 0.1em; text-transform: uppercase;
  color: rgba(var(--bone-rgb), 0.72); text-shadow: 0 1px 4px rgba(0, 0, 0, 0.45);
}
.dp-show__media img,
.dp-show__media video { width: 100%; height: 100%; object-fit: cover; display: block; }
.dp-show__media iframe { width: 100%; height: 100%; border: 0; display: block; }   /* interactive embeds (the 3D walkthrough) fill the frame */
/* Full-bleed "show" media — the Details feature stretches the full viewport (vw × vh).
   On small screens it stays horizontal (3:2) so a landscape frame is not over-cropped. */
.dp-show--full { padding-bottom: 0; }
.dp-show--full .dp-show__media {
  max-width: none; aspect-ratio: auto; border-radius: 0; box-shadow: none;
  width: 100vw; height: 100vh; margin: 0 0 0 calc(50% - 50vw);
}
@media (max-width: 820px) { .dp-show--full .dp-show__media { height: auto; aspect-ratio: 3 / 2; } }

/* A sharp poster overlay covers each background video while it ramps to a crisp
   rung, then fades out — so the low first rung is never seen. The video keeps
   PLAYING underneath (occluded, not hidden); hiding it with opacity would pause
   playback and stall the quality ramp. */
.video-poster {
  position: absolute;
  inset: 0;
  background-size: cover;
  background-position: center;
  transition: opacity 0.9s var(--ease);
  pointer-events: none;
}
.video-poster.is-hidden { opacity: 0; }
/* Home panels load on a flat black (footer ink) backdrop — no still image to "jump"
   from when the clip starts; it simply fades out to the video. */
.video-poster--ink { background: var(--ink); }
video.panel__img { background-color: var(--ink); }
.panel > .video-poster {                 /* paints over the panel video (-2), under the scrim (-1) */
  z-index: -2;
  scale: 1.18;
  transition: opacity 0.9s var(--ease), scale var(--slower) var(--ease);
}
.panel.is-visible > .video-poster { scale: 1.1; }   /* match the video's gentle rest-zoom */
.dp-show__media { position: relative; }
.dp-show__media > .video-poster { z-index: 2; }      /* over the inset feature video */

/* Loop video for a feature panel — a wrapper holding two stacked copies that crossfade at
   the loop (see main.js). The wrapper carries a dark (and poster) backdrop so nothing of the
   page's bone ever shows through behind the video. */
.panel__video {
  position: absolute; inset: 0; z-index: -2; overflow: hidden;
  background-color: var(--ink);
  background-size: cover; background-position: center; background-repeat: no-repeat;
}
.panel__video__el {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  object-fit: cover; object-position: center;
  display: block; will-change: opacity;
}

/* The closing invitation — a quiet statement, a touch larger than body */
.dp-invite__body { font-size: clamp(1.15rem, 1rem + 0.7vw, 1.5rem); max-width: 36rem; margin-inline: auto; }
.dp-show__text {
  max-width: 44rem;
  margin: clamp(2.4rem, 5vw, 3.6rem) auto 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 30px;
}
/* --lead: the copy leads, the framed media follows. The gap matches Discover's
   intro→video rhythm (one full --section-y), so the two pages feel the same. */
.dp-show--lead .dp-show__text { margin: var(--section-y) auto 0; }   /* viewer leads, copy sits below it */
.dp-show--lead .dp-show__media { max-width: 78rem; }   /* 3D viewer widened to match the split modules */
.dp-show--bare .dp-show__media { max-width: 78rem; }   /* match the 3D walkthrough width */
.dp-show__lead-label { display: block; text-align: center; margin: 0 auto clamp(1rem, 3vw, 1.8rem); scroll-margin-top: 7rem; }

/* An interlude that fades into the sky field below it — no hard seam into the
   following inset feature. */
.dp-interlude.dp-to-field {
  background: transparent;            /* rides the band gradient below */
  padding-bottom: 0;                  /* blends into the video; the video's top padding sets the gap */
  color: var(--bone);                 /* white text on the deep-blue top of the band */
}

/* ---- Gradient band: Introduction · Video · The Price share one sky gradient ----
   Deep blue at the top, sky blue at the midpoint, pale sand at the carousel. */
.dp-band { background: linear-gradient(180deg, #1e3267 0%, #5476b6 50%, #a3b0bf 100%); }
.dp-band .dp-interlude { background: transparent; color: var(--bone); }   /* intro · price · provenance all ride the band in white */
.dp-show--bare { background: transparent; }   /* the video frame floats on the band */

/* Copy overlaid on an inset video frame — a scrim and centred white caption sit inside the
   show frame (over the video and its buffer poster), the inset answer to a full-bleed feature. */
.dp-show__media--caption { position: relative; }
.dp-show__media--caption::after {
  content: ""; position: absolute; inset: 0; z-index: 3; pointer-events: none;
  background: linear-gradient(180deg, rgba(var(--scrim-rgb), 0.32) 0%, rgba(var(--scrim-rgb), 0.58) 100%);
}
.dp-show__caption {
  position: absolute; inset: 0; z-index: 4;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; gap: clamp(0.8rem, 2vw, 1.4rem);
  padding: clamp(1.5rem, 5vw, 3.5rem);
  color: var(--bone);
}
.dp-show__caption .dp-title { color: var(--bone); }
.dp-show__caption .dp-body { color: rgba(var(--bone-rgb), 0.92); max-width: 40rem; }

/* =============================================================================
   The Spaces — gallery carousel (peek slider)
   ============================================================================= */
.spaces { padding: var(--section-y) 0; }
.spaces__viewport { position: relative; overflow: hidden; }
.spaces__track {
  position: relative;
  display: flex;
  gap: clamp(1.2rem, 2.4vw, 2.2rem);
  padding-top: clamp(6.5rem, 7vw, 7.5rem);    /* breathing room above + top shadow */
  padding-bottom: 30px;                        /* tight gap to the dots; holds the (small) shadow */
  will-change: transform;
  transition: transform var(--slower) var(--ease);
}
.spaces__slide {
  position: relative;
  flex: 0 0 min(56vw, 52rem);   /* the active sits large and centred — neighbours peek */
  aspect-ratio: 3 / 2;
  overflow: hidden;
  margin: 0;
  box-shadow: 0 8px 22px rgba(var(--scrim-rgb), 0.20);   /* soft lift, fits the tight gap */
  scale: 0.84;                                            /* neighbours sit ~10% smaller */
  filter: brightness(0.5);                                /* …and dimmed */
  transition: scale var(--slower) var(--ease), filter var(--slower) var(--ease);
}
.spaces__slide.is-active { scale: 1; filter: brightness(1); }   /* centred slide takes focus */
.spaces__track.no-anim, .spaces__track.no-anim .spaces__slide { transition: none; }   /* during the loop snap-back */
.spaces__slide img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* Glass cursor-follower — replaces the visible arrows; click the image's left/right half */
@media (hover: hover) { .spaces__viewport { cursor: none; } }
.spaces__cursor {
  position: fixed; top: 0; left: 0; z-index: 60; margin: 0;
  width: 3.6rem; height: 3.6rem; border-radius: 50%;
  display: grid; place-items: center;
  color: #fff;
  background: rgba(var(--bone-rgb), 0.14);
  -webkit-backdrop-filter: blur(12px) saturate(125%); backdrop-filter: blur(12px) saturate(125%);
  pointer-events: none;
  opacity: 0; transform: translate(-50%, -50%) scale(0.6);
  transition: opacity 0.25s var(--ease), transform 0.25s var(--ease);
}
.spaces__cursor.is-on { opacity: 1; transform: translate(-50%, -50%) scale(1); }
.spaces__cursor svg { width: 1.2rem; height: 1.2rem; }
.spaces__cursor.is-left svg { transform: scaleX(-1); }   /* point left on the left half */
@media (hover: none) { .spaces__cursor { display: none; } }

/* Thin-bar dot nav, close to the image; the active bar fills as a countdown */
.spaces__dots {
  display: flex; align-items: center; justify-content: center; gap: 0.5rem;
  margin-top: 0; padding: 0 var(--pad-x);
}
.spaces__dot {
  position: relative; width: 30px; height: 3px; padding: 0; overflow: hidden;
  border-radius: 2px; background: rgba(var(--bone-rgb), 0.3);
}
.spaces__dot__fill {
  position: absolute; inset: 0; transform-origin: left; transform: scaleX(0);
  background: var(--bone);
}
.spaces__dot[aria-current="true"] .spaces__dot__fill { animation: dotfill 5s linear forwards; }
@keyframes dotfill { from { transform: scaleX(0); } to { transform: scaleX(1); } }

/* Caption — changes with the active slide */
.spaces__caption { text-align: center; max-width: 42rem; margin: clamp(1.6rem, 3.5vw, 2.6rem) auto 0; padding: 0 var(--pad-x); }
.spaces__caption-title { font-weight: 200; text-transform: uppercase; letter-spacing: var(--tr-h2); font-size: clamp(1.3rem, 1rem + 1.4vw, 1.9rem); line-height: 1.12; margin-bottom: 0.7rem; color: var(--bone); }
.spaces__caption-body { font-weight: 400; font-size: clamp(1rem, 0.97rem + 0.3vw, 1.12rem); line-height: 1.4; color: rgba(var(--bone-rgb), 0.82); text-wrap: balance; }

@media (prefers-reduced-motion: reduce) {
  .spaces__track, .spaces__slide { transition: none; }
  .spaces__dot[aria-current="true"] .spaces__dot__fill { animation: none; transform: scaleX(1); }
}
@media (max-width: 760px) { .spaces__slide { flex-basis: 84vw; } }

/* =============================================================================
   Content pages (Details · Villas Del Mar · Los Cabos) — shared additions
   ============================================================================= */

/* Hero subhead + full-bleed scene body — quiet lines under the panel title */
.panel__subhead {
  font-weight: 200;
  font-size: clamp(1.15rem, 0.95rem + 1vw, 1.75rem);
  line-height: 1.3;
  color: rgba(var(--bone-rgb), 0.92);
  max-width: 32rem;
}
.panel__body {
  font-weight: 300;
  font-size: clamp(1.05rem, 1rem + 0.4vw, 1.25rem);
  line-height: 1.7;
  color: rgba(var(--bone-rgb), 0.94);
  max-width: 34rem;
  text-wrap: balance;
}
.panel--feature .panel__title { font-size: clamp(2rem, 1.3rem + 2.6vw, 3.4rem); }
/* Stronger, still-even wash for white text over bright images (sky, beach, sea) */
.panel--scrim-strong .panel__scrim {
  background: linear-gradient(180deg,
    rgba(var(--scrim-rgb), 0.6) 0%,
    rgba(var(--scrim-rgb), 0.5) 34%,
    rgba(var(--scrim-rgb), 0.5) 66%,
    rgba(var(--scrim-rgb), 0.64) 100%);
}

/* Split feature — image and text side by side, alternating sides */
.dp-split { background: var(--bone); padding: clamp(3.5rem, 7vw, 6rem) var(--pad-x); }
.dp-split__inner {
  width: 100%; max-width: 78rem; margin-inline: auto;
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);   /* truly equal halves — content min-size can't collapse a column */
  align-items: center; gap: clamp(2rem, 5vw, 5.5rem);
}
.dp-split__media {
  width: 100%;                /* fill the grid column (align-items:center otherwise shrinks it to intrinsic size) */
  aspect-ratio: 4 / 5; overflow: hidden;
  box-shadow: 0 30px 70px rgba(var(--scrim-rgb), 0.18);
}
/* The image is taller than its frame so it can slide *within* the clip (parallax window). */
.dp-split__media img { width: 100%; height: 144%; object-fit: cover; display: block; position: relative; top: -22%; will-change: transform; }
.dp-split__text { display: flex; flex-direction: column; align-items: flex-start; text-align: left; gap: 30px; }
.dp-split__text .dp-title { font-size: clamp(1.7rem, 1.1rem + 2.1vw, 2.7rem); }
.dp-split__text .dp-body { max-width: 34rem; }
.dp-split--flip .dp-split__media { order: 2; }
@media (max-width: 820px) {
  .dp-split__inner { grid-template-columns: 1fr; gap: clamp(1.5rem, 5vw, 2.2rem); }
  .dp-split--flip .dp-split__media { order: 0; }
  .dp-split__media { aspect-ratio: 3 / 2; }
}
/* Below the parallax breakpoint (or reduced motion): the image fills its frame normally. */
@media (max-width: 760px) { .dp-split__media img { height: 100%; top: 0; transform: none !important; } }

/* Specification — the Key Details list (fact-first, on bone) */
.spec { background: var(--bone); padding: var(--section-y) var(--pad-x); }
.spec__inner { max-width: 72rem; margin-inline: auto; }
.spec__list { columns: 2; column-gap: clamp(2.4rem, 5vw, 4.5rem); border-top: 1px solid rgba(var(--scrim-rgb), 0.12); }
.spec__head { text-align: center; display: flex; flex-direction: column; align-items: center; gap: 0.8rem; margin-bottom: clamp(2.2rem, 5vw, 3.4rem); }
.spec__row {
  display: grid; grid-template-columns: minmax(8rem, 0.8fr) 1.6fr;
  gap: clamp(1rem, 3vw, 2.4rem); align-items: baseline;
  padding: clamp(0.85rem, 1.7vw, 1.1rem) 0;
  border-bottom: 1px solid rgba(var(--scrim-rgb), 0.12);
  break-inside: avoid;
}
.spec__row:last-of-type { border-bottom: 1px solid rgba(var(--scrim-rgb), 0.12); }
.spec__key { font-weight: 400; text-transform: uppercase; letter-spacing: 0.14em; font-size: 0.78rem; color: var(--mute); }
.spec__val { font-weight: 300; font-size: clamp(1rem, 0.97rem + 0.3vw, 1.15rem); color: var(--ink); line-height: 1.5; }
.spec__note { margin-top: clamp(1.6rem, 3vw, 2.2rem); font-size: 0.82rem; color: var(--mute); line-height: 1.6; text-align: center; max-width: 40rem; margin-inline: auto; }
@media (max-width: 768px) { .spec__inner { max-width: 54rem; } .spec__list { columns: 1; } }
@media (max-width: 540px) { .spec__row { grid-template-columns: 1fr; gap: 0.25rem; } }

/* =============================================================================
   Rooms That Adapt — a pinned module (Details · Flexibility).
   The heading + one large, inset frame hold centred in the viewport while five
   rooms cross-fade through the frame on scroll, so the section feels like it
   stays in place. The tall track + sticky pin are JS-gated; without JS it falls
   back to a single static frame.
   ============================================================================= */
/* ---- Gradient band — Rooms That Adapt · Self-Contained Suite · Service Kept Out of
   Sight read as one continuous deep-blue field. The wrapper carries the gradient; the
   sections inside go transparent and their copy flips to bone for legibility. Keep the
   wrapper free of overflow/transform — either would break the adapt pin's sticky. */
.band { background: linear-gradient(180deg, #2a506b 0%, #4b88b2 100%); }
.band .adapt,
.band .dp-split { background: transparent; }
.band .dp-title { color: var(--bone); }
.band .dp-body { color: rgba(var(--bone-rgb), 0.86); }
/* The Residence — this band warms to peach so Rooms → Casita → Service → the closing
   image read as one continuous section, the gradient bleeding into the sunset. */
.band--warm { background: linear-gradient(180deg, #2a506b 0%, #4b88b2 58%, #fed9c6 100%); }
.invite-hero--closer-warm { background: #fed9c6; }
.invite-hero--closer-warm::before { background: linear-gradient(180deg, #fed9c6 0%, rgba(254, 217, 198, 0) 100%); }
/* Service sits on the warm peach foot — its copy flips to ink so it still reads. */
.band--warm .dp-split--ink .dp-title { color: var(--ink); }
.band--warm .dp-split--ink .dp-body { color: rgba(var(--ink-rgb), 0.82); }

/* Los Cabos tinted band — a warm mauve-to-blush wash behind the introduction through the
   gallery-district culture section. Dark copy stays legible across the whole range (no flip);
   the full-bleed video panel inside keeps its own opaque background and covers the gradient. */
.band-coast { background: linear-gradient(180deg, #7a667b 0%, #d6b9be 100%); }
.band-coast .dp-interlude,
.band-coast .dp-split,
.band-coast .dp-show { background: transparent; }
/* The two sections on the dark (mauve) head of the band read in white. */
.on-band-dark .dp-title,
.on-band-dark .btn-quiet { color: var(--bone); }
.on-band-dark .dp-body { color: rgba(var(--bone-rgb), 0.9); }

.adapt { background: var(--field-sky); position: relative; }
.js .adapt__track { height: 750vh; margin-top: -24vh; }   /* scroll distance — ~0.7 screen per room across the nine; pulled up under the head so the image stays put while the copy centres above it */
.adapt__pin {
  display: grid;
  place-items: center;            /* the image alone, centred — pure image once pinned */
  padding: 0 40px;                /* 40px gap left and right; the image floats within the field */
}
.js .adapt__pin { position: sticky; top: 0; min-height: 100vh; min-height: 100svh; }
/* The copy reads first, in normal flow, then scrolls away before the pin engages. */
/* The head fills the space from the section top to the image and centres the copy in it;
   the track is pulled up by the same amount (below) so the image itself never moves. */
.adapt__head { max-width: 50rem; margin-inline: auto; text-align: center; display: flex; flex-direction: column; justify-content: center; gap: clamp(0.8rem, 2vw, 1.3rem); min-height: 56vh; padding: clamp(2rem, 5vh, 3.5rem) var(--pad-x); }
/* The script pulls the image up by 24vh (.adapt__track margin); match that on the head's foot
   so the copy sits optically centred — equal space above the title and below the body to the image. */
.js .adapt__head { padding-bottom: calc(clamp(2rem, 5vh, 3.5rem) + 24vh); }
.adapt__head .dp-body { max-width: 46rem; margin-inline: auto; text-wrap: balance; }
.adapt__stage {
  position: relative;
  width: 100%; height: 100vh;        /* the pinned image fills the full viewport (vw × vh) */
  margin: 0;
  overflow: hidden;
}
.adapt__frame {
  position: absolute; inset: 0;
  margin: 0;
  opacity: 0;
  transition: opacity 0.85s var(--ease);
  will-change: opacity;
}
.adapt__frame.is-active { opacity: 1; }
.adapt__img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* A quiet label so the current rooms read apart from the AI-restyled inspirations. */
.adapt__tag {
  position: absolute;
  left: 0;
  bottom: 0;
  font-size: 0.62rem;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: rgba(var(--bone-rgb), 0.92);
  padding: 0.4em 0.7em;
  background: rgba(var(--scrim-rgb), 0.2);
  -webkit-backdrop-filter: blur(3px);
  backdrop-filter: blur(3px);
  /* The box stays faint, so a soft shadow keeps the word legible over bright rooms. */
  text-shadow: 0 1px 3px rgba(var(--scrim-rgb), 0.5);
}
/* On phones the pinned image goes edge-to-edge and square, so the room reads as large as possible. */
@media (max-width: 820px) {
  .adapt__pin { padding: 0; }
  .adapt__stage { height: auto; aspect-ratio: 1 / 1; }
}

/* =============================================================================
   Rooms That Adapt (Details) — a crossfade slideshow: one big image set 40px in
   from the viewport, auto-advancing on a dot-nav countdown. No side-peek; the
   dark-blue band shows as the frame around the image.
   ============================================================================= */
.dshow { padding: var(--section-y) 0; position: relative; }   /* transparent — sits on the .band blue gradient with the section below */
.dshow__head { max-width: 50rem; margin: 0 auto var(--section-y); text-align: center; padding: 0 var(--pad-x); }
.dshow__head .dp-body { max-width: 46rem; margin: 30px auto 0; text-wrap: balance; }
.dshow__stage {
  position: relative;
  width: calc((100vw - 80px) * 0.9);   /* 40px inset, then 10% smaller again */
  height: calc((100svh - 80px) * 0.9);
  margin-inline: auto;
  overflow: hidden;
  border-radius: 3px;
  background: rgba(var(--ink-rgb), 0.05);
  box-shadow: 0 40px 90px rgba(var(--scrim-rgb), 0.28);
}
.dshow__slide {
  position: absolute; inset: 0;
  margin: 0;
  opacity: 0;
  transition: opacity 0.9s var(--ease);
  pointer-events: none;
}
.dshow__slide.is-active { opacity: 1; pointer-events: auto; }
.dshow__slide img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* A quiet label — current rooms read apart from the AI-restyled inspirations. */
.dshow__tag {
  position: absolute; left: 0; bottom: 0;
  font-size: 0.62rem; font-weight: 400; text-transform: uppercase; letter-spacing: 0.22em;
  color: rgba(var(--bone-rgb), 0.92);
  padding: 0.5em 0.8em;
  background: rgba(var(--scrim-rgb), 0.2);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  text-shadow: 0 1px 3px rgba(var(--scrim-rgb), 0.5);
}
/* Dot-nav with a countdown fill — dark, so it reads on the pale field. */
.dshow__dots { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.6rem; margin-top: clamp(1.3rem, 3vw, 2rem); padding: 0 var(--pad-x); }
.dshow__dot { position: relative; width: 2.2rem; height: 3px; padding: 0; border: 0; border-radius: 2px; background: rgba(var(--bone-rgb), 0.28); cursor: pointer; overflow: hidden; }
.dshow__dot__fill { position: absolute; inset: 0; transform-origin: left; transform: scaleX(0); background: var(--bone); }
.dshow__dot[aria-current="true"] .dshow__dot__fill { animation: dotfill 5s linear forwards; }
.dshow__dot:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* Glass cursor-follower over the image — flips by pointer half; click to navigate. */
@media (hover: hover) { .dshow__stage { cursor: none; } }
.dshow__cursor {
  position: fixed; top: 0; left: 0; z-index: 60; margin: 0;
  width: 3.6rem; height: 3.6rem; border-radius: 50%;
  display: grid; place-items: center;
  color: #fff;
  background: rgba(var(--bone-rgb), 0.14);
  -webkit-backdrop-filter: blur(12px) saturate(125%); backdrop-filter: blur(12px) saturate(125%);
  pointer-events: none;
  opacity: 0; transform: translate(-50%, -50%) scale(0.6);
  transition: opacity 0.25s var(--ease), transform 0.25s var(--ease);
}
.dshow__cursor.is-on { opacity: 1; transform: translate(-50%, -50%) scale(1); }
.dshow__cursor svg { width: 1.2rem; height: 1.2rem; }
.dshow__cursor.is-left svg { transform: scaleX(-1); }
@media (max-width: 820px) {
  /* keep the image large on a phone — a slim 16px frame, square crop (as preferred) */
  .dshow__stage { width: calc((100vw - 32px) * 0.9); height: auto; aspect-ratio: 1 / 1; }
}
@media (prefers-reduced-motion: reduce) {
  .dshow__slide { transition: opacity 0.2s linear; }
}

/* ============================ Widow control ============================
   Hunt stranded last-line words site-wide. `balance` re-wraps short headings
   (and centred copy) evenly at every width; `pretty` lifts a lone last word in
   left-aligned body. Hero h1.panel__title keeps its own nowrap rule (higher
   specificity), so it stays a single scaling line. */
.dp-title,
.panel__title,
.dp-explore__title,
.invite-hero__title,
.spaces__caption-title,
.eyebrow,
.support,
.dp-interlude .dp-body { text-wrap: balance; }

.dp-body,
.panel__body,
.invite-hero__body,
.spaces__caption-body { text-wrap: pretty; }

/* ============================ Contact (request) ======================
   The Los Cabos purple gradient (#7a667b → #d6b9be) carries the intro,
   the email + phone, and the enquiry form on a smoked glass card — all
   set in light type (the card is deep enough to read over the pale foot). */
.contact-field {
  position: relative;
  min-height: 100vh; min-height: 100svh;
  display: flex; flex-direction: column; justify-content: center;
  background: linear-gradient(180deg, #7a667b 0%, #d6b9be 100%);
  padding: calc(var(--section-y) + 3rem) var(--pad-x) var(--section-y);
}
.contact-field .field__intro { padding-top: 0; }
.contact-field .field__intro .dp-title { font-size: clamp(2.4rem, 1.6rem + 3vw, 4rem); color: var(--bone); }
.contact-field .field__intro .dp-body { max-width: 40rem; margin-inline: auto; text-wrap: balance; color: rgba(var(--bone-rgb), 0.9); }

/* email + phone — between the text and the form */
.contact-reach {
  position: relative; z-index: 2;
  display: flex; flex-wrap: wrap; justify-content: center; align-items: center;
  gap: 0.6rem clamp(1.4rem, 3.5vw, 2.6rem);
  margin: clamp(2rem, 4.5vw, 3.2rem) auto 0;
  font-size: clamp(1.2rem, 1rem + 0.7vw, 1.55rem); font-weight: 300; text-align: center;
}
.contact-reach a {
  color: var(--bone);
  border-bottom: 1px solid rgba(var(--bone-rgb), 0.35); padding-bottom: 1px;
  transition: border-color var(--slow) var(--ease);
}
.contact-reach a:hover, .contact-reach a:focus-visible { border-bottom-color: var(--bone); }

/* the enquiry form on a frosted glass card */
.contact-card {
  position: relative; z-index: 2;
  max-width: 47rem; margin: clamp(2rem, 4.5vw, 3.4rem) auto 0;
  background: rgba(var(--scrim-rgb), 0.42);
  -webkit-backdrop-filter: blur(22px) saturate(125%);
  backdrop-filter: blur(22px) saturate(125%);
  border: 1px solid rgba(var(--bone-rgb), 0.16);
  box-shadow: 0 34px 80px rgba(var(--scrim-rgb), 0.28);
  padding: clamp(2rem, 4.5vw, 3.4rem) clamp(1.6rem, 4vw, 3rem);
}

.contact-form { display: grid; gap: clamp(1.5rem, 3vw, 2.1rem); }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(1.5rem, 3vw, 2.1rem); }
@media (max-width: 460px) { .form-row { grid-template-columns: 1fr; } }
.form-group { display: flex; flex-direction: column; gap: 0.5rem; text-align: left; }
.form-group label {
  font-size: 13px; text-transform: uppercase; letter-spacing: 0.16em;
  color: rgba(var(--bone-rgb), 0.72);
}
.form-group label .opt { letter-spacing: 0.08em; opacity: 0.6; text-transform: none; }
.form-group input,
.form-group textarea {
  font-family: inherit; font-size: 1.05rem; font-weight: 300; color: var(--bone);
  background: transparent; border: 0; border-bottom: 1px solid rgba(var(--bone-rgb), 0.3);
  padding: 0.5rem 0; border-radius: 0; width: 100%; box-sizing: border-box;
  transition: border-color var(--slow) var(--ease);
}
.form-group textarea { resize: vertical; min-height: 6.5rem; line-height: 1.65; }
.form-group input:focus,
.form-group textarea:focus { outline: none; border-bottom-color: var(--bone); }
.form-group input::placeholder,
.form-group textarea::placeholder { color: rgba(var(--bone-rgb), 0.42); }

.btn-solid {
  width: 100%; cursor: pointer; -webkit-appearance: none; appearance: none;
  font-family: inherit; font-weight: 400; text-transform: uppercase;
  letter-spacing: var(--tr-link); font-size: 16px;
  color: var(--bone); background: rgba(var(--bone-rgb), 0.12);
  border: 0; border-radius: 100px;
  -webkit-backdrop-filter: blur(16px) saturate(120%); backdrop-filter: blur(16px) saturate(120%);
  padding: 0.9rem 1.95rem; margin-top: 0.6rem;
  transition: background var(--slow) var(--ease), border-color var(--slow) var(--ease), transform 0.24s var(--ease);
}
.btn-solid:hover, .btn-solid:focus-visible { background: rgba(var(--bone-rgb), 0.26); }
/* CTAs lift toward you a touch on hover — a 5% rise. Pointer devices, motion allowed. */
@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .btn-quiet:hover, .btn-quiet:focus-visible,
  .btn-solid:hover, .btn-solid:focus-visible { transform: scale(1.05); }
}
/* Honeypot — kept far off-screen, hidden from assistive tech and the tab order. */
.hp-field { position: absolute !important; left: -9999px !important; top: auto; width: 1px; height: 1px; overflow: hidden; }
/* After a successful enquiry: the form is hidden and the thank-you sits centred in the card at 18pt. */
.contact-card.is-sent { display: grid; place-items: center; min-height: 20rem; }
.contact-card.is-sent .contact-form { display: none; }
.contact-card.is-sent .form-status { margin: 0; text-align: center; font-size: 18pt; line-height: 1.5; max-width: 30rem; color: var(--bone); }
.form-status { font-size: 0.95rem; color: rgba(var(--bone-rgb), 0.8); line-height: 1.5; min-height: 1.2em; }

/* ============================ Legal pages ============================
   Privacy & Cookies — a clean reading column on bone. Pages with no dark hero
   carry .solid-nav so the header stays legible from the very top. */
.solid-nav .site-header { background: var(--ink); }
.solid-nav .site-header::before { opacity: 0; }

.legal {
  max-width: 44rem; margin-inline: auto;
  padding: calc(var(--section-y) + 3.5rem) var(--pad-x) var(--section-y);
}
.legal__head { text-align: center; margin-bottom: clamp(2.4rem, 5vw, 3.4rem); }
.legal__head .eyebrow { color: rgba(var(--ink-rgb), 0.5); }
.legal__head h1 {
  font-weight: 200; text-transform: uppercase; letter-spacing: var(--tr-h2);
  font-size: clamp(2rem, 1.5rem + 2.4vw, 3.2rem); line-height: 1.1; margin-top: 0.6rem;
}
.legal__updated { color: rgba(var(--ink-rgb), 0.5); font-size: 0.9rem; margin-top: 0.9rem; }
.legal h2 {
  font-weight: 400; text-transform: uppercase; letter-spacing: 0.12em;
  font-size: clamp(1.1rem, 1rem + 0.5vw, 1.35rem);
  margin: clamp(2rem, 4vw, 2.8rem) 0 30px;
}
.legal p, .legal li { font-size: 1.02rem; font-weight: 300; line-height: 1.4; color: rgba(var(--ink-rgb), 0.84); }
.legal p { margin: 0 0 1rem; }
.legal ul { margin: 0 0 1rem; padding-left: 1.25rem; }
.legal li { margin-bottom: 0.55rem; }
.legal strong { font-weight: 400; color: var(--ink); }
.legal a { color: var(--ink); border-bottom: 1px solid var(--hairline); transition: border-color var(--slow) var(--ease); }
.legal a:hover, .legal a:focus-visible { border-bottom-color: var(--ink); }

/* ====================== Cookie consent (GDPR / CCPA) ======================
   A one-time notice, injected by main.js on first visit; choice stored in
   localStorage ('vl-consent'). The site sets only essential cookies. */
.cookie-banner {
  position: fixed; z-index: 200;
  left: clamp(1rem, 3vw, 2rem); right: clamp(1rem, 3vw, 2rem); bottom: clamp(1rem, 3vw, 2rem);
  max-width: 46rem; margin-inline: auto;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 0.9rem clamp(1.2rem, 3vw, 1.8rem);
  padding: clamp(1rem, 2.4vw, 1.35rem) clamp(1.2rem, 3vw, 1.8rem);
  background: rgba(var(--scrim-rgb), 0.94);
  -webkit-backdrop-filter: blur(14px) saturate(120%); backdrop-filter: blur(14px) saturate(120%);
  color: var(--bone);
  box-shadow: 0 22px 60px rgba(var(--scrim-rgb), 0.45);
  transform: translateY(130%); opacity: 0;
  transition: transform 0.6s var(--ease), opacity 0.6s var(--ease);
}
.cookie-banner.is-in { transform: none; opacity: 1; }
.cookie-banner__text { flex: 1 1 17rem; font-size: 0.92rem; font-weight: 300; line-height: 1.55; color: rgba(var(--bone-rgb), 0.9); }
.cookie-banner__text a { color: var(--bone); border-bottom: 1px solid rgba(var(--bone-rgb), 0.4); }
.cookie-banner__actions { display: flex; gap: 0.6rem; flex: 0 0 auto; }
.cookie-banner__btn {
  cursor: pointer; font-family: inherit; font-size: 12px; text-transform: uppercase; letter-spacing: 0.14em;
  padding: 0.55rem 1.25rem; border-radius: 100px; border: 1px solid transparent;
  background: var(--bone); color: var(--ink);
  transition: background var(--slow) var(--ease), border-color var(--slow) var(--ease);
}
.cookie-banner__btn:hover, .cookie-banner__btn:focus-visible { background: rgba(var(--bone-rgb), 0.85); }
.cookie-banner__btn--ghost { background: transparent; color: var(--bone); border-color: rgba(var(--bone-rgb), 0.4); }
.cookie-banner__btn--ghost:hover, .cookie-banner__btn--ghost:focus-visible { background: transparent; border-color: var(--bone); }
@media (max-width: 540px) { .cookie-banner__actions { width: 100%; } .cookie-banner__btn { flex: 1; } }

/* footer legal link */
.footer-legal { margin-top: 0.6rem; font-size: 0.82rem; }
.footer-legal a { color: rgba(var(--bone-rgb), 0.55); border-bottom: 1px solid transparent; transition: color var(--slow) var(--ease); }
.footer-legal a:hover, .footer-legal a:focus-visible { color: rgba(var(--bone-rgb), 0.85); }

/* ============================ Gallery ============================
   A column masonry of the residence, on the contact-page purple gradient. */
.gallery {
  background: var(--ink);                 /* same as the footer */
  padding: calc(var(--section-y) + 3rem) 0 0;
}
.gallery__head { text-align: center; max-width: 46rem; margin: 0 auto clamp(2.5rem, 5vw, 4rem); padding-inline: var(--pad-x); }
.gallery__head .eyebrow { color: rgba(var(--bone-rgb), 0.6); }
.gallery__head .dp-title { color: var(--bone); }
.gallery__head .dp-body { color: rgba(var(--bone-rgb), 0.78); max-width: 36rem; margin-inline: auto; }
/* Full-width mosaic — a repeating "1 large, 2 small" rhythm. */
.gallery-mosaic {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 21vw;
  gap: clamp(4px, 0.5vw, 8px);
  grid-auto-flow: dense;
}
.gallery-mosaic img { width: 100%; height: 100%; object-fit: cover; display: block; cursor: zoom-in; }
/* Alternating rhythm — large + 2 small, then 2 small + large, repeating down the grid. */
.gallery-mosaic img:nth-child(6n+1) { grid-column: 1 / span 2; grid-row: span 2; }   /* large on the left */
.gallery-mosaic img:nth-child(6n+4) { grid-column: 2 / span 2; grid-row: span 2; }   /* large on the right */
/* Keyboard focus ring for the now-operable gallery tiles (Enter/Space opens the lightbox). */
.gallery-mosaic img:focus-visible { outline: 3px solid rgba(var(--bone-rgb), 0.92); outline-offset: -3px; }
/* Full-width finale — the last image spans all three columns so the lone-tile remainder leaves no gap. */
.gallery-mosaic img:last-child { grid-column: 1 / -1; }
@media (max-width: 640px) { .gallery-mosaic { grid-auto-rows: 28vw; } }

/* Dark pill CTA — reads clearly on light/bone sections (e.g. the spec sheet's "View the Gallery"). */
.btn-ink { display: inline-block; font-family: inherit; font-size: 0.78rem; font-weight: 300; text-transform: uppercase; letter-spacing: 0.2em; color: var(--bone); background: var(--ink); padding: 1rem 2.6rem; border: 0; border-radius: 999px; text-decoration: none; cursor: pointer; transition: background var(--tr-link), transform var(--tr-link); }
.btn-ink:hover, .btn-ink:focus-visible { background: var(--ink-soft); transform: translateY(-1px); }
.spec__cta { text-align: center; margin-top: clamp(2rem, 5vw, 3.5rem); }

/* Lightbox — click a tile for a full-screen slideshow (count top-left, close top-right). */
.lightbox { position: fixed; inset: 0; z-index: 400; display: none; background: rgba(var(--scrim-rgb), 0.96); -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px); }
.lightbox.is-open { display: grid; place-items: center; }
.lightbox__stage { margin: 0; display: grid; place-items: center; }
.lightbox__img { max-width: 92vw; max-height: 86vh; object-fit: contain; display: block; box-shadow: 0 30px 90px rgba(0, 0, 0, 0.55); }
.lightbox__count { position: absolute; top: clamp(1.1rem, 3vw, 2rem); left: clamp(1.1rem, 3vw, 2rem); color: rgba(var(--bone-rgb), 0.75); font-size: 14px; letter-spacing: 0.16em; }
.lightbox__close { position: absolute; top: clamp(1rem, 3vw, 1.9rem); right: clamp(1.1rem, 3vw, 2rem); background: transparent; border: 0; color: var(--bone); cursor: pointer; font-family: inherit; font-size: 13px; text-transform: uppercase; letter-spacing: 0.16em; padding: 0.4rem; }
.lightbox__close:hover, .lightbox__close:focus-visible { color: rgba(var(--bone-rgb), 0.65); }
.lightbox__nav { position: absolute; top: 50%; transform: translateY(-50%); background: rgba(var(--bone-rgb), 0.1); border: 0; color: var(--bone); width: clamp(2.6rem, 5vw, 3.4rem); height: clamp(2.6rem, 5vw, 3.4rem); border-radius: 50%; cursor: pointer; display: grid; place-items: center; transition: background var(--slow) var(--ease); }
.lightbox__nav:hover, .lightbox__nav:focus-visible { background: rgba(var(--bone-rgb), 0.22); }
.lightbox__nav svg { width: 42%; height: 42%; }
.lightbox__nav--prev { left: clamp(0.5rem, 2vw, 1.5rem); }
.lightbox__nav--next { right: clamp(0.5rem, 2vw, 1.5rem); }

/* The "View the full Gallery" CTA in the One of Their Own field — more breathing
   room above it, and a solid, whiter pill so it reads clearly on the pale field. */
.field .field__intro .btn-quiet {
  margin-top: clamp(2.8rem, 7vw, 4rem);
  margin-bottom: clamp(1.6rem, 4vw, 2.4rem);
  background: var(--bone);
  box-shadow: 0 12px 30px rgba(var(--scrim-rgb), 0.16);
  -webkit-backdrop-filter: none; backdrop-filter: none;
}
.field .field__intro .btn-quiet:hover,
.field .field__intro .btn-quiet:focus-visible { background: rgba(var(--bone-rgb), 0.86); }
