/* go_2040 — token CSS for the listing_2040-ported theme. The chrome (header,
   hero, footer, nav, menus) and the detail/project pages are now authored with
   Tailwind utilities (built into static/app.css). This file keeps only what
   those don't cover: the theme's own tokens, base element styles, the
   .muted/.read-more/.error helpers, the .theme-switch toggle styling, and the
   articles/listings INDEX cards (still authored with semantic classes).
   Colour roles come from the SHARED design-templates semantic system
   (--color-surface*/heading/ink*/edge* in app.css, flipped in one place by the
   .dark/[data-theme="dark"] --sem-* block) — the old per-theme --page-bg /
   --card-bg / --body-text / --heading-text / --border / --muted-text vars are
   collapsed into it; the neutral scale (--n*) and the theme's own --secondary
   (navy display headings, flipped below) stay, having no semantic equivalent. */
:root {
  color-scheme: light dark;
  --secondary: #273656;          /* --color-secondary default (navy headings) */
  --header-height: 80px;         /* sticky header offset */
  /* In-page anchor (#hash / TOC) scroll offset: lands a fragment target BELOW
     the pinned sticky chrome instead of hidden under it. Clears the site header
     PLUS the microsite sub-nav when present — --ms-nav-height is published by the
     project sub-nav partial (3.75rem) and unset (→ 0px) everywhere else, so this
     is the go_2040 analogue of pc_2040's html:has(.detail-nav) stacking cases,
     built on the same primitive the sticky enquiry card offsets with. */
  --scroll-offset: calc(var(--header-height) + var(--ms-nav-height, 0px) + 8px);
  /* neutral scale (Tailwind neutral) */
  --n50: #fafafa;  --n100: #f5f5f5; --n200: #e5e5e5; --n300: #d4d4d4;
  --n400: #a3a3a3; --n500: #737373; --n600: #525252; --n700: #404040;
  --n800: #262626; --n900: #171717; --n950: #0a0a0a;
}
*, *::before, *::after { box-sizing: border-box; }
/* clip (not hidden): clips any horizontal overflow without forcing overflow-y
   to `auto`, which would spawn a second scroll container → double scrollbar. */
html, body { overflow-x: clip; }
/* Smooth in-page anchor scrolling, and land #hash / TOC targets clear of the
   sticky chrome via --scroll-offset (pc_2040 parity — critical-inline anchor
   scroll-offset). scroll-padding-top lives on the scroll root (<html>). */
html { scroll-behavior: smooth; scroll-padding-top: var(--scroll-offset); }
body {
  font-family: "Roboto", "Arial", system-ui, -apple-system, "Segoe UI", Helvetica, sans-serif;
  background: var(--color-surface); color: var(--color-ink);
  margin: 0; display: flex; flex-direction: column; min-height: 100vh;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility;
}
main { flex: 1; }

/* Headings use the Plus Jakarta Sans display face (pc_2040 parity); body stays
   Roboto. Scoped to the authored-body wrapper + the chrome sets font-display
   directly via the --font-display @theme token. */
.detail-content h1, .detail-content h2, .detail-content h3 { font-family: "Plus Jakarta Sans", "Roboto", system-ui, sans-serif; color: var(--color-heading); letter-spacing: -0.02em; line-height: 1.15; }
h1 { font-size: 2.25rem; font-weight: 700; margin: 0 0 14px; }
h2 { font-size: 1.5rem; font-weight: 600; margin-top: 40px; }
h3 { font-size: 1.15rem; font-weight: 600; }
/* Content typography is scoped to `.detail-content` — the authored-body wrapper
   (page/article body). These are bare, unlayered element rules, and an unlayered
   rule beats Tailwind's layered utilities regardless of specificity — so a global
   `p`/`ul`/`a`/`h* {}` would clobber the text-white/text-primary utilities on the
   chrome (nav, hero eyebrow/heading/lede, footer copyright) and tint it with the
   theme-dependent --heading-text / --body-text / --primary, flipping chrome text
   dark in light mode and teal on the nav. The hero/masthead now lives inside
   <main> (semantic: the page <h1> belongs to <main>), so scoping to <main> would
   re-clobber it — scoping to `.detail-content` (which the hero is never inside)
   leaves all chrome to its theme-independent utilities while authored content
   keeps brand typography. Mirrors listing_2040's .detail-content prose scope. */
.detail-content p { color: var(--color-ink); line-height: 1.7; font-size: 1.02rem; }
.detail-content a { color: var(--brand-primary, #4674a4); }
.detail-content ul { color: var(--color-ink); line-height: 1.85; padding-left: 1.15rem; }
.muted { color: var(--color-ink-muted); font-size: 0.9rem; }
.error { background: #fef2f2; border: 1px solid #fecaca; color: #b91c1c; padding: 11px 16px; border-radius: 12px; }

/* Dark/light colour mode. theme-init sets <html data-theme>, which the SHARED
   --sem-* flip block (app.css, from design-templates) keys on. The only
   per-theme dark override is --secondary: the navy display-heading token has
   no semantic equivalent, so text-secondary flips to white here (replacing
   the 37 per-element dark:text-white variants the templates used to carry).
   The @media block is the no-JS fallback (OS preference when the user hasn't
   chosen): it mirrors the shared flip's values onto the same --sem-* vars —
   keep in lockstep with shared/theme-tokens.css. */
:root[data-theme="dark"] {
  --secondary: #ffffff;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]):not([data-theme="dark"]) {
    --secondary: #ffffff;
    --sem-primary-soft: color-mix(in oklab, var(--brand-primary, #4674a4) 55%, white);
    --sem-surface-warm: #1c1917;
    --sem-surface: #0a0a0a;
    --sem-surface-raised: #171717;
    --sem-surface-muted: #262626;
    --sem-heading: #ffffff;
    --sem-ink: #d4d4d4;
    --sem-ink-muted: #a3a3a3;
    --sem-edge: #262626;
    --sem-edge-strong: #404040;
    --sem-edge-raised: rgba(255, 255, 255, .14);
  }
}
[data-theme="dark"] .error { background: #2a1414; border-color: #5b2424; color: #fca5a5; }

/* Dark/light toggle button — dark icon on the light (white) header; flips to a
   light icon on the dark-mode header. */
.theme-switch {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; padding: 0; margin-left: 4px;
  border: 0; border-radius: 999px; background: transparent; color: var(--n700);
  cursor: pointer; transition: background .15s ease, color .15s ease;
}
.theme-switch:hover { background: rgba(0, 0, 0, 0.06); color: var(--brand-primary, #4674a4); }
[data-theme="dark"] .theme-switch { color: var(--n200); }
[data-theme="dark"] .theme-switch:hover { background: rgba(255, 255, 255, 0.12); }
.theme-switch__sun { display: none; }
.theme-switch__moon { display: block; }
[data-theme="dark"] .theme-switch__moon { display: none; }
[data-theme="dark"] .theme-switch__sun { display: block; }

/* Smaller sticky-header offset on phones (the Tailwind header is
   h-[var(--header-height)]). */
@media (max-width: 639.98px) { :root { --header-height: 60px; } }

/* Scroll shadow on the light header — the header carries transition-shadow and
   the scroll handler toggles .active-scroll past a few px (pc_2040 parity). */
.site-header.active-scroll { box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06), 0 4px 12px rgba(0, 0, 0, 0.05); }

/* Favourites heart — the card toggle (favorites.js) flips aria-pressed; the
   pressed state fills the heart and tints it brand-primary. */
.js-fav-toggle[aria-pressed="true"] { color: var(--brand-primary, #4674a4); }
.js-fav-toggle[aria-pressed="true"] svg { fill: currentColor; }

/* Home quick-search: the active Projects/Listings tab is brand-filled. Plain CSS
   (not an arbitrary Tailwind variant) so it's robust regardless of the build. */
.js-home-search-tabs li.is-active { background: var(--brand-primary, #4674a4); border-color: var(--brand-primary, #4674a4); color: #fff; }

/* Development "Amenities" section — the ###[amenities]### page-builder token
   expansion (microsite_sections.go) emits these semantic classes, styled here
   (not Tailwind) like the index cards. Colours key off the theme tokens so the
   section flips with dark mode automatically. The sibling JSON sections
   (location/factsheets/…) are authored HTML and inherit .detail-content prose. */
/* Page-builder section wrapper (the ###[token]### expansion emits
   <section class="page-builder">). Same anchor offset as the scroll root so a
   TOC link pointing straight at a block lands clear of the sticky chrome —
   pc_2040 parity (was a hardcoded 96px there). */
.page-builder { scroll-margin-top: var(--scroll-offset, 96px); }
.default-sections { margin: 1.5rem 0; }
.project-amenities__group { margin: 0 0 1.75rem; }
.project-amenities__group:last-child { margin-bottom: 0; }
.project-amenities__category {
  font-size: 1.05rem; font-weight: 600; color: var(--color-heading);
  margin: 0 0 .8rem; padding-bottom: .45rem; border-bottom: 1px solid var(--color-edge);
}
.project-amenities__list {
  list-style: none; margin: 0; padding: 0;
  display: grid; gap: .55rem 1.25rem;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
}
.project-amenities__item {
  display: flex; align-items: flex-start; gap: .55rem;
  font-size: .95rem; line-height: 1.45; color: var(--color-ink);
}
.project-amenities__item i {
  flex: none; width: 1.15rem; margin-top: .12rem;
  color: var(--brand-primary, #4674a4); text-align: center; font-style: normal;
}
.project-amenities__item span { min-width: 0; }
