/*
 * Map Search.
 * Extends the existing --lux-* design tokens from homepage.css (primary/
 * secondary/gold/bg/border/radius/shadow/fonts) rather than inventing a
 * parallel palette. Only genuinely new tokens (map-specific sizing) are
 * declared here.
 *
 * Redesigned from a split map/list shell (map on one side, an
 * independently-scrolling card column on the other, each with its own
 * scrollbar) into a single normal page scroll: filters, then a full-width
 * map at a fixed height, then a plain property grid with classic
 * pagination underneath — reusing /properties/search's filter component
 * (public/properties/_search_fields.php) and card (public/properties/
 * _card_premium.php) rather than this page's old bespoke ones. The map
 * itself (markers, clustering, zoom, layer switcher, Search-as-I-move,
 * Draw Search Area, Nearby Places, marker-click popups with their own
 * Quick View/Compare/View Details actions, and the floating Compare bar)
 * is untouched; only the layout around it changed. Dropped along with the
 * old shell: just the sticky topbar's Share/Save Search/Saved Searches
 * actions — those were tied to the split-panel layout itself, not the map.
 */

:root {
    --ms-header-h: 6.5rem;
    --ms-gap: 1.25rem;
    --ms-map-h: 600px;
}

/* This page has no hero image behind the fixed header, so give it a solid
   background immediately — same fix already used for the property detail
   page (.pdp-page-wrap) and blog post page (.post-page-wrap). */
body:has(.ms-page-wrap) .lux-header {
    background: var(--lux-header-bg, var(--lux-primary));
}

.ms-page-wrap {
    padding-top: var(--ms-header-h);
    background: var(--lux-bg);
}

/* --ms-header-h alone matched the header's own height, but the topbar
   (phone/WhatsApp/social/language row) added above it is a second fixed
   element clients only see on >=768px (it hides on mobile) — without this,
   its extra height wasn't accounted for and the page title rendered
   partly underneath the fixed header. Same fix already applied to
   .pdp-page-wrap/.post-page-wrap in homepage.css. */
@media (min-width: 768px) {
    .ms-page-wrap { padding-top: calc(var(--ms-header-h) + var(--lux-topbar-h) + var(--lux-extra-clearance, 0px)); }
}

/* ---------- Page heading ---------- */

.ms-page-wrap--flat { padding-bottom: 3rem; }

/* Plain Bootstrap .container (see index.php) for the max-width/side
   margins — same as every other page on the site — this just adds the
   top spacing below the header. */
.ms-container { padding-top: 1.5rem; }

.ms-page-heading {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1rem;
}

.ms-page-title {
    font-family: var(--lux-font-heading);
    font-size: 1.6rem;
    font-weight: 700;
    color: var(--lux-primary);
    margin: 0;
}

/* ---------- Filter bar ---------- */
/* .pd-filter-bar/.pd-field/.pd-dropdown/... come from homepage.css/
   theme.css (the shared _search_fields.php component) — already loaded
   globally via layouts/home.php, so nothing needs importing here. This
   page's own Min. Area / Sort pills (_search_bar.php) reuse those exact
   classes for a seamless look, plus the More Filters/Reset actions. */

.ms-filter-form { position: relative; z-index: 2; }

.ms-filter-bar { align-items: flex-end; }

.ms-filter-bar-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: auto;
}

.ms-field-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: auto;
}

.ms-more-filters,
.ms-reset-filters {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    height: 2.5rem;
    padding: 0 1rem;
    border-radius: var(--lux-radius-sm);
    font-family: var(--lux-font-button);
    font-size: 0.85rem;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
}

.ms-more-filters {
    background: var(--lux-primary);
    color: var(--lux-light);
    border: 1px solid var(--lux-primary);
}

.ms-more-filters[aria-expanded="true"] { background: var(--lux-secondary); }
.ms-more-filters svg { width: 16px; height: 16px; }

.ms-filter-count {
    background: var(--lux-gold);
    color: var(--lux-primary);
    border-radius: 999px;
    font-size: 0.72rem;
    font-weight: 700;
    padding: 0.05rem 0.45rem;
}

.ms-reset-filters {
    background: transparent;
    color: var(--lux-muted);
    border: 1px solid var(--lux-border);
}

.ms-reset-filters:hover { color: var(--lux-primary); border-color: var(--lux-primary); }

/* ---------- Advanced filter panel (floating dropdown) ---------- */

.ms-filter-panel {
    position: absolute;
    top: 100%;
    right: 0;
    margin-top: 0.5rem;
    width: min(420px, calc(100vw - 2 * var(--ms-gap)));
    max-height: min(70vh, 640px);
    overflow-y: auto;
    background: var(--lux-light);
    border-radius: var(--lux-radius-md);
    box-shadow: var(--lux-shadow-lg);
    padding: 1.25rem;
    z-index: 30;
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
}

.ms-filter-panel[hidden] { display: none; }

.ms-filter-group-title {
    font-family: var(--lux-font-body);
    font-size: 0.8rem;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--lux-primary);
    margin: 0 0 0.6rem;
}

.ms-checkbox-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.5rem;
}

.ms-checkbox-grid-compact { grid-template-columns: repeat(4, 1fr); }

.ms-checkbox {
    display: flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 0.85rem;
    color: var(--lux-dark);
    cursor: pointer;
}

.ms-checkbox input { accent-color: var(--lux-primary); }

.ms-checkbox-pill {
    justify-content: center;
    border: 1px solid var(--lux-border);
    border-radius: var(--lux-radius-sm);
    padding: 0.35rem 0.3rem;
}

.ms-checkbox-pill:has(input:checked) {
    border-color: var(--lux-primary);
    background: var(--lux-bg);
    font-weight: 700;
}

.ms-filter-text {
    font-family: var(--lux-font-body);
    font-size: 0.88rem;
    color: var(--lux-dark);
    background: var(--lux-bg);
    border: 1px solid var(--lux-border);
    border-radius: var(--lux-radius-sm);
    padding: 0.5rem 0.65rem;
    height: 2.5rem;
    width: 100%;
}

.ms-filter-text:focus {
    outline: none;
    border-color: var(--lux-primary);
    background: var(--lux-light);
}

.ms-range-inputs {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    color: var(--lux-muted);
}

.ms-range-inputs input {
    width: 5.5rem;
    font-family: var(--lux-font-body);
    font-size: 0.88rem;
    color: var(--lux-dark);
    background: var(--lux-bg);
    border: 1px solid var(--lux-border);
    border-radius: var(--lux-radius-sm);
    padding: 0.5rem 0.65rem;
    height: 2.5rem;
}

.ms-range-inputs input:focus {
    outline: none;
    border-color: var(--lux-primary);
    background: var(--lux-light);
}

.ms-filter-panel-actions {
    display: flex;
    justify-content: flex-end;
    padding-top: 0.25rem;
    border-top: 1px solid var(--lux-border);
}

/* ---------- Full-width map ---------- */

.ms-map-full-wrap {
    /* z-index (not just position) is what matters here: Leaflet's own
       controls sit at z-index:1000 inside #msMap, and position:relative
       alone doesn't create a new stacking context — without an explicit
       z-index those controls compare directly against page UI outside the
       map (e.g. the filter dropdown panel below, z-index:45) and win,
       rendering on top of/through it. Giving this wrapper its own
       z-index traps Leaflet's internal stacking inside it. */
    position: relative;
    z-index: 1;
    margin: 1.5rem 0;
    border-radius: var(--lux-radius-md);
    overflow: hidden;
    box-shadow: var(--lux-shadow);
}

.ms-map-full {
    width: 100%;
    height: var(--ms-map-h);
    background: var(--lux-bg);
}

@media (max-width: 767.98px) {
    :root { --ms-map-h: 420px; }
}

/* ---------- Results bar + count ---------- */

.ms-topbar-count {
    font-family: var(--lux-font-body);
    font-size: 0.9rem;
    color: var(--lux-muted);
}

.ms-results-bar {
    padding: 0 0 0.75rem;
}

.ms-results-bar .ms-topbar-count {
    font-size: 1.05rem;
    font-weight: 600;
    color: var(--lux-primary);
}

/* ---------- Property grid ---------- */
/* .fp-card (the property card itself) is styled globally in homepage.css
   — this is just the grid that lays 12-per-page cards out 4 columns wide
   on desktop, matching the client's target 4x3 layout, stepping down to 2
   then 1 column exactly like /properties/search's own grid does. */

.ms-results-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: var(--ms-gap);
}

@media (max-width: 1199.98px) {
    .ms-results-grid { grid-template-columns: repeat(2, 1fr); }
}

/* 767.98px, not 575.98 — matching every other property grid on the site
   (properties/_results.php etc.), so 2-up cards don't show through the
   whole phone range (client screenshot: two property cards crammed side
   by side, both partly cut off, on a normal-width phone). */
@media (max-width: 767.98px) {
    .ms-results-grid { grid-template-columns: 1fr; }
}

.ms-empty-state {
    grid-column: 1 / -1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    padding: 3rem 1rem;
    color: var(--lux-muted);
    text-align: center;
}

.ms-empty-state svg { width: 40px; height: 40px; opacity: 0.5; }

/* ---------- Pagination ---------- */
/* Same visual language as the site-wide pager (app/Views/pager/theme.php,
   .pager-nav/.pager-btn/.pager-page), scoped under its own classes rather
   than reusing those directly — this page builds its own Prev/1 2 3/Next
   links server-side (MapSearchController::paginationHtml()) instead of
   going through CI4's Pager object, since one of its two fetch paths
   (an exact drawn circle/polygon) can't produce a real Pager instance. */

.ms-pagination-wrap { margin-top: 2rem; }

.ms-pager-nav {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    flex-wrap: wrap;
}

.ms-pager-list {
    display: flex;
    gap: 0.4rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

.ms-pager-btn,
.ms-pager-page {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 2.4rem;
    height: 2.4rem;
    padding: 0 0.75rem;
    border: 1px solid var(--lux-border);
    border-radius: var(--lux-radius-sm);
    background: var(--lux-light);
    color: var(--lux-dark);
    font-size: 0.85rem;
    font-weight: 600;
    text-decoration: none;
    transition: background 0.2s ease, color 0.2s ease, transform 0.2s ease;
}

.ms-pager-btn:hover,
.ms-pager-page:hover {
    background: var(--lux-primary);
    color: var(--lux-light);
    transform: translateY(-2px);
}

.ms-pager-page.active {
    background: var(--lux-gold);
    border-color: var(--lux-gold);
    color: var(--lux-light);
}

.ms-pager-btn.disabled { opacity: 0.4; pointer-events: none; }
.ms-pager-ellipsis { color: var(--lux-muted); padding: 0 0.3rem; }

/* ---------- Leaflet marker (custom price bubble) ---------- */

/* A location pin (navy circle + pointer tail, like a map-pin icon) with
   the price shown as its own label beside it, rather than the price
   being the marker's whole shape — the pin's tail tip is the marker's
   true anchored coordinate, and stays put regardless of the price
   label's width. */
.ms-marker {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    cursor: pointer;
    transition: transform 0.15s ease;
}

/* Leaflet's own CSS puts a white box + border behind every divIcon by
   default (.leaflet-div-icon) — used by setLocationMarker's single red
   pin (a location page's own marker, and the contact map's office pin),
   which is meant to float free with no background of its own. */
.lux-map-pin { background: transparent !important; border: none !important; }

.ms-marker-pin {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    border-radius: 50%;
    background: var(--lux-primary);
    border: 2px solid var(--lux-light);
    box-shadow: var(--lux-shadow);
    transition: background 0.15s ease;
}

.ms-marker-pin::after {
    content: '';
    position: absolute;
    left: 50%;
    bottom: -7px;
    width: 12px;
    height: 12px;
    background: inherit;
    border-right: 2px solid var(--lux-light);
    border-bottom: 2px solid var(--lux-light);
    border-radius: 0 0 3px 0;
    transform: translateX(-50%) rotate(45deg);
    z-index: -1;
}

.ms-marker-house {
    width: 15px;
    height: 15px;
    color: var(--lux-light);
}

.ms-marker-price {
    padding: 0.35rem 0.7rem;
    border-radius: 999px;
    background: var(--lux-light);
    color: var(--lux-primary);
    font-family: var(--lux-font-button);
    font-size: 0.78rem;
    font-weight: 700;
    box-shadow: var(--lux-shadow);
    white-space: nowrap;
}

.ms-marker:hover,
.ms-marker.is-hovered {
    transform: scale(1.08);
    z-index: 10;
}

.ms-marker.is-active {
    transform: scale(1.12);
    z-index: 20;
}

.ms-marker.is-active .ms-marker-pin { background: var(--lux-gold); }
.ms-marker.is-active .ms-marker-price { background: var(--lux-gold); color: var(--lux-primary); }

/* ---------- Leaflet popup (property preview) ---------- */

.leaflet-popup.ms-popup .leaflet-popup-content-wrapper {
    padding: 0;
    border-radius: var(--lux-radius-md);
    overflow: hidden;
    box-shadow: var(--lux-shadow-lg);
}

.leaflet-popup.ms-popup .leaflet-popup-content {
    margin: 0;
    width: 250px !important;
}

.ms-popup-card { display: block; }

.ms-popup-media {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 10;
    background: var(--lux-bg);
    overflow: hidden;
}

.ms-popup-media img { width: 100%; height: 100%; object-fit: cover; }

.ms-popup-body { padding: 0.75rem 0.9rem 0.9rem; }

.ms-popup-price {
    display: block;
    font-family: var(--lux-font-heading);
    font-weight: 700;
    color: var(--lux-primary);
    font-size: 1rem;
}

.ms-popup-title {
    display: block;
    font-size: 0.85rem;
    color: var(--lux-dark);
    margin: 0.15rem 0 0.6rem;
    line-height: 1.3;
    text-decoration: none;
}

.ms-popup-title:hover { color: var(--lux-primary); }

.ms-popup-actions {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
}

.ms-popup-quickview {
    background: none;
    border: none;
    padding: 0;
    font-size: 0.76rem;
    font-weight: 600;
    color: var(--lux-muted);
    cursor: pointer;
}

.ms-popup-quickview:hover { color: var(--lux-primary); }

.ms-popup-cta {
    display: inline-block;
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--lux-primary);
    text-decoration: none;
}

.ms-popup-cta:hover { text-decoration: underline; }

/* ---------- Skeleton loader (list mid-fetch) ---------- */

.ms-skeleton-card {
    border-radius: var(--lux-radius-md);
    overflow: hidden;
    background: var(--lux-light);
    box-shadow: var(--lux-shadow);
}

.ms-skeleton-media { aspect-ratio: 4 / 3; }

.ms-skeleton-media,
.ms-skeleton-line {
    background: linear-gradient(90deg, var(--lux-bg) 25%, var(--lux-border) 37%, var(--lux-bg) 63%);
    background-size: 400% 100%;
    animation: ms-shimmer 1.4s ease infinite;
}

.ms-skeleton-body { padding: 1rem 1.1rem 1.1rem; display: flex; flex-direction: column; gap: 0.6rem; }
.ms-skeleton-line { height: 0.7rem; border-radius: 999px; }
.ms-skeleton-line.w-60 { width: 60%; }
.ms-skeleton-line.w-80 { width: 80%; }
.ms-skeleton-line.w-40 { width: 40%; }

@keyframes ms-shimmer {
    0% { background-position: 100% 50%; }
    100% { background-position: 0 50%; }
}

/* ---------- Entrance animations ---------- */

@keyframes ms-fade-in {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: translateY(0); }
}

.fp-card { animation: ms-fade-in 0.35s ease both; }

/*
 * These dropdown panels are shown/hidden purely by toggling the `hidden`
 * attribute in JS (see filters.js/map.js/nearby.js/saved-searches.js) —
 * `hidden` maps to `display:none` by default, and a `@keyframes` animation
 * tied to `:not([hidden])` does not reliably (re)trigger across a
 * display:none <-> visible flip in the same synchronous tick: measured in
 * the browser, the panel was left stuck at the animation's `from` state
 * (opacity: 0) — open in the DOM, completely invisible. Removed rather
 * than reworked into a transition-based version, since that would need
 * real visual verification this environment can't do; correctness over
 * the entrance flourish.
 */

@keyframes ms-marker-bounce {
    0%, 100% { transform: translateY(0); }
    30% { transform: translateY(-10px); }
    55% { transform: translateY(0); }
    75% { transform: translateY(-4px); }
}

.ms-marker.is-active { animation: ms-marker-bounce 0.5s ease; }

@media (prefers-reduced-motion: reduce) {
    .fp-card,
    .fp-card-media img,
    .ms-marker,
    .ms-filter-panel,
    .ms-layer-panel,
    .ms-nearby-panel {
        transition: none;
        animation: none !important;
    }

    .ms-skeleton-media,
    .ms-skeleton-line {
        animation: none;
        background: var(--lux-bg);
    }
}

/* ---------- Cluster icons ---------- */

.ms-cluster {
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    background: var(--lux-primary);
    color: var(--lux-light);
    font-family: var(--lux-font-button);
    font-weight: 700;
    box-shadow: 0 0 0 6px rgba(13, 27, 42, 0.15), var(--lux-shadow);
    transition: transform 0.15s ease;
}

.ms-cluster:hover { transform: scale(1.08); }

.ms-cluster-sm { width: 38px; height: 38px; font-size: 0.8rem; }
.ms-cluster-md { width: 46px; height: 46px; font-size: 0.88rem; background: var(--accent-teal, #1f8a8c); }
.ms-cluster-lg { width: 54px; height: 54px; font-size: 0.95rem; background: var(--lux-gold-hover, #b3922c); }

/* ---------- Leaflet control chrome (premium styling) ---------- */

.leaflet-bar,
.leaflet-control-locate.leaflet-bar {
    border: none !important;
    border-radius: var(--lux-radius-sm) !important;
    box-shadow: var(--lux-shadow) !important;
    overflow: hidden;
}

/* Deliberately NOT sharing the rule above: .ms-layer-panel is a child of
   .ms-layer-switcher positioned outside its 34px box (it opens to the
   left via right: calc(100% + ...) below) — overflow:hidden on the
   parent clipped the panel out of existence the instant it needed to
   render past that box, so the button worked but the menu never showed.
   The element carries both classes ("ms-layer-switcher leaflet-bar"), so
   the plain .leaflet-bar rule above still matches it and still sets
   overflow:hidden regardless of what this rule declares — omitting
   `overflow` here isn't enough, it has to be overridden explicitly.
   Rounding comes from .ms-layer-toggle itself instead of a clipped
   parent, since the parent can no longer safely clip anything. */
.ms-layer-switcher.leaflet-bar {
    border: none !important;
    border-radius: var(--lux-radius-sm) !important;
    box-shadow: var(--lux-shadow) !important;
    overflow: visible !important;
}

/* background-color (not the `background` shorthand) matters here: the
   shorthand resets every background sub-property it doesn't mention,
   including background-image — which is exactly how Leaflet.draw's
   polygon/rectangle/circle icons and Leaflet.fullscreen's icon are drawn
   (sprite images, no visible text/SVG content of their own). The
   shorthand version silently wiped those sprites out, leaving blank
   white buttons; the zoom +/- buttons looked fine regardless since
   they're plain text glyphs with no background-image to lose. */
.leaflet-bar a {
    background-color: var(--lux-light) !important;
    color: var(--lux-primary) !important;
    border-bottom-color: var(--lux-border) !important;
}

.leaflet-bar a:hover { background-color: var(--lux-bg) !important; }

.leaflet-control-scale-line {
    background: rgba(255, 255, 255, 0.85) !important;
    border-color: var(--lux-dark) !important;
    color: var(--lux-dark) !important;
    border-radius: 0 0 var(--lux-radius-sm) var(--lux-radius-sm);
}

/* ---------- Layer switcher ---------- */

.ms-layer-switcher { position: relative; }

.ms-layer-toggle {
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    border-radius: var(--lux-radius-sm);
    background: var(--lux-light);
    color: var(--lux-primary);
    cursor: pointer;
}

.ms-layer-toggle svg { width: 18px; height: 18px; }
.ms-layer-toggle:hover { background: var(--lux-bg); }

.ms-layer-panel {
    position: absolute;
    top: 0;
    right: calc(100% + 0.5rem);
    background: var(--lux-light);
    border-radius: var(--lux-radius-sm);
    box-shadow: var(--lux-shadow-lg);
    padding: 0.4rem;
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    min-width: 120px;
}

.ms-layer-panel[hidden] { display: none; }

.ms-layer-option {
    text-align: left;
    padding: 0.4rem 0.6rem;
    border: none;
    background: transparent;
    border-radius: var(--lux-radius-sm);
    font-size: 0.82rem;
    color: var(--lux-dark);
    cursor: pointer;
}

.ms-layer-option:hover { background: var(--lux-bg); }
.ms-layer-option.is-active { background: var(--lux-primary); color: var(--lux-light); font-weight: 600; }

/* ---------- Locate control ---------- */

.ms-locate-icon::before {
    content: '';
    display: block;
    width: 16px;
    height: 16px;
    margin: 9px;
    border: 2px solid var(--lux-primary);
    border-radius: 50%;
}

/* ---------- Nearby Places ---------- */

.ms-nearby-control { position: relative; }

.ms-nearby-toggle {
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: var(--lux-light);
    color: var(--lux-primary);
    cursor: pointer;
}

.ms-nearby-toggle svg { width: 18px; height: 18px; }
.ms-nearby-toggle:hover { background: var(--lux-bg); }

.ms-nearby-panel {
    position: absolute;
    top: 0;
    left: calc(100% + 0.5rem);
    background: var(--lux-light);
    border-radius: var(--lux-radius-sm);
    box-shadow: var(--lux-shadow-lg);
    padding: 0.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-width: 190px;
}

.ms-nearby-panel[hidden] { display: none; }

.ms-nearby-option {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.4rem 0.5rem;
    border-radius: var(--lux-radius-sm);
    font-size: 0.82rem;
    color: var(--lux-dark);
    cursor: pointer;
}

.ms-nearby-option:hover { background: var(--lux-bg); }
.ms-nearby-option input { accent-color: var(--ms-poi-color, var(--lux-primary)); }

.ms-nearby-option span:nth-child(2)::before {
    content: '';
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--ms-poi-color, var(--lux-primary));
    margin-right: 0.35rem;
}

.ms-nearby-status {
    margin-left: auto;
    font-size: 0.7rem;
    color: var(--lux-muted);
    white-space: nowrap;
}

.ms-poi-marker {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: var(--ms-poi-color, var(--lux-primary));
    color: var(--lux-light);
    font-size: 0.68rem;
    font-weight: 700;
    border: 2px solid var(--lux-light);
    box-shadow: var(--lux-shadow);
}

/* ---------- Heatmap toggle ---------- */

.ms-heatmap-toggle-btn {
    width: 34px;
    height: 34px;
    display: flex;
    align-items: center;
    justify-content: center;
    border: none;
    background: var(--lux-light);
    color: var(--lux-primary);
    cursor: pointer;
}

.ms-heatmap-toggle-btn svg { width: 17px; height: 17px; }
.ms-heatmap-toggle-btn:hover { background: var(--lux-bg); }

.ms-heatmap-toggle-btn.is-active {
    background: var(--lux-gold);
    color: var(--lux-primary);
}

/* ---------- Search-as-I-move toggle ---------- */

.ms-move-toggle-btn {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    height: 34px;
    padding: 0 0.75rem;
    border: none;
    background: var(--lux-light);
    color: var(--lux-primary);
    font-family: var(--lux-font-button);
    font-size: 0.78rem;
    font-weight: 600;
    white-space: nowrap;
    cursor: pointer;
}

.ms-move-toggle-btn svg { width: 15px; height: 15px; flex-shrink: 0; }
.ms-move-toggle-btn:hover { background: var(--lux-bg); }

.ms-move-toggle-btn.is-active {
    background: var(--lux-primary);
    color: var(--lux-light);
}

/* ---------- Draw Search Area ---------- */

.leaflet-draw-toolbar a {
    background-color: var(--lux-light) !important;
    border-radius: 0 !important;
}

.leaflet-draw-toolbar a:hover { background-color: var(--lux-bg) !important; }

.ms-draw-actions {
    position: absolute;
    left: 50%;
    bottom: 1.25rem;
    transform: translateX(-50%);
    z-index: 1000;
    display: flex;
    align-items: center;
    gap: 0.6rem;
    background: var(--lux-light);
    border-radius: 999px;
    box-shadow: var(--lux-shadow-lg);
    padding: 0.5rem 0.6rem 0.5rem 1rem;
}

.ms-draw-actions[hidden] { display: none; }

.ms-draw-area {
    font-size: 0.8rem;
    font-weight: 600;
    color: var(--lux-primary);
    white-space: nowrap;
}

.ms-draw-actions button {
    height: 2.1rem;
    padding: 0 0.9rem;
    border-radius: 999px;
    border: none;
    font-family: var(--lux-font-button);
    font-size: 0.78rem;
    font-weight: 600;
    cursor: pointer;
    white-space: nowrap;
}

.ms-draw-search { background: var(--lux-primary); color: var(--lux-light); }
.ms-draw-search:hover { background: var(--lux-secondary); }

.ms-draw-edit { background: var(--lux-bg); color: var(--lux-dark); }
.ms-draw-edit:hover { background: var(--lux-border); }
.ms-draw-edit.is-active { background: var(--lux-gold); color: var(--lux-primary); }

.ms-draw-clear { background: transparent; color: var(--lux-muted); }
.ms-draw-clear:hover { color: var(--lux-primary); }

@media (max-width: 767.98px) {
    .ms-draw-actions {
        left: 1rem;
        right: 1rem;
        bottom: 5.5rem;
        transform: none;
        flex-wrap: wrap;
        justify-content: center;
    }
}

/* ---------- Dark mode tiles: lift marker/popup chrome for contrast ---------- */

.ms-map-dark .ms-marker-pin { background: var(--lux-dark); border-color: rgba(255, 255, 255, 0.15); }
.ms-map-dark .ms-marker-price { background: var(--lux-dark); color: var(--lux-light); }

/* ---------- Quick View modal ---------- */

/* Sized to fit its content (up to the max-height safety cap below), not
   forced to a fixed height — an earlier version of this forced every
   level to a fixed 720px, which fixed a real bug (a huge, unbounded photo
   blowing the popup out) but overcorrected: .ms-qv-body's actual text
   content is rarely anywhere near 720px tall, so it left a large dead gap
   at the bottom of the right column, stretched to match a height it never
   needed. Now that the hero photo itself has a fixed height (see
   .ms-qv-hero-wrap below, no longer flex-grown to fill available space),
   there's nothing left that can grow unboundedly, so natural
   shrink-to-fit sizing is safe again. */
.ms-qv-modal .modal-dialog {
    max-height: min(85vh, 720px);
    /* Bootstrap's .modal-dialog-centered sets its own min-height
       (calc(100% - 3.5rem)) for vertical centering, and min-height always
       wins over a smaller max-height — without this override the dialog
       stretches to almost the full viewport regardless of the cap above. */
    min-height: 0;
}

.ms-qv-modal .modal-content {
    /* The same concrete value as .modal-dialog above, not max-height:100%
       — a percentage max-height only resolves against a *definite* parent
       height, and .modal-dialog only has a max-height itself (no plain
       height), so 100% here would have been silently ignored. */
    max-height: min(85vh, 720px);
    border: none;
    border-radius: var(--lux-radius-lg);
    overflow: hidden;
}

.ms-qv-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 320px;
}

.ms-spinner {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    border: 3px solid var(--lux-border);
    border-top-color: var(--lux-primary);
    animation: ms-spin 0.8s linear infinite;
}

@keyframes ms-spin { to { transform: rotate(360deg); } }

.ms-qv {
    display: grid;
    grid-template-columns: 1.1fr 1fr;
}

/* CSS Grid stretches .ms-qv-media's cell to match .ms-qv-body's (taller,
   text-driven) height — the client's screenshot showed the gap that left
   underneath the old fixed-height hero image + thumbnail strip, since
   neither one grew to fill that taller cell. Flexing the column and
   letting the upper photo grow (flex:1, on .ms-qv-hero-wrap below) to take
   up whatever's left above the gallery removes that gap — the small
   padding-bottom is the client's requested "little bit of white space",
   so the gallery row lines up with .ms-qv-body's own bottom padding on
   the right instead of sitting flush against the modal's rounded corner. */
.ms-qv-media {
    position: relative;
    background: var(--lux-bg);
    display: flex;
    flex-direction: column;
    padding-bottom: 1.1rem;
    /* Grid items default to min-width:auto (never shrink below their own
       content's size) — without this override, the gallery's Swiper
       (slidesPerView:'auto' laying all 25 slides out in a single ~1850px-
       wide scrollable strip) counted as this column's minimum content
       width, forcing the 1.1fr/1fr split to give this column ~1850px and
       squeeze .ms-qv-body down to a sliver — the missing right column in
       an earlier version of this. */
    min-width: 0;
    /* CSS Grid's default align-items:stretch would otherwise pull this
       column's height up to match .ms-qv-body's (usually taller, text-
       driven) height, leaving blank .ms-qv-bg space below the fixed-height
       photo + gallery — the dead gap in the client's screenshot. Aligning
       to the top instead lets this column just be its own natural height
       (photo + gallery + padding), whatever that turns out to be. */
    align-self: start;
}

/* Upper zone: one big static feature photo. A fixed height (not flex:1
   growing to fill whatever the row turns out to be) is what the client
   asked for after seeing the right column stretched into a dead gap to
   match a taller photo — this way the photo has its own sensible size
   regardless of how tall .ms-qv-body's text content happens to be, and
   neither column is forcing the other one taller than it needs. */
.ms-qv-hero-wrap {
    position: relative;
    height: 380px;
    overflow: hidden;
}

.ms-qv-hero {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.ms-qv-hero-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    color: var(--lux-muted);
}

.ms-qv-hero-placeholder svg { width: 56px; height: 56px; }

.ms-qv-status {
    position: absolute;
    top: 0.85rem;
    left: 0.85rem;
    padding: 0.3rem 0.7rem;
    border-radius: var(--lux-radius-sm);
    font-size: 0.72rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--lux-light);
    background: var(--lux-primary);
}

/* Lower zone: multi-thumbnail auto-sliding carousel (client reference:
   codepen.io/jackcohle/pen/ZxyjwQ) — several photos visible and sliding at
   once, a fixed (not flex-grown) row height so it can never be the thing
   that blows the popup's overall height out — reuses the same Swiper
   build already loaded site-wide for the homepage hero, initialized on
   demand in quickview.js once this markup is fetched in. Clicking (or
   autoplay advancing past) a thumbnail swaps the big photo above via
   data-qv-hero, so the "feature" photo stays in sync with the slider
   instead of only ever showing the first photo. */
.ms-qv-gallery {
    flex: 0 0 auto;
    width: 100%;
    margin-top: 4px;
}
.ms-qv-gallery .swiper-slide {
    width: 70px;
    height: 58px;
    cursor: pointer;
}
.ms-qv-gallery .swiper-slide img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    border-radius: 4px;
}
.ms-qv-gallery .swiper-slide-active img { outline: 2px solid var(--lux-primary); outline-offset: -2px; }

.ms-qv-body {
    padding: 1.5rem 1.5rem 1.25rem;
    display: flex;
    flex-direction: column;
    min-height: 0;
    min-width: 0;
    /* Everything in this modal now sizes to its own content (see
       .modal-dialog above) rather than being forced to a fixed height, so
       this needs its own cap for the rare case of an unusually long
       description — scrolls internally past that point instead of
       silently getting clipped by .modal-content's own overflow:hidden. */
    max-height: min(85vh, 690px);
    overflow-y: auto;
}

/* Reserves room on the right for the modal's floating close button (see
   .ms-qv-modal .btn-close below) — without this the price sat directly
   underneath it, the collision the client's screenshot circled in red. */
.ms-qv-top { display: flex; align-items: center; justify-content: space-between; margin-bottom: 0.35rem; padding-right: 2.5rem; }

.ms-qv-type {
    font-size: 0.75rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--lux-muted);
}

.ms-qv-price {
    font-family: var(--lux-font-heading);
    font-weight: 700;
    font-size: 1.2rem;
    color: var(--lux-primary);
}

.ms-qv-title { font-size: 1.15rem; font-weight: 700; margin: 0 0 0.4rem; color: var(--lux-dark); }

.ms-qv-address {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    font-size: 0.85rem;
    color: var(--lux-muted);
    margin-bottom: 0.85rem;
}

.ms-qv-address svg { width: 15px; height: 15px; flex-shrink: 0; }

.ms-qv-facts {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1rem;
    padding: 0.85rem 0;
    border-top: 1px solid var(--lux-border);
    border-bottom: 1px solid var(--lux-border);
    margin-bottom: 0.85rem;
}

.ms-qv-facts span { display: flex; align-items: center; gap: 0.35rem; font-size: 0.85rem; color: var(--lux-dark); }
.ms-qv-facts svg { width: 16px; height: 16px; color: var(--lux-muted); }

.ms-qv-desc { font-size: 0.87rem; color: var(--lux-muted); line-height: 1.55; margin-bottom: 1.1rem; }

.ms-qv-travel { margin-bottom: 1.1rem; }

.ms-qv-travel-btn {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.5rem 0.9rem;
    border: 1px solid var(--lux-border);
    border-radius: var(--lux-radius-sm);
    background: var(--lux-bg);
    color: var(--lux-primary);
    font-family: var(--lux-font-button);
    font-size: 0.8rem;
    font-weight: 600;
    cursor: pointer;
}

.ms-qv-travel-btn svg { width: 15px; height: 15px; }
.ms-qv-travel-btn:hover { background: var(--lux-border); }
.ms-qv-travel-btn:disabled { opacity: 0.7; cursor: wait; }

.ms-qv-travel-results {
    display: flex;
    gap: 0.75rem;
    margin-top: 0.75rem;
}

.ms-qv-travel-mode {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.25rem;
    padding: 0.6rem 0.4rem;
    border-radius: var(--lux-radius-sm);
    background: var(--lux-bg);
    text-align: center;
}

.ms-qv-travel-mode svg { width: 18px; height: 18px; color: var(--lux-primary); }
.ms-qv-travel-label { font-size: 0.7rem; color: var(--lux-muted); text-transform: uppercase; letter-spacing: 0.02em; }
.ms-qv-travel-mode strong { font-size: 0.88rem; color: var(--lux-dark); }
.ms-qv-travel-mode span:not(.ms-qv-travel-label) { font-size: 0.72rem; color: var(--lux-muted); }
.ms-qv-travel-unavailable { font-size: 0.78rem; color: var(--lux-muted); margin: 0; }

.ms-qv-footer { margin-top: auto; display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; }

.ms-qv-ref { font-size: 0.78rem; color: var(--lux-muted); }

/* Floating close button (index.php's <button class="btn-close ...">,
   shared by every state — loading spinner, error, and the loaded gallery
   above): a plain circle so it always reads as its own control regardless
   of what's under it, rather than the bare Bootstrap "X" glyph the client's
   screenshot showed sitting directly on top of the price text. */
.ms-qv-modal .btn-close {
    width: 2rem;
    height: 2rem;
    padding: 0;
    background-color: var(--lux-light);
    background-size: 0.8rem;
    border-radius: 50%;
    box-shadow: var(--lux-shadow);
    opacity: 1;
}

@media (max-width: 767.98px) {
    .ms-qv { grid-template-columns: 1fr; }
    .ms-qv-hero-wrap { height: 200px; }
}


/* ---------- Comparison bar (floating, on Map Search) ---------- */

.ms-compare-bar {
    position: fixed;
    left: 50%;
    bottom: 1.5rem;
    transform: translateX(-50%);
    /* Hidden by three independent, non-interacting mechanisms rather than
       a translateY slide alone: that used to leave a visible sliver of
       the bar peeking above the bottom edge even with nothing selected
       (120% of its own ~56px height is only ~67px — not reliably enough
       to clear the viewport), and only looked hidden by coincidence.
       opacity/visibility/pointer-events all default "off" here and flip
       "on" together under .is-visible below — no client-reported "always
       showing" case can slip through this whichever one a given browser
       honors first. */
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    z-index: 1040;
    display: flex;
    align-items: center;
    gap: 1rem;
    background: var(--lux-primary);
    color: var(--lux-light);
    border-radius: 999px;
    box-shadow: var(--lux-shadow-lg);
    padding: 0.6rem 0.6rem 0.6rem 1.1rem;
    transition: opacity 0.3s ease;
    max-width: calc(100vw - 2rem);
}

.ms-compare-bar.is-visible {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;
}

.ms-compare-bar-label {
    font-family: var(--lux-font-button);
    font-size: 0.82rem;
    font-weight: 600;
    white-space: nowrap;
}

.ms-compare-thumbs {
    display: flex;
    align-items: center;
    gap: 0.4rem;
}

.ms-compare-thumb {
    position: relative;
    width: 40px;
    height: 40px;
    border-radius: var(--lux-radius-sm);
    overflow: hidden;
    background: rgba(255, 255, 255, 0.12);
    flex-shrink: 0;
}

.ms-compare-thumb img { width: 100%; height: 100%; object-fit: cover; }

.ms-compare-thumb-remove {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(13, 27, 42, 0.55);
    border: none;
    color: var(--lux-light);
    opacity: 0;
    cursor: pointer;
    transition: opacity 0.15s ease;
}

.ms-compare-thumb:hover .ms-compare-thumb-remove { opacity: 1; }
.ms-compare-thumb-remove svg { width: 14px; height: 14px; }

.ms-compare-bar-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: 0.25rem;
}

.ms-compare-go {
    height: 2.3rem;
    padding: 0 1.1rem;
    border: none;
    border-radius: 999px;
    background: var(--lux-gold);
    color: var(--lux-primary);
    font-family: var(--lux-font-button);
    font-size: 0.82rem;
    font-weight: 700;
    cursor: pointer;
    white-space: nowrap;
}

.ms-compare-go:disabled { opacity: 0.5; cursor: not-allowed; }
.ms-compare-go:not(:disabled):hover { background: var(--lux-gold-hover); }

.ms-compare-clear {
    background: none;
    border: none;
    color: rgba(255, 255, 255, 0.75);
    font-size: 0.78rem;
    text-decoration: underline;
    cursor: pointer;
    white-space: nowrap;
}

.ms-compare-clear:hover { color: var(--lux-light); }

@media (max-width: 767.98px) {
    .ms-compare-bar {
        left: 1rem;
        right: 1rem;
        bottom: 1rem;
        transform: none;
        max-width: none;
        flex-wrap: wrap;
        justify-content: center;
    }
}

/* ---------- Compare checkbox on cards/popups ---------- */

.ms-card-compare {
    position: absolute;
    bottom: 0.75rem;
    left: 0.75rem;
    display: flex;
    align-items: center;
    gap: 0.35rem;
    height: 30px;
    padding: 0 0.6rem;
    border: none;
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.92);
    color: var(--lux-dark);
    font-family: var(--lux-font-button);
    font-size: 0.72rem;
    font-weight: 600;
    box-shadow: var(--lux-shadow);
    cursor: pointer;
}

.ms-card-compare svg { width: 14px; height: 14px; }

.ms-card-compare.is-checked {
    background: var(--lux-primary);
    color: var(--lux-light);
}

.ms-popup-compare {
    background: none;
    border: none;
    padding: 0;
    font-size: 0.76rem;
    font-weight: 600;
    color: var(--lux-muted);
    cursor: pointer;
}

.ms-popup-compare.is-checked,
.ms-popup-compare:hover { color: var(--lux-primary); }


/* ---------- Compare page ---------- */

.ms-compare-wrap { padding-bottom: 4rem; }

.ms-compare-header {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 1rem;
    flex-wrap: wrap;
    max-width: 1400px;
    margin: 0 auto 1.5rem;
    padding: 2rem var(--ms-gap) 0;
}

/* .lux-btn (shared sitewide) never sizes its own icons — this is the only
   button on the page carrying one, so it's scoped here rather than added
   to the shared class. */
.ms-compare-header .lux-btn svg {
    width: 18px;
    height: 18px;
    flex-shrink: 0;
}

.ms-compare-subtitle {
    color: var(--lux-muted);
    font-size: 0.92rem;
    margin: 0.35rem 0 0;
}

.ms-compare-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.75rem;
    max-width: 420px;
    margin: 3rem auto;
    text-align: center;
    color: var(--lux-muted);
}

.ms-compare-empty svg { width: 48px; height: 48px; opacity: 0.5; }
.ms-compare-empty h2 { font-family: var(--lux-font-heading); color: var(--lux-primary); font-size: 1.3rem; margin: 0; }
.ms-compare-empty p { margin: 0; }

.ms-compare-table-wrap {
    max-width: 1400px;
    margin: 0 auto;
    padding: 0 var(--ms-gap);
    overflow-x: auto;
}

.ms-compare-table {
    border-collapse: separate;
    border-spacing: 0;
    width: 100%;
}

.ms-compare-table th,
.ms-compare-table td {
    padding: 0.75rem 1.1rem;
    border-bottom: 1px solid var(--lux-border);
    text-align: center;
    white-space: nowrap;
    font-size: 0.88rem;
}

.ms-compare-table thead th {
    vertical-align: top;
    border-bottom: 2px solid var(--lux-border);
    padding: 0;
}

.ms-compare-attr-col {
    min-width: 160px;
}

.ms-compare-table tbody th {
    position: sticky;
    left: 0;
    background: var(--lux-bg);
    text-align: left;
    font-weight: 600;
    color: var(--lux-dark);
    white-space: nowrap;
}

.ms-compare-card {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 240px;
    padding: 1rem;
    text-align: left;
}

.ms-compare-remove {
    position: absolute;
    top: 0.6rem;
    right: 0.6rem;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border: none;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.92);
    color: var(--lux-dark);
    cursor: pointer;
}

.ms-compare-remove svg { width: 13px; height: 13px; }
.ms-compare-remove:hover { background: var(--lux-primary); color: var(--lux-light); }

.ms-compare-media {
    display: block;
    aspect-ratio: 4 / 3;
    border-radius: var(--lux-radius-sm);
    overflow: hidden;
    background: var(--lux-bg);
    margin-bottom: 0.6rem;
}

.ms-compare-media img { width: 100%; height: 100%; object-fit: cover; }

.ms-compare-price {
    font-family: var(--lux-font-heading);
    font-weight: 700;
    color: var(--lux-primary);
    font-size: 1rem;
}

.ms-compare-title {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 0.85rem;
    color: var(--lux-dark);
    text-decoration: none;
    white-space: normal;
    margin: 0.2rem 0 0.7rem;
    line-height: 1.35;
}

.ms-compare-title:hover { color: var(--lux-primary); }

.ms-compare-cta {
    font-size: 0.78rem;
    padding: 0.4rem 0.8rem;
    align-self: flex-start;
}

.ms-compare-check svg.ms-compare-yes { width: 18px; height: 18px; color: var(--accent-teal, #1f8a8c); }
.ms-compare-no { color: var(--lux-border); }
