/*
  listings-discover.css — Wave 1 of Listings_Discovery_Design_Spec_2026-04-24.md
  (origin/main bbae071). Loaded only on listings/discover/index.html.

  Decisions implemented:
  - E (desktop): 3-pane split filter-rail + cards + map at >=1280px;
    2-pane (cards + map sticky) at 1024-1279px with rail behind a button;
    2-pane stacked (cards + fullscreen-map toggle) at 768-1023px.
  - D (mobile): list view default; "Map" button enters fullscreen-map state
    (Wave 2 swaps this for 3-snap bottom-sheet pattern).
  - F (filter set): 10 filters render in the rail (chrome only Wave 1; Wave 2 wires).
  - H (pin strategy): map pane is a placeholder with copy describing the Wave 3 plan.

  Convention #14: this file must be tracked + committed alongside the HTML.
  Convention #15: single-copy file; no cross-site duplication today.
*/

/* ═══════════════════════════════════════════════════════════════════════
   Shell + sticky top bar
   ═══════════════════════════════════════════════════════════════════════ */

.ldisc-shell {
  background: #0a0a0a;
  color: #fff;
  min-height: calc(100vh - 88px); /* approx nav-top + main-nav height */
}

.ldisc-topbar {
  position: sticky;
  top: 0;
  z-index: 50;
  background: rgba(10, 10, 10, 0.92);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border-bottom: 1px solid #222;
}

.ldisc-topbar-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 20px;
}

.ldisc-back {
  color: rgba(255, 255, 255, 0.55);
  font-size: 1.4rem;
  text-decoration: none;
  padding: 6px 8px;
  border-radius: 4px;
  line-height: 1;
}
.ldisc-back:hover { color: #fff; background: #1a1a1a; }

.ldisc-search-wrap {
  flex: 1;
  display: flex;
  gap: 8px;
  margin: 0;
}

.ldisc-search {
  flex: 1;
  background: #1a1a1a;
  border: 1px solid #333;
  color: #fff;
  padding: 10px 14px;
  border-radius: 4px;
  font-family: 'Roboto', sans-serif;
  /* font-size: 1rem honors the user's accessibility text-size preference
     (iOS dynamic type, browser default zoom). Under default user settings
     1rem == 16px, which avoids iOS Safari's <16px auto-zoom-on-focus quirk.
     Under reduced-text-size accessibility settings, 1rem will compute below
     16px and iOS WILL auto-zoom — that's the user's accessibility choice
     and we honor it. The codebase has no html/:root font-size override,
     so 1rem reliably computes to 16px under default settings. If a future
     change sets a non-16px root font-size, audit input font-sizes for
     auto-zoom risk. Discussion 2026-04-25. */
  font-size: 1rem;
  min-width: 0; /* allow flex to shrink past intrinsic width */
}
.ldisc-search::placeholder { color: rgba(255, 255, 255, 0.4); }
.ldisc-search:focus { outline: none; border-color: #EA002A; }

.ldisc-search-submit {
  background: #EA002A;
  color: #fff;
  border: none;
  padding: 10px 22px;
  border-radius: 4px;
  font-family: 'Raleway', sans-serif;
  font-weight: 700;
  font-size: 0.85rem;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  cursor: pointer;
  transition: background 0.15s ease;
}
.ldisc-search-submit:hover { background: #c00024; }

.ldisc-result-count {
  font-family: 'Roboto', sans-serif;
  font-size: 0.85rem;
  color: rgba(255, 255, 255, 0.6);
  white-space: nowrap;
}
.ldisc-result-count strong {
  color: #fff;
  font-weight: 700;
}

.ldisc-mobile-filter,
.ldisc-view-toggle {
  display: none; /* shown via media queries below */
  align-items: center;
  gap: 8px;
  background: #1a1a1a;
  border: 1px solid #333;
  color: #fff;
  padding: 10px 14px;
  border-radius: 4px;
  font-family: 'Raleway', sans-serif;
  font-weight: 700;
  font-size: 0.85rem;
  cursor: pointer;
  white-space: nowrap;
}
.ldisc-mobile-filter:hover,
.ldisc-view-toggle:hover {
  border-color: #EA002A;
}

.ldisc-filter-count {
  background: #EA002A;
  color: #fff;
  font-size: 0.7rem;
  font-weight: 700;
  padding: 1px 7px;
  border-radius: 10px;
  min-width: 18px;
  text-align: center;
}

/* Quick-filter chip row */
/* WIRED 2026-05-01 (#231): 5 of 6 chips now have click handlers in
 * js/listings-index.js wiring against pre-computed flags in data.json:
 *   - Under $300k        → price filter (l.price <= 300000)
 *   - New construction   → year_built >= currentYear - 5
 *   - Waterfront         → public_remarks regex (Python pre-compute)
 *   - Ocean view         → public_remarks regex (Python pre-compute)
 *   - Cottage country    → city_slug in COTTAGE_CITY_SLUGS (Python list)
 * The 6th chip (Acreage) stays hidden via the [data-chip="acreage"]
 * selector below until lot_size data is reliably populated in the cache
 * (currently None for most listings).
 */
.ldisc-chips {
  display: flex;
  gap: 8px;
  padding: 0 20px 14px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.ldisc-chips::-webkit-scrollbar { display: none; }
/* Hide the unwired Acreage chip until lot_size data lands. Defensive
 * skip in the JS click handler too — see listings-index.js. */
.ldisc-chip[data-chip="acreage"] { display: none; }
/* Active state for top-bar chips (matches filter-rail .ldisc-active
 * convention used elsewhere in this file). */
.ldisc-chip.ldisc-active {
  background: #EA002A;
  border-color: #EA002A;
  color: #fff;
}

.ldisc-chip {
  background: transparent;
  border: 1px solid #333;
  color: rgba(255, 255, 255, 0.75);
  padding: 6px 14px;
  border-radius: 20px;
  font-family: 'Roboto', sans-serif;
  font-size: 0.85rem;
  cursor: pointer;
  white-space: nowrap;
  transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}
.ldisc-chip:hover {
  border-color: #EA002A;
  color: #fff;
}
.ldisc-chip[aria-pressed="true"] {
  background: #EA002A;
  border-color: #EA002A;
  color: #fff;
}

/* ═══════════════════════════════════════════════════════════════════════
   3-pane container (Decision E desktop ≥1280px)
   ═══════════════════════════════════════════════════════════════════════ */

.ldisc-panes {
  display: grid;
  grid-template-columns: 280px minmax(0, 1fr) 520px;
  gap: 0;
  align-items: start;
}

/* Filter rail (left, persistent on ≥1280px) */
.ldisc-rail {
  background: #0f0f0f;
  border-right: 1px solid #222;
  padding: 22px 18px;
  position: sticky;
  top: 102px; /* sticky-topbar height + chip row */
  max-height: calc(100vh - 102px);
  overflow-y: auto;
  align-self: start;
}

.ldisc-rail-status {
  font-family: 'Roboto', sans-serif;
  font-size: 0.78rem;
  color: rgba(234, 0, 42, 0.85);
  background: rgba(234, 0, 42, 0.08);
  border: 1px solid rgba(234, 0, 42, 0.25);
  border-radius: 4px;
  padding: 8px 12px;
  margin: 0 0 16px;
  line-height: 1.4;
}

.ldisc-rail details {
  border-bottom: 1px solid #1a1a1a;
  padding: 12px 0;
}
.ldisc-rail details:first-of-type { padding-top: 0; }
.ldisc-rail details:last-of-type { border-bottom: none; }

.ldisc-rail summary {
  font-family: 'Raleway', sans-serif;
  font-weight: 700;
  font-size: 0.92rem;
  color: #fff;
  cursor: pointer;
  list-style: none;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 4px 0;
}
.ldisc-rail summary::-webkit-details-marker { display: none; }
.ldisc-rail summary::after {
  content: "+";
  color: rgba(255, 255, 255, 0.4);
  font-size: 1.1rem;
  font-weight: 400;
  margin-left: 8px;
}
.ldisc-rail details[open] summary::after { content: "−"; }
.ldisc-rail summary:hover { color: #EA002A; }

.ldisc-moat {
  background: rgba(234, 0, 42, 0.15);
  color: #EA002A;
  font-size: 0.65rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
  padding: 2px 7px;
  border-radius: 10px;
  margin-left: 6px;
}

.ldisc-filter-body {
  margin-top: 12px;
}

.ldisc-price-chips,
.ldisc-segment {
  display: grid;
  gap: 6px;
}
.ldisc-price-chips { grid-template-columns: repeat(2, 1fr); }
.ldisc-segment    { grid-template-columns: repeat(4, 1fr); }

.ldisc-price-chips button,
.ldisc-segment button {
  background: #1a1a1a;
  border: 1px solid #333;
  color: rgba(255, 255, 255, 0.78);
  padding: 8px 8px;
  border-radius: 4px;
  font-family: 'Roboto', sans-serif;
  font-size: 0.82rem;
  cursor: pointer;
  text-align: center;
  transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.ldisc-price-chips button:hover,
.ldisc-segment button:hover {
  border-color: #EA002A;
  color: #fff;
}
/* Active state — set by JS when the button represents the current filter
   value for its group. Only one button per group is active at a time
   (single-active toggle pattern). Filled red so it's unmistakable
   against the dark rail. */
.ldisc-price-chips button.ldisc-active,
.ldisc-segment button.ldisc-active {
  background: #EA002A;
  border-color: #EA002A;
  color: #fff;
  font-weight: 600;
}
.ldisc-price-chips button.ldisc-active:hover,
.ldisc-segment button.ldisc-active:hover {
  background: #c8001f;
  border-color: #c8001f;
}

.ldisc-checkbox {
  display: flex;
  align-items: center;
  gap: 8px;
  font-family: 'Roboto', sans-serif;
  font-size: 0.88rem;
  color: rgba(255, 255, 255, 0.78);
  padding: 6px 0;
  cursor: pointer;
}
.ldisc-checkbox input { accent-color: #EA002A; }

.ldisc-range-row {
  display: flex;
  gap: 8px;
  align-items: center;
}
.ldisc-range-row input {
  flex: 1;
  background: #1a1a1a;
  border: 1px solid #333;
  color: #fff;
  padding: 8px 10px;
  border-radius: 4px;
  font-family: 'Roboto', sans-serif;
  font-size: 0.85rem;
  min-width: 0;
}
.ldisc-range-row input:focus { outline: none; border-color: #EA002A; }
.ldisc-range-row span { color: rgba(255, 255, 255, 0.4); }

.ldisc-city-search {
  width: 100%;
  background: #1a1a1a;
  border: 1px solid #333;
  color: #fff;
  padding: 8px 12px;
  border-radius: 4px;
  font-family: 'Roboto', sans-serif;
  font-size: 0.85rem;
  box-sizing: border-box;
}
.ldisc-city-search:focus { outline: none; border-color: #EA002A; }

.ldisc-coming-soon {
  font-family: 'Roboto', sans-serif;
  font-size: 0.74rem;
  color: rgba(255, 255, 255, 0.4);
  font-style: italic;
  margin: 8px 0 0;
  line-height: 1.4;
}
.ldisc-coming-soon code {
  background: rgba(255, 255, 255, 0.06);
  padding: 1px 4px;
  border-radius: 3px;
  font-size: 0.92em;
}

.ldisc-rail-actions {
  margin-top: 18px;
  padding-top: 14px;
  border-top: 1px solid #1a1a1a;
}
.ldisc-clear-all {
  width: 100%;
  background: transparent;
  border: 1px solid #333;
  color: rgba(255, 255, 255, 0.5);
  padding: 9px;
  border-radius: 4px;
  font-family: 'Raleway', sans-serif;
  font-weight: 700;
  font-size: 0.82rem;
  cursor: pointer;
}
.ldisc-clear-all:disabled { cursor: not-allowed; opacity: 0.5; }

/* ═══════════════════════════════════════════════════════════════════════
   Cards (middle pane)
   ═══════════════════════════════════════════════════════════════════════ */

.ldisc-cards {
  padding: 24px 22px 60px;
}

.ldisc-cards-meta {
  margin-bottom: 22px;
}
.ldisc-cards-meta h1 {
  font-family: 'Raleway', sans-serif;
  font-weight: 900;
  font-size: clamp(1.4rem, 2vw, 1.8rem);
  margin: 0 0 6px;
  color: #fff;
  letter-spacing: -0.3px;
}
.ldisc-cards-meta p {
  font-family: 'Roboto', sans-serif;
  color: rgba(255, 255, 255, 0.6);
  font-size: 0.9rem;
  margin: 0;
  line-height: 1.55;
}

/* Override .lst-card-grid for the middle-pane context.
   Default .lst-card-grid uses minmax(320px, 1fr) which gives 1 column at narrower
   widths. We want 2 columns when the rail + map are taking the sides. */
.ldisc-cards .lst-card-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
}

.ldisc-load-more {
  margin-top: 32px;
  display: flex;
  justify-content: center;
}
.ldisc-load-more button {
  background: transparent;
  border: 1px solid #333;
  color: rgba(255, 255, 255, 0.5);
  padding: 12px 24px;
  border-radius: 4px;
  font-family: 'Raleway', sans-serif;
  font-weight: 700;
  font-size: 0.85rem;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  cursor: pointer;
}
.ldisc-load-more button:disabled { cursor: not-allowed; opacity: 0.7; }

/* ═══════════════════════════════════════════════════════════════════════
   Map pane (right, sticky)
   ═══════════════════════════════════════════════════════════════════════ */

.ldisc-map {
  background: #0f0f0f;
  border-left: 1px solid #222;
  position: sticky;
  top: 102px;
  height: calc(100vh - 102px);
  align-self: start;
}

.ldisc-map-placeholder {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 40px 30px;
  box-sizing: border-box;
}
.ldisc-map-placeholder-icon {
  font-size: 4rem;
  color: rgba(255, 255, 255, 0.12);
  margin: 0 0 14px;
  font-family: monospace;
  line-height: 1;
}
.ldisc-map-placeholder-title {
  font-family: 'Raleway', sans-serif;
  font-weight: 800;
  font-size: 1.05rem;
  color: rgba(255, 255, 255, 0.75);
  margin: 0 0 12px;
  letter-spacing: -0.2px;
}
.ldisc-map-placeholder-meta {
  font-family: 'Roboto', sans-serif;
  font-weight: 400;
  font-size: 0.85rem;
  color: rgba(255, 255, 255, 0.45);
  max-width: 360px;
  line-height: 1.6;
  margin: 0;
}

/* ═══════════════════════════════════════════════════════════════════════
   1024-1279px: 2-pane (cards + map sticky), filter rail collapses to button
   ═══════════════════════════════════════════════════════════════════════ */

@media (max-width: 1279px) {
  .ldisc-panes {
    grid-template-columns: minmax(0, 1fr) 440px;
  }
  .ldisc-rail {
    display: none;
  }
  .ldisc-mobile-filter {
    display: inline-flex;
  }
  .ldisc-cards .lst-card-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Mobile/tablet filter drawer — slides in from left when the
     "Filters" button toggles .ldisc-shell--filter-open on the shell.
     Wired by setupFilterDrawer() in index.html. Replaces the alert
     stub that shipped with Wave 1 (Mike caught this 2026-04-27 via
     Chris Morrison reporting "map search not working on mobile" —
     turned out to be filters being inaccessible on the mobile UX). */
  .ldisc-shell--filter-open .ldisc-rail {
    display: block;
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: 320px;
    max-width: 88vw;
    z-index: 60;
    box-shadow: 0 0 30px rgba(0, 0, 0, 0.7);
    overflow-y: auto;
    padding-top: 56px;
    animation: ldisc-rail-slide-in 0.18s ease-out;
  }
  @keyframes ldisc-rail-slide-in {
    from { transform: translateX(-100%); }
    to   { transform: translateX(0); }
  }

  /* Backdrop — full-viewport dim overlay behind the drawer. Tap to close. */
  .ldisc-rail-backdrop {
    display: none;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.6);
    z-index: 55;
    animation: ldisc-backdrop-fade-in 0.18s ease-out;
  }
  .ldisc-shell--filter-open .ldisc-rail-backdrop {
    display: block;
  }
  @keyframes ldisc-backdrop-fade-in {
    from { opacity: 0; }
    to   { opacity: 1; }
  }

  /* Close (×) button at top-right of the drawer.
     Display block here overrides the hide-at-desktop rule outside the
     media query — the close button only makes sense in drawer mode. */
  .ldisc-rail-close {
    display: block;
    position: absolute;
    top: 10px;
    right: 10px;
    background: transparent;
    border: 0;
    color: #fff;
    font-size: 28px;
    line-height: 1;
    cursor: pointer;
    padding: 6px 14px;
    border-radius: 4px;
    transition: color 0.12s ease, background 0.12s ease;
  }
  .ldisc-rail-close:hover {
    color: #EA002A;
    background: rgba(234, 0, 42, 0.08);
  }

  /* "Apply (N)" button at the bottom of the drawer — closes it.
     Filter changes update cards/pins underneath in real time, but
     this gives users an explicit "I'm done filtering, show me the
     map/cards" affordance. Number reflects the current filtered count. */
  .ldisc-rail-apply {
    display: block;
    width: 100%;
    margin-top: 18px;
    padding: 14px 16px;
    background: #EA002A;
    color: #fff;
    border: 0;
    border-radius: 4px;
    font-family: 'Raleway', sans-serif;
    font-weight: 700;
    font-size: 0.95rem;
    cursor: pointer;
  }
  .ldisc-rail-apply:hover { background: #c8001f; }
}

/* Map fixed-position fix — use a CSS variable measured by JS so the
   map sits below the actual topbar height (mobile topbar wraps to
   2-3 rows and is taller than 88px). Variable falls back to 88px if
   JS hasn't measured yet. Set by setTopbarHeightVar() in index.html. */
:root { --ldisc-topbar-h: 88px; }

/* Hide drawer-only controls at desktop (≥1280px) where the filter rail
   is always in-flow and these buttons are pointless. The @media block
   above re-shows them inside .ldisc-shell--filter-open at <1280px.
   .ldisc-rail-backdrop MUST also be hidden by default outside any
   @media query — otherwise at desktop the <div> takes its default
   display:block and eats a grid cell in .ldisc-panes, shoving the
   cards into the map's column and pushing the map out of the grid
   entirely (catastrophic layout bug caught live 2026-04-27 right
   after 26778c8 deployed). */
.ldisc-rail-close,
.ldisc-rail-apply,
.ldisc-rail-backdrop {
  display: none;
}

/* ═══════════════════════════════════════════════════════════════════════
   768-1023px: 2-pane stacked. Map hides; toggle button enters fullscreen-map.
   ═══════════════════════════════════════════════════════════════════════ */

@media (max-width: 1023px) {
  .ldisc-panes {
    grid-template-columns: minmax(0, 1fr);
  }
  .ldisc-map {
    display: none;
    position: fixed;
    top: var(--ldisc-topbar-h, 88px); /* JS-measured topbar height */
    left: 0;
    right: 0;
    /* Explicit height instead of `auto + bottom: 0`. Browsers don't
       reliably stretch a position:fixed element via top+bottom+auto;
       the spec says they should but the computed height collapses to
       0px in practice (caught live 2026-04-27 — map element had
       top:113px, bottom:0, height:auto but computed height was 0,
       so Leaflet drew tiles into a 0-height box on mobile). */
    height: calc(100vh - var(--ldisc-topbar-h, 88px));
    border-left: none;
    z-index: 40;
  }
  .ldisc-shell--map-view .ldisc-map {
    display: block;
  }
  .ldisc-shell--map-view .ldisc-cards,
  .ldisc-shell--map-view .ldisc-rail {
    display: none;
  }
  .ldisc-view-toggle {
    display: inline-flex;
  }
  .ldisc-cards .lst-card-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   <768px: mobile. List view default, single column, Map button toggles fullscreen
   ═══════════════════════════════════════════════════════════════════════ */

@media (max-width: 767px) {
  .ldisc-topbar-row {
    flex-wrap: wrap;
    gap: 8px;
    padding: 10px 14px;
  }
  .ldisc-back {
    order: 1;
  }
  .ldisc-search-wrap {
    flex: 1 1 100%;
    order: 2;
  }
  .ldisc-search-submit {
    padding: 10px 16px;
    font-size: 0.78rem;
  }
  .ldisc-mobile-filter {
    flex: 1;
    order: 3;
    justify-content: center;
  }
  .ldisc-view-toggle {
    flex: 1;
    order: 4;
    justify-content: center;
  }
  .ldisc-result-count {
    order: 5;
    flex: 1;
    text-align: center;
    font-size: 0.78rem;
  }
  .ldisc-chips {
    padding: 0 14px 10px;
  }
  .ldisc-cards {
    padding: 18px 14px 50px;
  }
  .ldisc-cards .lst-card-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: 14px;
  }
  .ldisc-cards-meta h1 {
    font-size: 1.3rem;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   Reduced-motion / a11y
   ═══════════════════════════════════════════════════════════════════════ */

@media (prefers-reduced-motion: reduce) {
  .ldisc-chip,
  .ldisc-search-submit,
  .ldisc-mobile-filter,
  .ldisc-view-toggle,
  .ldisc-price-chips button,
  .ldisc-segment button {
    transition: none;
  }
}

/* Focus rings — overrides any global outline:none */
.ldisc-search:focus-visible,
.ldisc-city-search:focus-visible,
.ldisc-range-row input:focus-visible,
.ldisc-search-submit:focus-visible,
.ldisc-mobile-filter:focus-visible,
.ldisc-view-toggle:focus-visible,
.ldisc-chip:focus-visible,
.ldisc-price-chips button:focus-visible,
.ldisc-segment button:focus-visible,
.ldisc-clear-all:focus-visible {
  outline: 2px solid #EA002A;
  outline-offset: 2px;
}

/* ═══════════════════════════════════════════════════════════════════════
   Listing card styles — cribbed from inline <style> in listings/index.html
   (which is generator-emitted, ~lines 597-729). The .lst-card* rules live
   inline in every generator-emitted page rather than in a shared CSS file,
   so this canary needs its own copy to render the cards correctly.

   Convention #15 drift candidate: keep these in lockstep with the inline
   copy in listings/index.html (and the generator's emit template) until
   the canary promotes to /listings/, at which point all card styles should
   move to a shared css/listing-cards.css imported by both surfaces.

   Discovered 2026-04-25 during Chrome MCP visual sweep — cards rendered
   unstyled at first paint because I'd copied the markup without these
   styles. Fix shipping as part of Wave 1 follow-up commit.
   ═══════════════════════════════════════════════════════════════════════ */

.lst-card {
  background: #111;
  border: 1px solid #1e1e1e;
  border-radius: 4px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transition: transform .3s, border-color .3s;
  color: inherit;
  position: relative; /* anchors .lst-card-hide overlay (#9 Hide UX) */
}
.lst-card:hover { transform: translateY(-4px); border-color: #EA002A; }
.lst-card-link {
  display: block;
  text-decoration: none;
  color: inherit;
  flex: 1 1 auto;
}
.lst-card-link:focus-visible {
  outline: 2px solid #EA002A;
  outline-offset: -2px;
}
.lst-card-realtor {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 10px 14px;
  border-top: 1px solid #1e1e1e;
  background: #0d0d0d;
  font-family: 'Roboto', sans-serif;
  font-size: 0.72rem;
  letter-spacing: 0.4px;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
  text-decoration: none;
  transition: background .2s, color .2s;
}
.lst-card-realtor:hover,
.lst-card-realtor:focus-visible {
  background: #151515;
  color: #fff;
  outline: none;
}
.lst-card-realtor strong {
  color: #EA002A;
  font-weight: 700;
}
.lst-card-img {
  aspect-ratio: 3 / 2;
  background: #0a0a0a;
  overflow: hidden;
  position: relative;
}
.lst-card-img img {
  width: 100%; height: 100%; object-fit: cover; display: block;
  transition: transform .4s;
}
.lst-card:hover .lst-card-img img { transform: scale(1.05); }
.lst-card-img .lst-card-noimg {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  color: rgba(255, 255, 255, 0.3);
  font-family: 'Raleway', sans-serif; font-weight: 800; font-size: 2rem;
  background: linear-gradient(135deg, #1a1a1a, #0f0f0f);
}
.lst-card-body { padding: 18px 20px 20px; }
.lst-card-price {
  font-family: 'Raleway', sans-serif;
  font-weight: 900;
  font-size: 1.4rem;
  color: #fff;
  margin: 0 0 4px;
}
.lst-card-addr {
  font-family: 'Roboto', sans-serif;
  color: rgba(255, 255, 255, 0.85);
  font-size: 0.95rem;
  font-weight: 500;
  margin: 0 0 2px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.lst-card-city {
  font-family: 'Roboto', sans-serif;
  color: rgba(255, 255, 255, 0.55);
  font-size: 0.85rem;
  margin: 0 0 12px;
}
.lst-card-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 18px;
  font-family: 'Roboto', sans-serif;
  color: rgba(255, 255, 255, 0.65);
  font-size: 0.82rem;
  border-top: 1px solid #1e1e1e;
  padding-top: 12px;
}
.lst-card-meta span strong {
  color: #fff; font-weight: 700; margin-right: 4px;
}
.lst-card-mls {
  font-family: 'Roboto', sans-serif;
  color: rgba(255, 255, 255, 0.4);
  font-size: 0.75rem;
  margin-top: 10px;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.lst-card-team {
  font-family: 'Roboto', sans-serif;
  color: rgba(255, 255, 255, 0.55);
  font-size: 0.8rem;
  margin: 6px 0 0;
  padding-top: 8px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.lst-card-team strong { color: #fff; font-weight: 600; }
.lst-card-new {
  position: absolute;
  top: 10px; left: 10px;
  background: #EA002A;
  color: #fff;
  font-family: 'Raleway', sans-serif;
  font-weight: 800;
  font-size: 0.7rem;
  padding: 4px 10px;
  border-radius: 2px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
}

/* Pending status badge — Zach's ask 2026-05-22. Amber/gold to distinguish
   from red "NEW" badge; top-right of photo box so it doesn't collide with
   NEW (top-left) or the hide-button (also top-right but offset). Status
   string in the label (Conditional Pending / Under Contract / Pending) is
   rendered by js/listings-index.js:pendingLabel(). */
.lst-card-status {
  position: absolute;
  top: 10px; right: 50px;  /* offset from hide-button at right:10px */
  color: #1a1a1a;
  font-family: 'Raleway', sans-serif;
  font-weight: 800;
  font-size: 0.7rem;
  padding: 4px 10px;
  border-radius: 2px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  z-index: 2;
}
.lst-card-status--pending {
  background: #f5c518;  /* amber/gold — clearly different from red NEW */
}
@media (max-width: 480px) {
  .lst-card-status {
    font-size: 0.65rem;
    padding: 3px 8px;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   Wave 3 — Leaflet map (Decisions B, C, G, H per Listings_Discovery_Design_Spec_2026-04-24.md)
   ═══════════════════════════════════════════════════════════════════════ */

/* Map canvas fills the .ldisc-map container; .ldisc-map already has
   position:sticky from the desktop layout block above. We need it to
   ALSO be a positioning context for the absolute "Search this area"
   button — sticky already implies that. */
#ldisc-map {
  width: 100%;
  height: 100%;
  z-index: 0;
  background: #0a0a0a;
}

/* Mobile: when in fullscreen-map state at <1024px, the .ldisc-map gets
   position:fixed (per the existing media query block). Map canvas needs
   to fill that fixed-positioned parent. Already covered by the 100%/100%
   above — no extra rule needed. */

/* Decision H — price pins, color-coded by state. Default = navy. New <=7d = green.
   Price-drop in last 30d = red. Wave 3 sample data sets state; Wave 2 will
   compute it from real DDF cache fields. */
.ldisc-pin {
  background: transparent;  /* divIcon container; the .ldisc-pin-label is the visible chip */
  border: none;
}
.ldisc-pin-label {
  display: inline-block;
  background: #1a3a5c;
  color: #fff;
  border: 2px solid #fff;
  border-radius: 4px;
  padding: 4px 10px;
  font-family: 'Raleway', sans-serif;
  font-weight: 700;
  font-size: 0.78rem;
  white-space: nowrap;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
  position: relative;
  cursor: pointer;
  transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.ldisc-pin-label::after {
  content: '';
  position: absolute;
  bottom: -6px;
  left: 50%;
  transform: translateX(-50%);
  border: 6px solid transparent;
  border-top-color: #fff;
  width: 0;
  height: 0;
}
.ldisc-pin:hover .ldisc-pin-label {
  transform: translateY(-2px);
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.5);
  z-index: 1000;
}
.ldisc-pin--new .ldisc-pin-label { background: #1f6f3a; }
.ldisc-pin--drop .ldisc-pin-label { background: #b51d2e; }

/* Hover state — toggled on a marker's _icon when the matching card is
   hovered in the cards rail. Bright gold outline + scale-up + z-index
   boost so the pin pops above its neighbors. The matching .lst-card on
   the cards side gets .lst-card--highlighted (separate rule below) for
   the reverse direction (pin click → card flash). */
.ldisc-pin--hover {
  z-index: 9999 !important;
}
.ldisc-pin--hover .ldisc-pin-label {
  transform: scale(1.25);
  box-shadow:
    0 0 0 2px #ffd34d,
    0 0 0 6px rgba(255, 211, 77, 0.45),
    0 6px 18px rgba(0, 0, 0, 0.55);
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}

/* Card-flash state — toggled on a .lst-card for ~2.4s after its pin is
   clicked on the map. Royal LePage red outline so the card is obvious
   even if the user has to scroll within the rail to find it. */
.lst-card--highlighted {
  outline: 3px solid #EA002A;
  outline-offset: 2px;
  transition: outline-color 0.2s ease;
}

/* Pin popup — !important throughout because Leaflet's stylesheet loads
   AFTER ours (CDN <link> appears later in <head>) and Leaflet's defaults
   would otherwise win the cascade at equal specificity, leaving the
   popup with a white background + invisible white-on-white body text.
   Spotted live 2026-04-26: only the colored "View details" link was
   visible; price/address/city all rendered transparent on white. */
.leaflet-popup-content-wrapper {
  background: #1a1a1a !important;
  color: #fff !important;
  border-radius: 6px !important;
  padding: 4px 6px !important;
  box-shadow: 0 6px 24px rgba(0, 0, 0, 0.45) !important;
}
.leaflet-popup-tip {
  background: #1a1a1a !important;
}
.leaflet-popup-content {
  margin: 12px 14px !important;
  color: #fff !important;
}
.leaflet-popup-close-button { color: rgba(255, 255, 255, 0.55) !important; }
.leaflet-popup-close-button:hover { color: #fff !important; }
.ldisc-pin-popup {
  font-family: 'Roboto', sans-serif;
  font-size: 0.85rem;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.92);
  min-width: 180px;
}
.ldisc-pin-popup strong {
  font-family: 'Raleway', sans-serif;
  font-weight: 800;
  font-size: 1.05rem;
  color: #fff;
}
.ldisc-pin-popup-city {
  color: rgba(255, 255, 255, 0.6);
  font-size: 0.78rem;
}
.ldisc-pin-popup-link {
  display: inline-block;
  margin-top: 8px;
  color: #ff4d6d;
  text-decoration: none;
  font-weight: 700;
  font-size: 0.85rem;
}
.ldisc-pin-popup-link:hover { color: #ff7a8f; text-decoration: underline; }

/* Decision G — "Search this area" button. Appears top-center of the map
   after pan/zoom (250ms debounce). Hides on click; Wave 2 wires the
   click to actual filter re-execution against new bounds. */
.ldisc-search-area-btn {
  position: absolute;
  top: 14px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 600;  /* above tile layer (z=200) and markers (z=600 default), below popups (z=700) */
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: #fff;
  color: #0a0a0a;
  border: none;
  padding: 9px 18px;
  border-radius: 24px;
  font-family: 'Raleway', sans-serif;
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.5);
  white-space: nowrap;
}
.ldisc-search-area-btn:hover {
  background: #EA002A;
  color: #fff;
}
.ldisc-search-area-btn[hidden] { display: none; }
.ldisc-search-area-btn svg { display: block; }

/* Leaflet tile-fade workaround: Leaflet sets new tiles to inline opacity:0
   and expects its `.leaflet-fade-anim .leaflet-tile-loaded { opacity: 1 }`
   rule to fade them in once loaded. On this surface the fade-in never
   completes (tiles stay invisible at opacity:0) — likely a CSS-cascade
   interaction with the inherited `transition: ...` from elsewhere. Force
   loaded tiles to opacity:1 unconditionally. Cost: tiles snap-appear at
   zoom transitions instead of fading. Worth-it tradeoff for visible map.
   Discovered 2026-04-25 via Chrome MCP visual sweep on the Wave 3 ship. */
.leaflet-tile-loaded {
  opacity: 1 !important;
}

/* MarkerCluster customization to match dark theme */
.marker-cluster {
  background: rgba(26, 58, 92, 0.6) !important;
}
.marker-cluster div {
  background: #1a3a5c !important;
  color: #fff !important;
  font-family: 'Raleway', sans-serif !important;
  font-weight: 800 !important;
  font-size: 0.85rem !important;
  border: 2px solid #fff;
}
.marker-cluster span { line-height: 28px !important; }

/* Leaflet zoom control — match dark theme */
.leaflet-bar a, .leaflet-bar a:hover {
  background-color: #1a1a1a;
  color: #fff;
  border-bottom: 1px solid #333;
}
.leaflet-bar a:hover {
  background-color: #EA002A;
}

/* Attribution control — keep readable on dark theme */
.leaflet-control-attribution {
  background: rgba(0, 0, 0, 0.7) !important;
  color: rgba(255, 255, 255, 0.6) !important;
  font-size: 0.7rem !important;
}
.leaflet-control-attribution a {
  color: rgba(255, 255, 255, 0.85) !important;
}

/* Wave 2 step 3 — MLS# instant-redirect notice (task #172).
   Slot lives below the topbar row inside .ldisc-topbar so it spans the
   full width without disrupting the search/filter/view-toggle layout.
   Two visual states:
     .ldisc-search-msg--info     — non-MLS input or "still loading"
     .ldisc-search-msg--notfound — valid MLS pattern but not in dataset */
.ldisc-search-msg {
  margin: 8px 0 0;
  padding: 10px 14px;
  border-radius: 6px;
  font-size: 0.85rem;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.92);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.12);
}
.ldisc-search-msg--notfound {
  background: rgba(234, 0, 42, 0.08);
  border-color: rgba(234, 0, 42, 0.35);
}
.ldisc-search-msg a {
  color: #EA002A;
  text-decoration: underline;
}
.ldisc-search-msg a:hover {
  color: #ff4d6d;
}
.ldisc-search-msg strong {
  color: #fff;
  font-weight: 600;
}
@media (max-width: 767px) {
  .ldisc-search-msg {
    font-size: 0.8rem;
    padding: 9px 12px;
  }
}

/* Wave 2 — loading + fallback states for the JS-rendered card grid.
   .ldisc-cards-loading shows while data.json is in flight (and on error
   replaces the grid contents). .lst-card-img-fallback handles the rare
   case where a listing has no photo URL — keeps the card layout stable
   instead of collapsing the photo box. */
.ldisc-cards-loading {
  grid-column: 1 / -1;
  text-align: center;
  padding: 64px 24px;
  color: rgba(255, 255, 255, 0.6);
  font-size: 0.95rem;
  margin: 0;
}
.lst-card-img-fallback {
  width: 100%;
  height: 100%;
  background: linear-gradient(135deg, #1a1a1a 0%, #0a0a0a 100%);
}

/* ── Map overlay controls (Chris Morrison mobile feedback 2026-04-27) ──
   Three new controls inside the .ldisc-map area:
   1. .ldisc-map-overlay-actions — top-right pill stack, MOBILE-ONLY,
      contains Exit (← List) + Filters buttons. Escape hatches so users
      don't get "stuck" in map view on mobile (where the topbar
      view-toggle and topbar filter button exist but aren't always
      obvious). Hidden on desktop (≥1024px) where the persistent
      3-pane layout makes them redundant.
   2. .ldisc-map-recenter — bottom-right circular button, visible at
      ALL breakpoints, calls window.ldiscRecenter() to restore the
      initial Central NL viewport.
   z-index 600 matches .ldisc-search-area-btn — above tile layer (200)
   and default markers (600), below Leaflet popups (700). */

.ldisc-map-overlay-actions {
  display: none;  /* desktop default; mobile media query below shows it */
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 600;
  flex-direction: column;
  gap: 8px;
  pointer-events: none;  /* container is transparent; child buttons re-enable */
}
.ldisc-map-overlay-actions > button {
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: rgba(10, 10, 10, 0.92);
  color: #fff;
  border: 1px solid rgba(255, 255, 255, 0.18);
  padding: 9px 14px;
  border-radius: 22px;
  font-family: 'Raleway', sans-serif;
  font-weight: 700;
  font-size: 0.74rem;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.5);
  white-space: nowrap;
  transition: background 0.15s, border-color 0.15s;
}
.ldisc-map-overlay-actions > button:hover,
.ldisc-map-overlay-actions > button:focus-visible {
  background: #EA002A;
  border-color: #EA002A;
  outline: none;
}
.ldisc-map-overlay-actions > button svg { display: block; flex-shrink: 0; }
.ldisc-map-overlay-actions .ldisc-filter-count {
  display: inline-block;
  min-width: 18px;
  padding: 0 5px;
  margin-left: 2px;
  background: #EA002A;
  color: #fff;
  border-radius: 10px;
  font-size: 0.68rem;
  font-weight: 800;
  text-align: center;
}
/* Hide the count badge entirely when zero so the button stays compact. */
.ldisc-map-overlay-actions .ldisc-filter-count:empty,
.ldisc-map-filters .ldisc-filter-count:not(:empty)[data-zero] { display: none; }

/* Recenter button — bottom-right, visible at every breakpoint.
   Sits above Leaflet's default attribution control (which is at z-index
   ~800 but in bottom-right too — we place this slightly higher up so
   they don't overlap). Circular icon-only button matches Leaflet's
   visual idiom. */
.ldisc-map-recenter {
  position: absolute;
  bottom: 36px;  /* clears the Leaflet attribution strip */
  right: 12px;
  z-index: 600;
  width: 36px;
  height: 36px;
  background: #fff;
  color: #0a0a0a;
  border: 1px solid rgba(0, 0, 0, 0.2);
  border-radius: 50%;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}
.ldisc-map-recenter:hover,
.ldisc-map-recenter:focus-visible {
  background: #EA002A;
  color: #fff;
  border-color: #EA002A;
  outline: none;
}
.ldisc-map-recenter svg { display: block; }

/* Mobile: show the Exit/Filters pill stack. Desktop hides them via the
   container's default `display: none`. Breakpoint matches the existing
   list/map view-toggle pattern (.ldisc-shell--map-view fires <1024px). */
@media (max-width: 1023px) {
  .ldisc-map-overlay-actions { display: flex; }
}

/* ═══════════════════════════════════════════════════════════════════════
   Tier 1 cold-start strip — "Just Listed in Central NL" (#173)
   ═══════════════════════════════════════════════════════════════════════
   Server-rendered hero band that sits ABOVE the listings shell on
   /listings/. Surfaces 6 cards from the past 7 days so cold visitors
   land on fresh inventory before the JS-driven main grid loads.
   Decision I of Listings_Discovery_Design_Spec_2026-04-24.md.

   Reuses the existing .lst-card-* classes from ddf-fragment.css inline
   styles (the generator inlines those rules into <style> in
   head_block_simple). Layout-only rules here. */

.ldisc-just-listed {
  background: linear-gradient(180deg, #1a1a1a 0%, #0a0a0a 100%);
  border-bottom: 3px solid #EA002A;
  padding: 36px 0 32px;
}
.ldisc-just-listed-inner {
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 20px;
}
.ldisc-just-listed-header {
  margin-bottom: 24px;
}
.ldisc-just-listed-eyebrow {
  font-family: 'Raleway', sans-serif;
  font-size: 0.72rem;
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: #EA002A;
  margin: 0 0 6px 0;
}
.ldisc-just-listed-header h2 {
  font-family: 'Raleway', sans-serif;
  font-size: 1.65rem;
  font-weight: 800;
  color: #ffffff;
  margin: 0 0 8px 0;
  letter-spacing: 0.005em;
  line-height: 1.15;
}
.ldisc-just-listed-meta {
  font-family: 'Roboto', sans-serif;
  font-size: 0.95rem;
  color: rgba(255, 255, 255, 0.72);
  margin: 0;
  max-width: 640px;
  line-height: 1.45;
}
.ldisc-just-listed-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 20px;
}

/* Mobile: collapse the grid into a horizontal scroller so 6 cards stay
   reachable without dominating the page. Snap-points keep card-edges
   aligned on momentum-scroll. */
@media (max-width: 768px) {
  .ldisc-just-listed { padding: 28px 0 24px; }
  .ldisc-just-listed-header h2 { font-size: 1.35rem; }
  .ldisc-just-listed-meta { font-size: 0.88rem; }
  .ldisc-just-listed-grid {
    display: flex;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    -webkit-overflow-scrolling: touch;
    gap: 12px;
    padding-bottom: 8px;
  }
  .ldisc-just-listed-grid > .lst-card,
  .ldisc-just-listed-grid > article {
    flex: 0 0 280px;
    scroll-snap-align: start;
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   #9 Hide Listings UX (Strategic Vision Rank #9)
   Zillow pattern: × button in top-right of each card dismisses it,
   stored in localStorage per-browser. "Show hidden (N)" toggle injected
   dynamically at bottom of filter rail when count ≥1 lets users restore.
   ═══════════════════════════════════════════════════════════════════════ */
.lst-card-hide {
  position: absolute;
  top: 8px; right: 8px;
  width: 28px; height: 28px;
  border: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, 0.62);
  color: #fff;
  font-family: 'Raleway', sans-serif;
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  z-index: 5;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  opacity: 0;
  transition: opacity .15s ease, background .15s ease, transform .15s ease;
}
.lst-card:hover .lst-card-hide,
.lst-card:focus-within .lst-card-hide,
.lst-card-hide:focus-visible { opacity: 1; }
.lst-card-hide:hover { background: rgba(234, 0, 42, 0.92); transform: scale(1.08); }
.lst-card-hide:focus-visible { outline: 2px solid #EA002A; outline-offset: 2px; }
.lst-card-hide--restore {
  width: auto;
  height: 28px;
  border-radius: 14px;
  padding: 0 12px;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.3px;
  opacity: 1; /* always visible in restore state — hidden cards are intentionally surfaced */
  background: rgba(234, 0, 42, 0.92);
}
.lst-card-hide--restore:hover { background: #EA002A; }

.lst-card--hidden { opacity: 0.42; }
.lst-card--hidden:hover { opacity: 0.55; }

.ldisc-hidden-block {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.ldisc-hidden-toggle {
  width: 100%;
  border: 1px solid rgba(255, 255, 255, 0.18);
  background: transparent;
  color: #cfcfcf;
  padding: 9px 12px;
  border-radius: 3px;
  font-family: 'Raleway', sans-serif;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.3px;
  cursor: pointer;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.ldisc-hidden-toggle:hover { background: rgba(234, 0, 42, 0.12); border-color: #EA002A; color: #fff; }
.ldisc-hidden-toggle.ldisc-active {
  background: rgba(234, 0, 42, 0.18);
  border-color: #EA002A;
  color: #fff;
}
.ldisc-hidden-toggle:focus-visible { outline: 2px solid #EA002A; outline-offset: 2px; }

@media (max-width: 767px) {
  /* On touch devices, hover-to-reveal hides the button entirely — keep it
     visible (lower opacity) so it's discoverable without hover state. */
  .lst-card-hide { opacity: 0.78; }
}


/* ============ VOW Ship #6 — Recently-viewed strip ============
   Pure-JS section rendered by js/recently-viewed.js after reading
   localStorage. Hidden when empty (Convention #74 fail-safe).
   Visual pattern follows .ldisc-just-listed but with subtler
   accent (grey eyebrow vs red) so the page hierarchy stays:
   Just-listed (newest market activity, red emphasis) →
   Recently-viewed (your personal session, grey accent) →
   Main browse results. */
.lst-rv-section {
  background: linear-gradient(180deg, #141414 0%, #0c0c0c 100%);
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  padding: 28px 0 24px;
}
.lst-rv-inner {
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 20px;
}
.lst-rv-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 18px;
  flex-wrap: wrap;
  gap: 12px;
}
.lst-rv-eyebrow {
  font-family: "Raleway", sans-serif;
  font-size: 0.7rem;
  font-weight: 800;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.55);
  margin: 0 0 4px 0;
}
.lst-rv-header h2 {
  font-family: "Raleway", sans-serif;
  font-size: 1.35rem;
  font-weight: 800;
  color: #ffffff;
  margin: 0;
  letter-spacing: 0.005em;
  line-height: 1.2;
}
.lst-rv-clear {
  background: transparent;
  color: rgba(255, 255, 255, 0.5);
  border: 1px solid rgba(255, 255, 255, 0.15);
  border-radius: 3px;
  padding: 6px 12px;
  font-family: "Roboto", sans-serif;
  font-size: 0.82rem;
  font-weight: 400;
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease;
}
.lst-rv-clear:hover {
  color: #EA002A;
  border-color: #EA002A;
}
.lst-rv-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 14px;
}
.lst-rv-card {
  background: #1a1a1a;
  border: 1px solid #262626;
  border-radius: 4px;
  overflow: hidden;
  text-decoration: none;
  color: #ffffff;
  transition: border-color 0.15s ease, transform 0.15s ease;
  display: block;
}
.lst-rv-card:hover {
  border-color: #EA002A;
  transform: translateY(-2px);
}
.lst-rv-card-img {
  position: relative;
  aspect-ratio: 3 / 2;
  background: linear-gradient(135deg, #2a2a2a 0%, #1a1a1a 100%);
  overflow: hidden;
}
.lst-rv-card-img img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.lst-rv-card-noimg {
  width: 100%;
  height: 100%;
  background: linear-gradient(135deg, #2a2a2a 0%, #1a1a1a 100%);
}
.lst-rv-card-badge {
  position: absolute;
  top: 8px;
  left: 8px;
  background: rgba(234, 0, 42, 0.9);
  color: #ffffff;
  font-family: "Raleway", sans-serif;
  font-size: 0.65rem;
  font-weight: 800;
  letter-spacing: 0.14em;
  padding: 3px 7px;
  border-radius: 2px;
}
.lst-rv-card-badge-sold {
  background: rgba(60, 60, 60, 0.9);
}
.lst-rv-card-body {
  padding: 10px 12px;
}
.lst-rv-card-price {
  font-family: "Raleway", sans-serif;
  font-size: 1.05rem;
  font-weight: 800;
  color: #ffffff;
  margin: 0 0 3px 0;
}
.lst-rv-card-addr {
  font-family: "Roboto", sans-serif;
  font-size: 0.82rem;
  color: rgba(255, 255, 255, 0.7);
  margin: 0;
  line-height: 1.35;
}
@media (max-width: 720px) {
  .lst-rv-section { padding: 20px 0 18px; }
  .lst-rv-header h2 { font-size: 1.15rem; }
  .lst-rv-grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
  }
  .lst-rv-card-price { font-size: 0.95rem; }
  .lst-rv-card-addr { font-size: 0.76rem; }
}


/* ============ VOW Ship #2 — Polygon search ============
   Floating action button bottom-left of map overlay (recenter is
   bottom-right). 44px touch target. Royal LePage red hover/active. */
.ldisc-map-draw {
  position: absolute;
  bottom: 36px;
  left: 12px;
  z-index: 600;
  width: 44px;
  height: 44px;
  background: #1a1a1a;
  color: #ffffff;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 4px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
.ldisc-map-draw:hover,
.ldisc-map-draw:focus-visible {
  background: #EA002A;
  color: #ffffff;
  border-color: #EA002A;
  outline: none;
  transform: translateY(-1px);
}
.ldisc-map-draw:focus-visible {
  outline: 2px solid rgba(234, 0, 42, 0.5);
  outline-offset: 2px;
}
.ldisc-map-draw.is-active {
  background: #EA002A;
  color: #ffffff;
  border-color: #EA002A;
}
.ldisc-map-draw svg { display: block; }

/* Polygon-active status pill (Day 1+2 ships visual scaffold; full pill
   UX with match count lands in Day 3 polish per Decision G1). */
.ldisc-polygon-status {
  display: none;
  align-items: center;
  gap: 8px;
  background: rgba(234, 0, 42, 0.12);
  border: 1px solid rgba(234, 0, 42, 0.4);
  color: #EA002A;
  padding: 6px 10px;
  border-radius: 999px;
  font-family: "Roboto", sans-serif;
  font-size: 0.84rem;
  font-weight: 500;
  margin-left: 10px;
}
.ldisc-polygon-status.is-active { display: inline-flex; }
.ldisc-polygon-status button {
  background: transparent;
  border: none;
  color: #EA002A;
  font-size: 1.05rem;
  cursor: pointer;
  padding: 0 0 0 4px;
  font-family: inherit;
  line-height: 1;
}
.ldisc-polygon-status button:hover { opacity: 0.7; }


/* ============ VOW Ship #3 — Compare listings ============
   Plus-icon button injected into every .lst-card via compare-cart.js
   MutationObserver. Top-LEFT to differentiate from existing hide button
   (top-right). 36px touch target. */
.lst-card-compare {
  position: absolute;
  top: 8px;
  left: 8px;
  z-index: 20;
  width: 36px;
  height: 36px;
  background: rgba(0, 0, 0, 0.7);
  color: #ffffff;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 50%;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
  padding: 0;
}
.lst-card-compare:hover,
.lst-card-compare:focus-visible {
  background: #EA002A;
  color: #ffffff;
  border-color: #EA002A;
  outline: none;
  transform: scale(1.08);
}
.lst-card-compare:focus-visible {
  outline: 2px solid rgba(234, 0, 42, 0.5);
  outline-offset: 2px;
}
.lst-card-compare.is-active {
  background: #EA002A;
  color: #ffffff;
  border-color: #EA002A;
}
.lst-card-compare svg { display: block; }

/* Floating compare bar — appended to <body> when cart non-empty.
   Sticky bottom-right; matches dark theme. Hides when cart empty. */
.lst-compare-bar {
  position: fixed;
  bottom: 24px;
  right: 24px;
  z-index: 1000;
  background: #1a1a1a;
  border: 1px solid #EA002A;
  border-radius: 6px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.5);
  display: none;
  max-width: calc(100vw - 48px);
  font-family: "Roboto", sans-serif;
}
.lst-compare-bar.is-visible { display: block; }
.lst-compare-bar-inner {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px 14px;
  flex-wrap: wrap;
}
.lst-compare-bar-label {
  font-family: "Raleway", sans-serif;
  font-weight: 800;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-size: 0.7rem;
  color: #EA002A;
}
.lst-compare-bar-thumbs { display: flex; gap: 6px; }
.lst-compare-bar-thumb {
  background: #262626;
  color: #f5f5f5;
  border: 1px solid #333;
  border-radius: 4px;
  padding: 5px 8px;
  font-size: 0.78rem;
  display: flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  font-family: inherit;
  transition: background 0.12s ease, color 0.12s ease;
}
.lst-compare-bar-thumb:hover {
  background: #EA002A;
  color: #fff;
  border-color: #EA002A;
}
.lst-compare-bar-thumb-num { font-weight: 800; color: #EA002A; font-family: "Raleway", sans-serif; }
.lst-compare-bar-thumb:hover .lst-compare-bar-thumb-num { color: #fff; }
.lst-compare-bar-thumb-x { font-size: 1rem; line-height: 1; }
.lst-compare-bar-cta {
  background: #EA002A;
  color: #fff;
  border: none;
  padding: 8px 14px;
  border-radius: 4px;
  font-family: "Raleway", sans-serif;
  font-weight: 700;
  font-size: 0.82rem;
  letter-spacing: 0.04em;
  text-decoration: none;
  cursor: pointer;
}
.lst-compare-bar-cta:hover { background: #ff1a44; }
.lst-compare-bar-cta--disabled {
  background: #333;
  color: #888;
  cursor: not-allowed;
  pointer-events: none;
}
.lst-compare-bar-clear {
  background: transparent;
  color: #888;
  border: 1px solid #333;
  padding: 7px 10px;
  border-radius: 4px;
  font-family: inherit;
  font-size: 0.78rem;
  cursor: pointer;
  transition: color 0.12s ease, border-color 0.12s ease;
}
.lst-compare-bar-clear:hover {
  color: #EA002A;
  border-color: #EA002A;
}
@media (max-width: 720px) {
  .lst-compare-bar {
    bottom: 12px;
    right: 12px;
    left: 12px;
    max-width: none;
  }
  .lst-compare-bar-inner { gap: 8px; }
  .lst-compare-bar-thumb { padding: 4px 6px; font-size: 0.72rem; }
}

/* ═══════════════════════════════════════════════════════════════════════
   Rollup-page bounded-cards (2026-05-23 night, Mike's UX feedback)

   Without these rules, the discovery shell on rollup pages
   (/listings/new-construction/, /commercial/, /first-time-buyer/)
   renders as endless scroll: 169 new-construction cards = 44,232px
   of cards rail, page total ~52,367px (62× viewport). The map IS
   sticky and the filter rail IS sticky, but the CARDS aren't
   bounded — they grow to fit all matches, and you scroll forever
   while the map "appears" to stay beside you. Long-form copy below
   ends up buried at y=44,837 and consumers never reach it.

   Fix: scope the bound to `.ldisc-shell[data-rollup-prefilter]`
   (only set on rollup pages, NEVER on /listings/ index which
   legitimately serves "browse all" intent and should stay
   unbounded). Cards container becomes a scrollable inner pane;
   cards-meta headline sticks to the top of that inner scroll;
   map + rail keep their existing sticky behavior. Result: shell
   collapses from 44K → ~744px = 1 viewport.

   Long-form copy moves above the shell in the generator template
   so it's seen first instead of buried below 169 cards. Page
   ordering becomes: crumb → editorial intro → bounded discovery
   shell → Keep Exploring → footer.
   ═══════════════════════════════════════════════════════════════════════ */

.ldisc-shell[data-rollup-prefilter] .ldisc-cards {
  max-height: calc(100vh - 102px); /* topbar 88px + chip-row ~14px buffer */
  overflow-y: auto;
  /* Subtle inner scroll affordance — fades the bottom edge to hint
     there's more content below the visible cards. */
  background:
    linear-gradient(#0a0a0a 30%, rgba(10,10,10,0)) 0 0 / 100% 16px no-repeat,
    linear-gradient(rgba(10,10,10,0), #0a0a0a 70%) 0 100% / 100% 24px no-repeat,
    #0a0a0a;
  background-attachment: local, local, scroll;
}

/* Rollup-page banner — page chrome ABOVE the bounded shell.
   Replaces the broken sticky-meta-inside-bounded-scroll pattern
   (Mike caught 2026-05-24 — H1 was rendering between card image
   row and card-details row inside the bounded rail; sticky inside
   internal-scroll container hit a stacking edge case).
   New shape matches the universal US + Canadian portal pattern:
   header sits as page chrome ABOVE the 3-pane discovery experience.
   The .ldisc-rollup-banner element lives in the shell template as
   a sibling between the topbar header and the panes grid div. */
.ldisc-rollup-banner {
  max-width: 1240px;
  margin: 24px auto 18px;
  padding: 0 24px;
}
.ldisc-rollup-banner h1 {
  font-family: 'Raleway', sans-serif;
  font-weight: 800;
  font-size: clamp(1.6rem, 3.2vw, 2.2rem);
  color: #ffffff;
  margin: 0 0 8px;
  letter-spacing: -0.02em;
  line-height: 1.15;
}
.lst-rollup-banner-sub,
.ldisc-rollup-banner p {
  font-family: 'Roboto', sans-serif;
  font-size: 0.95rem;
  line-height: 1.5;
  color: rgba(255, 255, 255, 0.7);
  margin: 0;
  max-width: 760px;
}

/* The Load-more block lives outside the bounded scroll area visually
   but inside .ldisc-cards in markup terms; it gets a top divider when
   the rail scrolls so it doesn't run into the last card. */
.ldisc-shell[data-rollup-prefilter] .ldisc-load-more {
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  margin-top: 12px;
  padding-top: 12px;
}

/* Mobile (<1024px): the panes layout already drops to single-column
   stacking and the cards/map toggle takes over. Disable the bounded
   scroll on mobile so the cards scroll with the page (consumers
   expect to thumb-scroll vertically on a phone, not pinch into an
   inner scroll container). */
@media (max-width: 1023px) {
  .ldisc-shell[data-rollup-prefilter] .ldisc-cards {
    max-height: none;
    overflow-y: visible;
    background: #0a0a0a;
  }
  .ldisc-rollup-banner {
    margin: 18px auto 14px;
    padding: 0 20px;
  }
  .ldisc-rollup-banner h1 {
    font-size: clamp(1.3rem, 5vw, 1.7rem);
  }
}

/* ═══════════════════════════════════════════════════════════════════════
   Rollup-page Phase 2 enrichment (2026-05-23 night, research-driven):
   market-context band + FAQ section + cross-links section. Page
   ordering (per US + Canadian portal research):
     crumb → bounded shell → market-context → long-form → FAQ →
     cross-links → Keep Exploring → DDR → footer
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Market context band — numeric snapshot below the shell ── */
.lst-mkt-context {
  max-width: 1100px;
  margin: 32px auto 0;
  padding: 0 20px;
}
.lst-mkt-context-inner {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 1px;
  background: #1a1a1a;
  border: 1px solid #222;
  border-radius: 6px;
  overflow: hidden;
}
.lst-mkt-stat {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 22px 16px;
  background: #0a0a0a;
  text-align: center;
}
.lst-mkt-stat-num {
  font-family: 'Raleway', sans-serif;
  font-weight: 800;
  font-size: 1.6rem;
  color: #ffffff;
  letter-spacing: -0.02em;
  line-height: 1.1;
}
.lst-mkt-stat-label {
  font-family: 'Roboto', sans-serif;
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: rgba(255, 255, 255, 0.55);
  margin-top: 8px;
}
.lst-mkt-stat-count .lst-mkt-stat-num { color: #EA002A; }

@media (max-width: 600px) {
  .lst-mkt-context-inner { grid-template-columns: repeat(2, 1fr); }
  .lst-mkt-stat { padding: 16px 12px; }
  .lst-mkt-stat-num { font-size: 1.3rem; }
  .lst-mkt-stat-label { font-size: 0.68rem; }
}

/* ── FAQ section — accordion via native <details>/<summary> ── */
.lst-faq-h2 {
  font-family: 'Raleway', sans-serif;
  font-weight: 800;
  font-size: clamp(1.5rem, 3vw, 2rem);
  color: #ffffff;
  margin: 0 0 24px;
  letter-spacing: -0.02em;
}
.lst-faq-item {
  border-bottom: 1px solid rgba(255, 255, 255, 0.08);
  padding: 4px 0;
}
.lst-faq-item:first-of-type { border-top: 1px solid rgba(255, 255, 255, 0.08); }
.lst-faq-q {
  font-family: 'Raleway', sans-serif;
  font-weight: 700;
  font-size: 1.05rem;
  color: #ffffff;
  padding: 18px 36px 18px 0;
  cursor: pointer;
  position: relative;
  list-style: none;
  line-height: 1.4;
}
.lst-faq-q::-webkit-details-marker { display: none; }
.lst-faq-q::after {
  content: '+';
  position: absolute;
  right: 0;
  top: 50%;
  transform: translateY(-50%);
  font-family: 'Raleway', sans-serif;
  font-weight: 300;
  font-size: 1.8rem;
  color: rgba(255, 255, 255, 0.6);
  transition: transform 0.2s ease, color 0.2s ease;
  line-height: 1;
}
.lst-faq-item[open] > .lst-faq-q::after {
  content: '\2013';  /* en-dash */
  color: #EA002A;
}
.lst-faq-q:hover { color: #EA002A; }
.lst-faq-a {
  padding: 0 0 22px;
  color: rgba(255, 255, 255, 0.82);
}
.lst-faq-a p {
  font-family: 'Roboto', sans-serif;
  font-size: 0.96rem;
  line-height: 1.65;
  margin: 0 0 12px;
}
.lst-faq-a p:last-child { margin-bottom: 0; }
.lst-faq-a strong { color: #ffffff; font-weight: 600; }

/* ── Cross-links section — 2-column at desktop, stacked on mobile ── */
.lst-cross-links {
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  padding-top: 40px !important;
}
.lst-xlink-h2 {
  font-family: 'Raleway', sans-serif;
  font-weight: 800;
  font-size: clamp(1.3rem, 2.5vw, 1.7rem);
  color: #ffffff;
  margin: 0 0 28px;
  letter-spacing: -0.02em;
}
.lst-xlink-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 32px;
}
.lst-xlink-col h3.lst-xlink-h3 {
  font-family: 'Raleway', sans-serif;
  font-weight: 700;
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: rgba(255, 255, 255, 0.5);
  margin: 0 0 14px;
}
.lst-xlink-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.lst-xlink-item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 16px;
  background: #1a1a1a;
  border: 1px solid #222;
  border-radius: 4px;
  margin-bottom: 8px;
  text-decoration: none;
  color: #ffffff;
  font-family: 'Roboto', sans-serif;
  font-size: 0.96rem;
  font-weight: 500;
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
.lst-xlink-item:hover {
  background: #222;
  border-color: #EA002A;
  transform: translateX(2px);
}
.lst-xlink-arrow {
  color: #EA002A;
  font-size: 1.1rem;
  font-weight: 600;
  flex-shrink: 0;
}

/* ═══════════════════════════════════════════════════════════════════════
   Long-form editorial visual treatment (2026-05-24, Mike's UX feedback
   "this doesn't look very good. We need more pictures and visual appeal").

   Mike's existing pages/_long-form/new-construction.html ALREADY has
   semantic classes (.nc-content, .nc-section, .nc-list, .nc-grid,
   .nc-card, .nc-highlight) — they just had no CSS targeting them, so
   everything rendered as plain typography. This block adds visual
   hierarchy + card backgrounds + icon-prefixed bullets + accent
   borders + grid layout for the developments.

   Image acquisition is a SEPARATE pass — for actual pictures we should
   either (a) pull representative photos from our active new-construction
   listing pool (we have actual Avalon new builds with photos in
   /images/listings/), or (b) source generic stock from Unsplash/Pexels
   with CC0 licensing. Surfacing to Mike as Phase 4.
   ═══════════════════════════════════════════════════════════════════════ */

/* Twilight hero — restored 2026-05-24 from the legacy
   pages/new-construction.html that was 301'd during Phase 2 Wave B.
   Mike caught it was missing tonight ("we had the image of the new
   construction at twilight, it was in the hero"). The .nc-hero
   element was never copied into _long-form/new-construction.html
   when we extracted the editorial content earlier this evening.
   Hero is subordinate to the page-level rollup banner H1 above
   (no duplicate H1 — uses evocative caption text instead).
   Absolute image path so it resolves at any injection depth.

   Phase 4 candidate: pull hero photos from active new-construction
   listings in /images/listings/ for a rotating hero strip — real
   Avalon new builds rather than this one editorial photo. */
.nc-hero {
  position: relative;
  margin: 0 auto 32px;
  padding: 88px 24px;
  max-width: 1240px;
  text-align: center;
  border-radius: 8px;
  overflow: hidden;
  background:
    linear-gradient(135deg, rgba(10, 10, 10, 0.78) 0%, rgba(26, 26, 26, 0.72) 100%),
    url('/images/web/twilight-exterior.webp') center/cover no-repeat;
  border-bottom: 3px solid #EA002A;
}
.nc-hero-inner {
  max-width: 720px;
  margin: 0 auto;
}
.nc-hero-eyebrow {
  font-family: 'Raleway', sans-serif;
  font-weight: 700;
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: #EA002A;
  margin: 0 0 12px;
}
.nc-hero-lede {
  font-family: 'Raleway', sans-serif;
  font-weight: 600;
  font-size: clamp(1.15rem, 2.4vw, 1.55rem);
  line-height: 1.35;
  color: #ffffff;
  margin: 0;
  letter-spacing: -0.01em;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}
@media (max-width: 720px) {
  .nc-hero {
    padding: 56px 20px;
    margin-bottom: 24px;
    border-radius: 6px;
  }
}

.nc-content {
  max-width: 1100px;
  margin: 0 auto;
  font-family: 'Roboto', sans-serif;
  color: #e8e8e8;
  line-height: 1.7;
}

.nc-section {
  margin: 56px 0;
  padding: 0;
}
.nc-section + .nc-section {
  border-top: 1px solid rgba(255, 255, 255, 0.06);
  padding-top: 48px;
}

.nc-section h2 {
  font-family: 'Raleway', sans-serif;
  font-weight: 800;
  font-size: clamp(1.6rem, 3vw, 2.2rem);
  color: #ffffff;
  letter-spacing: -0.02em;
  line-height: 1.2;
  margin: 0 0 24px;
  padding-left: 18px;
  border-left: 4px solid #EA002A;
}

.nc-section h3 {
  font-family: 'Raleway', sans-serif;
  font-weight: 700;
  font-size: 1.2rem;
  color: #ffffff;
  margin: 0 0 12px;
  letter-spacing: -0.01em;
}

.nc-section p {
  font-size: 1rem;
  margin: 0 0 16px;
  color: rgba(255, 255, 255, 0.85);
  max-width: 820px;
}

.nc-section p strong { color: #ffffff; font-weight: 600; }

/* Icon-prefixed bullet list — replaces default <ul> dots with a red
   checkmark glyph in a circular accent. */
.nc-list {
  list-style: none;
  padding: 0;
  margin: 0 0 16px;
  display: grid;
  gap: 12px;
}
.nc-list li {
  position: relative;
  padding: 14px 18px 14px 54px;
  background: #131313;
  border: 1px solid #1f1f1f;
  border-radius: 6px;
  font-size: 0.97rem;
  line-height: 1.55;
  color: rgba(255, 255, 255, 0.82);
  transition: border-color 0.15s ease, background 0.15s ease;
}
.nc-list li:hover {
  border-color: rgba(234, 0, 42, 0.4);
  background: #181818;
}
.nc-list li::before {
  content: '\2713';   /* unicode checkmark */
  position: absolute;
  left: 16px;
  top: 50%;
  transform: translateY(-50%);
  width: 24px;
  height: 24px;
  line-height: 24px;
  text-align: center;
  border-radius: 50%;
  background: #EA002A;
  color: #ffffff;
  font-size: 0.85rem;
  font-weight: 800;
}
.nc-list li strong {
  color: #ffffff;
  font-weight: 700;
  display: block;
  margin-bottom: 4px;
  font-family: 'Raleway', sans-serif;
  letter-spacing: -0.01em;
  font-size: 1rem;
}

/* Developments grid — Mike's existing 6 .nc-card elements get a real
   card treatment with subtle gradient backgrounds + hover lift. */
.nc-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 20px;
  margin-top: 24px;
}
.nc-card {
  background:
    linear-gradient(135deg, #161616 0%, #0e0e0e 100%);
  border: 1px solid #222;
  border-radius: 8px;
  padding: 24px;
  position: relative;
  overflow: hidden;
  transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
}
.nc-card::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 3px;
  background: linear-gradient(90deg, #EA002A 0%, #c8001f 100%);
  opacity: 0.7;
  transition: opacity 0.2s ease;
}
.nc-card:hover {
  transform: translateY(-3px);
  border-color: rgba(234, 0, 42, 0.4);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
}
.nc-card:hover::before { opacity: 1; }
.nc-card h3 {
  font-family: 'Raleway', sans-serif;
  font-weight: 800;
  font-size: 1.3rem;
  color: #ffffff;
  margin: 4px 0 16px;
  letter-spacing: -0.02em;
}
.nc-card p {
  font-size: 0.92rem;
  line-height: 1.65;
  color: rgba(255, 255, 255, 0.78);
  margin: 0;
  max-width: none;
}
.nc-card p strong {
  color: #EA002A;
  font-weight: 600;
  font-family: 'Raleway', sans-serif;
  letter-spacing: 0.02em;
  font-size: 0.78rem;
  text-transform: uppercase;
}

/* Highlight callout — accent-bordered block for "Phase 1/2/3" pattern
   in the Building Process section. */
.nc-highlight {
  background: rgba(234, 0, 42, 0.04);
  border-left: 4px solid #EA002A;
  border-radius: 0 6px 6px 0;
  padding: 22px 26px;
  margin: 20px 0;
}
.nc-highlight h3 {
  color: #ffffff !important;
  margin: 0 0 10px !important;
}
.nc-highlight p {
  margin-bottom: 0;
  color: rgba(255, 255, 255, 0.88);
}

@media (max-width: 720px) {
  .nc-section { margin: 40px 0; }
  .nc-section + .nc-section { padding-top: 32px; }
  .nc-section h2 { padding-left: 14px; border-left-width: 3px; }
  .nc-list li { padding: 12px 14px 12px 48px; }
  .nc-card { padding: 18px; }
  .nc-highlight { padding: 16px 18px; }
}

/* ─── New Construction lifecycle badges (2026-05-24) ───────────────────
   CMHC-aligned per-card status. Renders top-RIGHT of photo box; offset
   from .lst-card-new (top-left) so the two don't collide. Driven by
   build_listing_card() emit of <span class="lst-card-nc lst-card-nc--*">.
   Color coding:
     --tbd       Cool blue   (pre-construction, plans only)
     --building  Amber       (under construction, foundation begun)
     --ready     Royal green (completed, ready to move in)
   See _research/New_Construction_Two_URL_Split_Design_Spec_2026-05-24.md */
.lst-card-nc {
  position: absolute;
  top: 10px;
  right: 10px;
  color: #fff;
  font-family: 'Raleway', sans-serif;
  font-weight: 800;
  font-size: 0.7rem;
  padding: 4px 10px;
  border-radius: 2px;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.18);
  z-index: 2;
}
.lst-card-nc--tbd       { background: #3a6ea5; }   /* Cool blue */
.lst-card-nc--building  { background: #c97a13; }   /* Amber  */
.lst-card-nc--ready     { background: #2a7a4a; }   /* Royal green */

/* ─── Standards Disclosure block (2026-05-24, Q F24 sign-off) ──────────
   Renders below long-form, above FAQ. 4-card grid layout; sits at the
   same max-width as long-form (1100px). Lighter visual weight than the
   long-form .nc-section blocks — this is a credibility/disclosure card
   set, not editorial. */
.lst-standards-block {
  margin: 0 auto;
  padding: 28px 0;
  border-top: 1px solid #2a2a2a;
  border-bottom: 1px solid #2a2a2a;
}
.lst-standards-h2 {
  font-family: 'Raleway', sans-serif;
  font-size: 1.45rem;
  font-weight: 800;
  color: #fff;
  margin: 0 0 12px;
  letter-spacing: -0.01em;
}
.lst-standards-lede {
  font-size: 1.02rem;
  color: #d4d4d4;
  margin: 0 0 24px;
  line-height: 1.55;
}
.lst-standards-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 18px;
  margin-bottom: 20px;
}
.lst-standards-card {
  background: #161616;
  border: 1px solid #2a2a2a;
  border-radius: 6px;
  padding: 20px 22px;
}
.lst-standards-card h3 {
  font-family: 'Raleway', sans-serif;
  font-size: 0.85rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: #EA002A;
  margin: 0 0 10px;
}
.lst-standards-card p {
  font-size: 0.95rem;
  color: #c8c8c8;
  margin: 0;
  line-height: 1.6;
}
.lst-standards-card a {
  color: #ff5c7a;
  text-decoration: underline;
  text-underline-offset: 2px;
}
.lst-standards-card a:hover { color: #ff8094; }
.lst-standards-footnote {
  font-size: 0.88rem;
  color: #9a9a9a;
  margin: 16px 0 0;
  text-align: center;
}
.lst-standards-footnote a {
  color: #d4d4d4;
  text-decoration: underline;
}
@media (max-width: 768px) {
  .lst-standards-grid { grid-template-columns: 1fr; gap: 14px; }
  .lst-standards-card { padding: 16px 18px; }
}
