/* ============================================================================
   Bandra Bay — styles.css
   Editorial coastal design system for bandrabay.co (Realspace Assets LLP)
   Vanilla CSS. Reusable custom properties. Mobile-first, reduced-motion aware.
   ========================================================================== */

/* ---------- 1. Design tokens ---------------------------------------------- */
:root {
  /* Palette — coastal / architectural */
  --navy:        #14202e;   /* deep midnight navy */
  --navy-800:    #1b2c3d;
  --sea-grey:    #5c6b76;   /* 5.26:1 on paper — AA */
  --blue-grey:   #5f6b76;   /* was #8695a0 (2.95:1 — failed AA); now 5.22:1 */
  --limestone:   #e8e2d6;   /* warm limestone */
  --sand:        #d8cdb8;   /* muted sand */
  --off-white:   #f6f3ec;
  --paper:       #fbfaf6;
  --bronze:      #9a7b4f;   /* oxidised bronze — DECORATIVE ONLY (3.78:1) */
  --bronze-text: #7a5f3a;   /* bronze for text/labels — 5.70:1 paper, 4.62:1 limestone */
  --bronze-dark: #7d6440;   /* links — 5.33:1 on paper */
  --burgundy:    #6d2f36;   /* restrained accent */
  --terracotta:  #b4643f;
  --ink:         #202a33;

  /* Semantic */
  --bg:          var(--paper);
  --surface:     #ffffff;
  --text:        var(--ink);
  --text-soft:   #4a5762;   /* 7.10:1 on paper */
  --text-mute:   #59656f;   /* was #74828c (3.78:1 — failed AA); now 5.72:1 */
  --line:        #e2ddd0;
  --line-soft:   #ece7db;

  /* Confidence labels — all ≥4.5:1 on paper, off-white and limestone */
  --verified:    #3f6b52;
  --indicative:  #7a5f3a;   /* was #9a7b4f (3.78:1 — failed AA) */
  --editorial:   #4d6272;
  --proposed:    #7f6436;   /* was #8a6d3b — lifted for limestone backgrounds */
  --awaited:     #8b6144;   /* was #97694a — lifted for limestone backgrounds */

  /* Type */
  --serif: "Cormorant Garamond", Georgia, "Times New Roman", serif;
  --sans:  "Manrope", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;

  /* Scale / rhythm */
  --wrap: 1240px;
  --wrap-narrow: 760px;
  --gap: clamp(1rem, 3vw, 2rem);
  --section-y: clamp(3.5rem, 8vw, 7rem);
  --radius: 4px;
  --radius-lg: 8px;
  --shadow-sm: 0 1px 2px rgba(20,32,46,.06), 0 2px 8px rgba(20,32,46,.05);
  --shadow-md: 0 6px 24px rgba(20,32,46,.10);
  --shadow-lg: 0 20px 60px rgba(20,32,46,.16);
  --ease: cubic-bezier(.22,.61,.36,1);
  --nav-h: 76px;

  /* Minimum interactive sizes (WCAG 2.5.8 / 2.5.5) */
  --tap: 44px;        /* every control clears this */
  --tap-lg: 48px;     /* primary buttons + form fields */
  --mobile-bar-h: 68px;
}

/* ---------- 2. Reset / base ----------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  font-family: var(--sans);
  font-size: 1.06rem;
  line-height: 1.68;
  color: var(--text);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}
img, svg, video { max-width: 100%; height: auto; display: block; }
a { color: var(--bronze-dark); text-decoration: none; }
a:hover { color: var(--burgundy); }
/* Links inside running prose are underlined — colour alone is not a
   sufficient distinguisher (WCAG 1.4.1). Navigation and buttons opt out. */
.article-body a, .faq-a-inner a, .lede a, .legal-body a, p a:not(.btn):not(.link-arrow) {
  text-decoration: underline; text-underline-offset: 3px; text-decoration-thickness: 1px;
}
.article-body a:hover, .faq-a-inner a:hover, .legal-body a:hover, p a:not(.btn):not(.link-arrow):hover {
  text-decoration-thickness: 2px;
}
button { font-family: inherit; cursor: pointer; }
ul { margin: 0; padding: 0; }
h1, h2, h3, h4 { font-weight: 600; line-height: 1.12; margin: 0 0 .5em; color: var(--navy); }
p { margin: 0 0 1em; }

.serif { font-family: var(--serif); }
h1, h2, h3 { font-family: var(--serif); letter-spacing: .2px; }
h1 { font-size: clamp(2.4rem, 6vw, 4.4rem); font-weight: 500; }
h2 { font-size: clamp(1.9rem, 4vw, 3rem); font-weight: 500; }
h3 { font-size: clamp(1.3rem, 2.4vw, 1.7rem); font-weight: 600; }
h4 { font-family: var(--sans); font-size: .82rem; letter-spacing: .16em; text-transform: uppercase; color: var(--sea-grey); }

/* ---------- 3. Utilities -------------------------------------------------- */
.wrap { width: min(100% - 2.5rem, var(--wrap)); margin-inline: auto; }
.narrow { width: min(100% - 2.5rem, var(--wrap-narrow)); margin-inline: auto; }
.section { padding-block: var(--section-y); }
.eyebrow {
  font-family: var(--sans); font-size: .7rem; font-weight: 700;
  letter-spacing: .2em; text-transform: uppercase; color: var(--bronze-text);
  margin: 0 0 1rem;
}
.lede { font-size: clamp(1rem, 1.4vw, 1.15rem); color: var(--text-soft); line-height: 1.6; }
.muted { color: var(--text-mute); }
.center { text-align: center; }
.skip-link {
  position: absolute; left: 1rem; top: -60px; z-index: 2000;
  background: var(--navy); color: #fff; padding: .7rem 1.2rem; border-radius: var(--radius);
  transition: top .2s var(--ease);
}
.skip-link:focus { top: 1rem; color: #fff; }
/* Focus: a 3px bronze ring plus a navy halo so it stays visible on light,
   dark and photographic backgrounds alike. Never removed, only restyled. */
:focus-visible {
  outline: 3px solid var(--bronze);
  outline-offset: 2px;
  box-shadow: 0 0 0 5px rgba(20,32,46,.28);
  border-radius: 3px;
}
.bg-navy :focus-visible, .site-footer :focus-visible, .hero :focus-visible, .estimate-out :focus-visible {
  outline-color: var(--sand);
  box-shadow: 0 0 0 5px rgba(0,0,0,.45);
}
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.bg-navy { background: var(--navy); color: var(--off-white); }
.bg-navy h1, .bg-navy h2, .bg-navy h3 { color: #fff; }
/* ...but a component that paints its own light surface inside a navy band
   keeps dark headings. Without this, .card-title rendered white-on-white and
   the residence names in the featured carousel were invisible. */
.bg-navy :is(.card, .tool-card, .form-card, .chart-card, .facts-panel, .method-card, .step, .intel-box, .search-panel) :is(h1, h2, h3) {
  color: var(--navy);
}
.bg-paper { background: var(--paper); }

/* Limestone is the darkest of the light surfaces, so the standard text tokens
   land between 4.18:1 and 4.32:1 on it — just under AA. Re-point the tokens
   for this surface only; every descendant inherits the corrected values. */
.bg-limestone, .page-hero:not(.has-media) {
  background: var(--limestone);
  --text-mute:    #545f69;   /* 5.06:1 on limestone */
  --sea-grey:     #515c66;   /* 5.30:1 */
  --blue-grey:    #545f69;   /* 5.06:1 */
  --bronze-text:  #6d5737;   /* 5.31:1 */
  --bronze-dark:  #6d5737;   /* 5.31:1 — links on limestone */
  --indicative:   #6d5737;   /* 5.31:1 */
  --proposed:     #70582e;   /* 5.21:1 */
  --awaited:      #7a553b;   /* 5.10:1 */
}
.divider { height: 1px; background: var(--line); border: 0; margin: 0; }

/* ---------- 4. Buttons ---------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .55rem;
  font-family: var(--sans); font-weight: 600; font-size: .95rem;
  min-height: var(--tap-lg); padding: .8rem 1.5rem;
  border-radius: var(--radius); border: 1px solid transparent;
  transition: background .25s var(--ease), color .25s var(--ease), border-color .25s var(--ease), transform .15s var(--ease);
  letter-spacing: .01em; text-align: center;
}
.btn:active { transform: translateY(1px); }
.btn-primary { background: var(--navy); color: #fff; }
.btn-primary:hover { background: var(--bronze-dark); color: #fff; }
.btn-outline { background: transparent; color: var(--navy); border-color: var(--navy); }
.btn-outline:hover { background: var(--navy); color: #fff; }
.btn-ghost { background: transparent; color: var(--bronze-dark); padding-inline: .6rem; }
.btn-ghost:hover { color: var(--burgundy); text-decoration: underline; }
.btn-light { background: rgba(255,255,255,.16); color: #fff; border-color: rgba(255,255,255,.55); }
.btn-light:hover { background: #fff; color: var(--navy); }
.btn-sm { min-height: var(--tap); padding: .5rem 1rem; font-size: .86rem; }
.btn-block { display: flex; width: 100%; justify-content: center; }
.link-arrow { font-weight: 600; display: inline-flex; align-items: center; gap: .4rem; }
.link-arrow::after { content: "→"; transition: transform .2s var(--ease); }
.link-arrow:hover::after { transform: translateX(4px); }

/* ---------- 5. Confidence chips ------------------------------------------- */
.chip {
  display: inline-flex; align-items: center; gap: .35rem;
  font-family: var(--sans); font-size: .68rem; font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; padding: .2rem .55rem; border-radius: 100px;
  border: 1px solid currentColor; line-height: 1.4;
  /* Long statuses ("Under construction / phased") must wrap rather than
     overflow their container — nowrap here caused horizontal overflow. */
  max-width: 100%; white-space: normal; text-align: left;
}
.chip::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: none; }
.chip-verified   { color: var(--verified); }
.chip-indicative { color: var(--indicative); }
.chip-editorial  { color: var(--editorial); }
.chip-proposed   { color: var(--proposed); }
.chip-awaited    { color: var(--awaited); }
.chip-status     { color: var(--sea-grey); }

/* ---------- 6. Header / navigation ---------------------------------------- */
.site-header {
  position: fixed; top: 0; right: 0; bottom: auto; left: 0; z-index: 1000; height: var(--nav-h);
  display: flex; align-items: center;
  transition: background .35s var(--ease), box-shadow .35s var(--ease), border-color .35s var(--ease);
  border-bottom: 1px solid transparent;
}
.site-header .wrap { display: flex; align-items: center; justify-content: space-between; gap: 1rem; width: min(100% - 2.5rem, 1360px); }
.site-header.transparent { background: transparent; }
.site-header.transparent .nav-link,
.site-header.transparent .brand-name,
.site-header.transparent .brand-sig,
.site-header.transparent .nav-icon { color: rgba(255,255,255,.92); }
.site-header.transparent .brand-sig { color: rgba(255,255,255,.6); }
/* Opaque, not frosted. At .86 (and still faintly at .97) whatever scrolled
   underneath showed through — card edges and images read as a smudge across
   the bar, so the header looked like it had no background at all.
   backdrop-filter is dropped with it: pointless behind an opaque fill, and it
   forces an extra compositing layer on every scroll frame. */
.site-header.scrolled {
  background: var(--paper);
  border-bottom-color: var(--line);
  box-shadow: 0 2px 16px rgba(20,32,46,.07);
}
/* Permanently opaque header, for pages whose hero is light at the top (the
   split homepage hero, 404). Use this rather than hard-coding `scrolled` in
   the markup — the scroll handler removes `scrolled` above the fold. */
.site-header.solid {
  background: var(--paper);
  border-bottom-color: var(--line);
}
.brand { display: flex; flex-direction: column; line-height: 1; }
.brand-name { font-family: var(--serif); font-size: 1.4rem; font-weight: 600; color: var(--navy); letter-spacing: .3px; }
.brand-sig { font-family: var(--sans); font-size: .58rem; letter-spacing: .22em; text-transform: uppercase; color: var(--sea-grey); margin-top: 3px; }
.nav { display: flex; align-items: center; gap: clamp(.6rem, 1.4vw, 1.5rem); }
.nav-links { display: flex; align-items: center; gap: clamp(.5rem, 1.3vw, 1.4rem); list-style: none; }
.nav-link {
  font-family: var(--sans); font-size: .86rem; font-weight: 500; color: var(--text);
  padding: .4rem 0; position: relative; letter-spacing: .01em;
}
.nav-link::after {
  content: ""; position: absolute; left: 0; bottom: -2px; width: 0; height: 1.5px;
  background: var(--bronze); transition: width .25s var(--ease);
}
.nav-link:hover::after, .nav-link.active::after { width: 100%; }
.nav-link.active { color: var(--bronze-dark); }
.nav-actions { display: flex; align-items: center; gap: .7rem; }
.nav-icon { background: none; border: 0; color: var(--navy); width: var(--tap); height: var(--tap); border-radius: var(--radius); display: inline-flex; align-items: center; justify-content: center; }
.nav-icon:hover { color: var(--bronze-text); background: var(--off-white); }
/* Declared BEFORE the 940px block: an identical-specificity rule placed after
   a media query wins at every width, which was hiding Enquire in the mobile
   menu entirely. */
.nav-links .nav-mobile-cta { display: none; }
.nav-toggle { display: none; background: none; border: 0; width: 44px; height: 44px; position: relative; color: var(--navy); }
.nav-toggle span { position: absolute; left: 10px; right: 10px; height: 2px; background: currentColor; transition: transform .3s var(--ease), opacity .2s; }
.nav-toggle span:nth-child(1) { top: 15px; }
.nav-toggle span:nth-child(2) { top: 21px; }
.nav-toggle span:nth-child(3) { top: 27px; }
.site-header.transparent .nav-toggle { color: #fff; }
body.nav-open .nav-toggle span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
body.nav-open .nav-toggle span:nth-child(2) { opacity: 0; }
body.nav-open .nav-toggle span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

@media (max-width: 940px) {
  .nav-toggle { display: block; }
  .nav-links {
    position: fixed; top: var(--nav-h); right: 0; bottom: 0; left: 0; flex-direction: column; justify-content: center;
    gap: 1.2rem; background: var(--paper); transform: translateX(100%); transition: transform .35s var(--ease);
    padding: 2rem; z-index: 999;
  }
  body.nav-open .nav-links { transform: translateX(0); }
  .nav-link {
    font-size: 1.3rem; font-family: var(--serif);
    display: flex; align-items: center; justify-content: center;
    min-height: var(--tap-lg); width: 100%; padding: .3rem 1rem; border-radius: var(--radius);
  }
  .nav-link:hover, .nav-link.active { background: var(--off-white); }
  .nav-link::after { display: none; }
  .site-header.transparent .nav-link { color: var(--text); }
  .nav-desktop-cta { display: none; }
  /* Mobile menu needs its own Enquire action once the desktop CTA is hidden */
  .nav-links .nav-mobile-cta { display: flex; }
}

/* ---------- 7. Search overlay --------------------------------------------- */
.search-overlay {
  position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 1100; background: rgba(20,32,46,.55);
  backdrop-filter: blur(6px); display: none; align-items: flex-start; justify-content: center;
  padding-top: 14vh;
}
.search-overlay.open { display: flex; }
.search-panel { background: var(--paper); width: min(92%, 640px); border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); padding: 1.5rem; }
.search-panel input {
  width: 100%; font-size: 1.4rem; font-family: var(--serif); padding: .6rem .2rem;
  border: 0; border-bottom: 2px solid var(--line); background: transparent; color: var(--navy);
}
.search-panel input:focus { outline: none; border-bottom-color: var(--bronze); }
.search-results { margin-top: 1rem; max-height: 46vh; overflow-y: auto; }
.search-result { display: block; min-height: var(--tap-lg); padding: .8rem .6rem; margin-inline: -.3rem; border-radius: var(--radius); border-bottom: 1px solid var(--line-soft); }
.search-result:hover { background: var(--off-white); }
.search-result strong { color: var(--navy); }
.search-hint { font-size: .8rem; color: var(--text-mute); margin-top: .8rem; }

/* ---------- 8. Hero (wide plate + overlapping content card) ---------------
   The image stays full-bleed and landscape at every width, so an aerial is
   never squeezed into a portrait crop. The headline sits on a solid card that
   overlaps the plate's lower edge — contrast comes from the surface, not from
   the photograph. Every dimension is fluid (clamp/vw/svh), so the layout
   scales continuously between breakpoints instead of stepping.
   ------------------------------------------------------------------------ */
.hero {
  padding-top: var(--nav-h);                      /* clear the fixed header */
  padding-bottom: clamp(1.5rem, 4vw, 3.5rem);
}

.hero-media {
  position: relative;
  /* Width-driven so the plate grows with the viewport, capped by height so it
     never eats a short screen. min() picks whichever limit binds first. */
  height: clamp(240px, min(42vw, 56vh), 640px); height: clamp(240px, min(42vw, 56svh), 640px);
  background: var(--navy);
  overflow: hidden;
}
.hero-media img { width: 100%; height: 100%; object-fit: cover; object-position: center 52%; }
/* Depth at the lower edge so the card reads as lifted off the plate */
.hero-media::after {
  content: ""; position: absolute; top: auto; right: 0; bottom: 0; left: 0; height: 55%;
  background: linear-gradient(0deg, rgba(20,32,46,.55), transparent);
  pointer-events: none;
}
.hero-coords {
  position: absolute; top: clamp(.8rem, 2vw, 1.4rem); right: clamp(1rem, 3vw, 2rem); z-index: 1;
  margin: 0; font-family: var(--sans); font-size: clamp(.6rem, 1.4vw, .7rem);
  letter-spacing: .18em; text-transform: uppercase;
  /* .72 keeps white text ≥4.5:1 even where the image behind is pure white sky */
  color: #fff; background: rgba(20,32,46,.72); backdrop-filter: blur(4px);
  padding: .4rem .7rem; border-radius: 100px;
}

/* The lift lives on the wrapper, not the card, so it can't be swallowed by
   margin collapsing between the card and its container. */
.hero > .wrap {
  position: relative; z-index: 2;
  margin-top: clamp(-11rem, -12vw, -2rem);
}
/* Single centred column. The card is narrower than the wrap and centred in
   it; every child is centred and measure-capped so the centred text keeps a
   readable line length instead of running the full card width. */
.hero-card {
  max-width: 56rem;
  margin-inline: auto;
  text-align: center;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  padding: clamp(1.6rem, 3.4vw, 3rem) clamp(1.4rem, 3.2vw, 3.4rem);
}
.hero .eyebrow { color: var(--bronze-text); margin-bottom: .7rem; }
.hero h1 {
  color: var(--navy); font-weight: 500; margin: 0;
  font-size: clamp(1.8rem, 4vw, 2.9rem);
  text-wrap: balance;
}
.hero-sub {
  font-size: clamp(1rem, 1.5vw, 1.22rem); color: var(--text-soft); line-height: 1.55;
  max-width: 54ch; margin: clamp(.8rem, 2vw, 1.15rem) auto clamp(1.4rem, 3vw, 1.9rem);
}
.hero-cta { display: flex; flex-wrap: wrap; gap: .7rem; justify-content: center; }
.hero-cta .btn { flex: 0 1 auto; min-width: 13rem; }

@media (max-width: 760px) {
  .hero-cta .btn { flex: 1 1 100%; min-width: 0; }
}
@media (max-width: 400px) {
  .hero-media { height: clamp(200px, 34vh, 300px); height: clamp(200px, 34svh, 300px); }
  .hero > .wrap { margin-top: -2rem; }
  .hero-card { border-radius: var(--radius); }
}
/* Short landscape viewports: shrink the plate so the card stays reachable */
@media (max-height: 560px) and (orientation: landscape) {
  .hero-media { height: clamp(160px, 40vh, 260px); height: clamp(160px, 40svh, 260px); }
  .hero > .wrap { margin-top: -2rem; }
}
/* Ultra-wide: cap the plate so it doesn't become a letterbox strip */
@media (min-width: 1800px) {
  .hero-media { height: clamp(480px, 40vh, 620px); height: clamp(480px, 40svh, 620px); }
}

/* ---------- 9. Reveal animation ------------------------------------------- */
.reveal { opacity: 0; transform: translateY(24px); transition: opacity .8s var(--ease), transform .8s var(--ease); }
.reveal.in { opacity: 1; transform: none; }
.reveal-delay-1 { transition-delay: .08s; }
.reveal-delay-2 { transition-delay: .16s; }
.reveal-delay-3 { transition-delay: .24s; }

/* ---------- 10. Definition + facts ---------------------------------------- */
.def-grid { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr); gap: clamp(1.5rem, 4vw, 3.5rem); align-items: start; }
.facts-panel { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 1.6rem 1.7rem; box-shadow: var(--shadow-sm); }
.facts-panel h3 { font-family: var(--sans); font-size: .78rem; letter-spacing: .16em; text-transform: uppercase; color: var(--bronze-text); margin-bottom: 1rem; }
.facts-list { list-style: none; }
.facts-list li { display: flex; justify-content: space-between; gap: 1rem; padding: .6rem 0; border-bottom: 1px solid var(--line-soft); font-size: .92rem; }
.facts-list li:last-child { border-bottom: 0; }
.facts-list .k { color: var(--text-mute); }
.facts-list .v { color: var(--navy); font-weight: 600; text-align: right; }
/* Block, not flex: as a flex container the text node and any trailing link
   became separate items and squeezed into two cramped columns. */
.reviewed { font-size: .8rem; color: var(--text-mute); margin-top: 1.4rem; }
.reviewed svg { display: inline-block; vertical-align: -2px; margin-right: .4rem; }

/* ---------- 11. Theme tiles (4 themes) ------------------------------------ */
.themes { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1.2rem; }
.theme-tile { border-top: 2px solid var(--bronze); padding-top: 1.1rem; }
.theme-tile h3 { font-family: var(--serif); font-size: 1.5rem; margin-bottom: .4rem; }
.theme-tile p { font-size: .92rem; color: var(--text-soft); margin: 0; }

/* ---------- 12. Answer blocks (answer-first) ------------------------------ */
.answer { border-left: 3px solid var(--bronze); padding: .2rem 0 .2rem 1.2rem; margin-bottom: 1.5rem; }
.answer p { font-size: 1.12rem; color: var(--navy); font-weight: 500; margin: 0; }

/* ---------- 13. Cards / residences ---------------------------------------- */
.card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg);
  overflow: hidden; display: flex; flex-direction: column; transition: box-shadow .3s var(--ease), transform .3s var(--ease);
}
.card:hover { box-shadow: var(--shadow-md); transform: translateY(-3px); }
.card-media { position: relative; aspect-ratio: 4/3; background: var(--limestone); overflow: hidden; }
.card-media img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--ease); }
.card:hover .card-media img { transform: scale(1.04); }
.card-tag { position: absolute; left: .8rem; top: .8rem; background: rgba(251,250,246,.92); color: var(--navy); font-size: .68rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; padding: .3rem .6rem; border-radius: 3px; }
.placeholder-note { position: absolute; right: .6rem; bottom: .6rem; background: rgba(20,32,46,.88); color: #fff; font-size: .68rem; letter-spacing: .04em; padding: .25rem .5rem; border-radius: 3px; }
.card-body { padding: 1.2rem 1.3rem 1.4rem; display: flex; flex-direction: column; flex: 1; }
.card-dev { font-size: .76rem; letter-spacing: .1em; text-transform: uppercase; color: var(--bronze-text); margin-bottom: .3rem; }
.card-title { font-family: var(--serif); font-size: 1.4rem; margin-bottom: .3rem; }
.card-loc { font-size: .84rem; color: var(--text-mute); margin-bottom: .8rem; }
.card-meta { display: grid; grid-template-columns: 1fr 1fr; gap: .5rem 1rem; font-size: .82rem; margin-bottom: .9rem; }
.card-meta .k { color: var(--text-mute); display: block; font-size: .72rem; }
.card-meta .v { color: var(--navy); font-weight: 600; }
.card-summary { font-size: .9rem; color: var(--text-soft); margin-bottom: 1rem; flex: 1; }
.card-actions { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; margin-top: auto; }

/* Horizontal carousel */
.carousel { position: relative; }
/* Scrollbar hidden — the prev/next buttons are the affordance. Still fully
   scrollable by touch, trackpad and keyboard; only the bar is suppressed. */
.carousel-track {
  display: flex; gap: 1.3rem; overflow-x: auto; scroll-snap-type: x mandatory;
  padding-bottom: .25rem;
  scrollbar-width: none;          /* Firefox */
  -ms-overflow-style: none;       /* legacy Edge */
}
.carousel-track > * { flex: 0 0 clamp(280px, 32vw, 380px); scroll-snap-align: start; }
.carousel-track::-webkit-scrollbar { display: none; }   /* Chrome / Safari */
.carousel-nav { display: flex; gap: .5rem; justify-content: flex-end; margin-top: .3rem; }
.carousel-btn { width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--line); background: var(--surface); color: var(--navy); font-size: 1.1rem; display: inline-flex; align-items: center; justify-content: center; }
.carousel-btn:hover { background: var(--navy); color: #fff; border-color: var(--navy); }
.carousel-btn:disabled { opacity: .35; cursor: default; }

/* Sub-heading for a column that no longer carries the page H1 */
.section-sub { font-family: var(--serif); font-size: clamp(1.25rem, 2.2vw, 1.6rem); font-weight: 500; margin: 0; }

/* ---------- 14. Section headers -------------------------------------------
   Heading and description sit SIDE BY SIDE rather than stacking, so a section
   header costs one block of height instead of three. `.st` holds the eyebrow
   + H2; `.sd` holds the supporting copy; an optional button trails both.
   All three wrap onto their own rows once there isn't room.
   ------------------------------------------------------------------------ */
.section-head {
  display: flex; flex-wrap: wrap; align-items: flex-start;
  gap: clamp(.9rem, 2.5vw, 2.5rem);
  /* Breathing room before the section's content. Sections sit 224px apart at
     desktop; a 35px header gap read as cramped against that rhythm. */
  margin-bottom: clamp(2.2rem, 4.5vw, 3.75rem);
}
.section-head .st { flex: 1 1 20rem; min-width: 0; }
.section-head .sd { flex: 1 1 22rem; min-width: 0; }
.section-head .st > :last-child { margin-bottom: 0; }
.section-head .sd > :last-child { margin-bottom: 0; }
.section-head p { margin: 0 0 .6rem; color: var(--text-soft); }
.section-head .sd .answer { margin-bottom: 0; }
/* The section CTA sits BELOW its description, not beside it */
.section-head .sd .btn { margin-top: clamp(1rem, 2vw, 1.4rem); }
.section-head > .btn { flex: 0 0 auto; align-self: flex-start; }
/* Single-column when there's no room for two readable measures */
@media (max-width: 700px) {
  .section-head { gap: .8rem; }
  .section-head .st, .section-head .sd { flex: 1 1 100%; }
}

/* ---------- 15. Scrollytelling map ---------------------------------------- */
/* minmax(0,1fr) — a bare 1fr floors at min-content, and the maps below carry a
   400px min-content (aspect-ratio driven by min-height), which would inflate
   the track past the page gutter on phones. */
.scrolly { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: clamp(1.5rem,4vw,3rem); align-items: start; }
.scrolly-sticky { position: sticky; top: calc(var(--nav-h) + 1.5rem); height: fit-content; min-width: 0; }
.map-frame { background: var(--navy); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-md); border: 1px solid var(--navy-800); }
/* Leaflet puts its controls and attribution at z-index 1000, which beat the
   mobile nav panel (999) and painted through the open menu. A stacking
   context here keeps every Leaflet layer local to the map. */
.map-frame { min-width: 0; position: relative; z-index: 0; }
/* 4/3.4 suits a map sitting in a half-width column. A cap stops any map
   growing taller than the viewport when its container goes full width. */
#district-map, #project-map, #dev-map {
  width: 100%; aspect-ratio: 4/3.4; min-height: min(340px, 78vw);
  max-height: 520px; background: var(--navy);
}
/* The development map spans the full wrap, so a near-square ratio made it
   1238 × 1052 at desktop — taller than the screen. Landscape ratio instead. */
#dev-map { aspect-ratio: 16 / 7; min-height: min(300px, 72vw); }
.leaflet-container { font-family: var(--sans) !important; background: var(--navy) !important; }
.map-cap { font-size: .78rem; color: var(--text-mute); padding: .7rem .2rem 0; }
.scrolly-steps { display: flex; flex-direction: column; gap: 1rem; }
.scrolly-step {
  background: var(--surface); border: 1px solid var(--line); border-left: 3px solid var(--line);
  border-radius: var(--radius); padding: 1.3rem 1.4rem; transition: border-color .3s var(--ease), box-shadow .3s var(--ease);
}
.scrolly-step.active { border-left-color: var(--bronze); box-shadow: var(--shadow-sm); }
.scrolly-step h3 { font-size: 1.25rem; margin-bottom: .35rem; }
.scrolly-step p { margin: 0; font-size: .92rem; color: var(--text-soft); }
.scrolly-step .num { font-size: .76rem; letter-spacing: .1em; color: var(--bronze-text); font-weight: 700; }
.travel-note { font-size: .74rem; color: var(--text-mute); font-style: italic; margin-top: .5rem; }

/* Static map fallback list (crawlable) */
.map-places { list-style: none; display: flex; flex-wrap: wrap; gap: .5rem; margin-top: 1rem; }
.map-places li { font-size: .8rem; background: var(--off-white); border: 1px solid var(--line); padding: .35rem .7rem; border-radius: 100px; color: var(--navy); }

/* ---------- 16. Timeline -------------------------------------------------- */
.timeline { position: relative; display: grid; gap: 1.4rem; }
.timeline::before { content: ""; position: absolute; left: 9px; top: 6px; bottom: 6px; width: 2px; background: var(--line); }
.tl-item { position: relative; padding-left: 2.4rem; }
.tl-item::before { content: ""; position: absolute; left: 3px; top: 6px; width: 14px; height: 14px; border-radius: 50%; background: var(--surface); border: 2px solid var(--bronze); }
.tl-item h3 { font-size: 1.2rem; margin-bottom: .25rem; }
.tl-item p { margin: 0; font-size: .92rem; color: var(--text-soft); }

/* ---------- 17. Filters / finder ------------------------------------------ */
.finder { display: grid; grid-template-columns: 300px 1fr; gap: 2rem; align-items: start; }
.filters { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 1.4rem; position: sticky; top: calc(var(--nav-h) + 1rem); }
.filter-group { margin-bottom: 1.3rem; }
.filter-group > label, .filter-legend { font-size: .74rem; letter-spacing: .12em; text-transform: uppercase; color: var(--sea-grey); font-weight: 700; display: block; margin-bottom: .6rem; }
fieldset { border: 0; padding: 0; margin: 0; }
/* Whole row is the hit area, not just the 20px box */
.filter-opt {
  display: flex; align-items: center; gap: .7rem; font-size: .94rem;
  min-height: var(--tap); padding: .35rem .5rem; margin-inline: -.5rem;
  border-radius: var(--radius); color: var(--text-soft); cursor: pointer;
}
.filter-opt:hover { background: var(--off-white); color: var(--text); }
.filter-opt:has(input:checked) { color: var(--navy); font-weight: 600; }
.filter-opt input { accent-color: var(--bronze-dark); width: 20px; height: 20px; flex: none; }
select, input[type="text"], input[type="email"], input[type="tel"], input[type="number"], input[type="date"], textarea {
  width: 100%; font-family: var(--sans); font-size: 1rem; min-height: var(--tap-lg); padding: .75rem .85rem;
  border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); color: var(--text);
}
textarea { min-height: 7rem; }
/* Keep the native outline suppressed but replace it with an equally strong ring */
select:focus-visible, input:focus-visible, textarea:focus-visible {
  outline: 3px solid var(--bronze); outline-offset: 1px;
  border-color: var(--bronze-dark); box-shadow: 0 0 0 5px rgba(20,32,46,.16);
}
.finder-bar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1.4rem; flex-wrap: wrap; gap: 1rem; }
/* On mobile the Filters button must stay reachable while scrolling results */
@media (max-width: 860px) {
  .finder-bar {
    position: sticky; top: var(--nav-h); z-index: 40;
    background: rgba(251,250,246,.94); backdrop-filter: saturate(140%) blur(10px);
    -webkit-backdrop-filter: saturate(140%) blur(10px);
    margin-inline: -1.25rem; padding: .7rem 1.25rem;
    border-bottom: 1px solid var(--line);
  }
}
.result-count { font-size: .95rem; color: var(--text-soft); }
.result-count strong { color: var(--navy); font-size: 1.1rem; }
/* min() keeps the track from demanding 300px inside a narrower gutter */
.results-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr)); gap: 1.4rem; }
.no-results { padding: 2.5rem; text-align: center; color: var(--text-mute); border: 1px dashed var(--line); border-radius: var(--radius-lg); }

/* Mobile filter drawer */
.filter-drawer-btn { display: none; }
@media (max-width: 860px) {
  .finder { grid-template-columns: 1fr; }
  .filters {
    position: fixed; top: auto; right: 0; bottom: 0; left: 0; z-index: 1050; max-height: 82vh; overflow-y: auto;
    border-radius: var(--radius-lg) var(--radius-lg) 0 0; transform: translateY(100%);
    transition: transform .35s var(--ease); box-shadow: var(--shadow-lg);
  }
  body.drawer-open .filters { transform: translateY(0); }
  .filter-drawer-btn { display: inline-flex; }
  .drawer-close { display: block; }
}
.drawer-close { display: none; width: 100%; margin-top: 1rem; }
.drawer-backdrop { position: fixed; top: 0; right: 0; bottom: 0; left: 0; background: rgba(20,32,46,.4); z-index: 1049; opacity: 0; visibility: hidden; transition: opacity .3s; }
body.drawer-open .drawer-backdrop { opacity: 1; visibility: visible; }

/* ---------- 18. Compare tray + table -------------------------------------- */
.data-table { width: 100%; border-collapse: collapse; font-size: .9rem; }
.data-table th, .data-table td { padding: .7rem .9rem; text-align: left; border-bottom: 1px solid var(--line-soft); }
.data-table thead th { background: var(--limestone); color: var(--navy); font-family: var(--sans); font-size: .78rem; letter-spacing: .08em; text-transform: uppercase; }

/* ---------- 18b. Find-a-residence promo + budget guide --------------------
   The budget bands were a static label/value list whose only action was a
   generic link. Each band is now a link that opens the finder with that
   budget filter pre-applied (script.js reads ?budget= from the URL), and the
   match count is filled in from data/projects.js.
   ------------------------------------------------------------------------ */
.finder-promo {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
  gap: clamp(1.6rem, 4vw, 3.5rem); align-items: start;
}
.fp-intro .lede { margin-top: .9rem; }
.fp-trust {
  font-size: .88rem; color: var(--text-mute);
  border-left: 2px solid var(--bronze); padding-left: .8rem; margin: 1rem 0 0;
}
.fp-actions { display: flex; flex-wrap: wrap; gap: .7rem; margin-top: clamp(1.3rem, 3vw, 1.9rem); }

.budget-guide {
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-sm);
  padding: clamp(1.3rem, 3vw, 1.9rem);
}
.budget-guide h3 { font-family: var(--serif); font-size: clamp(1.2rem, 2.2vw, 1.5rem); margin-bottom: .3rem; }
.bg-sub { font-size: .88rem; color: var(--text-mute); margin: 0 0 1.1rem; }

.budget-bands { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line-soft); }
.budget-bands li { border-bottom: 1px solid var(--line-soft); }
.budget-bands a {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  align-items: center; column-gap: 1rem;
  min-height: var(--tap-lg); padding: .8rem .6rem;
  margin-inline: -.6rem; border-radius: var(--radius);
  color: var(--text); text-decoration: none;
}
.budget-bands a:hover { background: var(--off-white); }
.bb-range { grid-column: 1; grid-row: 1; font-weight: 600; color: var(--navy); }
.bb-label { grid-column: 1; grid-row: 2; font-size: .84rem; color: var(--text-mute); }
.bb-count {
  grid-column: 2; grid-row: 1 / 3;
  display: inline-flex; align-items: center; gap: .45rem;
  font-size: .82rem; font-weight: 600; color: var(--bronze-dark); white-space: nowrap;
}
.bb-count::after { content: "→"; transition: transform .2s var(--ease); }
.budget-bands a:hover .bb-count::after { transform: translateX(3px); }
/* Bands with nothing currently listed stay clickable but read as quieter */
.budget-bands a[data-empty="true"] .bb-range { color: var(--text-soft); font-weight: 500; }
.budget-bands a[data-empty="true"] .bb-count { color: var(--text-mute); font-weight: 500; }
.bb-note { font-size: .78rem; color: var(--text-mute); margin: 1rem 0 0; }

@media (max-width: 900px) { .finder-promo { grid-template-columns: minmax(0, 1fr); } }

/* Notice shown on residences.html when filters arrived via the URL */
.preset-note {
  flex: 1 1 100%; margin: .2rem 0 0; font-size: .86rem; color: var(--text-soft);
  display: flex; align-items: center; flex-wrap: wrap; gap: .4rem;
}

/* ---------- 19. Tools (matcher, estimator) -------------------------------- */
.tool-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: clamp(1.4rem, 3vw, 2.2rem); box-shadow: var(--shadow-sm); }
.tool-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(220px, 100%), 1fr)); gap: 1.1rem; }
.field { display: flex; flex-direction: column; gap: .4rem; margin-bottom: 1.1rem; }
.field label { font-size: .82rem; font-weight: 600; color: var(--navy); }
.field .hint { font-size: .76rem; color: var(--text-mute); }
.estimate-out { background: var(--navy); color: #fff; border-radius: var(--radius-lg); padding: 1.6rem; margin-top: 1.4rem; }
.estimate-out .total { font-family: var(--serif); font-size: clamp(2rem, 5vw, 3rem); color: #fff; }
.estimate-rows { list-style: none; margin: 1rem 0 0; }
.estimate-rows li { display: flex; justify-content: space-between; padding: .4rem 0; border-bottom: 1px solid rgba(255,255,255,.12); font-size: .88rem; color: rgba(255,255,255,.85); }
.disclaimer-inline { font-size: .78rem; color: var(--text-mute); font-style: italic; margin-top: 1rem; }
.match-result { border: 1px solid var(--line); border-radius: var(--radius); padding: 1rem 1.2rem; margin-bottom: .8rem; display: flex; justify-content: space-between; align-items: center; gap: 1rem; background: var(--surface); }
.match-score { font-family: var(--serif); font-size: 1.6rem; color: var(--bronze-dark); }

/* ---------- 20. Amenities / project page ---------------------------------- */
.amenity-groups { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(250px, 100%), 1fr)); gap: 1.4rem; }
.amenity-col h4 { color: var(--bronze-text); margin-bottom: .7rem; }
.amenity-col ul { list-style: none; }
.amenity-col li { font-size: .9rem; padding: .3rem 0; color: var(--text-soft); border-bottom: 1px solid var(--line-soft); }
/* 150px fitted eight columns at desktop, wrapping every value. */
.glance-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr)); gap: 1px; background: var(--line); border: 1px solid var(--line); border-radius: var(--radius-lg); overflow: hidden; }
.glance-cell { background: var(--surface); padding: 1.1rem 1.2rem; }
/* project.html / article.html render their H1 from JS, so they fell through to
   the global h1 scale (4.4rem / 70px) — far larger than every other page. */
#project-host h1, #article-host h1 { font-size: clamp(1.9rem, 4vw, 3rem); }
/* Location + status chip on one wrapping row, instead of a literal "·" that
   dangled at the end of a line when the chip wrapped. */
.project-meta { display: flex; flex-wrap: wrap; align-items: center; gap: .5rem; }
.glance-cell .k { font-size: .72rem; letter-spacing: .1em; text-transform: uppercase; color: var(--text-mute); }
.glance-cell .v { font-family: var(--serif); font-size: 1.25rem; color: var(--navy); margin-top: .2rem; }
.floorplan-row { display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding: 1rem 0; border-bottom: 1px solid var(--line-soft); flex-wrap: wrap; }
.pricing-checklist { list-style: none; }
.pricing-checklist li { display: flex; align-items: flex-start; gap: .7rem; padding: .55rem 0; border-bottom: 1px solid var(--line-soft); font-size: .92rem; }
.pricing-checklist li::before { content: "○"; color: var(--bronze); font-size: 1.1rem; line-height: 1.3; }
.intel-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 1.6rem; }
.intel-box { background: var(--off-white); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.3rem; }
.intel-box h4 { color: var(--navy); font-size: .8rem; margin-bottom: .8rem; }
.intel-box ul { list-style: none; }
.intel-box li { font-size: .9rem; padding: .35rem 0 .35rem 1.2rem; position: relative; color: var(--text-soft); }
.intel-box li::before { content: "—"; position: absolute; left: 0; color: var(--bronze); }

/* ---------- 21. FAQ accordion --------------------------------------------- */
.faq-item { border-bottom: 1px solid var(--line); }
.faq-q { width: 100%; text-align: left; background: none; border: 0; padding: 1.25rem 2.5rem 1.25rem 0; font-family: var(--serif); font-size: clamp(1.1rem, 2vw, 1.35rem); color: var(--navy); position: relative; display: flex; }
.faq-q::after { content: "+"; position: absolute; right: .3rem; top: 50%; transform: translateY(-50%); font-size: 1.5rem; color: var(--bronze); transition: transform .3s var(--ease); font-family: var(--sans); }
.faq-q[aria-expanded="true"]::after { transform: translateY(-50%) rotate(45deg); }
.faq-a { max-height: 0; overflow: hidden; transition: max-height .4s var(--ease); }
.faq-a-inner { padding: 0 0 1.4rem; color: var(--text-soft); max-width: 68ch; }
.faq-a-inner p { margin: 0 0 .8rem; }

/* ---------- 22. Lifestyle themes ------------------------------------------ */
/* Lifestyle themes scroll horizontally (same carousel component as the
   featured residences) — a wrapping grid left an orphan card on its own row. */
.lifestyle-carousel .carousel-track > * { flex: 0 0 clamp(260px, 27vw, 340px); }
.lifestyle-card { position: relative; border-radius: var(--radius-lg); overflow: hidden; min-height: 320px; display: flex; align-items: flex-end; color: #fff; }
.lifestyle-card img { position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 100%; height: 100%; object-fit: cover; z-index: -2; }
.lifestyle-card::after { content: ""; position: absolute; top: 0; right: 0; bottom: 0; left: 0; background: linear-gradient(180deg, transparent 30%, rgba(20,32,46,.82)); z-index: -1; }
.lifestyle-card .lc-body { padding: 1.4rem; }
.lifestyle-card h3 { color: #fff; font-size: 1.7rem; margin-bottom: .3rem; }
.lifestyle-card p { color: rgba(255,255,255,.9); font-size: .9rem; margin: 0; }

/* ---------- 23. Advisory steps -------------------------------------------- */
/* A six-stage process, not six generic tiles. 320px forces exactly three
   tracks at desktop so the six steps land 3+3 — the old 210px fitted five and
   stranded step 06 alone on its own row. */
.steps {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
  gap: clamp(.9rem, 2vw, 1.3rem);
}
/* Grid, not flex: as flex siblings the badge, title and copy all sat on one
   row, so the heading ran inline with its own description. */
.step {
  display: grid; grid-template-columns: auto minmax(0, 1fr);
  column-gap: clamp(.9rem, 2vw, 1.2rem); align-items: start;
  padding: clamp(1.2rem, 2.4vw, 1.5rem);
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background: var(--surface);
  transition: border-color .25s var(--ease), box-shadow .25s var(--ease);
}
.step:hover { border-color: var(--sand); box-shadow: var(--shadow-sm); }
/* Number as a marker, not a heading — reads as a sequence */
.step .step-n {
  grid-column: 1; grid-row: 1 / 3;
  width: 2.5rem; height: 2.5rem; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--serif); font-size: 1rem; line-height: 1;
  color: var(--bronze-text); background: var(--off-white);
  border: 1px solid var(--line);
}
.step h3 { grid-column: 2; grid-row: 1; font-size: 1.1rem; margin: .15rem 0 .3rem; }
.step p { grid-column: 2; grid-row: 2; font-size: .89rem; color: var(--text-soft); margin: 0; }

/* ---------- 24. Feature strip / CTA bands --------------------------------- */
.split { display: grid; grid-template-columns: 1fr 1fr; gap: 0; align-items: stretch; }
.split-media { min-height: 420px; background: var(--limestone); position: relative; }
.split-media img { position: absolute; top: 0; right: 0; bottom: 0; left: 0; width: 100%; height: 100%; object-fit: cover; }
.split-body { padding: clamp(2rem, 5vw, 4.5rem); display: flex; flex-direction: column; justify-content: center; }
.cta-band { text-align: center; }
.cta-band .btn-row { display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap; margin-top: 1.6rem; }

/* ---------- 25. Chart panels ---------------------------------------------- */
.chart-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: 1.5rem; box-shadow: var(--shadow-sm); }
.chart-holder { position: relative; height: 340px; }
.demo-flag { display: inline-block; font-size: .72rem; letter-spacing: .06em; color: var(--awaited); background: rgba(151,105,74,.1); border: 1px solid rgba(151,105,74,.3); padding: .2rem .55rem; border-radius: 3px; margin-bottom: 1rem; }

/* ---------- 26. Journal --------------------------------------------------- */
.article-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(300px, 100%), 1fr)); gap: 1.6rem; }
.article-card { display: flex; flex-direction: column; }
.article-card .card-media { aspect-ratio: 16/10; }
.article-cat { font-size: .76rem; letter-spacing: .1em; text-transform: uppercase; color: var(--bronze-text); font-weight: 700; }
.article-card h3 { font-size: 1.35rem; margin: .4rem 0 .5rem; }
.article-card time { font-size: .8rem; color: var(--text-mute); }
.cat-filter { display: flex; flex-wrap: wrap; gap: .5rem; margin-bottom: 2rem; }
.cat-btn { display: inline-flex; align-items: center; font-size: .86rem; font-weight: 600; min-height: var(--tap); padding: .5rem 1.1rem; border-radius: 100px; border: 1px solid var(--line); background: var(--surface); color: var(--text-soft); }
.cat-btn.active, .cat-btn:hover { background: var(--navy); color: #fff; border-color: var(--navy); }

/* Article reading */
.reading-progress { position: fixed; top: 0; left: 0; height: 3px; background: var(--bronze); width: 0; z-index: 1200; transition: width .1s linear; }
.article-body { font-size: 1.12rem; line-height: 1.75; color: var(--text-soft); }
.article-body p { margin-bottom: 1.3rem; }
.article-body p:first-of-type::first-letter { font-family: var(--serif); font-size: 3.4rem; float: left; line-height: .8; padding: .1em .1em 0 0; color: var(--bronze-dark); }
.toc { background: var(--off-white); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.2rem 1.4rem; font-size: .9rem; }
.toc h4 { margin-bottom: .7rem; }
.toc a { display: flex; align-items: center; min-height: var(--tap); padding: .3rem .5rem; margin-inline: -.5rem; border-radius: var(--radius); color: var(--text-soft); }
.toc a:hover { background: var(--surface); color: var(--bronze-dark); }
.article-meta-row { display: flex; gap: 1.5rem; flex-wrap: wrap; align-items: center; font-size: .85rem; color: var(--text-mute); border-block: 1px solid var(--line); padding: 1rem 0; margin: 1.5rem 0; }

/* ---------- 27. Forms / enquiry ------------------------------------------- */
.form-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-lg); padding: clamp(1.5rem, 3vw, 2.4rem); box-shadow: var(--shadow-sm); }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 1.1rem; }
.form-step { display: none; }
.form-step.active { display: block; animation: fadeIn .4s var(--ease); }
@keyframes fadeIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
/* Confirms the project/intent carried over from a CTA on another page */
.form-context {
  background: var(--off-white); border: 1px solid var(--line);
  border-left: 3px solid var(--bronze); border-radius: var(--radius);
  padding: .85rem 1.1rem; margin: 0 0 1.4rem; font-size: .92rem; color: var(--text-soft);
}
.form-context strong { color: var(--navy); }
.form-progress { display: flex; gap: .5rem; margin-bottom: 1.6rem; }
.form-progress span { flex: 1; height: 4px; background: var(--line); border-radius: 100px; }
.form-progress span.done { background: var(--bronze); }
.form-nav { display: flex; justify-content: space-between; gap: 1rem; margin-top: 1.4rem; }
.consent { display: flex; gap: .6rem; align-items: flex-start; font-size: .84rem; color: var(--text-soft); }
.consent input { margin-top: .2rem; accent-color: var(--bronze); }
.field-error { color: var(--burgundy); font-size: .78rem; margin-top: .25rem; display: none; }
.field.invalid .field-error { display: block; }
.field.invalid input, .field.invalid select, .field.invalid textarea { border-color: var(--burgundy); }
.form-success { text-align: center; padding: 2rem 1rem; display: none; }
.form-success.show { display: block; animation: fadeIn .5s var(--ease); }
.form-success .tick { width: 64px; height: 64px; border-radius: 50%; background: var(--verified); color: #fff; display: inline-flex; align-items: center; justify-content: center; font-size: 2rem; margin-bottom: 1rem; }

/* ---------- 27b. Legal pages (privacy, disclaimer) ------------------------
   These used .article-body, which carries the journal drop cap and a large
   editorial heading scale — wrong for a document of 9–10 short clauses.
   ------------------------------------------------------------------------ */
.legal-updated {
  font-size: .88rem; color: var(--text-soft); line-height: 1.6;
  background: var(--off-white); border: 1px solid var(--line);
  border-left: 3px solid var(--bronze); border-radius: var(--radius);
  padding: .9rem 1.1rem; margin: 0 0 clamp(1.4rem, 3vw, 2rem);
}
.legal-toc {
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 1rem 1.2rem; margin-bottom: clamp(1.6rem, 3.5vw, 2.4rem);
  background: var(--surface);
}
.legal-toc h2 { font-family: var(--sans); font-size: .7rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--text-mute); margin: 0 0 .5rem; border: 0; padding: 0; }
.legal-toc ol { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(min(210px, 100%), 1fr)); gap: 0 1.2rem; }
.legal-toc a { display: flex; align-items: center; min-height: var(--tap); font-size: .9rem; color: var(--text-soft); }
.legal-toc a:hover { color: var(--bronze-dark); }

.legal-body { font-size: 1.02rem; line-height: 1.7; color: var(--text-soft); }
.legal-body h2 {
  font-family: var(--serif); font-size: clamp(1.2rem, 2vw, 1.45rem); color: var(--navy);
  margin: clamp(1.8rem, 3.5vw, 2.6rem) 0 .55rem;
  padding-top: clamp(1.2rem, 2.5vw, 1.6rem);
  border-top: 1px solid var(--line-soft);
  scroll-margin-top: calc(var(--nav-h) + 1rem);
}
.legal-body h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.legal-body p { margin: 0 0 1rem; max-width: 68ch; }
.legal-body ul { margin: 0 0 1rem 1.1rem; padding: 0; list-style: disc; }
.legal-body li { margin-bottom: .35rem; }

/* ---------- 28. Trust / methodology --------------------------------------- */
/* 200px fitted five columns at desktop, which squeezed these cards to ~200px
   and wrapped every line. Raised so tracks stay readable. */
.method-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(260px, 100%), 1fr)); gap: 1.3rem; }
/* Infrastructure cards carry far more copy than a method card (title, chip,
   description, authority, relevance, source, confidence, date) so they get a
   wider floor of their own. */
.infra-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(340px, 100%), 1fr)); gap: 1.4rem; }
/* Equal-height cards with the source/confidence/date footer pinned to the
   bottom, so it lines up across a row instead of floating mid-card. */
.infra-grid .method-card { display: flex; flex-direction: column; }
.infra-meta {
  display: flex; justify-content: space-between; align-items: center;
  flex-wrap: wrap; gap: .5rem; margin-top: auto; padding-top: .9rem;
}
.method-card { border: 1px solid var(--line); border-radius: var(--radius); padding: 1.3rem; background: var(--surface); }
.method-card h3 { font-family: var(--sans); font-size: .95rem; display: flex; align-items: center; gap: .5rem; margin-bottom: .5rem; }
.sources-panel { background: var(--off-white); border: 1px solid var(--line); border-radius: var(--radius); padding: 1.2rem 1.4rem; }
.sources-panel ul { list-style: none; }
.sources-panel li { padding: .35rem 0; font-size: .88rem; }
.trust-strip { display: flex; flex-wrap: wrap; gap: 1.5rem; justify-content: center; align-items: center; }
.trust-item { font-size: .82rem; color: var(--text-mute); display: flex; align-items: center; gap: .5rem; }
.placeholder-block { border: 1px dashed var(--sea-grey); border-radius: var(--radius); padding: 1.2rem; text-align: center; color: var(--text-mute); font-size: .85rem; background: repeating-linear-gradient(45deg, transparent, transparent 10px, rgba(154,123,79,.04) 10px, rgba(154,123,79,.04) 20px); }

/* ---------- 29. Footer ---------------------------------------------------- */
.site-footer { background: var(--navy); color: rgba(255,255,255,.75); padding-top: clamp(3rem, 6vw, 5rem); }
.site-footer a { color: rgba(255,255,255,.75); }
.site-footer a:hover { color: #fff; }
.footer-top { display: grid; grid-template-columns: 1.6fr 4fr; gap: 2rem; padding-bottom: 3rem; border-bottom: 1px solid rgba(255,255,255,.12); }
.footer-cols { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 2rem; }
/* Below 860px the four link columns scroll horizontally instead of stacking —
   four stacked lists made the footer enormously tall on a phone. Scrollbar is
   hidden to match the other rails; the columns bleed to the screen edges so
   the cut-off column reads as "there is more this way". */
@media (max-width: 860px) {
  .footer-cols {
    display: flex; gap: 1.75rem;
    overflow-x: auto; overscroll-behavior-x: contain;
    scrollbar-width: none; -ms-overflow-style: none;
    /* Must match .wrap's gutter exactly (min(100% - 2.5rem, …) = 1.25rem a
       side). Using --gap here overshot it and overflowed the viewport.
       No scroll-snap here: snapping the first column's start edge to the
       scroll port auto-scrolled by exactly the padding, cancelling it out and
       leaving the list flush against the screen edge. */
    margin-inline: -1.25rem; padding-inline: 1.25rem;
    padding-bottom: .25rem;
  }
  .footer-cols::-webkit-scrollbar { display: none; }
  .footer-col { flex: 0 0 auto; min-width: 9.5rem; }
}
.footer-brand .brand-name { color: #fff; font-size: 1.6rem; }
.footer-brand .brand-sig { color: var(--sand); }
.footer-brand p { font-size: .88rem; margin-top: 1rem; max-width: 34ch; color: rgba(255,255,255,.6); }
.footer-col h4 { color: var(--sand); margin-bottom: 1rem; font-size: .72rem; }
.footer-col ul { list-style: none; }
.footer-col li { font-size: .9rem; }
.footer-col li a { display: flex; align-items: center; min-height: var(--tap); padding: .2rem 0; }
.footer-bottom .foot-links a { display: inline-flex; align-items: center; min-height: var(--tap); }
.footer-disclaimers { padding: 2rem 0; border-bottom: 1px solid rgba(255,255,255,.12); display: grid; gap: 1rem; }
.footer-disclaimers p { font-size: .78rem; color: rgba(255,255,255,.55); margin: 0; max-width: 95ch; line-height: 1.6; }
.footer-disclaimers strong { color: rgba(255,255,255,.8); }
.footer-bottom { display: flex; justify-content: space-between; align-items: center; gap: 1rem; padding: 1.6rem 0; flex-wrap: wrap; font-size: .8rem; color: rgba(255,255,255,.5); }
.footer-bottom .foot-links { display: flex; gap: 1.2rem; flex-wrap: wrap; }

/* ---------- 30. Breadcrumbs -----------------------------------------------
   The breadcrumb does NOT own the fixed-header clearance — its container does
   (.page-hero, or .breadcrumb-standalone for the JS-rendered templates).
   Both carrying it stacked ~150px of dead space on every interior page. */
.breadcrumb { font-size: .82rem; color: var(--text-mute); }
.breadcrumb-standalone { padding-top: calc(var(--nav-h) + 1.3rem); }
/* Links were ~18px tall — below the 24px AA target size (WCAG 2.5.8). The
   negative margin keeps the added padding from changing the visual rhythm. */
.breadcrumb a { display: inline-block; padding-block: .45rem; margin-block: -.45rem; }
/* Each <li> is its own flex row so the "/" stays vertically centred against
   the link, which is an inline-block with its own padding (see below). */
.breadcrumb ol { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; align-items: center; gap: .1rem .55rem; }
.breadcrumb li { display: inline-flex; align-items: center; gap: .55rem; }
/* Was var(--line) — 1.05:1 on the limestone band, i.e. invisible, so the
   trail read as two words with an unexplained gap between them. */
.breadcrumb li::after { content: "/"; color: var(--text-mute); opacity: .7; }
.breadcrumb li:last-child::after { content: none; }
.breadcrumb a { color: var(--sea-grey); }

/* ---------- 31. Page hero (interior) --------------------------------------
   A limestone band holding breadcrumb + eyebrow + H1 + lede, so every
   interior page opens the same way and echoes the solid surface of the
   homepage card. It owns the fixed-header clearance (see §30). Limestone
   token overrides are inherited from the .bg-limestone rule in §3.
   ------------------------------------------------------------------------ */
.page-hero {
  border-bottom: 1px solid var(--line);
  padding: calc(var(--nav-h) + clamp(1.3rem, 3vw, 2.2rem)) 0 clamp(1.6rem, 3.5vw, 2.6rem);
}
.page-hero .breadcrumb { margin-bottom: clamp(.9rem, 2vw, 1.5rem); }
.page-hero .eyebrow { color: var(--bronze-text); margin-bottom: .55rem; }
.page-hero h1 {
  max-width: 24ch; margin-bottom: 0;
  font-size: clamp(1.9rem, 4vw, 3rem);   /* matches the homepage hero scale */
  text-wrap: balance;
}
/* The band owns the separation — the following section must not add a full
   section-height gap on top of it. */
.page-hero + .section,
.page-hero + article.section { padding-top: clamp(2.4rem, 5vw, 4.25rem); }
.page-hero .lede, .page-hero > .wrap > p { max-width: 64ch; margin-top: clamp(.75rem, 2vw, 1.05rem); }
/* Optional right-hand meta slot */
.page-hero-grid { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr); gap: clamp(1.2rem, 3vw, 2.5rem); align-items: end; }
@media (max-width: 820px) { .page-hero-grid { grid-template-columns: minmax(0, 1fr); align-items: start; } }

/* --- Variant: slim photo plate + overlapping card ------------------------
   Same language as the homepage hero, at reduced height. Content pages use
   it; the legal templates keep the plain limestone band. */
.page-hero.has-media { border-bottom: 0; padding: var(--nav-h) 0 0; }
.ph-media {
  position: relative; overflow: hidden; background: var(--navy);
  height: clamp(170px, min(26vw, 38vh), 380px); height: clamp(170px, min(26vw, 38svh), 380px);
}
.ph-media img { width: 100%; height: 100%; object-fit: cover; object-position: center 50%; }
.ph-media::after {
  content: ""; position: absolute; top: auto; right: 0; bottom: 0; left: 0; height: 55%;
  background: linear-gradient(0deg, rgba(20,32,46,.5), transparent);
  pointer-events: none;
}
/* Lift on the wrapper, not the card — margin collapsing would swallow it */
.page-hero.has-media > .wrap {
  position: relative; z-index: 2;
  margin-top: clamp(-6rem, -7vw, -2rem);
}
.ph-card {
  max-width: 52rem; margin-inline: auto; text-align: center;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-lg);
  padding: clamp(1.3rem, 3vw, 2.4rem);
}
.ph-card .breadcrumb { margin-bottom: clamp(.7rem, 2vw, 1.1rem); }
.ph-card .breadcrumb ol { justify-content: center; }
.ph-card h1 { margin-inline: auto; }
/* No measure cap inside the card — the card's own width sets the line length.
   `none` is needed because .page-hero .lede above still applies a 64ch cap. */
.ph-card .lede, .ph-card > p { max-width: none; margin-inline: auto; }
@media (max-width: 400px) {
  .ph-media { height: clamp(150px, 30vh, 220px); height: clamp(150px, 30svh, 220px); }
  .page-hero.has-media > .wrap { margin-top: -1.75rem; }
  .ph-card { border-radius: var(--radius); }
}
@media (max-height: 560px) and (orientation: landscape) {
  .ph-media { height: clamp(130px, 32vh, 220px); height: clamp(130px, 32svh, 220px); }
}

/* ---------- 32. Toast ----------------------------------------------------- */
.toast {
  position: fixed; bottom: 1.4rem; right: 1.4rem; z-index: 1500; background: var(--navy); color: #fff;
  padding: .9rem 1.3rem; border-radius: var(--radius); box-shadow: var(--shadow-lg); font-size: .9rem;
  transform: translateY(150%); transition: transform .35s var(--ease); max-width: 320px;
}
.toast.show { transform: translateY(0); }

/* ---------- 33. Mobile sticky CTA ----------------------------------------- */
.mobile-cta { display: none; }
@media (max-width: 720px) {
  .mobile-cta {
    position: fixed; top: auto; right: 0; bottom: 0; left: 0; z-index: 900; display: flex; gap: .6rem;
    padding: .6rem .6rem calc(.6rem + env(safe-area-inset-bottom));
    background: rgba(251,250,246,.97); backdrop-filter: blur(10px); border-top: 1px solid var(--line);
    box-shadow: 0 -2px 16px rgba(20,32,46,.07);
  }
  .mobile-cta .btn { flex: 1; }
  body { padding-bottom: calc(var(--mobile-bar-h) + env(safe-area-inset-bottom)); }
}

/* ---------- 34. Responsive collapses -------------------------------------- */
@media (max-width: 980px) {
  .def-grid, .scrolly, .intel-cols, .split, .footer-top { grid-template-columns: minmax(0, 1fr); }
  .scrolly-sticky { position: relative; top: 0; margin-bottom: 1.5rem; }
  .themes { grid-template-columns: repeat(2, 1fr); }
  .footer-top { grid-template-columns: minmax(0, 1fr); }
  .form-row { grid-template-columns: 1fr; }
  .split-media { min-height: 300px; }
}
@media (max-width: 560px) {
  .themes { grid-template-columns: 1fr; }
  .card-meta { grid-template-columns: 1fr 1fr; }
  .hero-coords { display: none; }
  .section-head { margin-bottom: 2rem; }
}

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

/* ---------- 36. Print ----------------------------------------------------- */
@media print {
  .site-header, .mobile-cta, .search-overlay, .filters { display: none !important; }
}

/* ---------- 37. No-JS fallback -------------------------------------------- */
.no-js .reveal { opacity: 1; transform: none; }
.no-js .carousel-track { flex-wrap: wrap; overflow: visible; }
