/* Shared overlay-z scale (bayside-5tj). The :root custom properties
 * declared here are consumed by any module that needs to stack
 * overlays consistently (see lib/shared/overlay-z.js for the per-
 * layer rationale). Fallbacks at consumer sites still match these
 * values so a missed import does not silently re-flatten the stack. */
@import url("lib/shared/overlay-z.css");
@import url("lib/scene-05-gather/styles.module.css");
@import url("lib/scene-07-active-well/styles.module.css");
@import url("lib/scene-02-arrival/styles.module.css");
@import url("lib/scene-08-floor-plan-scroller/styles.module.css");
@import url("lib/scene-08-residences/styles.module.css");
@import url("lib/scene-04-easy-living/styles.module.css");
@import url("lib/scene-09-neighborhood/styles.module.css");
@import url("shared/drawer/styles.module.css");

@font-face {
  font-family: "Montserrat Bayside";
  src: url("01-brand/Fonts/Montserrat-Light/Montserrat-Light.ttf") format("truetype");
  font-weight: 300;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: "Lora Bayside";
  src: url("01-brand/Fonts/Lora Italic/Lora-Italic.ttf") format("truetype");
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}

@font-face {
  font-family: "Acumin Bayside";
  src: url("01-brand/Fonts/Acumin Variable/AcuminVariableConcept-subset.woff2") format("woff2-variations"),
       url("01-brand/Fonts/Acumin Variable/AcuminVariableConcept-subset.woff2") format("woff2");
  font-weight: 300 800;
  font-style: normal;
  font-display: swap;
}

:root {
  color-scheme: light;
  --green: oklch(0.364 0.047 210.2);
  --green-deep: oklch(0.28 0.046 211);
  --green-soft: oklch(0.47 0.047 210);
  --turquoise: oklch(0.693 0.089 207.6);
  --turquoise-pale: oklch(0.86 0.049 207.6);
  --pink: oklch(0.824 0.061 41.5);
  --pink-soft: oklch(0.9 0.041 42);
  --ink: oklch(0.335 0.044 207);
  --ink-soft: oklch(0.48 0.032 207);
  --shell: oklch(0.966 0.008 73.7);
  --sand: oklch(0.903 0.023 71.8);
  --sand-deep: oklch(0.82 0.035 72);
  --line: oklch(0.82 0.018 72);
  --paper: oklch(0.985 0.006 74);
  --paper-soft: oklch(0.945 0.011 74);
  --night: oklch(0.23 0.043 211);
  --veil: oklch(0.985 0.006 74 / 0.72);
  --shadow-soft: 0 22px 80px oklch(0.28 0.04 210 / 0.16);
  --shadow-deep: 0 30px 110px oklch(0.18 0.042 210 / 0.34);
  --display: "Montserrat Bayside", Montserrat, system-ui, sans-serif;
  --script: "Lora Bayside", Lora, Georgia, serif;
  --body: "Acumin Bayside", Barlow, "Avenir Next", system-ui, sans-serif;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --max: 1440px;
  /* Type weight system (bayside-v8e): three picked weights, used everywhere.
     `--w-display` for Acumin display headings (Montserrat caps run at 300 via
     @font-face), `--w-body` for paragraph copy, `--w-label` for every uppercase
     microcopy treatment — kickers, buttons, form labels, captions. */
  --w-display: 300;
  --w-body: 400;
  --w-label: 600;
  --opening-p: 0;
  --water-opacity: 1;
  --water-scale: 1;
  --water-y: 0px;
  --water-hole: 0%;
  --water-core-alpha: 1;
  --water-edge-alpha: 1;
  --brand-opacity: 1;
  --brand-y: 0px;
  --building-opacity: 0;
  --building-scale: 1;
  --building-y: 20px;
  --veil-opacity: 0;
  --copy-opacity: 0;
  --copy-y: 24px;
  --header-opacity: 0;
  --header-y: -18px;
  --nav-progress: 0;
  --nav-y: -8px;
  --cue-opacity: 1;
}

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  overflow-x: hidden;
  background:
    linear-gradient(90deg, oklch(0.364 0.047 210.2 / 0.035) 1px, transparent 1px),
    linear-gradient(0deg, oklch(0.364 0.047 210.2 / 0.026) 1px, transparent 1px),
    var(--shell);
  background-size: 72px 72px, 72px 72px, auto;
  color: var(--ink);
  font-family: var(--body);
  font-size: 17px;
  font-weight: var(--w-body);
  line-height: 1.58;
  text-rendering: geometricPrecision;
}

/* Atmospheric grain layer (bayside-v8e). DESIGN.md calls for a bitmap noise
   asset that unifies all surfaces and breaks digital flatness — this fixed
   overlay sits above scene backgrounds (z 49) but below header/drawer chrome
   (z 50+), so it tints imagery and bands without interfering with focus or
   modal stacking. soft-light keeps the tone teal-warm without bleaching whites. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 49;
  pointer-events: none;
  background-image: url("04-renderings/web/grain-overlay.svg");
  background-size: 240px 240px;
  background-repeat: repeat;
  opacity: 0.06;
  mix-blend-mode: soft-light;
}

@media (prefers-reduced-motion: reduce) {
  body::after { opacity: 0.04; }
}

body.menu-open {
  overflow: hidden;
}

img {
  display: block;
  max-width: 100%;
}

button,
input,
select {
  font: inherit;
}

a {
  color: inherit;
}

h1,
h2,
h3,
p,
figure {
  margin-top: 0;
}

.skip-link {
  position: fixed;
  z-index: 60;
  top: 14px;
  left: 14px;
  transform: translateY(-180%);
  padding: 12px 16px;
  background: var(--pink);
  color: var(--green);
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  text-decoration: none;
  transition: transform 320ms var(--ease);
}

.skip-link:focus {
  transform: translateY(0);
}

.site-header {
  position: fixed;
  z-index: 70;
  inset: 0;
  color: var(--green);
  opacity: 1;
  pointer-events: none;
  transform: none;
  transition:
    color 500ms var(--ease);
}

.opening-header-ready .site-header {
  pointer-events: none;
}

.site-header.is-solid {
  color: var(--green);
}

.brand-mark {
  display: inline-flex;
  align-items: center;
  position: fixed;
  z-index: 72;
  top: clamp(14px, 2.2vw, 24px);
  left: clamp(14px, 3vw, 40px);
  /* Header chrome rework (bayside-mgs): pure type, no chip. Color comes
     from currentColor on .site-header, which scene-tone adaptation flips. */
  padding: 0;
  border: 0;
  background: transparent;
  box-shadow: none;
  backdrop-filter: none;
  opacity: var(--header-opacity);
  /* a11y (bayside-is0): chrome is always focusable. The reveal is purely
     visual (opacity + translate driven by hero scroll progress); keyboard
     tab order is intact from first paint. The parent .site-header keeps
     pointer-events:none so the inset:0 overlay does not trap clicks; the
     children opt back in to auto so they stay clickable + focusable. */
  pointer-events: auto;
  text-decoration: none;
  transform: translate3d(0, var(--header-y), 0);
  transition:
    opacity 520ms var(--ease),
    transform 520ms var(--ease),
    color 320ms var(--ease),
    filter 320ms var(--ease);
  /* will-change intentionally absent (bayside-opp): the header reveal is a
     one-shot translate+fade tied to hero scroll progress; promoting this
     element to its own GPU layer for the entire session inflates VRAM on
     iPad without buying any motion fidelity. */
}

.brand-mark img {
  width: clamp(158px, 15vw, 224px);
  transition: filter 320ms var(--ease);
}

/* Scene-tone driven chrome color (bayside-mgs). Default: ink-on-light. When
   the IntersectionObserver in app.js detects a dark cinematic scene crossing
   the header line, body[data-header-tone="dark"] flips chrome to paper.
   The brand-mark SVG is a green-source asset, so on dark scenes it gets
   inverted to read warm-paper. */
.brand-mark,
.menu-toggle,
.desktop-nav,
.header-cta {
  color: var(--green);
}

body[data-header-tone="dark"] .brand-mark,
body[data-header-tone="dark"] .menu-toggle,
body[data-header-tone="dark"] .desktop-nav,
body[data-header-tone="dark"] .header-cta {
  color: oklch(0.96 0.011 74);
  text-shadow: 0 1px 8px oklch(0.16 0.04 210 / 0.36);
}

body[data-header-tone="dark"] .brand-mark img {
  filter: brightness(0) invert(1) saturate(0.6) sepia(0.04);
}

.desktop-nav {
  display: none;
}

.desktop-nav a,
.button,
.mobile-panel a,
.header-cta {
  text-decoration: none;
}

/* Desktop top-strip nav (bayside-v8e + bayside-mgs + bayside-9qt). At >=1100px
   the brand-mark sits top-left as pure type, the desktop-nav floats top-center
   carrying Residences / Amenities / Neighborhood / Join the Priority List as
   four inline links, and the hamburger collapses. No backgrounds, no chips,
   no pill — chrome is type-only and color-flips via body[data-header-tone]. */

@media (min-width: 1100px) {
  /* Desktop chrome (bayside-mgs): pure type. No glass chip, no pink pill,
     no underline strip. Just three text elements floating at the viewport
     edges; color tracks scene-tone. */
  .desktop-nav {
    display: inline-flex;
    align-items: center;
    position: fixed;
    z-index: 72;
    top: calc(clamp(14px, 2.2vw, 24px) + 14px);
    left: 50%;
    padding: 0;
    gap: clamp(22px, 3vw, 40px);
    border: 0;
    background: transparent;
    box-shadow: none;
    backdrop-filter: none;
    color: currentColor;
    font-size: 11px;
    font-weight: var(--w-label);
    letter-spacing: 0.16em;
    text-transform: uppercase;
    opacity: var(--header-opacity);
    /* a11y (bayside-is0): nav links are always in the tab order. Visual
       reveal is opacity + translate only; keyboard users can tab through
       Residences / Amenities / Neighborhood / CTA from first paint. */
    pointer-events: auto;
    transform: translate3d(-50%, var(--header-y), 0);
    transition:
      opacity 520ms var(--ease),
      transform 520ms var(--ease),
      color 320ms var(--ease);
    /* will-change absent (bayside-opp): one-shot reveal — see .brand-mark. */
  }

  .desktop-nav a {
    position: relative;
    padding: 6px 0;
    color: inherit;
  }

  .desktop-nav a::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: 1px;
    transform: scaleX(0);
    transform-origin: right;
    background: currentColor;
    transition: transform 420ms var(--ease);
  }

  .desktop-nav a:hover::after,
  .desktop-nav a:focus-visible::after {
    transform: scaleX(1);
    transform-origin: left;
  }

  /* CTA now lives inside .desktop-nav as the 4th link (bayside-9qt). It
     inherits the underline-on-hover treatment from .desktop-nav a; the only
     additions are an arrow that translates on hover and a slight padding
     bump so the arrow doesn't crowd the underline. */
  .desktop-nav .header-cta {
    display: inline-flex;
    align-items: center;
    padding: 6px 0;
    color: inherit;
    font: inherit;
  }

  .desktop-nav .header-cta::after {
    content: " →";
    margin-left: 8px;
    transition: transform 360ms var(--ease);
  }

  .desktop-nav .header-cta:hover::after,
  .desktop-nav .header-cta:focus-visible::after {
    transform: translate3d(4px, 0, 0);
  }

  /* a11y (bayside-is0): .opening-header-ready no longer gates focusability.
     The reveal is purely visual (opacity + translate via --header-* vars);
     desktop-nav is in the tab order from first paint. */

  /* On desktop the hamburger collapses — desktop-nav + header-cta cover the
     same affordances. Keep the toggle in the DOM for state continuity but
     visually remove it. */
  .menu-toggle {
    display: none;
  }
}

.button,
.lead-form button {
  --mx: 0px;
  --my: 0px;
  min-height: 46px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  border: 1px solid currentColor;
  padding: 0 22px;
  color: inherit;
  background: transparent;
  font-size: 11px;
  font-weight: var(--w-label);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  cursor: pointer;
  transform: translate3d(var(--mx), var(--my), 0);
  transition:
    transform 360ms var(--ease),
    background 360ms var(--ease),
    color 360ms var(--ease),
    border-color 360ms var(--ease),
    box-shadow 360ms var(--ease);
}

.button:hover,
.lead-form button:hover {
  transform: translate3d(var(--mx), calc(var(--my) - 2px), 0);
}

.button.primary:hover,
.button.primary:focus-visible,
.lead-form button:hover,
.lead-form button:focus-visible {
  background: var(--green);
  color: var(--paper);
  border-color: var(--green);
  box-shadow: 0 24px 70px oklch(0.42 0.055 42 / 0.32);
}

.button.secondary:hover,
.button.secondary:focus-visible {
  background: oklch(0.985 0.006 74 / 0.22);
  border-color: var(--paper);
  box-shadow: 0 18px 56px oklch(0.18 0.042 210 / 0.28);
}

.button.secondary.dark:hover,
.button.secondary.dark:focus-visible {
  background: var(--green);
  color: var(--paper);
  border-color: var(--green);
  box-shadow: 0 18px 56px oklch(0.28 0.04 210 / 0.24);
}

.header-sentinel {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
}

.button.primary,
.lead-form button {
  background: var(--pink);
  color: var(--green);
  border-color: var(--pink);
  box-shadow: 0 12px 36px oklch(0.42 0.055 42 / 0.24);
}

.button.secondary {
  background: oklch(0.985 0.006 74 / 0.12);
  color: var(--paper);
  border-color: oklch(0.985 0.006 74 / 0.62);
}

.button.secondary.dark {
  color: var(--green);
  border-color: oklch(0.364 0.047 210.2 / 0.28);
  background: oklch(0.985 0.006 74 / 0.58);
}

.menu-toggle {
  display: flex;
  position: fixed;
  z-index: 74;
  top: clamp(14px, 2.2vw, 24px);
  right: clamp(14px, 3vw, 40px);
  width: 36px;
  height: 36px;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 7px;
  /* Pure type chrome (bayside-mgs): no fill, no border, no shadow. The
     hamburger reads as two stacked hairlines; color tracks scene-tone. */
  border: 0;
  color: currentColor;
  background: transparent;
  box-shadow: none;
  backdrop-filter: none;
  cursor: pointer;
  opacity: var(--header-opacity);
  /* a11y (bayside-is0): hamburger is always focusable so a keyboard user
     can open the mobile nav without scrolling. Reveal is opacity-only. */
  pointer-events: auto;
  transform: translate3d(0, var(--header-y), 0);
  transition:
    opacity 520ms var(--ease),
    transform 520ms var(--ease),
    color 320ms var(--ease);
  /* will-change absent (bayside-opp): one-shot reveal — see .brand-mark. */
}

/* When the mobile menu is explicitly opened, force chrome fully visible
   regardless of scroll progress. Keyboard tab order is already permanent
   (bayside-is0) — this rule only handles the visual reveal. */
.menu-open .brand-mark,
.menu-open .menu-toggle {
  opacity: 1;
  transform: translate3d(0, 0, 0);
}

.menu-toggle span {
  display: block;
  width: 20px;
  height: 1px;
  background: currentColor;
  transition: transform 320ms var(--ease);
}

.menu-toggle[aria-expanded="true"] span:first-child {
  transform: translateY(3.75px) rotate(45deg);
}

.menu-toggle[aria-expanded="true"] span:last-child {
  transform: translateY(-3.75px) rotate(-45deg);
}

.mobile-panel {
  position: fixed;
  z-index: 48;
  top: clamp(12px, 2vw, 20px);
  right: clamp(12px, 3vw, 40px);
  bottom: clamp(12px, 2vw, 20px);
  width: min(430px, calc(100vw - 24px));
  display: grid;
  align-content: start;
  gap: 10px;
  padding: 96px 14px 14px;
  border: 1px solid oklch(0.364 0.047 210.2 / 0.18);
  background:
    linear-gradient(180deg, oklch(0.985 0.006 74 / 0.96), oklch(0.966 0.008 73.7 / 0.92)),
    var(--shell);
  color: var(--green);
  box-shadow: var(--shadow-deep);
  backdrop-filter: blur(20px) saturate(1.1);
  transform-origin: right center;
  animation: drawerReveal 420ms var(--ease) both;
}

.mobile-panel[hidden] {
  display: none;
}

.mobile-panel a {
  min-height: 58px;
  display: flex;
  align-items: center;
  padding: 0 18px;
  border: 1px solid oklch(0.364 0.047 210.2 / 0.12);
  background: oklch(0.985 0.006 74 / 0.62);
  font-size: 12px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.hero {
  --hero-x: 0;
  --hero-y: 0;
  position: relative;
  min-height: 100dvh;
  overflow: hidden;
  display: grid;
  align-items: end;
  isolation: isolate;
  color: var(--paper);
  background: var(--night);
}

.hero-media,
.hero-media img,
.hero-shade {
  position: absolute;
  inset: 0;
}

.hero-media {
  z-index: -3;
  overflow: hidden;
}

.hero-media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 58% 52%;
  transform: scale(1.08) translate3d(calc(var(--hero-x) * -6px), calc(var(--hero-y) * -4px), 0);
  animation: heroBreathe 18000ms var(--ease-out) forwards;
  /* will-change absent (bayside-opp): heroBreathe is a forwards animation
     that settles in 18s; permanently promoting the hero <img> to its own
     compositor layer leaves a high-resolution texture pinned in VRAM for
     the rest of the session. */
}

.hero-shade {
  z-index: -2;
  background:
    linear-gradient(90deg, oklch(0.18 0.043 211 / 0.92), oklch(0.2 0.043 211 / 0.56) 38%, oklch(0.2 0.043 211 / 0.1) 70%),
    linear-gradient(0deg, oklch(0.16 0.043 211 / 0.72), transparent 52%);
}

.hero-grid {
  width: min(var(--max), calc(100% - clamp(32px, 7vw, 112px)));
  min-height: calc(100dvh - 136px);
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 0.98fr) minmax(320px, 0.62fr);
  gap: clamp(34px, 7vw, 104px);
  align-items: end;
  padding: clamp(128px, 15vw, 190px) 0 clamp(112px, 12vw, 168px);
}

.hero-content {
  min-width: 0;
  width: 100%;
  max-width: 780px;
}

.eyebrow,
.section-kicker {
  margin: 0 0 18px;
  color: currentColor;
  font-size: 11px;
  font-weight: var(--w-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* Kicker variants (bayside-v8e). The default treatment repeats across 8+
   sections; these modifiers introduce rhythm without inventing a new component.
   --accent leads with a turquoise hairline rule. --tinted swaps to turquoise
   color on light surfaces. --numeral pairs the kicker with a small numeric
   prefix (e.g., "03 — Residences"). */
.section-kicker--accent {
  display: inline-flex;
  align-items: center;
  gap: 14px;
}

.section-kicker--accent::before {
  content: "";
  width: clamp(28px, 4vw, 56px);
  height: 1px;
  background: currentColor;
  opacity: 0.5;
}

.section-kicker--tinted {
  color: var(--turquoise);
}

.section-kicker--numeral::before {
  content: attr(data-numeral) " — ";
  letter-spacing: 0.16em;
  opacity: 0.6;
}

h1 {
  max-width: 820px;
  margin-bottom: 24px;
  font-family: var(--display);
  font-size: clamp(62px, 9vw, 134px);
  font-weight: 300;
  line-height: 0.92;
  letter-spacing: 0;
  text-transform: uppercase;
  text-wrap: balance;
}

.hero-copy {
  width: min(100%, 660px);
  margin-bottom: 34px;
  color: oklch(0.93 0.014 74);
  font-size: clamp(18px, 2vw, 24px);
  line-height: 1.45;
}

.hero-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
}

.hero-collage {
  position: relative;
  min-height: clamp(430px, 48vw, 670px);
}

.collage-frame,
.priority-note {
  position: absolute;
  margin: 0;
  box-shadow: var(--shadow-deep);
  transition: transform 900ms var(--ease), box-shadow 600ms var(--ease);
}

.collage-frame::before,
.lead-form::before,
.gallery-main::before,
.gallery-inset::before,
.neighborhood-visual::before {
  content: "";
  position: absolute;
  inset: 10px;
  pointer-events: none;
  border: 1px solid oklch(0.985 0.006 74 / 0.54);
  z-index: 2;
}

.collage-frame img,
.priority-note {
  width: 100%;
  height: 100%;
}

.collage-frame img {
  object-fit: cover;
}

.frame-arrival {
  top: 0;
  right: 2%;
  width: min(410px, 78%);
  aspect-ratio: 0.78;
  transform: translate3d(calc(var(--hero-x) * 12px), calc(var(--hero-y) * 10px), 0) rotate(2.5deg);
}

.frame-lobby {
  left: 0;
  bottom: 0;
  width: min(360px, 68%);
  aspect-ratio: 0.92;
  transform: translate3d(calc(var(--hero-x) * -10px), calc(var(--hero-y) * -7px), 0) rotate(-4deg);
}

.priority-note {
  right: 0;
  bottom: 12%;
  z-index: 3;
  width: min(250px, 58%);
  height: auto;
  min-height: 142px;
  display: grid;
  align-content: end;
  gap: 12px;
  padding: 22px;
  border: 1px solid oklch(0.985 0.006 74 / 0.32);
  background: oklch(0.985 0.006 74 / 0.86);
  color: var(--green);
  box-shadow: 0 22px 60px oklch(0.16 0.04 210 / 0.25);
  transform: translate3d(calc(var(--hero-x) * 7px), calc(var(--hero-y) * 8px), 0);
}

.priority-note span {
  font-size: 10px;
  font-weight: var(--w-label);
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.priority-note strong {
  font-family: var(--script);
  font-size: clamp(24px, 3vw, 34px);
  font-style: italic;
  font-weight: 400;
  line-height: 1;
}

.hero-facts {
  position: absolute;
  left: clamp(16px, 4vw, 52px);
  right: clamp(16px, 4vw, 52px);
  bottom: 22px;
  z-index: 2;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1px;
  border: 1px solid oklch(0.985 0.006 74 / 0.24);
  background: oklch(0.985 0.006 74 / 0.1);
  backdrop-filter: blur(14px);
}

.hero-facts span {
  min-height: 52px;
  display: flex;
  align-items: center;
  padding: 0 clamp(12px, 2vw, 22px);
  color: oklch(0.94 0.012 74);
  font-size: 11px;
  font-weight: var(--w-label);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.opening-hero {
  min-height: 255vh;
  display: block;
  overflow: visible;
  color: var(--paper);
  background:
    linear-gradient(180deg, oklch(0.88 0.035 205), oklch(0.72 0.082 207));
}

.opening-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  min-height: 620px;
  overflow: hidden;
  isolation: isolate;
  background: oklch(0.72 0.082 207);
}

.water-layer,
.building-layer,
.water-veil {
  position: absolute;
  inset: 0;
}

.building-layer {
  z-index: 1;
  margin: 0;
  opacity: var(--building-opacity);
  transform: translate3d(0, var(--building-y), 0) scale(var(--building-scale));
  transform-origin: 50% 50%;
  /* will-change absent (bayside-opp): the building-layer is only scrubbed
     during the opening hero pin (one viewport). Once the user scrolls past
     the hero, the layer never animates again — keeping it on the compositor
     for the rest of the session is pure cost. */
}

.building-layer img,
.water-layer img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.building-layer img {
  object-position: 58% 52%;
}

.building-layer::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(90deg, oklch(0.18 0.043 211 / 0.62), oklch(0.2 0.043 211 / 0.2) 42%, transparent 68%),
    linear-gradient(0deg, oklch(0.16 0.043 211 / 0.62), transparent 54%);
  pointer-events: none;
}

/* Painted Curtain stroke field — the watercolor wash is composed from
   discrete vertical brush stroke PNGs that translate horizontally on
   scroll (curtain parting). See lib/hero/strokes.js + dom.js. */
.stroke-field {
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
}

.stroke-field .stroke {
  position: absolute;
  /* Set by JS: left/top from anchorX/anchorY, transform from engine. */
  height: min(96vh, 1100px);
  width: auto;
  max-width: 320px;
  /* The translate(-50%, -50%) inside the JS-applied transform centers
     the stroke on its anchor point; will-change keeps the layer on the
     compositor for 60fps drift. */
  will-change: transform, opacity;
  user-select: none;
}

/* stroke-09 is the widest brush (natural 626x1400, ratio 0.45). The
   shared 320px max-width crushes its aspect ratio and trips Lighthouse's
   image-aspect-ratio audit. Lift the cap so it renders at natural ratio
   off its computed height. See bayside-7uf.2. */
.stroke-field .stroke[data-stroke-index="8"] {
  max-width: min(495px, 50vw);
}

/* Paint-on intro: when setupStrokeField is called with { intro: true },
   each stroke gets a randomized --intro-delay and fades in. The engine
   skips opacity writes while data-intro-active is set on the field, so
   the animation owns opacity until it completes. */
@keyframes strokeIntro {
  from {
    opacity: 0;
    transform: translate(-50%, -50%) translate3d(0, 14px, 0) scale(0.96);
  }
  to {
    opacity: 1;
    transform: translate(-50%, -50%) translate3d(0, 0, 0) scale(1);
  }
}

.stroke-field[data-intro-active="true"] .stroke {
  animation: strokeIntro 380ms cubic-bezier(0.18, 0.84, 0.24, 1) var(--intro-delay, 0ms) both;
}

@media (prefers-reduced-motion: reduce) {
  .stroke-field[data-intro-active="true"] .stroke {
    animation: none;
  }
}

.water-veil {
  z-index: 3;
  opacity: var(--veil-opacity);
  background:
    radial-gradient(circle at 46% 40%, oklch(0.966 0.008 74 / 0.12), transparent 34%),
    linear-gradient(110deg, transparent 0%, oklch(0.77 0.07 207 / 0.24) 42%, oklch(0.966 0.008 74 / 0.1) 58%, transparent 100%);
  mix-blend-mode: screen;
  pointer-events: none;
}

.brand-lockup {
  position: absolute;
  z-index: 5;
  left: 50%;
  top: 50%;
  width: min(660px, 78vw);
  opacity: var(--brand-opacity);
  transform: translate3d(-50%, calc(-50% + var(--brand-y)), 0);
  /* will-change absent (bayside-opp): the lockup fades and translates
     during the hero pin only. After the hero, the element either holds
     state or is offscreen — promoting it permanently is wasted VRAM. */
}

.brand-lockup img {
  width: 100%;
  height: auto;
  /* Subtle drop-shadow only — gives the dark teal logo lines a soft
     edge against the painted brush field without a backdrop. */
  filter: drop-shadow(0 4px 14px oklch(0.20 0.04 210 / 0.28));
}

/* Brand surface unification (bayside-v8e.14): a quiet hairline rule below the
   hero lockup, echoing the kicker--accent language and tying the hero brand
   surface to the footer brand block (same hairline, same proportions). */
.brand-lockup::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: clamp(-44px, -3.4vw, -28px);
  width: clamp(40px, 6vw, 72px);
  height: 1px;
  background: oklch(0.985 0.006 74 / 0.62);
  transform: translateX(-50%);
  opacity: var(--brand-opacity);
  pointer-events: none;
  transition: opacity 480ms var(--ease);
}

.opening-copy {
  position: absolute;
  z-index: 6;
  left: clamp(22px, 6vw, 86px);
  bottom: clamp(88px, 12vh, 150px);
  width: min(760px, 82vw);
  max-width: none;
  opacity: var(--copy-opacity);
  transform: translate3d(0, var(--copy-y), 0);
  text-shadow: 0 18px 58px oklch(0.16 0.03 210 / 0.42);
  /* will-change absent (bayside-opp): forwards-finished hero copy reveal —
     same rationale as .brand-lockup. */
}

.opening-copy h1 {
  max-width: 12ch;
  margin: 0;
  font-size: clamp(48px, 8vw, 126px);
  line-height: 0.98;
}

.opening-copy .hero-copy {
  width: min(100%, 520px);
  margin: 22px 0 0;
  color: oklch(0.93 0.014 74);
  font-family: var(--script);
  font-size: clamp(19px, 1.9vw, 27px);
  font-style: italic;
  line-height: 1.5;
}

.opening-copy .hero-actions {
  margin-top: 32px;
}

.scroll-cue {
  position: absolute;
  z-index: 7;
  left: 50%;
  bottom: max(34px, env(safe-area-inset-bottom));
  display: grid;
  justify-items: center;
  gap: 14px;
  color: var(--green);
  opacity: var(--cue-opacity);
  transform: translateX(-50%);
  text-decoration: none;
  pointer-events: auto;
}

.scroll-cue span {
  min-height: 38px;
  display: inline-flex;
  align-items: center;
  padding: 0 18px;
  border: 1px solid oklch(0.364 0.047 210.2 / 0.18);
  background: oklch(0.985 0.006 74 / 0.62);
  box-shadow: 0 12px 40px oklch(0.2 0.04 210 / 0.1);
  backdrop-filter: blur(12px);
  font-size: 12px;
  font-weight: var(--w-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.scroll-cue i {
  display: block;
  width: 2px;
  height: 56px;
  overflow: hidden;
  background: oklch(0.364 0.047 210.2 / 0.34);
}

.scroll-cue i::after {
  content: "";
  display: block;
  width: 2px;
  height: 22px;
  background: var(--green);
  animation: cueLine 1800ms var(--ease-out) infinite;
}

.band,
.priority-band,
.arrival-journey,
.residence-band,
.neighborhood {
  padding: clamp(86px, 12vw, 168px) clamp(20px, 6vw, 96px);
}

.intro {
  display: grid;
  grid-template-columns: minmax(0, 0.95fr) minmax(300px, 0.48fr);
  gap: clamp(34px, 7vw, 116px);
  align-items: end;
  width: min(var(--max), 100%);
  margin: 0 auto;
  background: transparent;
}

.intro h2,
.priority-copy h2,
.section-head h2,
.residence-copy h2,
.neighborhood-copy h2,
.closing-copy h2 {
  margin-bottom: 0;
  font-family: var(--script);
  font-size: clamp(40px, 6.2vw, 88px);
  font-style: italic;
  font-weight: 400;
  line-height: 0.99;
  letter-spacing: 0;
  text-wrap: balance;
}

.intro-body,
.priority-copy p,
.residence-copy p,
.neighborhood-copy p {
  max-width: 720px;
  color: var(--ink-soft);
  font-size: clamp(17px, 1.65vw, 21px);
}

/* Scene 05 — Gather: migrated to lib/scene-05-gather/styles.module.css (bayside-fgs). */

.render-reel {
  overflow: hidden;
  background: var(--green);
  color: var(--paper);
}

.reel-heading {
  width: min(var(--max), 100%);
  margin: 0 auto clamp(34px, 5vw, 62px);
  display: grid;
  grid-template-columns: minmax(0, 0.65fr) minmax(260px, 0.35fr);
  gap: 36px;
  align-items: end;
}

.reel-heading h2 {
  margin-bottom: 0;
  font-family: var(--display);
  font-size: clamp(42px, 7.5vw, 106px);
  font-weight: var(--w-display);
  line-height: 0.94;
  text-transform: uppercase;
  text-wrap: balance;
}

.reel-mask {
  margin-left: max(0px, calc((100vw - var(--max)) / 2));
  overflow: visible;
}

.reel-track {
  display: flex;
  align-items: center;
  gap: clamp(14px, 2.2vw, 28px);
  width: max-content;
  animation: reelDrift 48000ms linear infinite;
}

.reel-mask:hover .reel-track {
  animation-play-state: paused;
}

.reel-card {
  position: relative;
  flex: 0 0 clamp(250px, 28vw, 420px);
  aspect-ratio: 0.88;
  margin: 0;
  overflow: hidden;
  background: var(--green-deep);
  box-shadow: var(--shadow-deep);
}

.reel-card.tall {
  flex-basis: clamp(230px, 25vw, 350px);
  aspect-ratio: 0.72;
  transform: translateY(clamp(18px, 4vw, 54px));
}

.reel-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.03);
  transition: transform 900ms var(--ease);
}

.reel-card:hover img {
  transform: scale(1.08);
}

.reel-card figcaption {
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 14px;
  min-height: 42px;
  display: flex;
  align-items: center;
  padding: 0 14px;
  background: oklch(0.985 0.006 74 / 0.82);
  color: var(--green);
  font-size: 11px;
  font-weight: var(--w-label);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.priority-band {
  display: grid;
  grid-template-columns: minmax(0, 0.86fr) minmax(340px, 560px);
  gap: clamp(40px, 7vw, 120px);
  align-items: start;
  background:
    linear-gradient(115deg, oklch(0.903 0.023 71.8 / 0.94), oklch(0.985 0.006 74 / 0.8)),
    var(--sand);
}

.priority-copy {
  position: sticky;
  top: 128px;
  max-width: 760px;
}

.priority-copy h2 {
  margin-bottom: 28px;
}

.priority-list {
  display: grid;
  gap: 12px;
  padding: 0;
  margin: 34px 0 0;
  list-style: none;
}

.priority-list li {
  position: relative;
  padding: 16px 18px 16px 46px;
  border: 1px solid oklch(0.364 0.047 210.2 / 0.16);
  background: oklch(0.985 0.006 74 / 0.54);
  color: var(--green);
}

.priority-list li::before {
  content: "";
  position: absolute;
  left: 18px;
  top: 50%;
  width: 12px;
  height: 12px;
  border: 1px solid var(--turquoise);
  transform: translateY(-50%) rotate(45deg);
  background: var(--pink);
}

.lead-form {
  position: relative;
  display: grid;
  gap: 16px;
  padding: clamp(24px, 4vw, 44px);
  border: 1px solid oklch(0.364 0.047 210.2 / 0.15);
  background: var(--paper);
  color: var(--ink);
  box-shadow: var(--shadow-soft);
}

.lead-form::before {
  border-color: oklch(0.364 0.047 210.2 / 0.12);
}

.form-head {
  display: grid;
  gap: 8px;
  margin-bottom: 10px;
}

.form-head span,
.field > span,
.field-hint,
.field-error,
.form-status {
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.form-head span {
  color: var(--ink-soft);
  font-weight: var(--w-label);
}

.form-head strong {
  font-family: var(--script);
  font-size: clamp(28px, 4vw, 44px);
  font-style: italic;
  font-weight: 400;
  line-height: 1.04;
}

.field {
  display: grid;
  gap: 7px;
}

.field > span {
  color: var(--green);
  font-weight: var(--w-label);
}

input,
select {
  width: 100%;
  min-height: 52px;
  border: 1px solid var(--line);
  border-radius: 0;
  background: var(--shell);
  color: var(--ink);
  padding: 12px 14px;
  transition: border-color 260ms var(--ease), background 260ms var(--ease), box-shadow 260ms var(--ease);
}

input:hover,
select:hover {
  border-color: oklch(0.364 0.047 210.2 / 0.42);
}

input:focus,
select:focus,
button:focus-visible,
a:focus-visible {
  outline: 3px solid var(--turquoise);
  outline-offset: 4px;
}

/* Focus inset on form fields (bayside-v8e.10). border-radius:0 is preserved
   site-wide, but the hard edges read utilitarian when active. A 2px inner
   turquoise glow under the existing outline adds depth on focus without
   softening any corner. */
input:focus,
select:focus {
  border-color: var(--turquoise);
  box-shadow: inset 0 0 0 2px oklch(0.693 0.089 207.6 / 0.18);
  background: var(--paper);
}

input[aria-invalid="true"] {
  border-color: oklch(0.58 0.12 28);
  background: oklch(0.97 0.018 41);
}

.field-hint {
  color: var(--ink-soft);
  letter-spacing: 0.06em;
  text-transform: none;
}

.field-error {
  min-height: 16px;
  color: oklch(0.47 0.12 28);
  font-weight: var(--w-label);
}

.checkbox {
  display: grid;
  grid-template-columns: 22px 1fr;
  gap: 12px;
  align-items: start;
  color: var(--ink-soft);
  line-height: 1.4;
}

.checkbox input {
  width: 20px;
  min-height: 20px;
  margin: 2px 0 0;
  accent-color: var(--green);
}

.lead-form button {
  width: 100%;
  margin-top: 4px;
}

.lead-form button:disabled {
  cursor: default;
  opacity: 0.74;
  transform: none;
}

.form-status {
  min-height: 18px;
  margin: 0;
  color: var(--green);
  font-weight: var(--w-label);
}

.arrival-journey {
  background: var(--paper);
}

.section-head {
  width: min(var(--max), 100%);
  margin: 0 auto clamp(42px, 7vw, 92px);
  display: grid;
  grid-template-columns: minmax(0, 0.82fr) minmax(260px, 0.32fr);
  gap: clamp(28px, 5vw, 72px);
  align-items: end;
}

.section-head.contrast {
  color: var(--paper);
}

.scene-stack {
  width: min(var(--max), 100%);
  margin: 0 auto;
  display: grid;
  gap: clamp(38px, 7vw, 92px);
}

.scene-card {
  display: grid;
  grid-template-columns: minmax(0, 0.78fr) minmax(260px, 0.38fr);
  gap: clamp(22px, 4vw, 54px);
  align-items: end;
  width: min(1120px, 100%);
}

.scene-card.offset {
  justify-self: end;
  width: min(940px, 92%);
  grid-template-columns: minmax(240px, 0.44fr) minmax(0, 0.56fr);
}

.scene-card.reverse {
  justify-self: center;
  grid-template-columns: minmax(260px, 0.36fr) minmax(0, 0.74fr);
}

.scene-card.reverse picture {
  order: 2;
}

.scene-card picture {
  aspect-ratio: 1.42;
  overflow: hidden;
  box-shadow: var(--shadow-soft);
}

.scene-card.offset picture {
  aspect-ratio: 0.82;
}

.scene-card img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 1100ms var(--ease), filter 1100ms var(--ease);
}

.scene-card:hover img,
.scene-card:focus-within img {
  transform: scale(1.045);
  filter: saturate(1.06);
}

.scene-card h3 {
  transition: transform 520ms var(--ease), color 520ms var(--ease);
}

.scene-card:hover h3,
.scene-card:focus-within h3 {
  transform: translate3d(4px, 0, 0);
  color: var(--green);
}

.scene-card div {
  padding-bottom: clamp(8px, 3vw, 36px);
}

/* Default editorial label treatment for amenity scene-tags. */
.amenity-feature span,
.amenity-note span {
  display: inline-flex;
  margin-bottom: 14px;
  color: var(--turquoise);
  font-size: 11px;
  font-weight: var(--w-label);
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* Arrival-journey numerals (bayside-v8e). The 01 / 02 / 03 markers in the
   arrival sequence carry the editorial weight of the section — promote them
   from forgettable badges to display-scale numerals in Montserrat Light. */
.scene-stack .scene-card span {
  display: block;
  margin-bottom: clamp(6px, 0.6vw, 12px);
  font-family: var(--display);
  font-size: clamp(54px, 7vw, 96px);
  font-weight: var(--w-display);
  letter-spacing: -0.01em;
  line-height: 1;
  color: var(--turquoise);
  opacity: 0.78;
  text-transform: none;
}

.scene-card h3,
.amenity-feature h3 {
  margin-bottom: 14px;
  font-family: var(--display);
  font-size: clamp(28px, 4.8vw, 58px);
  font-weight: var(--w-display);
  line-height: 0.98;
  text-transform: uppercase;
  text-wrap: balance;
}

.scene-card p,
.amenity-note p {
  margin-bottom: 0;
  color: var(--ink-soft);
}

/* Residence band/copy/gallery: migrated to lib/scene-08-residences/styles.module.css (bayside-fgs). */
.residence-copy h2,
.neighborhood-copy h2,
.closing-copy h2 {
  margin-bottom: 28px;
}

/* Scene 07 — Stay Active & Well: migrated to lib/scene-07-active-well/styles.module.css (bayside-fgs). */

.amenity-grid {
  width: min(var(--max), 100%);
  margin: 0 auto;
  display: grid;
  grid-template-columns: minmax(0, 0.9fr) minmax(280px, 0.42fr) minmax(280px, 0.52fr);
  grid-template-rows: minmax(230px, auto) minmax(260px, auto);
  gap: clamp(14px, 2vw, 24px);
}

.amenity-feature,
.amenity-note {
  position: relative;
  overflow: hidden;
  min-height: 340px;
  display: grid;
  align-content: end;
  background: var(--green-deep);
}

.amenity-feature.large {
  grid-row: span 2;
  min-height: 680px;
}

.amenity-feature.garden {
  grid-column: span 2;
}

.amenity-feature.lounge {
  min-height: 360px;
}

.amenity-feature img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transform: scale(1.02);
  transition: transform 1100ms var(--ease), filter 1100ms var(--ease);
}

.amenity-feature::after,
.closing-cta::after,
.neighborhood-visual::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(0deg, oklch(0.17 0.043 211 / 0.82), transparent 58%);
}

.amenity-feature:hover img {
  filter: saturate(1.06);
  transform: scale(1.06);
}

.amenity-feature div,
.amenity-note {
  position: relative;
  z-index: 2;
}

.amenity-feature div {
  max-width: 600px;
  padding: clamp(22px, 4vw, 42px);
}

.amenity-feature span,
.amenity-note span {
  color: var(--pink);
}

.amenity-feature h3 {
  margin-bottom: 0;
  color: var(--paper);
}

.amenity-note {
  min-height: 100%;
  padding: clamp(22px, 3vw, 34px);
  border: 1px solid oklch(0.985 0.006 74 / 0.14);
  background:
    linear-gradient(135deg, oklch(0.985 0.006 74 / 0.11), transparent),
    var(--green);
}

.amenity-note p {
  color: oklch(0.91 0.015 74);
  font-size: clamp(18px, 2vw, 22px);
}

.neighborhood {
  display: grid;
  grid-template-columns: minmax(0, 0.78fr) minmax(300px, 0.42fr);
  gap: clamp(34px, 7vw, 104px);
  align-items: center;
  background: var(--sand);
}

.neighborhood-visual {
  position: relative;
  min-height: clamp(480px, 58vw, 760px);
  overflow: hidden;
  box-shadow: var(--shadow-soft);
}

.neighborhood-visual img {
  width: 100%;
  height: 100%;
  min-height: inherit;
  object-fit: cover;
}

.neighborhood-visual::after {
  background:
    linear-gradient(0deg, oklch(0.18 0.043 211 / 0.58), transparent 46%),
    linear-gradient(90deg, oklch(0.18 0.043 211 / 0.24), transparent 42%);
}

.map-overlay {
  position: absolute;
  inset: 9%;
  z-index: 3;
  border: 1px solid oklch(0.985 0.006 74 / 0.48);
}

.map-overlay::before,
.map-overlay::after {
  content: "";
  position: absolute;
  inset: 22% 8%;
  border: 1px solid oklch(0.985 0.006 74 / 0.34);
  transform: rotate(-9deg);
}

.map-overlay::after {
  inset: 8% 24%;
  transform: rotate(15deg);
}

.map-pin {
  position: absolute;
  z-index: 4;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 82px;
  min-height: 34px;
  padding: 0 12px;
  background: var(--paper);
  color: var(--green);
  box-shadow: 0 12px 28px oklch(0.16 0.043 211 / 0.24);
  font-size: 10px;
  font-weight: var(--w-label);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

.map-pin.bay {
  left: 8%;
  top: 15%;
}

.map-pin.arts {
  right: 9%;
  top: 28%;
}

.map-pin.home {
  left: 42%;
  top: 50%;
  background: var(--pink);
}

.map-pin.dining {
  right: 15%;
  bottom: 17%;
}

.closing-cta {
  position: relative;
  min-height: 78dvh;
  display: grid;
  align-items: end;
  overflow: hidden;
  color: var(--paper);
  background: var(--green);
}

.closing-cta picture,
.closing-cta picture img,
.closing-cta-loop {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.closing-cta picture img,
.closing-cta-loop {
  object-fit: cover;
}

.closing-cta-loop {
  z-index: 0;
}

.closing-copy p:not(.section-kicker) {
  max-width: 560px;
  color: oklch(0.91 0.015 74);
  font-size: clamp(18px, 1.7vw, 22px);
  line-height: 1.5;
}

.closing-italic {
  margin-top: 14px;
  font-family: var(--script);
  font-style: italic;
  font-size: clamp(20px, 2.1vw, 28px) !important;
  line-height: 1.35;
  color: oklch(0.94 0.014 74) !important;
}

/* Trust band (bayside-v8e.13). The missing closing trust beat between the
   Scene 09 neighborhood map and the closing CTA. One Lora-italic sentence,
   two partner marks rendered dark on sand so they read as quiet credits
   rather than promotional logos. */
.trust-band {
  display: grid;
  align-items: center;
  justify-items: center;
  gap: clamp(28px, 4.5vw, 64px);
  width: 100%;
  margin: 0;
  padding: clamp(72px, 9vw, 132px) clamp(20px, 6vw, 96px);
  background: var(--sand);
  text-align: center;
}

.trust-band-line {
  margin: 0;
  max-width: 760px;
  font-family: var(--script);
  font-style: italic;
  font-size: clamp(20px, 2.4vw, 30px);
  line-height: 1.45;
  color: var(--green);
  text-wrap: balance;
}

.trust-band-partners {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: clamp(40px, 7vw, 110px);
  flex-wrap: wrap;
  margin: 0;
  padding: 0;
  list-style: none;
}

.trust-band-partners li {
  display: inline-flex;
}

.trust-band-partners a {
  display: inline-flex;
  align-items: center;
  text-decoration: none;
}

.trust-band-partners img {
  max-height: clamp(38px, 4vw, 52px);
  width: auto;
  filter: brightness(0);
  opacity: 0.42;
  transition:
    opacity 320ms var(--ease-out),
    transform 320ms var(--ease-out);
}

.trust-band-partners a:hover img,
.trust-band-partners a:focus-visible img {
  opacity: 0.78;
  transform: translate3d(0, -1px, 0);
}

.priority-noscript {
  position: relative;
  z-index: 3;
  width: min(760px, calc(100% - 32px));
  margin: 0 auto clamp(40px, 7vw, 80px);
  padding: clamp(24px, 4vw, 44px);
  background: var(--paper);
  color: var(--ink);
}

.closing-copy {
  position: relative;
  z-index: 2;
  width: min(980px, calc(100% - clamp(36px, 10vw, 160px)));
  margin: 0 auto;
  padding: clamp(110px, 14vw, 180px) 0 clamp(70px, 9vw, 120px);
}

.closing-copy .button {
  margin-top: 30px;
}

.site-footer {
  display: grid;
  grid-template-columns:
    minmax(180px, 0.9fr)
    minmax(220px, 1.05fr)
    minmax(150px, 0.65fr)
    minmax(150px, 0.65fr)
    minmax(170px, 0.75fr)
    minmax(140px, 0.6fr);
  align-items: start;
  gap: clamp(24px, 4vw, 58px);
  padding: clamp(40px, 6vw, 76px) clamp(20px, 7vw, 112px);
  background: var(--green-deep);
  color: var(--paper);
}

.site-footer img {
  width: min(230px, 42vw);
}

/* Brand logo on dark green-deep — source is brand-green so invert it
   to a warm off-white that matches the partner logos' designed fill (#f5f0e8). */
.site-footer-brand img {
  filter: brightness(0) invert(1) sepia(0.04) saturate(0.6);
}

.site-footer-brand,
.site-footer-contact,
.site-footer-quick-links,
.site-footer-legal,
.site-footer-partners,
.site-footer-social {
  display: grid;
  gap: 11px;
}

.site-footer-brand {
  gap: 16px;
}

.site-footer-tagline {
  position: relative;
  margin: 0;
  padding-top: 16px;
  font-family: var(--script);
  font-size: clamp(18px, 2vw, 24px);
  line-height: 1.15;
  color: var(--turquoise-pale);
}

/* Brand surface unification (bayside-v8e.14): hairline rule between the footer
   typographic logo and "Bespoke Coastal Living" tagline — same proportions
   and language as the hero brand-lockup hairline and the kicker--accent. */
.site-footer-tagline::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: clamp(28px, 4vw, 56px);
  height: 1px;
  background: oklch(0.985 0.006 74 / 0.42);
}

.site-footer-contact {
  margin: 0;
  font-style: normal;
}

.site-footer-contact span {
  display: block;
}

.site-footer-logo-link {
  display: inline-flex;
  width: fit-content;
}

.site-footer a {
  color: var(--paper);
  text-decoration-color: oklch(0.985 0.006 74 / 0.38);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.22em;
  transition:
    color 180ms var(--ease-out),
    text-decoration-color 180ms var(--ease-out);
}

.site-footer a:hover,
.site-footer a:focus-visible {
  color: var(--turquoise-pale);
  text-decoration-color: currentColor;
}

.site-footer a:focus-visible {
  outline: 2px solid var(--pink);
  outline-offset: 4px;
}

.site-footer-cta {
  justify-self: start;
}

.site-footer-cta a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 11px 16px;
  border: 1px solid oklch(0.985 0.006 74 / 0.42);
  text-decoration: none;
  font-size: 13px;
  line-height: 1;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.site-footer-cta a:hover,
.site-footer-cta a:focus-visible {
  border-color: var(--turquoise-pale);
}

.site-footer-partners {
  grid-column: 1 / -1;
  grid-template-columns: repeat(2, minmax(160px, 220px));
  align-items: center;
  gap: 16px clamp(20px, 4vw, 48px);
  padding-top: 24px;
  border-top: 1px solid oklch(0.985 0.006 74 / 0.18);
}

.site-footer-partners a {
  display: inline-flex;
  min-height: 56px;
  align-items: center;
}

.site-footer-partners img {
  width: 100%;
  max-height: 56px;
  object-fit: contain;
  opacity: 0.72;
  transition:
    opacity 320ms var(--ease-out),
    transform 320ms var(--ease-out);
}

.site-footer-partners a:hover img,
.site-footer-partners a:focus-visible img {
  opacity: 1;
  transform: translate3d(0, -1px, 0);
}

.site-footer-social a {
  font-size: 13px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.site-footer p {
  max-width: 520px;
  margin: 0;
  color: oklch(0.9 0.018 74);
  font-size: 14px;
}

.site-footer-legal-copy {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  gap: 10px clamp(18px, 3vw, 34px);
  padding-top: 24px;
  border-top: 1px solid oklch(0.985 0.006 74 / 0.2);
}

.site-footer-disclaimer {
  flex: 1 1 360px;
}

[data-reveal] {
  opacity: 0;
  transform: translate3d(0, 30px, 0) scale(0.985);
  transition:
    opacity 900ms var(--ease),
    transform 900ms var(--ease);
  transition-delay: var(--delay, 0ms);
  /* will-change absent (bayside-opp): the [data-reveal] system fires once
     per element when it enters the viewport (see app.js IntersectionObserver
     adding .is-visible). Promoting every reveal target to its own GPU layer
     for the entire session — when the animation runs once and never again —
     is the "use sparingly" rule's textbook violation. */
}

/* Stagger pattern (bayside-v8e). Replaces inline style="--delay: NNNms" with
   a single attribute. Keeps the inline-style escape hatch for one-offs while
   making the common cadence declarative. */
[data-reveal][data-stagger="1"] { --delay: 110ms; }
[data-reveal][data-stagger="2"] { --delay: 220ms; }
[data-reveal][data-stagger="3"] { --delay: 330ms; }
[data-reveal][data-stagger="4"] { --delay: 440ms; }

[data-reveal].is-visible {
  opacity: 1;
  transform: translate3d(0, 0, 0) scale(1);
}

@keyframes heroBreathe {
  to {
    transform: scale(1) translate3d(calc(var(--hero-x) * -6px), calc(var(--hero-y) * -4px), 0);
  }
}

@keyframes reelDrift {
  to {
    transform: translate3d(calc(-50% - clamp(7px, 1.1vw, 14px)), 0, 0);
  }
}

@keyframes menuReveal {
  from {
    opacity: 0;
    transform: translate3d(0, -12px, 0) scaleY(0.96);
  }
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0) scaleY(1);
  }
}

@keyframes drawerReveal {
  from {
    opacity: 0;
    transform: translate3d(18px, 0, 0) scaleX(0.98);
  }
  to {
    opacity: 1;
    transform: translate3d(0, 0, 0) scaleX(1);
  }
}

@keyframes cueLine {
  0% {
    opacity: 0;
    transform: translateY(-18px);
  }
  30% {
    opacity: 1;
  }
  100% {
    opacity: 0;
    transform: translateY(52px);
  }
}

@media (max-width: 1100px) {
  .hero-grid,
  .priority-band,
  .residence-band,
  .neighborhood {
    grid-template-columns: 1fr;
  }

  .hero-collage {
    min-height: 420px;
  }

  .priority-copy {
    position: static;
  }

  .amenity-grid {
    grid-template-columns: 1fr 1fr;
  }

  .amenity-feature.large,
  .amenity-feature.garden,
  .amenity-feature.lounge {
    grid-column: auto;
    grid-row: auto;
    min-height: 460px;
  }

  .amenity-note {
    min-height: 260px;
  }

  .site-footer {
    grid-template-columns: minmax(180px, 0.9fr) minmax(220px, 1fr);
  }

  .site-footer-legal-copy {
    grid-column: 1 / -1;
  }
}

@media (max-width: 880px) {
  body {
    font-size: 16px;
  }

  .site-header {
    inset: 0;
  }

  .menu-toggle {
    display: flex;
  }

  .brand-mark img {
    width: 156px;
  }

  .hero-grid {
    width: calc(100vw - 32px);
    max-width: calc(100vw - 32px);
    min-height: auto;
    padding: 126px 0 28px;
  }

  .opening-hero {
    min-height: 210vh;
  }

  .opening-stage {
    min-height: 100vh;
  }

  .brand-lockup {
    width: min(420px, 82vw);
  }

  .opening-copy {
    left: 20px;
    right: 20px;
    bottom: 84px;
    width: auto;
  }

  .opening-copy h1 {
    max-width: 10.5ch;
    font-size: clamp(40px, 12vw, 72px);
  }

  .opening-copy .hero-copy {
    width: min(100%, 31ch);
  }

  .building-layer img {
    object-position: 56% center;
  }

  .hero-content,
  h1,
  .hero-copy {
    max-width: 100%;
  }

  .hero-copy {
    width: min(100%, 31ch);
  }

  h1 {
    font-size: clamp(40px, 11vw, 54px);
    line-height: 0.96;
  }

  .hero-collage {
    display: none;
  }

  .hero-facts {
    position: relative;
    left: auto;
    right: auto;
    bottom: auto;
    width: calc(100% - 32px);
    margin: 0 auto 14px;
    grid-template-columns: 1fr;
  }

  .hero-facts span {
    min-height: 40px;
  }

  .intro,
  .reel-heading,
  .section-head,
  .scene-card,
  .scene-card.offset,
  .scene-card.reverse {
    grid-template-columns: 1fr;
  }

  .scene-card,
  .scene-card.offset {
    width: 100%;
  }

  .scene-card.reverse picture {
    order: initial;
  }

  .scene-card picture,
  .scene-card.offset picture {
    aspect-ratio: 1.2;
  }

  .residence-gallery,
  .neighborhood-visual {
    min-height: 520px;
  }

  .gallery-main {
    inset: 0 0 15% 0;
  }

  .gallery-inset {
    width: min(310px, 58%);
  }

  .amenity-grid {
    grid-template-columns: 1fr;
  }

  .closing-cta {
    min-height: 70dvh;
  }
}

@media (max-width: 768px) {
  .site-footer {
    grid-template-columns: 1fr;
  }

  .site-footer img {
    width: min(230px, 64vw);
  }

  .site-footer-cta {
    justify-self: stretch;
  }

  .site-footer-cta a {
    width: 100%;
  }
}

@media (max-width: 560px) {
  .site-header {
    top: 12px;
    left: 12px;
    right: 12px;
    width: auto;
    min-height: 60px;
  }

  .brand-mark {
    top: 12px;
    left: 12px;
    min-height: 50px;
    padding: 0 13px;
  }

  .brand-mark img {
    width: min(176px, 46vw);
  }

  .menu-toggle {
    display: flex !important;
    position: fixed;
    right: 12px;
    left: auto;
    top: 14px;
    width: 50px;
    height: 50px;
    padding: 0;
    transform: none;
    z-index: 74;
    color: var(--green);
    border-color: oklch(0.364 0.047 210.2 / 0.42);
    background: var(--pink);
    box-shadow: 0 12px 36px oklch(0.2 0.04 210 / 0.18);
  }

  .menu-toggle span {
    width: 22px;
    height: 1.5px;
  }

  .mobile-panel {
    top: 10px;
    right: 10px;
    bottom: 10px;
    width: calc(100vw - 20px);
    padding-top: 86px;
  }

  .brand-lockup {
    width: min(320px, 76vw);
  }

  .hero-copy {
    font-size: 17px;
  }

  .hero-actions,
  .button {
    width: 100%;
  }

  .band,
  .render-reel,
  .priority-band,
  .arrival-journey,
  .residence-band,
  .amenity-cinema,
  .neighborhood {
    padding-left: 16px;
    padding-right: 16px;
  }

  .intro h2,
  .priority-copy h2,
  .section-head h2,
  .residence-copy h2,
  .neighborhood-copy h2,
  .closing-copy h2 {
    font-size: clamp(36px, 12vw, 54px);
  }

  .reel-card {
    flex-basis: 248px;
  }

  .priority-band {
    gap: 34px;
  }

  .lead-form {
    padding: 24px 18px;
  }

  .residence-gallery,
  .neighborhood-visual {
    min-height: 420px;
  }

  .gallery-inset {
    width: 64%;
  }

  .amenity-feature.large,
  .amenity-feature.garden,
  .amenity-feature.lounge,
  .amenity-feature {
    min-height: 380px;
  }

  .map-overlay {
    inset: 7%;
  }

  .map-pin {
    min-width: 70px;
    font-size: 9px;
  }
}

/* Scene 02 — Arrival: migrated to lib/scene-02-arrival/styles.module.css (bayside-fgs). */

/* Scene 08 — Residences Preview: migrated to lib/scene-08-residences/styles.module.css
   (bayside-fgs). The .scene08 [data-scene08-scroller-root] bridge rules below
   intentionally stay in this bundle — they cross the seam between scene-08-residences
   (which hosts the scroller mount) and scene-08-floor-plan-scroller (which styles the
   scroller body), and homepage-floor-plan-scroller.test.js pins them in styles.css. */
.scene08 [data-scene08-scroller-root] {
  position: absolute;
  inset: 0;
  z-index: 5;
  opacity: 0;
  pointer-events: none;
  transition: opacity 420ms var(--ease);
}

.scene08 [data-scene08-scroller-root].pinned,
.scene08 [data-scene08-scroller-root][data-scene08-scroller-reduced-motion="true"] {
  opacity: 1;
  pointer-events: auto;
}

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

  [data-reveal] {
    opacity: 1;
    transform: none;
  }

  .reel-track {
    animation: none;
  }

  :root {
    --water-opacity: 0.2;
    --water-scale: 1;
    --water-y: 0px;
    --water-hole: 0%;
    --water-core-alpha: 1;
    --water-edge-alpha: 1;
    --brand-opacity: 0;
    --brand-y: -40px;
    --building-opacity: 1;
    --building-scale: 1;
    --building-y: 0px;
    --veil-opacity: 0;
    --copy-opacity: 1;
    --copy-y: 0px;
    --header-opacity: 1;
    --header-y: 0px;
    --nav-progress: 1;
    --nav-y: 0px;
    --cue-opacity: 0;
  }

  .opening-hero {
    min-height: auto;
  }

  .opening-stage {
    position: relative;
    min-height: 100svh;
  }

  .water-layer {
    -webkit-mask-image: none;
    mask-image: none;
  }

  .scroll-cue {
    display: none;
  }
}

/* Shared Priority List Drawer: migrated to /shared/drawer/styles.module.css (bayside-fgs). */

/* Legal pages — privacy, fair-housing, accessibility (bayside-r1h).
   Replaces the duplicated inline <style> blocks that previously lived in each
   legal HTML file and introduced a fourth color system (--color-bg, --color-text,
   --color-accent). Now consumes brand tokens directly: --shell for ground,
   --ink for body text, --green for accent rules. Border-radius stays 0 to match
   the site-wide rule. */
.legal-page {
  background: var(--shell);
  color: var(--ink);
  font-family: var(--body);
  font-weight: var(--w-body);
}
.legal-page .legal-nav {
  display: flex;
  gap: 24px;
  margin-left: auto;
  font-size: 14px;
}
.legal-page .legal-nav a {
  color: inherit;
  text-decoration: none;
  opacity: 0.7;
}
.legal-page .legal-nav a:hover,
.legal-page .legal-nav a:focus-visible {
  opacity: 1;
}
.legal-page .legal-nav a[aria-current="page"] {
  opacity: 1;
  text-decoration: underline;
  text-underline-offset: 4px;
}
.legal-page .legal-main {
  max-width: 720px;
  margin: 0 auto;
  padding: 64px 24px 96px;
}
.legal-page .legal-article-header {
  margin-bottom: 48px;
  border-bottom: 1px solid var(--line);
  padding-bottom: 32px;
}
.legal-page .legal-article h1 {
  font-family: var(--display);
  font-weight: var(--w-display);
  font-size: clamp(2rem, 4vw, 3rem);
  line-height: 1.15;
  margin: 8px 0 24px;
  color: var(--green);
}
.legal-page .legal-article h2 {
  font-family: var(--display);
  font-weight: var(--w-display);
  font-size: 1.4rem;
  line-height: 1.25;
  margin: 48px 0 12px;
  color: var(--green);
}
.legal-page .legal-article h3 {
  font-family: var(--display);
  font-weight: var(--w-display);
  font-size: 1.1rem;
  line-height: 1.3;
  margin: 32px 0 8px;
  color: var(--green);
}
.legal-page .legal-article p,
.legal-page .legal-article li {
  line-height: 1.7;
  font-size: 1rem;
}
.legal-page .legal-article ul {
  padding-left: 20px;
  margin: 12px 0 24px;
}
.legal-page .legal-article li {
  margin-bottom: 8px;
}
.legal-page .legal-article a {
  color: var(--green);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.legal-page .legal-article a:hover,
.legal-page .legal-article a:focus-visible {
  color: var(--green-deep);
}
.legal-page .legal-article code {
  font-family: ui-monospace, "SF Mono", Menlo, monospace;
  font-size: 0.9em;
  padding: 0.1em 0.3em;
  background: var(--sand);
}
.legal-page .legal-effective-date {
  font-size: 0.95rem;
  color: var(--ink-soft);
  margin: 0;
}
.legal-page .legal-lede {
  font-size: 1.1rem;
  line-height: 1.7;
}
.legal-page .legal-callout {
  margin: 32px 0;
  padding: 20px 24px;
  background: var(--sand);
  border-left: 3px solid var(--green);
  font-size: 0.95rem;
}
.legal-page .legal-statement {
  margin: 32px 0;
  padding: 24px 28px;
  background: var(--sand);
  border-left: 3px solid var(--green);
  font-size: 1.05rem;
  line-height: 1.6;
}
.legal-page .legal-statement strong {
  display: block;
  margin-bottom: 8px;
  font-size: 0.85rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-soft);
}
.legal-page .legal-address {
  font-style: normal;
  line-height: 1.6;
}
.legal-page .equal-housing-logo {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 4px 8px;
  border: 1px solid var(--line);
  font-size: 0.8rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.legal-page .legal-footer-nav {
  display: flex;
  gap: 20px;
  justify-content: center;
  margin-top: 16px;
  font-size: 0.875rem;
}
.legal-page .legal-footer-nav a {
  color: inherit;
  opacity: 0.7;
  text-decoration: none;
}
.legal-page .legal-footer-nav a:hover,
.legal-page .legal-footer-nav a:focus-visible {
  opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
  .legal-page .legal-article * {
    transition: none !important;
    animation: none !important;
  }
}
/* /legal-page */
