/* ============================================================================
   PropertyInsider.sg — Quiet Ledger
   Typography, colour and density refresh. Loaded LAST in <head>, so it
   overrides the token blocks in site.css, nl.css, tools.css and the
   homepage's inline <style>.

   Direction
   ---------
   Warm paper, olive accent, calm. Until Aug 2026 the palette led with a hot
   vermilion (#DD372E) on every label, badge, border and hover state, which
   made a research site read like an alert. That red is gone: the accent is
   now a deep moss (#5E6B33) drawn from the house swatch, and it appears on
   links, calls to action, one live-data highlight and small marks only.
   Warm ink carries the weight instead. See section 16 for the full ramp
   and for the light hero treatment that replaced the navy heads.

   Type is Newsreader (a screen-cut text serif with a real italic) over
   Source Sans 3 (humanist, open, warm at small sizes). There is no
   monospace: figures use Source Sans 3 with tabular numerals, which aligns
   columns without the typewriter stiffness — and has no slash through
   the zero.
   ========================================================================== */

:root {
  /* ---- Ink: the structural colour ---- */
  --ink:            #232A1F;
  --ink-2:          #333B2B;
  --ink-3:          #444D39;

  /* ---- Brand accent: moss (replaced the red, Aug 2026) ---- */
  --clay:           #5E6B33;
  --clay-dark:      #46521F;
  --clay-soft:      #EDF1DC;

  /* ---- Supporting status colours ---- */
  --slate-teal:     #2F6E63;
  --slate-teal-soft:#ECEFDA;
  --ochre:          #8F6418;
  --ochre-soft:     #F7F0DF;
  --indigo:         #3B4A83;
  --indigo-soft:    #E9ECF6;
  --green:          #1F7A4C;
  --green-soft:     #E2F1E8;
  --blue:           #1D5FA8;
  --blue-soft:      #E4EEF9;
  --orange:         #8A6A1C;
  --orange-soft:    #F6EEDC;
  --yellow:         #8A6510;
  --yellow-soft:    #FAF0D6;

  /* ---- Paper ---- */
  --paper:          #FFFFFF;
  --mist:           #F5F4EC;
  --mist-2:         #FBFAF4;
  --line:           #E5E4D6;
  --line-strong:    #CFCEBB;
  --text-ink:       #262B1F;
  --text-soft:      #6C6E5E;

  /* ---- Legacy token names, remapped ------------------------------------
     Every existing rule in the codebase reads these. Remapping them here
     restyles the whole site without touching 160 files. --------------- */
  --red-primary:    var(--clay); --link-color:#4F5B2C; --text-accent:#6B7A38;
  --red-dark:       var(--clay-dark);
  --red-light:      var(--clay-soft);
  --navy:           var(--ink);
  --navy-light:     var(--ink-2);
  --grey-bg:        var(--mist);
  --grey-light:     var(--mist-2);
  --border:         var(--line);
  --text:           var(--text-ink);
  --text-muted:     var(--text-soft);
  --white:          var(--paper);
  --teal:           var(--slate-teal);
  --teal-light:     var(--slate-teal-soft);
  --amber:          var(--ochre);
  --amber-light:    var(--ochre-soft);
  --cmp-blue:       var(--indigo);
  --cmp-blue-dark:  #2F3C6C;

  /* ---- Type ---- */
  --font-serif: 'Newsreader', Georgia, 'Times New Roman', serif;
  --font-sans:  'Source Sans 3', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-num:   'Source Sans 3', -apple-system, BlinkMacSystemFont, sans-serif;
  --font-mono:  var(--font-num);   /* no monospace anywhere: see note above */

  /* ---- Depth: softer, lower, warmer ---- */
  --shadow-sm: 0 1px 2px rgba(35, 42, 31,.05);
  --shadow:    0 2px 6px rgba(35, 42, 31,.05), 0 1px 2px rgba(35, 42, 31,.04);
  --shadow-lg: 0 10px 28px rgba(35, 42, 31,.08), 0 2px 8px rgba(35, 42, 31,.04);
}

/* ============================================================================
   1. BASE TYPOGRAPHY
   ========================================================================== */

body {
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.65;
  color: var(--text-ink);
  letter-spacing: 0;
  text-rendering: optimizeLegibility;
}

/* Figures line up in columns, and the zero is a plain oval. */
.strip-item, .ticker-item, .num, .mono, td.mono, th.num,
table, .keybox, .proj-card, .proj-price, .proj-sub, .card .meta,
.kpi, .stat, .stat-value, .metric, .pager-status, .budget-readout,
.update-log time, .tc-facts, .data-strip, .pt-kpi, .lc-kpi {
  font-variant-numeric: tabular-nums lining-nums;
}

/* --- Display face -------------------------------------------------------- */
.hero h1, .page-head h1, .section-title, .newsletter h2, .advisor h2,
.editorial h2, .editorial h3, .prose h2, .faq-inner h2, .card h3,
.proj-card h3, .match-card h3, .tracker-card h3, .tc-body h3,
.pj-wrap h2, .calc-editorial h2, .faq-wrap h2, .footer-brand h3 {
  font-family: var(--font-serif);
  font-optical-sizing: auto;
}

.hero h1, .page-head h1 {
  font-weight: 500;
  letter-spacing: -0.018em;
  line-height: 1.14;
}
.hero h1 { font-size: clamp(33px, 4.4vw, 52px); }
.page-head h1 { font-size: clamp(30px, 3.9vw, 45px); }

.section-title, .newsletter h2, .advisor h2, .editorial h2,
.prose h2, .faq-inner h2, .pj-wrap h2, .calc-editorial h2, .faq-wrap h2,
.section h2, .viz h2, .pi-cal h2, .lc-section h2, .tl-wrap > h2 {
  font-weight: 500;
  letter-spacing: -0.014em;
  line-height: 1.22;
  font-size: clamp(25px, 3vw, 33px);
}

.editorial h3, .prose h3 {
  font-family: var(--font-sans);
  font-weight: 600;
  font-size: 18px;
  letter-spacing: -0.006em;
  color: var(--text-ink);
}

/* Body copy: a touch larger and looser than before. Research pages are
   read, not skimmed. */
.prose p, .prose li, .editorial p, .editorial li { font-size: 16.5px; line-height: 1.72; }
.lede-para, .page-lede, .hero-subtitle, .section-subtitle { font-weight: 400; }

/* ============================================================================
   2. BOLD / ITALIC DISCIPLINE
   ------------------------------------------------------------------------
   The old pattern changed three things at once inside a single heading:
   the weight dropped to 400, the style went italic, and the colour flipped
   to red. Italic alone carries the emphasis. Nothing else moves.
   ========================================================================== */

.italic,
h1 .italic, h2 .italic, h3 .italic,
.hero h1 .italic, .page-head h1 .italic, .section-title .italic,
.newsletter h2 .italic, .advisor h2 .italic, .editorial h2 .italic,
.pj-wrap h2 .italic, .calc-editorial h2 .italic, .faq-wrap h2 .italic,
.section h2 .italic, .pi-datasections .section h2 .italic,
.viz h2 .italic, .tl-wrap>h2 .italic, .tl-wrap > h2 .italic, .pi-cal h2 .italic,
.lc-section h2 .italic,
[style*="font-style:italic"] {
  font-style: italic;
  font-weight: 400;
  color: inherit;
}

/* Uppercase micro-labels: quieter weight, no accent colour, more air. */
.eyebrow, .hero-label, .section-label, .cat, .card .cat,
.keybox h3, .update-log h2, .update-log h3, .advisor-form label,
table.data thead th, table.prices th, .strip-item .k, .ticker-item .k,
.sort-bar .lbl, .match-controls label, .match-second label {
  font-weight: 600;
  letter-spacing: .1em;
}
.section-label, .card .cat, .cat {
  color: var(--text-soft);
  font-size: 11px;
}
.eyebrow, .hero-label { color: rgba(255,255,255,.6); font-weight: 600; }

/* Badges and table heads step down from 700 to 600. */
.badge, .status-badge, table.data thead th, table.prices th,
.tc-tag, .pill, .sort-btn, .pager-nav button { font-weight: 600; }

.prose strong, .editorial strong { font-weight: 600; color: var(--text-ink); }

/* ============================================================================
   3. NAVIGATION
   ========================================================================== */

.nav { border-bottom: 1px solid var(--line); background: rgba(255,255,255,.92); backdrop-filter: saturate(140%) blur(10px); }
.nav-inner { height: 72px; }   /* the filter bar and sticky table heads are offset against this */
.logo { font-weight: 600; font-size: 18px; letter-spacing: -.015em; }
.logo-mark { background: var(--red-primary); border-radius: 7px; }
.nav-links a { font-size: 14.5px; font-weight: 500; color: var(--text-soft); }
.nav-links a:hover, .nav-links a[aria-current] { color: var(--text-ink); }
.nav-cta {
  color: var(--paper) !important; background: var(--red-primary);
  padding: 8px 16px; border-radius: 999px; font-weight: 600;
}
.nav-cta:hover { background: var(--red-dark); color: var(--paper) !important; }

/* ============================================================================
   4. HERO AND PAGE HEADERS
   ========================================================================== */

.hero, .page-head { background: var(--ink); }
.hero::before, .page-head::before {
  background: radial-gradient(circle at 12% 30%, rgba(94, 107, 51,.10), transparent 58%);
}
.hero-subtitle, .page-lede {
  font-size: 17px; line-height: 1.6;
  color: rgba(255,255,255,.72); max-width: 640px;
}
.hero-label .dot, .eyebrow .dot { background: var(--clay); }

/* ============================================================================
   5. THE DATA STRIP — the one place boldness is spent
   ------------------------------------------------------------------------
   A market tape under the masthead. Generous tracking on the labels, clay
   on the live figure, hairline rules between readings.
   ========================================================================== */

.data-strip, .ticker { background: var(--ink-2); border-top: 1px solid rgba(255,255,255,.06); }
.strip-item, .ticker-item {
  border-right: 1px solid rgba(255,255,255,.1);
  font-family: var(--font-num);
}
.strip-item .k, .ticker-item .k {
  font-size: 10px; letter-spacing: .13em; text-transform: uppercase;
  color: rgba(255,255,255,.42); font-weight: 600;
}
.strip-item .v, .ticker-item .v {
  font-size: 16px; color: #fff; font-weight: 500; letter-spacing: -.005em;
}
.strip-item .v em, .ticker-item .v em {
  font-style: normal; font-weight: 400; font-size: 12.5px;
  color: rgba(255,255,255,.55); margin-left: 3px;
}

/* ============================================================================
   6. BUTTONS AND LINKS
   ========================================================================== */

a { color:var(--link-color); }
.prose a, .editorial a {
  color:var(--link-color); text-decoration: underline;
  text-decoration-thickness: 1px; text-underline-offset: 3px;
  text-decoration-color: rgba(79, 91, 44,.4);
}
.prose a:hover, .editorial a:hover { text-decoration-color: var(--link-color); }

.btn-primary, .newsletter-btn, .advisor-form button[type=submit] {
  background: var(--clay); border-radius: 999px; font-weight: 600;
  letter-spacing: .005em; box-shadow: none;
}
.btn-primary:hover, .newsletter-btn:hover, .advisor-form button[type=submit]:hover {
  background: var(--clay-dark); transform: none;
}
/* Outline button. The default has to read on paper, because that is where
   most of them sit; the white-on-transparent version is scoped to the dark
   bands. Previously the white version was the default and the research
   section's button vanished into its own background. */
.btn-secondary {
  border-radius: 999px; font-weight: 600;
  border: 1px solid var(--line-strong); background: transparent; color: var(--text-ink);
}
.btn-secondary:hover { border-color: var(--ink); background: var(--mist); color: var(--text-ink); }

.hero .btn-secondary, .page-head .btn-secondary,
.newsletter .btn-secondary, .advisor .btn-secondary, .footer .btn-secondary {
  border-color: rgba(255,255,255,.28); color: #fff;
}
.hero .btn-secondary:hover, .page-head .btn-secondary:hover,
.newsletter .btn-secondary:hover, .advisor .btn-secondary:hover, .footer .btn-secondary:hover {
  border-color: rgba(255,255,255,.55); background: rgba(255,255,255,.06); color: #fff;
}
.link-arrow { color:var(--text-accent); font-weight: 600; }

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

/* ============================================================================
   7. CARDS — generic (.card, used on /research/ and topic grids)
   ------------------------------------------------------------------------
   Shorter images, tighter deks, no red hairline sweeping in on hover.
   ========================================================================== */

.card-grid { gap: 22px; }
.card {
  border-radius: 10px; border: 1px solid var(--line);
  padding: 20px; box-shadow: none;
}
.card::before { display: none; }
a.card:hover {
  transform: translateY(-2px);
  border-color: var(--line-strong);
  box-shadow: var(--shadow-lg);
}
.card .card-img {
  height: 148px; border-radius: 0;
  margin: -20px -20px 16px;
  background: var(--mist);
}
.card .card-img::before { background: none; }
.card h3 {
  font-size: 19.5px; font-weight: 500; line-height: 1.3;
  letter-spacing: -.012em; margin-bottom: 8px;
}
.card p {
  font-size: 14.5px; line-height: 1.55; color: var(--text-soft);
  margin-bottom: 16px;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
  overflow: hidden;
}
.card .meta {
  font-size: 12px; color: var(--text-soft);
  border-top: 1px solid var(--line); padding-top: 12px;
}

/* Category filter pills */
.pill {
  border-radius: 999px; font-size: 13px;
  border: 1px solid var(--line); color: var(--text-soft); background: var(--paper);
}
.pill[aria-pressed="true"], .pill.active {
  background: var(--ink); border-color: var(--ink); color: #fff;
}

/* ============================================================================
   8. HOMEPAGE TRACKER CARDS
   ========================================================================== */

.tracker-card { border-radius: 10px; border: 1px solid var(--line); box-shadow: none; }
.tracker-card::before { display: none; }
.tracker-card:hover { border-color: var(--line-strong); box-shadow: var(--shadow-lg); transform: translateY(-2px); }
.tc-thumb { height: 168px; }
.tc-top { padding: 14px 18px 0; }
.tc-kind { display: none; }        /* the status badge already says this */
.tc-body { padding: 10px 18px 16px; }
.tc-body h3 { font-size: 20px; font-weight: 500; letter-spacing: -.012em; line-height: 1.28; }
.tc-loc { font-size: 13.5px; color: var(--text-soft); margin-bottom: 12px; }
.tc-facts { gap: 6px 18px; margin-bottom: 12px; font-size: 13.5px; }
.tc-fact svg { stroke: var(--text-soft); width: 13px; height: 13px; }
/* Callout chips are colour-coded by what they say, not decorated at random:
   blue for transit, yellow for mixed-use and retail, orange for price and
   land, green for demand and scale, plain grey for everything else. */
.tc-tag {
  background: var(--mist); color: var(--text-soft);
  border-radius: 4px; font-size: 11.5px; padding: 3px 8px;
}
.tc-tag.t-transit { background: var(--blue-soft);   color: var(--blue); }
.tc-tag.t-mixed   { background: var(--yellow-soft); color: var(--yellow); }
.tc-tag.t-price   { background: var(--orange-soft); color: var(--orange); }
.tc-tag.t-demand  { background: var(--green-soft);  color: var(--green); }
.tc-tag.t-plain   { background: var(--mist);        color: var(--text-soft); }
.tc-tag.hl        { background: var(--clay-soft);   color:var(--text-accent); }
.tc-foot { padding: 12px 18px; border-top: 1px solid var(--line); font-size: 12.5px; }
.tc-foot .tc-view { color:var(--text-accent); font-weight: 600; }

.status-badge, .badge {
  border-radius: 4px; font-size: 10.5px; letter-spacing: .07em; padding: 3px 8px;
}
.status-badge.awarded, .badge.awarded { background: var(--green-soft); color: var(--green); }
.status-badge.tendered, .badge.tendered { background: var(--indigo-soft); color: var(--indigo); }
.badge.selling, .badge.available { background: var(--indigo-soft); color: var(--indigo); }
.badge.upcoming, .badge.preview { background: var(--slate-teal-soft); color: var(--slate-teal); }
.badge.gls { background: var(--clay-soft); color:var(--text-accent); }
.badge.ec { background: var(--ochre-soft); color: var(--ochre); }
.badge.soldout, .badge.sold { background: var(--mist); color: var(--text-soft); }
.badge.launched { background: var(--ink); color: #fff; }

/* ============================================================================
   9. NEW LAUNCHES — landscape map, compact list beside it
   ------------------------------------------------------------------------
   The map is the feature: it takes two thirds of the width and is wider
   than it is tall. The list sits at a third beside it and scrolls inside
   itself, so the two panes start and end together instead of the page
   running on past a hundred cards.
   ========================================================================== */

.split {
  max-width: 1400px;
  grid-template-columns: minmax(300px, 33%) minmax(0, 1fr);
  gap: 24px;
  padding: 0 32px;
}
/* Both panes share one height so the split reads as a single unit, and the
   list scrolls inside itself rather than dragging the page down past a
   hundred cards. */
.list-pane {
  padding: 24px 4px 24px 0;
  max-height: clamp(480px, 72vh, 740px);
  overflow-y: auto;
  overscroll-behavior: contain;
}
.list-pane::-webkit-scrollbar { width: 8px; }
.list-pane::-webkit-scrollbar-thumb {
  background: var(--line-strong); border-radius: 999px;
}
.list-pane::-webkit-scrollbar-track { background: transparent; }
.list-pane { scrollbar-width: thin; scrollbar-color: var(--line-strong) transparent; }

.map-pane {
  position: sticky; top: 140px;   /* clears nav (72px) + filter bar */
  height: clamp(480px, 72vh, 740px);
  border: 1px solid var(--line); border-radius: 10px; overflow: hidden;
  margin-top: 24px;
}
/* OneMap Grey basemap: a light, desaturated canvas, so the markers and the
   1km/2km rings carry the colour instead of competing with the tiles. */
#map { background: var(--mist); border-radius: 10px; }
.map-legend {
  bottom: 12px; left: 12px; border-radius: 6px;
  font-size: 11.5px; gap: 12px; padding: 6px 10px;
  background: rgba(255,255,255,.94); border: 1px solid var(--line);
  box-shadow: var(--shadow-sm);
  backdrop-filter: blur(6px);
}
.map-legend span { color: var(--text-soft); }
.leaflet-control-zoom a {
  background: var(--paper); color: var(--text-ink); border-color: var(--line);
}
.leaflet-control-zoom a:hover { background: var(--mist); }
.leaflet-control-attribution { background: rgba(255,255,255,.82); color: var(--text-soft); }
.leaflet-bar { border: 0; box-shadow: var(--shadow-sm); }

/* --- Project cards: horizontal, one glance each ------------------------- */
/* Shared card chrome. `.proj-card` is reused in three places: the hub list
   pane, the "Compare with nearby launches" grid on project pages, and the
   upcoming-launches grid. Only the hub list runs horizontal — the others are
   vertical cards with a full-width banner image, so the horizontal rules are
   scoped to `.list-pane` rather than applied to every `.proj-card`. */
.proj-card {
  border-radius: 10px; border: 1px solid var(--line);
  margin-bottom: 12px; box-shadow: none;
}
.proj-card:hover { border-color: var(--line-strong); box-shadow: var(--shadow); transform: none; }
.proj-card.active { border-color:var(--text-accent); box-shadow: 0 0 0 2px var(--clay-soft); }
.proj-thumb { width: 100%; }
.proj-card-body { padding: 12px 14px; display: flex; flex-direction: column; gap: 6px; }
.proj-card-top { margin-bottom: 0; align-items: baseline; flex-wrap: wrap; gap: 4px 8px; }
.proj-card h3 { font-size: 17.5px; font-weight: 500; letter-spacing: -.01em; line-height: 1.28; }

/* Hub list pane only: thumbnail left, content right. */
.list-pane .proj-card {
  display: grid; grid-template-columns: 1fr; align-items: stretch;
}
.list-pane .proj-card:has(.proj-thumb) { grid-template-columns: 116px 1fr; }
.list-pane .proj-thumb { height: 100%; min-height: 112px; width: 116px; }
.list-pane .proj-card h3 { font-size: 16.5px; line-height: 1.25; }

/* Vertical grids keep their banner image intact. */
.sim-grid .proj-thumb, .up-grid .proj-thumb { width: 100%; height: 160px; object-fit: cover; }
.proj-meta { font-size: 12.5px; margin-bottom: 0; color: var(--text-soft); }
/* Direct children only — matches the scoping in nl.css, so the nested
   station-code chips do not inherit the separator dot. */
.proj-meta>span:not(:last-child)::after { margin: 0 6px; }
.proj-price-row {
  border-top: 1px solid var(--line); padding-top: 10px; margin-top: auto;
  align-items: center;
}
.proj-sub { font-family: var(--font-num); font-size: 13px; color: var(--text-ink); font-weight: 500; }
.proj-sub em { font-weight: 400; color: var(--text-soft); font-size: 12px; }
.proj-arrow { display: none; }
.proj-card-actions { margin-top: 0; }

/* The compare control is secondary: it should not read as the main action. */
.proj-card .cmp-add,
.proj-price-row .cmp-add {
  background: transparent; color: var(--text-soft);
  border: 1px solid var(--line); font-size: 12px; padding: 5px 12px;
}
.proj-card .cmp-add:hover:not([disabled]),
.proj-price-row .cmp-add:hover:not([disabled]) {
  background: var(--paper); border-color: var(--ink); color: var(--ink);
}
.proj-card .cmp-add[aria-pressed="true"],
.proj-price-row .cmp-add[aria-pressed="true"] {
  background: var(--ink); border-color: var(--ink); color: #fff;
}

@media (max-width: 1000px) {
  .split { grid-template-columns: 1fr; padding: 0 20px; gap: 0; }
  .map-pane { position: relative; top: 0; height: 340px; order: -1; margin: 20px 0 0; }
  .list-pane { max-height: none; overflow: visible; padding: 20px 0 40px; }
}
@media (max-width: 560px) {
  .list-pane .proj-card:has(.proj-thumb) { grid-template-columns: 104px 1fr; }
  .list-pane .proj-thumb { width: 104px; min-height: 104px; }
  .proj-card-body { padding: 12px 14px; }
}

/* ============================================================================
   10. FILTER BAR
   ========================================================================== */

.filter-bar { background: var(--paper); border-bottom: 1px solid var(--line); }
.filter-inner select, .filter-inner input[type=search], .filter-inner input[type=text] {
  border-radius: 8px; border: 1px solid var(--line); font-size: 14px;
}
.filter-inner label { font-size: 11px; letter-spacing: .1em; color: var(--text-soft); }
.btn-reset { border-radius: 999px; }
.section-tabs a {
  border-radius: 999px; font-size: 13.5px; font-weight: 500;
}

/* ============================================================================
   11. TABLES
   ========================================================================== */

.table-scroll { border-radius: 10px; box-shadow: none; border: 1px solid var(--line); }
table.data thead th, table.prices th {
  background: var(--mist); color: var(--text-soft);
  font-size: 11px; letter-spacing: .09em; border-bottom: 1px solid var(--line-strong);
}
table.prices th { border-bottom: 1px solid var(--line-strong); }
table.data tbody tr:nth-child(even) { background: transparent; }
table.data tbody tr:hover, table.prices tr:hover td { background: var(--mist-2); }
table.data tbody td, table.prices td { border-bottom: 1px solid var(--line); font-size: 14.5px; }
table.data thead th button:hover { color:var(--text-accent); }

/* ============================================================================
   12. EDITORIAL PROSE
   ========================================================================== */

/* 1080px is the width /research/, /guides/ and /tools/ already run their
   prose at (.wrap), so the editorial bands now match the rest of the site
   instead of sitting in a 720px column inside a 1180px page. Changed
   29 Aug 2026 — the old value made every "How to read this page" section
   look like it had been dropped in from another layout. */
.editorial-inner { max-width: 1080px; }
.wrap-narrow { max-width: 820px; }
.editorial h2 { margin-bottom: 14px; }
.editorial h3 { margin: 34px 0 10px; }
.editorial p { margin-bottom: 16px; color: var(--text-ink); }
.editorial .updated { font-size: 13px; color: var(--text-soft); }

.keybox {
  background: var(--mist-2); border: 1px solid var(--line);
  border-left:2px solid var(--text-accent); border-radius: 8px;
}
/* Open list, not a stack of boxes: one hairline between questions. */
.faq details {
  border: 0; border-bottom: 1px solid var(--line); border-radius: 0;
  background: none; margin-bottom: 0; padding: 16px 0;
}
.faq details:last-of-type { border-bottom: 0; }
.faq summary { font-weight: 600; font-size: 15.5px; padding: 0; }
.faq summary::after { color: var(--text-soft); font-weight: 400; font-size: 20px; }
.faq details p { font-size: 15px; line-height: 1.7; padding: 0; margin-top: 10px; }

/* ============================================================================
   13. FOOTER, NEWSLETTER, ADVISOR
   ========================================================================== */

.advisor .points li::before { color:var(--text-accent); font-weight: 400; }
.advisor-form { border-radius: 10px; box-shadow: var(--shadow-lg); }
.advisor-form input, .advisor-form select, .advisor-form textarea { border-radius: 8px; }
.newsletter-input { border-radius: 999px; border-width: 1px; }
.newsletter-btn { border-radius: 999px; }
.footer-brand h3 { font-weight: 500; }
.footer-links a:hover { color: #fff; }

/* ============================================================================
   14. QUALITY FLOOR
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  * { animation: none !important; transition: none !important; scroll-behavior: auto !important; }
}

/* ============================================================================
   15. HOMEPAGE PIPELINE MAP
   ------------------------------------------------------------------------
   Replaces the eight tracker cards. Same proportions as the new-launches
   split so the two pages feel like one system: map two thirds, list a third.
   ========================================================================== */

.pipe-split {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 33%);
  gap: 24px;
  /* Each column owns its height. Stretching them to match was the source of
     the dead space: whichever column won, the other had to fill or crop. */
  align-items: start;
}
.pipe-split.no-map { grid-template-columns: 1fr; }

.pipe-map-wrap {
  position: relative;
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
  background: var(--mist);
  height: clamp(400px, 54vh, 580px);   /* definite, so the canvas always fills it */
}
#pipeMap { height: 100%; width: 100%; display: block; }
.pipe-map-wrap .map-legend {
  position: absolute; bottom: 12px; left: 12px; z-index: 800;
  display: flex; gap: 12px; padding: 6px 10px;
  background: rgba(255,255,255,.94); border: 1px solid var(--line);
  border-radius: 6px; font-size: 11.5px; box-shadow: var(--shadow-sm);
  backdrop-filter: blur(6px);
}
.pipe-map-wrap .map-legend span {
  display: flex; align-items: center; gap: 6px;
  color: var(--text-soft); font-weight: 500;
}
.pipe-map-wrap .map-legend i {
  width: 9px; height: 9px; border-radius: 50%; display: inline-block;
}

/* Featured pin: a ring so it reads as raised above the quiet dots. */
.pipe-pin {
  display: block; width: 14px; height: 14px; border-radius: 50%;
  border: 3px solid #fff; box-shadow: 0 1px 5px rgba(35, 42, 31,.4);
  margin: 4px;
}

.pipe-list { display: flex; flex-direction: column; min-width: 0; }
.pipe-list-head {
  font-family: var(--font-sans);
  font-size: 11px; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase; color: var(--text-soft);
  margin: 0 0 10px;
}
.pipe-list ul { list-style: none; margin: 0; padding: 0; }
.pipe-list li + li { border-top: 1px solid var(--line); }
.pipe-list a {
  display: grid;
  grid-template-columns: 10px 1fr;
  grid-template-areas: 'dot name' '. meta';
  gap: 2px 10px;
  padding: 8px; margin: 0 -8px;
  text-decoration: none; border-radius: 6px;
  transition: background .15s ease;
}
.pipe-list a:hover, .pipe-list a:focus-visible { background: var(--mist); }
.pf-dot {
  grid-area: dot; width: 8px; height: 8px; border-radius: 50%;
  background: var(--text-soft); margin-top: 6px;
}
.pf-name {
  grid-area: name; font-family: var(--font-serif);
  font-size: 15.5px; font-weight: 500; line-height: 1.3;
  color: var(--text-ink); letter-spacing: -.008em;
}
.pipe-list a:hover .pf-name { color:var(--text-accent); }
.pf-meta { grid-area: meta; font-size: 12.5px; color: var(--text-soft); }

/* One centred link under the whole split, matching the "Explore the full
   dataset" pattern used by the price-trends section. */
.pipe-foot { text-align: center; margin-top: 24px; }
.pipe-foot .link-arrow {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: 14.5px;
}

/* Popups: content, so they stay on paper. */
.pipe-popup { min-width: 168px; }
.pipe-popup .pp-status {
  display: block; font-size: 10px; font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase; margin-bottom: 3px;
}
.pipe-popup .pp-name {
  font-family: var(--font-serif); font-size: 16.5px; font-weight: 500;
  color: var(--text-ink); text-decoration: none; line-height: 1.25;
}
.pipe-popup .pp-name:hover { color:var(--text-accent); text-decoration: underline; }
.pipe-popup .pp-meta { font-size: 12.5px; color: var(--text-soft); margin-top: 3px; }
.pipe-popup .pp-price {
  font-size: 13px; font-weight: 500; margin-top: 5px;
  font-variant-numeric: tabular-nums;
}

@media (max-width: 900px) {
  .pipe-split { grid-template-columns: 1fr; gap: 20px; }
  .pipe-map-wrap { height: 340px; }
  .pipe-foot { margin-top: 20px; }
}

/* ============================================================
   LEAFLET STACKING
   ============================================================
   Leaflet positions its panes at z-index 400 and its controls at 1000, both
   well above the sticky .nav at z-index 100. Because .leaflet-container sets
   only position:relative it does not open a stacking context, so those panes
   compete with the header directly and the map scrolls over it.

   isolation:isolate opens a stacking context on the container without
   touching layout or paint, confining every internal Leaflet z-index beneath
   the header. Applied globally so any page that mounts a map inherits the
   fix — the home page pipeline map, /new-launches/, /new-launches/schools/
   and every project page via location-map.js.

   Deliberately not solved by raising .nav above 1000: that would put the
   header over modals and the comparison tray as well. */
.leaflet-container { isolation: isolate; }

/* ============================================================================
   16. ORCHARD — the Aug 2026 palette change
   ------------------------------------------------------------------------
   Two changes ship together here.

   (a) The brand red is gone. Every #DD372E in the repo was rewritten to moss
       at source, so this section only has to name the new ramp; it does not
       have to fight the old one. The one deliberate exception is the set of
       official LTA rail colours (NSL #D42E12, CCL #FA9E0D, TEL #9D5B25 …),
       which are data encodings on the station chips and maps rather than
       brand accents — recolouring them would make the maps wrong.

   (b) The heads went light. .hero and .page-head used to be navy with white
       type and a red ember behind them. They are now cream, with deep-moss
       display type and a WebGL mesh drift (assets/hero-shader.js) painting
       the surface. .newsletter and .footer stay dark so the page still has
       a rhythm; .advisor goes light to match the mockup.

   Contrast, checked against the darkest tone the shader can put under the
   type (#E8C895 sand, relative luminance .606):
       moss-deep #2F3B22 on sand ........ 7.3:1   (AAA)
       body #4B5040 on sand ............. 5.4:1   (AA)
       moss #5E6B33 as text on paper .... 5.8:1   (AA)
       white on the strip #5C6739 ....... 5.7:1   (AA)
       white on the advisor CTA #7A6F22 . 5.0:1   (AA)
   ========================================================================== */

:root {
  /* The swatch, named. Ramp runs dark -> light. */
  --moss-deep:  #2F3B22;   /* display type on light heads */
  --moss:       #5E6B33;   /* the accent: CTAs, links, marks */
  --moss-dark:  #46521F;   /* hover */
  --moss-soft:  #EDF1DC;   /* tint */
  --olive:      #7B8852;
  --olive-deep: #5A6640;
  --strip:      #5C6739;   /* the data tape under the head */
  --gold:       #7A6F22;   /* the advisor call to action */
  --gold-dark:  #645B1B;
  --sand:       #E8C895;
  --stone:      #9D948D;
  --sage:       #C7C98A;
  --sage-2:     #D6D696;
  --butter:     #F5EBBA;
  --pale:       #F1F3CE;
  --cream:      #F5F1E1;
}

/* ---- 16.1 Light heads ---------------------------------------------------
   The gradient is the fallback and the first paint; hero-shader.js lays a
   canvas over it at z-index 0. Both are on-palette, so a browser with no
   WebGL loses the motion and nothing else. */

.hero, .page-head {
  background: linear-gradient(152deg, #FAF7EC 0%, #EFF1D8 46%, #E4DCB8 100%);
  color: var(--text-ink);
}
.hero::before, .page-head::before { background: none; }

.hero h1, .page-head h1 { color: var(--moss-deep); }
.hero h1 .italic, .page-head h1 .italic { color: var(--olive-deep); }
.hero-subtitle, .page-lede { color: #4B5040; }
.page-meta { color: #63684E; }
.page-meta strong { color: #3A4230; }
.crumbs, .crumbs a { color: #5F6449; }
.crumbs a:hover { color: var(--moss-dark); }
.crumbs .here { color: #39412C; }

/* Section 2 sets .eyebrow / .hero-label to white for the old dark heads. */
.eyebrow, .hero-label { color: #5A6335; }
.hero-label {
  background: rgba(94,107,51,.07);
  border: 1px solid rgba(94,107,51,.22);
  backdrop-filter: none;
}
.eyebrow .dot, .hero-label .dot { background: var(--moss); }

/* The breadcrumb, the byline link and the project research note carry their
   colour INLINE on 160+ generated pages. Beating them here is one rule; the
   alternative was a sed across every file, which would have to be repeated
   after every rebuild. Scoped to the heads, so the footer's white-on-dark
   inline styles are untouched. */
.hero [style*="255,255,255"],  .page-head [style*="255,255,255"],
.hero [style*="255, 255, 255"], .page-head [style*="255, 255, 255"] {
  color: #5A5F46 !important;
}
.hero [style*="255,255,255"] a:hover, .page-head [style*="255,255,255"] a:hover,
.hero a[style*="255,255,255"]:hover, .page-head a[style*="255,255,255"]:hover {
  color: var(--moss-dark) !important;
}

/* ---- 16.2 Section tabs on a light head ---------------------------------- */

/* Opaque, not translucent: the owl sits under the right-hand end of this
   row on wide viewports, and a 55%-alpha pill let its plumage through and
   made the last tab unreadable. */
.hero .section-tabs a, .page-head .section-tabs a {
  border-color: rgba(70,82,31,.22);
  color: #4B5528;
  background: rgba(255,255,255,.86);
}
.hero .section-tabs a:hover, .page-head .section-tabs a:hover {
  border-color: rgba(70,82,31,.48);
  background: #fff;
}
.hero .section-tabs a[aria-current], .page-head .section-tabs a[aria-current] {
  background: var(--moss); border-color: var(--moss-dark); color: #fff;
}

/* ---- 16.3 Buttons on a light head --------------------------------------- */

.hero .btn-secondary, .page-head .btn-secondary, .advisor .btn-secondary {
  border-color: rgba(70,82,31,.30);
  color: var(--moss-dark);
  background: rgba(255,255,255,.55);
}
.hero .btn-secondary:hover, .page-head .btn-secondary:hover,
.advisor .btn-secondary:hover {
  border-color: rgba(70,82,31,.55); background: #fff; color: var(--moss-dark);
}

/* ---- 16.4 The owl, relit ------------------------------------------------
   mascot.css tunes the drop shadow for a dark head. On cream a black shadow
   reads as dirt, so it becomes a soft olive one at every breakpoint. */

.hero .pi-mascot, .page-head .pi-mascot, .hero-mascot-m {
  filter: drop-shadow(0 10px 22px rgba(70,82,31,.16));
}
@media (max-width: 960px) {
  .page-head .pi-mascot { filter: drop-shadow(0 8px 18px rgba(70,82,31,.16)); }
}
@media (max-width: 640px) {
  .page-head .pi-mascot,
  .hero-mascot-m { filter: drop-shadow(0 8px 18px rgba(70,82,31,.16)); }
}

/* ---- 16.5 The data strip ------------------------------------------------- */

.data-strip, .ticker {
  background: var(--strip);
  border-top: 1px solid rgba(255,255,255,.14);
}

/* ---- 16.6 The advisor block --------------------------------------------- */

.advisor {
  background: linear-gradient(160deg, #F7F4E4 0%, #EFEFD5 55%, #E7DDB8 100%);
}
.advisor::before { background: none; }
.advisor h2 { color: var(--moss-deep); }
.advisor h2 .italic { color: var(--olive-deep); }
.advisor .lead, .advisor .points li { color: #4B5040; }
.advisor .points li::before { color: var(--moss); }
.advisor .disclosure { color: #63684E; }
.advisor .disclosure a { color: var(--moss-dark); }
.advisor-form {
  background: #FCFBF4;
  border: 1px solid rgba(70,82,31,.14);
  box-shadow: 0 10px 28px rgba(70,82,31,.10), 0 2px 8px rgba(70,82,31,.05);
}
.advisor-form button[type=submit] { background: var(--gold); }
.advisor-form button[type=submit]:hover { background: var(--gold-dark); }

/* ---- 16.7 Dark bands that stay dark -------------------------------------
   .newsletter and .footer keep white type, so they keep the white outline
   button from section 6. Named here only so the next reader knows it was a
   decision and not an oversight. */

.newsletter, .footer { background: var(--ink); }

/* ---- 16.9 Project hero meta on a light head -----------------------------
   `.proj-hero-meta` (Developer / Tenure / TOP / Nearest MRT) is styled by a
   per-page <style> block baked into every generated project page, so it was
   not caught by the inline-style override in 16.1 — it kept its white-on-navy
   colours and went invisible on the cream head. Beating it here fixes all
   ~160 shipped pages without a rebuild; the same colours are also written
   into new-launches/project/index.html so the next generator run agrees. */

.page-head .proj-hero-meta { color: #5A5F46; }
.page-head .proj-hero-meta span b { color: var(--moss-deep); }
