body {
  font-family: 'Inter', ui-sans-serif, system-ui, sans-serif;
}

.bed-filter-btn {
  color: #4b5563;
  background: white;
  transition: all 0.15s ease;
}

.bed-filter-btn.active-filter {
  background-color: #d43245;
  border-color: #d43245;
  color: white;
}

.line-clamp-1 {
  display: -webkit-box;
  -webkit-line-clamp: 1;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.line-clamp-2 {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.line-clamp-3 {
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* Smooth scrolling for anchor links like /how-it-works#lead-form */
html {
  scroll-behavior: smooth;
}

/* ---------- Multi-step Lead Form ---------- */
.lead-form-widget {
  max-width: 28rem;
  margin: 0 auto;
}

.lf-label {
  display: block;
  font-size: 11px;
  font-weight: 700;
  color: #0f172a;
  margin-bottom: 3px;
}

.lf-input {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid #cbd5e1;
  border-radius: 8px;
  font-size: 16px;
  outline: none;
  background: #fff;
  box-sizing: border-box;
  transition: border-color 0.15s ease;
}

.lf-input:focus {
  border-color: #d43245;
}

.lf-input[aria-invalid='true'] {
  border-color: #f87171;
}

.lf-conditional {
  padding-left: 10px;
  border-left: 2px solid rgba(212, 50, 69, 0.3);
  margin-bottom: 2px;
}

.lf-btn-primary {
  width: 100%;
  padding: 14px;
  background: #d43245;
  color: #fff;
  border: none;
  border-radius: 8px;
  font-weight: 700;
  font-size: 14px;
  cursor: pointer;
  transition: background 0.15s ease;
}

.lf-btn-primary:hover {
  background: #c02637;
}

.lf-btn-primary:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.lf-btn-back {
  padding: 14px 16px;
  border: 1px solid #cbd5e1;
  border-radius: 8px;
  font-size: 12px;
  color: #94a3b8;
  background: #fff;
  cursor: pointer;
}

.lf-btn-back:hover {
  border-color: #94a3b8;
}

/* ---------- Lead form modal ---------- */
#lead-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(15, 23, 42, 0.6);
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  overflow-y: auto;
}

#lead-modal-panel {
  background: #fff;
  border-radius: 1rem;
  padding: 1.5rem;
  max-width: 30rem;
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;
  position: relative;
}

/* ---------- Map Search: price-tag markers ---------- */
.price-pin-wrapper {
  background: transparent;
  border: none;
}

/* Marketplace marker pattern (design pass 2026-08-22): WHITE pills with
   dark text, the way Airbnb and Zillow paint hundreds of prices without
   the map screaming — brand color is reserved for the ACTIVE pin and the
   CTAs. Smaller type, hairline border, soft shadow. */
.price-pin {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  background: #fff;
  color: #0f172a;
  font-weight: 700;
  font-size: 11px;
  padding: 0 7px;
  border-radius: 999px;
  white-space: nowrap;
  box-shadow: 0 1px 4px rgba(15, 23, 42, 0.22);
  border: 1px solid rgba(15, 23, 42, 0.14);
  cursor: pointer;
  transition: transform 0.12s ease, background 0.12s ease, color 0.12s ease;
}

.price-pin:hover {
  transform: scale(1.08);
}

.price-pin.active {
  background: #0f172a;
  color: #fff;
  border-color: #0f172a;
  transform: scale(1.12);
  z-index: 1000 !important;
}

/* Communities with no displayed price: a quiet dot, not a shouting pill —
   they reveal themselves on tap. */
.price-dot {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: #fff;
  border: 2px solid #94a3b8;
  box-shadow: 0 1px 3px rgba(15, 23, 42, 0.25);
  cursor: pointer;
}

.price-dot.active {
  border-color: #0f172a;
  background: #0f172a;
}

.cluster-pin-wrapper {
  background: transparent;
  border: none;
}

.cluster-pin {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: #fff;
  color: #0f172a;
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 800;
  font-size: 12px;
  border: 1px solid rgba(15, 23, 42, 0.14);
  box-shadow: 0 1px 5px rgba(15, 23, 42, 0.25);
}

/* ---------- Map Search: mobile List/Map toggle ---------- */
@media (max-width: 1023px) {
  #map-search-layout.mobile-view-list #map-panel {
    display: none;
  }
  #map-search-layout.mobile-view-map #map-list-panel {
    display: none;
  }
  /* The list panel must SCROLL inside the fixed-height layout, never grow
     to its content. In the mobile column layout it had no height bound, so
     it overflowed thousands of pixels past the section and under the
     footer, whose white link text then painted over the cards (the "ghost
     area names" bug, operator report 2026-08-22). flex:1 + min-height:0
     gives overflow-y:auto a real boundary; overflow:hidden is the backstop
     so nothing can bleed into the footer again. */
  #map-search-layout {
    overflow: hidden;
  }
  #map-search-layout #map-list-panel {
    flex: 1 1 0%;
    min-height: 0;
  }
  /* Room for the floating List/Map pill over the last card. */
  #map-list-results {
    padding-bottom: 88px;
  }
}

/* Chip rows scroll without a visible scrollbar (phones). */
.scrollbar-none {
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.scrollbar-none::-webkit-scrollbar {
  display: none;
}

/* Map Search layout height. dvh tracks the REAL visible viewport on mobile
   Safari/Chrome (100vh includes the collapsed URL bar, which used to hide
   the bottom of the list and map behind browser chrome). vh line is the
   fallback for older browsers. */
#map-search-layout {
  height: calc(100vh - 180px);
  height: calc(100dvh - 180px);
  min-height: 520px;
}
/* Phone chrome is slimmer after the 2026-08-22 design pass (56px header +
   one control row + chip row = ~149px). MUST come after the base rule
   above — same specificity, so source order decides. */
@media (max-width: 1023px) {
  #map-search-layout {
    height: calc(100vh - 149px);
    height: calc(100dvh - 149px);
  }
}

/* ── Accessibility hardening (audit 2026-08-20) — sitewide ──────────── */
a:focus-visible,
button:focus-visible,
summary:focus-visible,
select:focus-visible,
input:focus-visible,
textarea:focus-visible,
[tabindex]:focus-visible {
  outline: 2px solid #0369a1;
  outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ── Modal motion (2026-08-20): fade the backdrop, rise the panel.
   display:none -> flex retriggers the animation on every open. ── */
@keyframes modal-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes modal-rise { from { opacity: 0; transform: translateY(14px) scale(0.98); } to { opacity: 1; transform: none; } }
#lead-modal-backdrop { animation: modal-fade 180ms ease-out both; }
#lead-modal-panel { animation: modal-rise 240ms cubic-bezier(0.22, 0.61, 0.21, 1) both; }

/* ── /map price range slider (two stacked native ranges) ──────────────
   The track/fill are plain divs; the two <input type=range> elements sit
   on top with transparent tracks and only their THUMBS interactive, which
   is the standard two-handle pattern that keeps native drag, keyboard and
   screen-reader behavior. */
#price-slider-track {
  position: absolute;
  top: 50%;
  left: 0;
  right: 0;
  height: 4px;
  margin-top: -2px;
  border-radius: 9999px;
  background: #e5e7eb;
}
#price-slider-fill {
  position: absolute;
  top: 50%;
  height: 4px;
  margin-top: -2px;
  border-radius: 9999px;
  background: #d43245;
}
#price-slider input[type='range'] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  -webkit-appearance: none;
  appearance: none;
  background: transparent;
  pointer-events: none;
}
#price-slider input[type='range']:focus {
  outline: none;
}
#price-slider input[type='range']::-webkit-slider-runnable-track {
  background: transparent;
}
#price-slider input[type='range']::-moz-range-track {
  background: transparent;
}
#price-slider input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none;
  pointer-events: auto;
  width: 26px;
  height: 26px;
  border-radius: 9999px;
  background: #fff;
  border: 2px solid #d43245;
  box-shadow: 0 2px 6px rgba(15, 23, 42, 0.25);
  cursor: pointer;
}
#price-slider input[type='range']::-moz-range-thumb {
  pointer-events: auto;
  width: 22px;
  height: 22px;
  border-radius: 9999px;
  background: #fff;
  border: 2px solid #d43245;
  box-shadow: 0 2px 6px rgba(15, 23, 42, 0.25);
  cursor: pointer;
}
#price-slider input[type='range']:focus-visible::-webkit-slider-thumb {
  outline: 3px solid #009ab9;
  outline-offset: 1px;
}
#price-histogram span {
  flex: 1 1 0%;
  min-height: 2px;
  background: #e5e7eb;
  border-radius: 2px 2px 0 0;
}
#price-histogram span.in-range {
  background: #d43245;
  opacity: 0.55;
}

/* An open popup CARD owns the screen (operator report 2026-08-22).
   Raising the popup pane's z-index is NOT enough: Leaflet's map pane
   carries a transform, which creates a stacking context that traps the
   popup BELOW the zoom control and our overlay buttons regardless of
   z-index. So while a popup is open (#map-panel gets .popup-open from
   map.js), the chrome yields — the same behavior Google Maps uses when a
   place card opens on a phone. */
#apartments-map .leaflet-pane.leaflet-popup-pane {
  z-index: 1200;
}
/* CONTAIN Leaflet's z-indexes (operator report 2026-08-22: map tiles
   painted OVER the sticky header when the desktop page scrolled).
   Leaflet's panes carry z-index 200-1200; without a stacking context on
   the map panel those values compete with the whole page and beat the
   header's z-50. isolation:isolate makes every Leaflet z-index local to
   the panel, so the header/toolbar always paint above the map. */
#map-panel {
  isolation: isolate;
}
#map-panel .leaflet-control-zoom,
#map-panel #map-tools,
#map-panel #search-this-area-btn {
  transition: opacity 0.15s ease;
}
#map-panel.popup-open .leaflet-control-zoom,
#map-panel.popup-open #map-tools,
#map-panel.popup-open #search-this-area-btn {
  opacity: 0;
  pointer-events: none;
}

/* Grocery store pins on /map (operator ask 2026-08-23): branded round
   badges (H, CM, WF, TJ, S) so the store a community is "0.4 mi" from is
   visible on the map itself when the grocery filter is on. */
.grocery-pin-wrapper {
  background: transparent;
  border: none;
}
.grocery-pin {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  color: #fff;
  font-weight: 800;
  font-size: 10px;
  letter-spacing: -0.02em;
  border-radius: 999px;
  border: 2px solid #fff;
  box-shadow: 0 1px 4px rgba(15, 23, 42, 0.35);
}
