/* ================================================================
   Long Island Home Search — visual identity
   Palette:  ink navy #0E2A3A · harbor brass #A87B2D · gull #F6F8F9
             card white #FFFFFF · hairline #DFE7EB · slate text #33454F
   !ype:     Fraunces (display / prices) · Public Sans (UI / body)
   ================================================================ */

:root {
  --ink: #0E2A3A;
  --ink-soft: #1B4257;
  --brass: #A87B2D;
  --brass-dark: #8A6320;
  --bg: #F6F8F9;
  --card: #FFFFFF;
  --line: #DFE7EB;
  --text: #33454F;
  --muted: #6B7E88;
  --good: #2E7D5B;
  --radius: 10px;
  --shadow: 0 1px 3px rgba(14, 42, 58, 0.08), 0 8px 24px rgba(14, 42, 58, 0.07);
  --display: "Fraunces", Georgia, serif;
  --body: "Public Sans", system-ui, sans-serif;
  /* Actual measured heights on mobile, set by app.js — the filter bar wraps
     to a different number of rows depending on screen width, so this can't
     be a fixed guess; these fallbacks only apply before JS runs once. */
  --topbar-h: 64px;
  --filters-h: 0px;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
/* Opening the detail overlay sets body overflow to hidden (removing the
   scrollbar), closing it restores it — without this, that toggling shifts
   the page's available width by the scrollbar's size every time, which
   shifts the map's fr-based column along with it and silently repositions
   every marker a few pixels right when someone returns to search, right as
   they're clicking based on where a pin used to be. Reserving the gutter
   permanently means that width never changes, so there's nothing to shift. */
html { scrollbar-gutter: stable; }
body {
  font-family: var(--body);
  color: var(--text);
  background: var(--bg);
  font-size: 15px;
  line-height: 1.5;
}

/* ---------- Header ---------- */
.topbar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 24px;
  background: var(--ink);
  color: #fff;
}
.brand { display: flex; align-items: center; gap: 10px; color: inherit; text-decoration: none; }
.brand:hover .brand-name { color: #D9C089; }
.brand-mark { width: 32px; height: 20px; color: var(--brass); flex: none; }
.brand-name {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.35rem;
  letter-spacing: 0.01em;
  white-space: nowrap;
}
.brand-name em { font-style: italic; color: #D9C089; }
.brand-tag { font-size: 0.78rem; color: #9FB4BF; letter-spacing: 0.04em; }

/* Site nav — this app is served outside WordPress, so these are plain links
   back into it rather than a generated menu. Scrolls sideways on narrow
   screens instead of wrapping and pushing the map down. */
.topnav {
  display: flex; align-items: center; gap: 18px;
  margin-left: auto;
  overflow-x: auto;
  scrollbar-width: none;
}
.topnav::-webkit-scrollbar { display: none; }
.topnav a {
  color: #C7D6DE; text-decoration: none; white-space: nowrap;
  font: 500 0.84rem var(--body);
}
.topnav a:hover { color: #fff; }
/* .saved-open already carries margin-left:auto for the no-nav case; with a
   nav present the nav takes that role and the button just sits after it. */
.topnav ~ .saved-open { margin-left: 0; }
.nav-toggle { display: none; }

/* Typing already searches on its own (debounced), but with no button and no
   Enter handling the box read as broken — people typed, saw nothing to
   click, and assumed it wasn't wired up. */
.search-group { display: flex; align-items: stretch; gap: 0; flex: 1 1 260px; }
.search-group .filter-input {
  flex: 1 1 auto;
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
  border-right: none;
}
.search-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; flex: none;
  background: var(--ink); color: #fff;
  border: 1px solid var(--ink);
  border-radius: 0 8px 8px 0;
  cursor: pointer;
}
.search-btn:hover { background: var(--brass); border-color: var(--brass); }

/* ---------- Filters ---------- */
.filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 12px 24px;
  background: var(--card);
  border-bottom: 1px solid var(--line);
  position: sticky;
  top: 0;
  z-index: 500;
}
.filter-input {
  font: inherit;
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 8px 10px;
  background: #fff;
  min-width: 0;
}
.filter-input:focus-visible { outline: 2px solid var(--brass); outline-offset: 1px; }
#f-q { flex: 1 1 220px; }
.filter-input.compact { padding: 5px 8px; font-size: 0.85rem; }
.btn-ghost {
  font: inherit;
  border: none;
  background: none;
  color: var(--muted);
  cursor: pointer;
  padding: 8px 10px;
  border-radius: 8px;
}
.btn-ghost:hover { color: var(--ink); background: var(--bg); }

.category-toggle { display: flex; border: 1px solid var(--line); border-radius: 8px; overflow: hidden; flex: none; }
.cat-btn { font: 600 0.85rem var(--body); border: none; background: #fff; color: var(--muted); padding: 8px 14px; cursor: pointer; }
.cat-btn.active { background: var(--ink); color: #fff; }
.cat-btn:not(.active):hover { background: var(--bg); color: var(--ink); }

.filter-check { display: flex; align-items: center; gap: 6px; font-size: 0.85rem; color: var(--text); padding: 0 4px; white-space: nowrap; }
/* Invisible full-width flex item — forces everything after it onto a new row
   of the wrapping flex container (regardless of viewport width) without
   itself taking up a visible slot, so the items that follow still sit
   together on that new row instead of each getting pushed to their own line. */
.filter-break { flex-basis: 100%; width: 0; }

.save-search-box {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
  padding: 10px 24px; background: #FBF9F4; border-bottom: 1px solid var(--line);
}
.save-search-box.hidden { display: none; }
.save-search-box #ss-email { flex: 1 1 220px; }
.ss-msg { margin: 0; font-size: 0.85rem; color: var(--good); flex-basis: 100%; }

/* ---------- Highlights (Just Listed / Just Sold) ---------- */
.highlights { padding: 14px 24px 4px; background: var(--card); border-bottom: 1px solid var(--line); }
.highlights.hidden { display: none; }
.highlights-row + .highlights-row { margin-top: 12px; }
.highlights-row h2 { font-family: var(--display); font-size: 0.95rem; font-weight: 600; color: var(--ink); margin: 0 0 8px; }
.highlights-strip { display: flex; gap: 10px; overflow-x: auto; padding-bottom: 6px; }
.highlights-strip:empty::after { content: "Nothing to show yet."; color: var(--muted); font-size: 0.82rem; }
.hi-card {
  flex: none; width: 168px; background: var(--card); border: 1px solid var(--line);
  border-radius: 8px; overflow: hidden; cursor: pointer;
}
.hi-card img { width: 100%; aspect-ratio: 3/2; object-fit: cover; display: block; background: var(--line); }
.hi-card .hi-price { font-family: var(--display); font-weight: 700; font-size: 0.95rem; color: var(--ink); margin: 6px 8px 0; }
.hi-card .hi-addr { font-size: 0.72rem; color: var(--muted); margin: 2px 8px 8px; }
.hi-badge {
  display: inline-block; margin: 6px 0 0 8px; font-size: 0.62rem; letter-spacing: 0.04em;
  text-transform: uppercase; color: #fff; background: var(--brass); border-radius: 4px; padding: 2px 6px;
}

.rentals-intro { background: var(--card); border-bottom: 1px solid var(--line); }
.rentals-intro.hidden { display: none; }
.rentals-intro-inner { max-width: 1080px; margin: 0 auto; padding: 22px 24px 18px; }
.rentals-intro-inner h1 { font-family: var(--display); font-size: 1.5rem; font-weight: 700; color: var(--ink); margin: 0 0 8px; }
.rentals-intro-lede { color: var(--muted); font-size: 0.95rem; line-height: 1.5; margin: 0 0 18px; max-width: 720px; }
.rentals-intro-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; }
.rentals-intro-grid h3 { font-family: var(--display); font-size: 0.95rem; font-weight: 600; color: var(--ink); margin: 0 0 8px; }
.rentals-intro-grid h3 + h3 { margin-top: 16px; }
.rentals-intro-grid p, .rentals-intro-grid li { font-size: 0.86rem; line-height: 1.5; color: var(--text); margin: 0 0 6px; }
.rentals-intro-grid ul { margin: 0; padding-left: 18px; }
.rentals-intro-grid a { color: var(--brass); }
@media (max-width: 700px) {
  .rentals-intro-grid { grid-template-columns: 1fr; gap: 16px; }
}

/* ---------- Layout ---------- */
.layout {
  display: grid;
  grid-template-columns: 1fr minmax(360px, 34%);
  height: calc(100vh - 118px);
}
.results { overflow-y: auto; padding: 16px 20px 32px; }
.results-head {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 12px;
  gap: 12px;
}
.result-count { margin: 0; font-size: 0.9rem; color: var(--muted); }
.result-count strong { color: var(--ink); }
.sort-label { font-size: 0.8rem; color: var(--muted); display: flex; align-items: center; gap: 6px; }

.mapwrap { position: relative; }
#map { position: absolute; inset: 0; }
.map-search-toggle {
  position: absolute;
  top: 10px;
  right: 10px;
  z-index: 800;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 6px 12px;
  font-size: 0.8rem;
  box-shadow: var(--shadow);
  display: flex;
  gap: 6px;
  align-items: center;
  cursor: pointer;
}

/* ---------- Cards ---------- */
.cards {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
.card {
  position: relative;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
.card:hover, .card:focus-visible { transform: translateY(-2px); box-shadow: var(--shadow); }
.card:focus-visible { outline: 2px solid var(--brass); }
.card.highlight { outline: 2px solid var(--brass); box-shadow: var(--shadow); }
.card-photo {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  display: block;
  background: var(--line);
}
.card-body { padding: 8px 10px 10px; }
.card-price {
  font-family: var(--display);
  font-weight: 700;
  font-size: 1.02rem;
  color: var(--ink);
  margin: 0 0 2px;
}
.card-facts { font-size: 0.72rem; color: var(--text); margin: 0 0 2px; }
.card-facts b { font-weight: 600; }
.card-addr { font-size: 0.72rem; color: var(--muted); margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.card-school {
  font-size: 0.68rem; color: var(--brass); font-weight: 600;
  margin: 2px 0 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.status-badge.pending {
  position: absolute;
  top: 10px;
  left: 10px;
  font: 700 0.68rem var(--body);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #fff;
  background: #B3364A;
  border-radius: 5px;
  padding: 3px 8px;
  z-index: 1;
}
.detail-price .status-badge.pending {
  position: static;
  vertical-align: middle;
  margin-left: 8px;
  font-size: 0.6rem;
}
.new-construction-badge {
  position: absolute;
  top: 10px;
  right: 10px;
  font: 700 0.68rem var(--body);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: #fff;
  background: var(--brass);
  border-radius: 5px;
  padding: 3px 8px;
  z-index: 1;
}
.detail-price .new-construction-badge {
  position: static;
  vertical-align: middle;
  margin-left: 8px;
  font-size: 0.6rem;
}
.detail-dom {
  font-size: 0.85rem;
  color: var(--muted);
  margin: 0 0 8px;
}

.share-row {
  display: flex; align-items: center; gap: 10px; margin: 0 0 10px;
  flex-wrap: wrap;
  position: relative; /* anchor for the share menu */
}
.share-menu {
  position: absolute; top: calc(100% + 6px); left: 0; z-index: 50;
  min-width: 168px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(14, 42, 58, 0.18);
  overflow: hidden;
  display: flex; flex-direction: column;
}
.share-menu a, .share-menu button {
  font: 500 0.85rem var(--body);
  color: var(--text); text-align: left; text-decoration: none;
  background: none; border: none; cursor: pointer;
  padding: 10px 14px;
  border-bottom: 1px solid var(--line);
}
.share-menu a:last-child, .share-menu button:last-child { border-bottom: none; }
.share-menu a:hover, .share-menu button:hover { background: var(--bg); color: var(--ink); }

/* Sent from our own server rather than handed to a mail client, so it works
   for people on webmail — which mailto: silently did not. */
.share-email-form { min-width: 280px; padding: 14px; gap: 8px; }
.sef-title { margin: 0 0 2px; font: 600 0.9rem var(--body); color: var(--ink); }
.share-email-form .filter-input { width: 100%; font-size: 0.85rem; }
.share-email-form textarea { resize: vertical; font-family: var(--body); }
.sef-actions { display: flex; gap: 8px; align-items: center; }
.sef-actions .lead-send { padding: 8px 18px; font-size: 0.85rem; }
.sef-msg { margin: 0; font-size: 0.78rem; min-height: 1.1em; color: var(--good, #2E7D5B); }
.sef-msg.error { color: #B3261E; }
.share-btn {
  display: inline-flex; align-items: center; gap: 7px;
  font: 600 0.8rem var(--body); color: var(--ink);
  background: var(--card); border: 1px solid var(--line);
  border-radius: 999px; padding: 7px 15px; cursor: pointer;
}
.share-btn:hover { border-color: var(--brass); color: var(--brass); }
.share-msg { font-size: 0.78rem; color: var(--good, #2E7D5B); font-weight: 600; }
.price-drop-badge {
  display: inline-block; margin: 0 0 12px; font-size: 0.8rem; font-weight: 700;
  color: #fff; background: #2E7D5B; border: 1px solid #2E7D5B;
  border-radius: 999px; padding: 5px 12px;
  box-shadow: 0 2px 8px rgba(46, 125, 91, 0.4);
}
.price-history {
  margin: 0 0 8px; font-size: 0.85rem; font-weight: 600; color: #2E7D5B;
}

/* ---- Saved homes ---- */
.saved-open {
  margin-left: auto; display: flex; align-items: center; gap: 6px;
  font: 600 0.82rem var(--body); color: inherit;
  background: rgba(255,255,255,0.12); border: 1px solid rgba(255,255,255,0.28);
  border-radius: 999px; padding: 6px 14px; cursor: pointer;
}
.saved-open:hover { background: rgba(255,255,255,0.2); }
.saved-count {
  background: var(--brass); color: #21170A; border-radius: 999px;
  font-size: 0.7rem; font-weight: 700; padding: 1px 7px;
}
.saved-count.hidden { display: none; }

.saved-panel {
  position: fixed; inset: 0; z-index: 1200;
  background: rgba(14, 42, 58, 0.55); overflow-y: auto;
  padding: 40px 16px;
}
.saved-panel.hidden { display: none; }
.saved-inner {
  max-width: 900px; margin: 0 auto; background: var(--bg);
  border-radius: var(--radius); overflow: hidden;
}
.saved-head {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 22px; background: var(--card); border-bottom: 1px solid var(--line);
  position: sticky; top: 0; z-index: 1;
}
.saved-head h2 { margin: 0; font-size: 1.1rem; color: var(--ink); }
.saved-close {
  background: none; border: none; font-size: 1.6rem; line-height: 1;
  color: var(--muted); cursor: pointer; padding: 0 4px;
}
.saved-body { padding: 20px 22px 28px; }
.saved-who { font-size: 0.82rem; color: var(--muted); margin: 0 0 16px; }
.saved-empty { color: var(--muted); font-size: 0.9rem; margin: 8px 0; }
.saved-empty-sub { color: var(--muted); font-size: 0.82rem; margin: 0 0 16px; max-width: 46ch; }
.saved-cards { margin-bottom: 8px; }
.saved-searches-title { margin-top: 26px; }
.saved-searches { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.saved-searches li {
  display: flex; justify-content: space-between; gap: 12px; flex-wrap: wrap;
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 10px 14px; font-size: 0.85rem;
}
.ss-label { font-weight: 600; color: var(--ink); }
.ss-state { color: var(--muted); font-size: 0.78rem; }
.saved-linkform { display: flex; gap: 8px; flex-wrap: wrap; max-width: 460px; }
.saved-linkform .filter-input { flex: 1 1 220px; }
.saved-msg { font-size: 0.85rem; color: var(--good, #2E7D5B); margin: 10px 0 0; min-height: 1.2em; }

@media (max-width: 560px) {
  .saved-panel { padding: 0; }
  .saved-inner { border-radius: 0; min-height: 100vh; }
  .saved-open span:not(.saved-count) { display: none; }
}

/* ---- Detail page sections (schools, street view, similar homes) ---- */
.detail-section { margin: 24px 0 0; }
.detail-section-title {
  font: 600 1rem var(--display, inherit);
  color: var(--ink); margin: 0 0 10px;
  padding-bottom: 6px; border-bottom: 1px solid var(--line);
}
.school-list { margin: 0; display: grid; gap: 6px; }
.school-list > div { display: flex; gap: 10px; font-size: 0.85rem; }
.school-list dt { flex: 0 0 84px; color: var(--muted); margin: 0; }
.school-list dd { margin: 0; color: var(--text); font-weight: 500; }

/* Location panel: Map / Satellite / Street View */
.loc-tabs { display: flex; gap: 6px; margin-bottom: 10px; flex-wrap: wrap; }
.loc-tab {
  font: 600 0.78rem var(--body); color: var(--text);
  background: var(--card); border: 1px solid var(--line);
  border-radius: 999px; padding: 6px 14px; cursor: pointer;
}
.loc-tab:hover { border-color: var(--brass); }
.loc-tab.on { background: var(--ink); color: #fff; border-color: var(--ink); }
.loc-stage {
  border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden;
}
.loc-map, .loc-street { width: 100%; height: 320px; }
.loc-map.hidden, .loc-street.hidden { display: none; }
.streetview { width: 100%; height: 100%; border: 0; display: block; }
.loc-note {
  margin: 8px 0 0; font-size: 0.76rem; color: var(--muted); line-height: 1.45;
}
@media (max-width: 560px) {
  .loc-map, .loc-street { height: 240px; }
}

.similar-grid {
  display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
}
.similar-card {
  background: var(--card); border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden; cursor: pointer;
}
.similar-card:hover, .similar-card:focus-visible { border-color: var(--brass); outline: none; }
.similar-card img {
  width: 100%; aspect-ratio: 3 / 2; object-fit: cover;
  display: block; background: var(--line);
}
.similar-body { padding: 8px 10px 10px; }
.similar-price { font-weight: 700; font-size: 0.92rem; color: var(--ink); margin: 0 0 2px; }
.similar-facts { font-size: 0.72rem; color: var(--text); margin: 0 0 2px; }
.similar-addr {
  font-size: 0.72rem; color: var(--muted); margin: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

.card-type {
  display: inline-block;
  margin-top: 5px;
  font-size: 0.6rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--brass-dark);
  border: 1px solid #E4D5B3;
  background: #FBF6EA;
  border-radius: 999px;
  padding: 2px 7px;
}

/* ---------- Map price pills (signature element) ---------- */
/* Lighter than it used to be: white ground with dark text instead of a solid
   navy slab, a hairline border, and a soft shadow. A few hundred of these
   sit on screen at once, so the goal is legible-but-quiet rather than each
   one competing for attention. */
.price-pill {
  background: #fff;
  color: var(--ink);
  font-family: var(--body);
  font-weight: 600;
  font-size: 0.68rem;
  padding: 2px 7px;
  border-radius: 999px;
  border: 1px solid rgba(14, 42, 58, 0.18);
  box-shadow: 0 1px 3px rgba(14, 42, 58, 0.18);
  white-space: nowrap;
  transition: transform 0.1s ease, background 0.1s ease;
}
.price-pill:hover, .price-pill.active {
  background: var(--brass);
  color: #fff;
  border-color: var(--brass);
  transform: scale(1.14);
  z-index: 1000;
}
/* Pending reads as a tint rather than a full colour swap, so it registers
   without shouting louder than the price itself. */
.price-pill.pending { background: #FBEDF0; border-color: rgba(179, 54, 74, 0.45); color: #8E2437; }
.price-pill.pending:hover, .price-pill.pending.active { background: #B3364A; color: #fff; border-color: #B3364A; }

/* (The old zoomed-out "collapse to dots" mode was removed — town pins cover
   the wide view now, so individual listings only ever draw as full price
   pills. The dots were the stray black/red specks appearing on filtered
   searches.) */
/* Per-town rollup shown at wide zoom. Each carries its own town name, so
   towns stay identifiable even where the basemap drops labels for smaller
   hamlets at that zoom level. */
/* Classic teardrop map pin. Blue reads as navigational and stays clear of
   the reds already carrying meaning elsewhere (Pending, price changes). The
   count sits in a white disc inside the head so it stays legible at these
   sizes without needing a heavy text shadow. */
.town-marker {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  /* The icon box is far wider than the pin so long names have room; the
     empty sides must not swallow clicks meant for the map underneath. */
  pointer-events: none;
}
.town-marker > * { pointer-events: auto; }
/* Printed rather than hover-only: there is no hover on a touchscreen, and a
   tap there is already the zoom gesture. The halo keeps names readable
   where they cross pins or coastline. */
.tm-name {
  margin-top: 1px;
  font: 600 0.64rem var(--body);
  color: var(--ink);
  white-space: nowrap;
  cursor: pointer;
  text-shadow: 0 0 3px #fff, 0 0 3px #fff, 0 0 3px #fff, 0 0 2px #fff;
}
.town-pin {
  display: block;
  overflow: visible;
  cursor: pointer;
  filter: drop-shadow(0 1px 2px rgba(14, 42, 58, 0.3));
  transition: transform 0.12s ease;
  transform-origin: 50% 100%; /* grow from the point, which is the location */
}
.town-pin path { fill: #1F63C4; stroke: #fff; stroke-width: 1.4; }
.town-pin .tp-hole { fill: #fff; }
.town-pin text { fill: #14498F; font-family: var(--body); }
.leaflet-marker-icon:hover .town-pin {
  transform: scale(1.22);
  filter: drop-shadow(0 3px 6px rgba(31, 99, 196, 0.55));
}
.leaflet-marker-icon:hover .town-pin path { fill: #14498F; }
/* Town name on hover instead of printed permanently under the bubble — the
   basemap already labels towns, including ones with no listings. */
.leaflet-tooltip.town-tip {
  background: var(--ink);
  color: #fff;
  border: none;
  border-radius: 6px;
  padding: 4px 9px;
  font: 600 0.72rem var(--body);
  box-shadow: 0 2px 8px rgba(14, 42, 58, 0.35);
}
.leaflet-tooltip.town-tip::before { border-top-color: var(--ink); }

.leaflet-div-icon { background: none; border: none; }
.map-pop { width: 190px; font-family: var(--body); cursor: pointer; }
.map-pop img { width: 100%; border-radius: 6px; aspect-ratio: 3/2; object-fit: cover; }
.map-pop .p { font-family: var(--display); font-weight: 700; color: var(--ink); margin: 6px 0 0; }
.map-pop .a { font-size: 0.75rem; color: var(--muted); margin: 0; }

/* ---------- Pager ---------- */
.pager { display: flex; gap: 6px; justify-content: center; margin-top: 20px; flex-wrap: wrap; }
.pager button {
  font: inherit;
  border: 1px solid var(--line);
  background: var(--card);
  border-radius: 8px;
  padding: 6px 12px;
  cursor: pointer;
  color: var(--text);
}
.pager button.current { background: var(--ink); color: #fff; border-color: var(--ink); }
.pager button:hover:not(.current) { border-color: var(--ink-soft); }

/* ---------- Detail overlay ---------- */
.detail {
  position: fixed;
  inset: 0;
  background: rgba(14, 42, 58, 0.55);
  z-index: 2000;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}
.detail.hidden { display: none; }
.detail-panel {
  background: var(--card);
  border-radius: 14px;
  max-width: 860px;
  width: 100%;
  max-height: 90vh;
  overflow-y: auto;
  position: relative;
  box-shadow: 0 24px 64px rgba(0,0,0,0.35);
}
.detail-close {
  position: absolute;
  top: 14px;
  left: 14px;
  z-index: 10;
  border: none;
  background: rgba(255,255,255,0.94);
  border-radius: 999px;
  padding: 9px 16px 9px 13px;
  font: 600 0.85rem var(--body);
  cursor: pointer;
  color: var(--ink);
  line-height: 1;
  display: flex;
  align-items: center;
  gap: 6px;
  box-shadow: var(--shadow);
}
.detail-close-arrow { font-size: 1rem; }
.detail-close:hover { background: #fff; }
.gallery { position: relative; background: var(--ink); }
.gallery-main { width: 100%; aspect-ratio: 16/9; object-fit: cover; display: block; }
.gallery-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  border: none;
  background: rgba(255,255,255,0.85);
  border-radius: 999px;
  width: 38px;
  height: 38px;
  font-size: 1.1rem;
  cursor: pointer;
  color: var(--ink);
}
.gallery-nav.prev { left: 12px; }
.gallery-nav.next { right: 12px; }
.gallery-count {
  position: absolute;
  bottom: 10px;
  left: 12px;
  background: rgba(14,42,58,0.75);
  color: #fff;
  font-size: 0.75rem;
  padding: 3px 10px;
  border-radius: 999px;
}
.thumbs { display: flex; gap: 6px; padding: 10px 14px 0; overflow-x: auto; }
.thumbs img {
  width: 84px;
  aspect-ratio: 3/2;
  object-fit: cover;
  border-radius: 6px;
  cursor: pointer;
  opacity: 0.65;
  flex: none;
}
.thumbs img.on { opacity: 1; outline: 2px solid var(--brass); }
.detail-info { padding: 16px 22px 26px; }
.detail-price { font-family: var(--display); font-weight: 700; font-size: 1.9rem; color: var(--ink); margin: 0; }
.detail-addr { margin: 2px 0 12px; color: var(--muted); }
.oh-badge {
  display: inline-block; margin: 0 0 12px; font-size: 0.8rem; font-weight: 700;
  color: #fff; background: #0066FF; border: 1px solid #0066FF;
  border-radius: 999px; padding: 5px 12px;
  box-shadow: 0 2px 8px rgba(0, 102, 255, 0.4);
}
.factbar {
  display: flex;
  flex-wrap: wrap;
  gap: 0 26px;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  padding: 10px 0;
  margin-bottom: 14px;
}
.factbar div { font-size: 0.85rem; color: var(--muted); }
.factbar b { display: block; font-size: 1.05rem; color: var(--ink); font-weight: 600; }
.detail-desc { line-height: 1.65; }
.detail-attrib { font-size: 0.68rem; color: #AEB9BF; margin-top: 16px; border-top: 1px solid var(--line); padding-top: 10px; }

/* ---------- Lead capture ---------- */
.lead-box {
  margin-top: 18px;
  border: 1px solid #E4D5B0;
  border-radius: var(--radius);
  background: #F1E7D2;
  padding: 16px 18px;
}
.lead-title { font-family: var(--display); color: var(--ink); font-size: 1.15rem; margin: 0 0 2px; }
.lead-sub { margin: 0 0 12px; font-size: 0.85rem; color: var(--muted); }
.lead-grid { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; margin-bottom: 8px; }
.lead-msg { width: 100%; resize: vertical; font-family: var(--body); }
.lead-hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.lead-error { color: #B3261E; font-size: 0.82rem; min-height: 1em; margin: 6px 0; }
.lead-send {
  font: 600 0.95rem var(--body);
  background: var(--ink);
  color: #fff;
  border: none;
  border-radius: 8px;
  padding: 11px 22px;
  cursor: pointer;
}
.lead-send:hover { background: var(--ink-soft); }
.lead-send:disabled { opacity: 0.6; cursor: default; }
@media (max-width: 640px) { .lead-grid { grid-template-columns: 1fr; } }

/* ---------- Favorites (heart a listing) ---------- */
.fav-heart {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 40px;
  height: 40px;
  border: none;
  border-radius: 50%;
  background: rgba(14, 42, 58, 0.35);
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform 0.12s ease, background 0.15s ease;
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.4));
}
.fav-heart svg { width: 24px; height: 24px; display: block; }
.fav-heart svg path {
  fill: rgba(255, 255, 255, 0.25);
  stroke: #fff;
  stroke-width: 1.6px;
  transition: fill 0.15s ease;
}
.fav-heart:hover { transform: scale(1.1); background: rgba(14, 42, 58, 0.55); }
.fav-heart.on svg path { fill: #E0304A; stroke: #fff; }

/* Same treatment, bigger, sitting on the gallery's main photo. */
.detail-heart { top: auto; bottom: 14px; right: 14px; width: 48px; height: 48px; }
.detail-heart svg { width: 28px; height: 28px; }

.fav-email-box.hidden { display: none; }
.fav-email-box {
  position: absolute;
  z-index: 2100;
  width: 260px;
  background: var(--card);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 14px 16px;
}
.fav-email-copy { margin: 0 0 10px; font-size: 0.85rem; color: var(--text); line-height: 1.4; }
.fav-email-box .filter-input { width: 100%; margin-bottom: 10px; }
.fav-email-actions { display: flex; gap: 8px; align-items: center; }
.fav-email-box .lead-error { margin: 8px 0 0; }

/* ---------- Contact buttons (click-to-call / click-to-email) ---------- */
.detail-contact { display: flex; gap: 8px; margin-top: 12px; flex-wrap: wrap; }
.contact-btn {
  flex: 1 1 160px; text-align: center; font: 600 0.88rem var(--body); text-decoration: none;
  border: 1px solid var(--line); border-radius: 8px; padding: 10px 14px; color: var(--ink);
}
.contact-btn:hover { background: var(--bg); }
.contact-btn.call { background: var(--ink); color: #fff; border-color: var(--ink); }
.contact-btn.call:hover { background: var(--ink-soft); }

/* ---------- Mortgage calculator ---------- */
.mortgage-calc { margin-top: 18px; border: 1px solid var(--line); border-radius: var(--radius); padding: 16px 18px; }
.mortgage-calc summary { font-family: var(--display); color: var(--ink); font-size: 1.05rem; cursor: pointer; }
.mc-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 12px 0 10px; }
.mc-grid label { display: block; font-size: 0.72rem; color: var(--muted); margin-bottom: 3px; }
.mc-result { display: flex; align-items: baseline; gap: 8px; padding-top: 10px; border-top: 1px solid var(--line); }
.mc-result .mc-amount { font-family: var(--display); font-weight: 700; font-size: 1.4rem; color: var(--ink); }
.mc-result .mc-label { font-size: 0.8rem; color: var(--muted); }
.mc-note { font-size: 0.72rem; color: var(--muted); margin: 8px 0 0; }
@media (max-width: 640px) { .mc-grid { grid-template-columns: 1fr; } }

/* ---------- Footer ---------- */
.disclaimer {
  padding: 18px 24px 26px;
  background: var(--bg);
  color: #AEB9BF;
  font-size: 0.68rem;
  line-height: 1.6;
}
.disclaimer p { max-width: 900px; margin: 0 0 6px; }
.disclaimer-note { color: #D9C089; }

/* ---------- Mobile ---------- */
/* Desktop keeps every filter on screen and puts the map beside the results.
   Phones get a different shape entirely: a compact sticky bar, a large map,
   then the listings underneath it in a two-up grid — one continuous scroll
   rather than a map/list toggle. The old fullscreen-map mode and its
   floating toggle button are gone; both surfaces are visible at once now. */
.filter-bar,
.filters-sheet-head,
.filters-apply,
.filters-scrim { display: none; }

@media (max-width: 900px) {
  .brand-tag { display: none; }

  /* Six inline links won't fit beside the brand and Saved button — at this
     width the nav was being crushed to a ~27px sliver. Collapse it behind a
     hamburger that drops the links down as a panel instead. */
  .topbar { position: relative; }
  .nav-toggle {
    display: inline-flex; align-items: center; justify-content: center;
    margin-left: auto;
    background: rgba(255,255,255,0.12);
    border: 1px solid rgba(255,255,255,0.28);
    color: inherit; border-radius: 10px;
    width: 38px; height: 34px; cursor: pointer;
  }
  .nav-toggle:hover { background: rgba(255,255,255,0.2); }
  .topnav {
    display: none;
    position: absolute;
    top: 100%; left: 0; right: 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    margin: 0;
    overflow: visible;
    background: var(--ink);
    border-top: 1px solid rgba(255,255,255,0.14);
    box-shadow: 0 10px 24px rgba(14, 42, 58, 0.35);
    z-index: 1200;
  }
  body.nav-open .topnav { display: flex; }
  .topnav a {
    padding: 13px 20px;
    font-size: 0.92rem;
    border-bottom: 1px solid rgba(255,255,255,0.08);
  }
  .topnav a:last-child { border-bottom: none; }
  /* Saved sits before the hamburger on mobile, so it must not also claim
     the auto margin. */
  .topnav ~ .saved-open { margin-left: 0; }

  /* --- Compact sticky bar: Buy/Rent + a Filters button --- */
  .filter-bar {
    display: flex;
    align-items: center;
    gap: 7px;
    position: sticky;
    top: 0;
    z-index: 950;
    padding: 9px 12px;
    background: var(--card);
    border-bottom: 1px solid var(--line);
    /* Everything stays on one row; it slides sideways when the chips don't
       fit rather than wrapping and eating another 40px of map. */
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .filter-bar::-webkit-scrollbar { display: none; }
  .filter-bar > * { flex: 0 0 auto; }
  /* Quick toggles for the three most-used filters, mirroring the checkboxes
     inside the sheet. */
  .fb-chip {
    font: 600 0.78rem var(--body);
    color: var(--text); background: var(--bg);
    border: 1px solid var(--line); border-radius: 999px;
    padding: 7px 13px; cursor: pointer; white-space: nowrap;
  }
  .fb-chip[aria-pressed="true"] {
    background: var(--ink); color: #fff; border-color: var(--ink);
  }
  .filters-open-btn {
    display: inline-flex; align-items: center; gap: 7px;
    font: 600 0.85rem var(--body);
    color: var(--ink); background: var(--bg);
    border: 1px solid var(--line); border-radius: 999px;
    padding: 8px 15px; cursor: pointer;
  }
  .filters-count {
    background: var(--brass); color: #21170A;
    border-radius: 999px; font-size: 0.68rem; font-weight: 700;
    padding: 1px 6px;
  }
  .filters-count.hidden { display: none; }
  .filter-bar-cats { display: flex; gap: 4px; }
  .filter-bar-cats .cat-btn { padding: 7px 14px; font-size: 0.82rem; }

  /* --- Full filter set becomes an opt-in sheet --- */
  .filters {
    display: none;
    position: fixed;
    inset: auto 0 0 0;
    max-height: 82vh;
    overflow-y: auto;
    z-index: 1400;
    border-radius: 16px 16px 0 0;
    box-shadow: 0 -8px 30px rgba(14, 42, 58, 0.28);
    padding: 0 16px 16px;
  }
  body.filters-open .filters { display: flex; }
  body.filters-open .filters-scrim {
    display: block; position: fixed; inset: 0;
    background: rgba(14, 42, 58, 0.45); z-index: 1300;
  }
  .filters-sheet-head {
    display: flex; align-items: center; justify-content: space-between;
    position: sticky; top: 0; z-index: 1;
    flex-basis: 100%; margin: 0 -16px 4px; padding: 14px 16px 10px;
    background: var(--card); border-bottom: 1px solid var(--line);
  }
  .filters-sheet-head h2 { margin: 0; font-size: 1rem; color: var(--ink); }
  .filters-close {
    background: none; border: none; font-size: 1.7rem; line-height: 1;
    color: var(--muted); cursor: pointer; padding: 0 4px;
  }
  .filters .filter-input, .filters .filter-check { flex: 1 1 46%; }
  .filters-apply {
    display: block; flex-basis: 100%;
    font: 600 0.95rem var(--body);
    background: var(--ink); color: #fff;
    border: none; border-radius: 10px; padding: 13px; cursor: pointer;
    margin-top: 4px;
  }

  /* --- Map sits inline and large, listings continue underneath --- */
  .layout { grid-template-columns: 1fr; height: auto; }
  .mapwrap {
    display: block;
    position: relative;
    /* Roughly half again as tall as it was (58vh) — zooming into a town
       needs the vertical room. Deliberately short of the full viewport so a
       sliver of the listings below stays visible, which is what signals
       there's more to scroll to. */
    height: 84vh;
    /* Full-bleed regardless of whatever horizontal padding the ancestors
       happen to have — measuring against a guessed padding value left the
       map 16px off centre and hanging past the left edge. */
    width: 100vw;
    margin-left: 50%;
    transform: translateX(-50%);
    z-index: 1;
  }
  .results { display: block; }

  /* Embedded on the WordPress homepage the app lives in a fixed-height
     iframe, so 84vh here means 84% of the IFRAME — the map swallowed the
     frame and pushed the listings out of sight entirely. Inside an embed the
     map takes a fixed slice instead, leaving room for the three rows of
     listings the standalone page shows. */
  body.embed .layout { height: auto; }
  body.embed .mapwrap { height: 420px; }

  /* --- Two cards per row, as on the desktop grid --- */
  .cards { grid-template-columns: repeat(2, 1fr); gap: 10px; }
  .card-price { font-size: 0.9rem; }
  .card-facts, .card-addr { font-size: 0.68rem; }
  .card-type { font-size: 0.62rem; }
}

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

/* ---------- Embed mode (?embed=1, used on the WordPress homepage) ---------- */
body.embed .topbar,
body.embed .disclaimer,
body.embed .highlights {
  display: none;
}
/* .filters stays visible in embed mode (unlike the standalone page's mobile
   view) — subtract its real height so .layout doesn't overflow the iframe
   and force the whole embed to scroll. --filters-h is measured by
   updateFixedHeights() in app.js, same mechanism as the mobile fix above. */
/* Desktop-width embeds only. On a narrow embed the app switches to the phone
   layout, which scrolls naturally — pinning .layout to the iframe's height
   there clipped the listings off below the map. Scoped rather than left
   global because this block sits after the mobile rules in the file and was
   silently overriding them at equal specificity. */
@media (min-width: 901px) {
  body.embed .layout { height: calc(100vh - var(--filters-h)); }
}
body.embed .filters { top: 0; }
