/* ==========================================================================
   Softbnb — Search results, "Editorial Grid" + "Map First"
   Boards: EditorialGrid / MapFirst / EditorialGridMobile / MapFirstMobile
   Conventions: docs/property-themes.md → "CSS ground rules"

   WHERE THIS LOADS
     resources/views/search/view.blade.php pushes this in @push('css'), which
     common/head.blade.php renders at :124 — BEFORE bootstrap.min.css (:179)
     and style.css (:181). Ties in specificity are therefore lost, so every
     selector below carries at least two classes and starts inside .sr-page.
     It is also pushed AFTER the view's own <style> block, so where specificity
     ties with the old search CSS, this file wins on order.

   SCOPE
     .sr-page            page root   <div class="sr-page sb-page sr-view-grid">
     .sr-page.sr-view-grid   Editorial Grid — the default view
     .sr-page.sr-view-map    Map First     — the toggled view
     .sr-overlays        wrapper for everything rendered outside the root
                         (more-filters modal, confirm, toast) — carries
                         .sb-modal so softbnb-ds.css tokens reach it
     #map-hover-card     appended to <body> by the view, so it gets its own
                         top-level namespace (section 11), never a
                         .sr-page-scoped rule

   TOKENS
     .sr-page carries .sb-page, so every --sb-* token from css/softbnb-ds.css
     applies and dark mode (body.dark-mode) follows for free. Section 1 also
     re-points the page's OWN legacy --sr-* tokens at the --sb-* palette, so
     the components this file does not restyle (filter panels, the price
     slider, the daterangepicker) come along instead of staying blue-grey.
     1rem = 10px on this site (html{font-size:62.5%}) — sizes are written in
     px or --sb-* tokens, never bare rem.

   REAL CONTENT
     Cards, counts, the hero lede and the collection rail are all rendered
     from the live /search/result paginator by js/search-redesign.js. Nothing
     here invents a listing, a price or a rating.
   ========================================================================== */


/* ==========================================================================
   1. Tokens
   ========================================================================== */

.sr-page.sb-page {
    /* Editorial values, taken from the approved boards' kit. */
    --sre-pad:          72px;   /* desktop page gutter */
    --sre-row-gap:      40px;   /* grid row rhythm */
    --sre-col-gap:      28px;   /* grid column rhythm */
    --sre-card-radius:  20px;
    --sre-tile-w:       236px;
    --sre-tile-h:       132px;
    --sre-bar-h:        92px;   /* sticky bar (18px + 56px pill + 18px) */
    --sre-header-h:     66px;   /* .site-topnav, fixed — header.blade.php:8 */

    /* Always-dark glass — Map First chrome. Deliberately literal: it must not
       invert with dark mode, it is dark in both themes. */
    --sre-glass:        rgba(26, 22, 20, 0.82);
    --sre-glass-strong: rgba(26, 22, 20, 0.92);
    --sre-glass-line:   rgba(255, 255, 255, 0.14);
    --sre-glass-line-2: rgba(255, 255, 255, 0.12);
    --sre-glass-fill:   rgba(255, 255, 255, 0.10);
    --sre-glass-ink:    #FFFFFF;
    --sre-glass-muted:  #A99E95;
    --sre-glass-card:   #1A1614;
    --sre-glass-border: #332B26;
    --sre-glass-blur:   blur(18px);

    /* ── Re-point the legacy --sr-* tokens the old stylesheet still uses ── */
    --sr-primary:   var(--sb-primary-strong);
    --sr-primary-d: var(--sb-primary-hover);
    --sr-text:      var(--sb-text);
    --sr-muted:     var(--sb-muted);
    --sr-border:    var(--sb-border);
    --sr-bg:        var(--sb-surface-2);
    --sr-shadow:    var(--sb-shadow-2);
    --sr-radius:    var(--sb-r-md);

    background: var(--sb-bg);
    color: var(--sb-text);
    font-family: var(--sb-font-body);
    /* .sr-panel is position:fixed with JS-assigned top/left (view:1795-1807).
       softbnb-ds.css sets overflow-x:clip on .sb-page, which clips them in
       Chromium — so it is explicitly released here. Nothing inside the page
       overflows horizontally: the chip rail and the results both scroll in
       their own containers. */
    overflow-x: visible;
}

/* The shell inherits the same tokens so old rules that read them from
   .sr-shell (css/softbnb-search.css did this) keep resolving. */
.sr-page .sr-shell {
    font-family: var(--sb-font-body);
    color: var(--sb-text);
    background: var(--sb-bg);
}

.sr-overlays.sb-modal {
    --sre-card-radius: 20px;
    --sr-primary:   var(--sb-primary-strong);
    --sr-primary-d: var(--sb-primary-hover);
    --sr-text:      var(--sb-text);
    --sr-muted:     var(--sb-muted);
    --sr-border:    var(--sb-border);
    --sr-bg:        var(--sb-surface-2);
    --sr-radius:    var(--sb-r-md);
}


/* ==========================================================================
   2. Reset — only inside the page, only what Bootstrap/style.css break
   ========================================================================== */

.sr-page *,
.sr-page *::before,
.sr-page *::after { box-sizing: border-box; }

.sr-page h1, .sr-page h2, .sr-page h3, .sr-page h4, .sr-page p { margin: 0; }
.sr-page img { display: block; max-width: 100%; }

.sr-page a,
.sr-page a:hover,
.sr-page a:focus { text-decoration: none; }

/* style.css ships `button:focus{border:0}` — keep declared borders in every
   state by driving them from a variable, as css/property-themes/shared.css does. */
.sr-page button {
    font-family: inherit;
    cursor: pointer;
    border-style: solid;
    border-width: var(--sre-bw, 0);
    border-color: var(--sre-bc, transparent);
}
.sr-page button:focus { border-width: var(--sre-bw, 0); border-color: var(--sre-bc, transparent); }

.sr-page :focus-visible,
.sr-overlays :focus-visible {
    outline: 3px solid var(--sb-focus);
    outline-offset: 3px;
    border-radius: var(--sb-r-sm);
}
/* Controls that sit ON the map need their own ring: Google's zoom buttons live
   in a rounded container with its own shadow, so an offset halo clips. The old
   rule here hung off .sr-e-mapwrap, which exists in no blade, no JS and nowhere
   else in this file — it never matched anything. */
.sr-page.sr-view-map .gm-style :focus-visible {
    outline: 3px solid var(--sb-focus);
    outline-offset: 2px;
}

.sr-page .sr-e-sr {
    position: absolute; width: 1px; height: 1px;
    padding: 0; margin: -1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}


/* ==========================================================================
   3. Shell and the two views
   ========================================================================== */

.sr-page .sr-shell {
    display: flex;
    position: relative;
    height: calc(100vh - var(--sre-header-h));
    margin: 0;
    overflow: visible;
}

.sr-page .sr-results {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    background: var(--sb-bg);
}

.sr-page .sr-results-inner {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    overflow-x: hidden;
    padding: 0;
    -webkit-overflow-scrolling: touch;
    overscroll-behavior: contain;
}

/* ── Editorial Grid: the map leaves the page but stays alive ───────────────
   #map_view must remain laid out and locationpicker-initialised, or
   google.maps.Map#getBounds() never resolves and getProperties() silently
   returns nothing (view:2169). So the panel is parked off-screen at a real
   size — never display:none. This rule is three classes deep so it beats the
   view's own `.sr-map-panel.hidden{display:none}`. */
.sr-page.sr-view-grid .sr-map-panel,
.sr-page.sr-view-grid .sr-map-panel.hidden {
    display: block;
    position: absolute;
    top: 0;
    left: -200vw;
    width: 900px;
    height: 640px;
    pointer-events: none;
    opacity: 0;
    z-index: -1;
    border: 0;
}
.sr-page.sr-view-grid .sr-map-close { display: none; }

/* ── Map First: the map is the page, results ride over it ───────────────── */
/* ── Map view: SPLIT MAP ───────────────────────────────────────────────────
   Results keep their grid and sit in a solid column on the left; the map takes
   the rest and stays put while the list scrolls. The earlier treatment floated
   a narrow glass rail over a full-bleed map, which looked striking but showed
   three listings at a time and changed the page's mental model when you toggled.
   Here the toggle changes the LAYOUT, not the model: the same cards, the same
   order, now beside a map.

   Column count is the visitor's choice — --sre-map-cols, flipped by the density
   control and remembered in localStorage. Two is the default because at this
   width a single column wastes half the panel. */
/* Split view is a LIGHT panel beside the map, not dark chrome floating over it.
   The --sre-glass-* tokens were written for the earlier full-bleed treatment and
   are referenced by ~50 rules; re-pointing them here turns all of those light at
   once, instead of rewriting each one and leaving white-on-white behind. They
   stay literal, not token aliases, because they must not invert with dark mode —
   the dark-mode block further down handles that case on its own. */
.sr-page.sr-view-map {
    --sre-glass:        var(--sb-surface);
    --sre-glass-strong: var(--sb-surface);
    --sre-glass-line:   var(--sb-border);
    --sre-glass-line-2: var(--sb-border);
    --sre-glass-fill:   var(--sb-surface-2);
    --sre-glass-ink:    var(--sb-ink);
    --sre-glass-muted:  var(--sb-muted);
    --sre-glass-card:   var(--sb-surface);
    --sre-glass-border: var(--sb-border);
    --sre-glass-blur:   none;
}

.sr-page.sr-view-map { --sre-map-cols: 2; }

/* Single-column mode: one card needs about half the width two did, so the
   results panel gives up half of its 56% and the map takes it — 28% list,
   72% map. The track list is animated rather than snapped, so the map is
   visibly gaining the space rather than the page re-laying out. */
.sr-page.sr-view-map.sr-map-cols-1 {
    --sre-map-cols: 1;
    --sre-map-w: 72%;
}

.sr-page.sr-view-map .sr-shell {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, var(--sre-map-w, 44%));
    align-items: stretch;
    gap: 0;
    transition: grid-template-columns 460ms cubic-bezier(0.4, 0, 0.2, 1);
}
@media (prefers-reduced-motion: reduce) {
    .sr-page.sr-view-map .sr-shell { transition: none; }
}

.sr-page.sr-view-map .sr-results {
    position: static;
    width: auto;
    /* The results column still carries Bootstrap's .col-md-7. Inside a grid its
       max-width:58.33% resolves against the TRACK, not the page, so the panel
       was capped at 466px of the 798px it had been given and the two-column
       cards came out 191px wide. */
    max-width: none;
    flex: none;
    min-width: 0;
    display: flex;
    flex-direction: column;
    background: var(--sb-bg);
    border: 0;
    border-radius: 0;
    color: var(--sb-text);
    box-shadow: none;
    overflow: visible;
}
.sr-page.sr-view-map .sr-results-inner {
    padding: 0;
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
}

/* The map is the one part that stays still. Sticky rather than fixed so it
   cannot escape the grid column or cover the footer.

   `inset: auto` clears the grid view's off-screen parking (left: -200vw) and
   MUST come before the offset, not after: it is shorthand for all four sides,
   so declared later it wiped the `top` below it. The panel was sticky with
   `top: auto`, which never sticks — the map simply scrolled with the page. */
.sr-page.sr-view-map .sr-map-panel,
.sr-page.sr-view-map .sr-map-panel.hidden {
    display: block;
    inset: auto;
    position: sticky;
    top: var(--sre-header-h);
    align-self: start;
    height: calc(100vh - var(--sre-header-h));
    width: auto;
    opacity: 1;
    pointer-events: auto;
    z-index: 1;
    border: 0;
    border-left: 1px solid var(--sb-border);
    border-radius: 0;
}
.sr-page.sr-view-map .map-view { width: 100%; height: 100%; }

/* Map view is a fixed board, not a long page: the shell is exactly one
   viewport below the header, the map fills its half and never moves, and the
   ONLY thing that scrolls is the results list inside .sr-results-inner.
   Without this the document itself still had a little overhang to scroll, and
   the map rode up with it before the sticky caught — which read as the map
   drifting. Desktop only: below 992px the map becomes a full-screen panel the
   list is toggled against, and the page must scroll normally there. */
@media (min-width: 992px) {
    /* Both elements: the scrolling box is the documentElement, so hiding
       overflow on body alone still left the document with its overhang. */
    html:has(body.sr-body-map),
    body.sr-body-map { overflow: hidden; height: 100%; }
    /* No `overflow` here either, for the same reason as .sr-results below:
       any clipping ancestor becomes the scrollport that .sr-sticky-header's
       `top: 66px` resolves against, which dropped the search menu bar 66px
       into its own panel. The html/body lock already stops the page moving. */
    .sr-page.sr-view-map .sr-shell { height: calc(100vh - var(--sre-header-h)); }
    /* .sr-results is a stretched grid item, so it already has the row's
       height; this just guarantees it when the row is content-sized.

       It must NOT get `overflow: hidden`: that makes it a scroll container, and
       .sr-sticky-header — the bar carrying the view toggle, sort and filters —
       is sticky with `top: 66px`, which then resolves against THIS box instead
       of the viewport and drops the whole menu 66px down its own panel. The
       shell above already clips; the column itself stays visible. */
    .sr-page.sr-view-map .sr-results { height: 100%; min-height: 0; }
    .sr-page.sr-view-map .sr-results-inner {
        flex: 1 1 auto;
        min-height: 0;
        overflow-y: auto;
        overscroll-behavior: contain;   /* the page behind must not take over */
        -webkit-overflow-scrolling: touch;
    }
}

/* Split view keeps the ordinary sticky bar — no floating glass chrome. */
.sr-page.sr-view-map .sr-sticky-header {
    position: sticky;
    left: auto;
    right: auto;
    top: var(--sre-header-h);
    z-index: 6;
    background: var(--sb-bg);
    border-bottom: 1px solid var(--sb-border);
    box-shadow: none;
}

/* Cards go horizontal in the panel: at half width a stacked card gives a
   letterbox photo and a lot of empty column. */
.sr-page.sr-view-map .sr-e-grid {
    grid-template-columns: repeat(var(--sre-map-cols), minmax(0, 1fr));
    gap: 16px;
}
.sr-page.sr-view-map .sr-e-card {
    flex-direction: row;
    gap: 14px;
    padding: 12px;
    border: 1px solid var(--sb-border);
    border-radius: 18px;
    background: var(--sb-surface);
}
.sr-page.sr-view-map .sr-e-card .sr-e-media {
    flex: 0 0 auto;
    width: 148px;
    height: 128px;
    border-radius: 12px;
}
.sr-page.sr-view-map .sr-e-card .sr-e-body {
    min-width: 0;
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 2px 2px 2px 0;
}
.sr-page.sr-view-map .sr-e-card .sr-e-name { font-size: 15px; }
.sr-page.sr-view-map .sr-e-card .sr-e-price { font-size: 16px; }
/* The hairline above the price is for the tall card; horizontally it just
   cuts the body in half. */
.sr-page.sr-view-map .sr-e-card .sr-e-pricerow { border-top: 0; padding-top: 0; margin-top: auto; }

/* Hovering a card lifts its pin, and vice versa — the pairing is the whole
   reason the two halves sit together. */
.sr-page.sr-view-map .sr-e-card.is-active {
    border-color: var(--sb-ink);
    box-shadow: var(--sb-shadow-2);
}

/* Density control: only meaningful in split view. */
.sr-page .sr-e-density { display: none; }
.sr-page.sr-view-map .sr-e-density {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 3px;
    border: 1px solid var(--sb-border);
    border-radius: 999px;
    background: var(--sb-surface);
}
.sr-page .sr-e-dbtn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    border: 0;
    border-radius: 999px;
    background: transparent;
    color: var(--sb-muted);
    cursor: pointer;
}
/* Paired with --sb-ink, which INVERTS at night — a literal white here left the
   pressed glyph white on near-white in dark mode. */
.sr-page .sr-e-dbtn[aria-pressed="true"] { background: var(--sb-ink); color: var(--sb-bg); }
.sr-page .sr-e-dbtn:focus-visible { outline: 2px solid var(--sb-ink); outline-offset: 2px; }

@media (max-width: 1279.98px) {
    /* The toggle has no effect here — the split is already one column — so the
       wider single-column map must not apply either; there is not enough room. */
    .sr-page.sr-view-map,
    .sr-page.sr-view-map.sr-map-cols-1 { --sre-map-w: 40%; --sre-map-cols: 1; }
}
/* Below 992px the split cannot hold two useful halves: the map becomes a
   full-width panel the list is toggled against, which is what the phone board
   shows. */
@media (max-width: 991.98px) {
    .sr-page.sr-view-map .sr-shell { display: block; }
    .sr-page.sr-view-map .sr-map-panel,
    .sr-page.sr-view-map .sr-map-panel.hidden {
        position: fixed;
        inset: var(--sre-header-h) 0 0 0;
        height: auto;
        border-left: 0;
        z-index: 40;
    }
    .sr-page.sr-view-map .sr-e-density { display: none; }
}

/* ==========================================================================
   4. Sticky bar — search pill + chips + view toggle
   ========================================================================== */

/* Sticks BELOW the site nav, not under it. .site-topnav is position:fixed at
   height 66px (common/header.blade.php:8), so a sticky top of 0 parks this bar
   in the 66px the nav already occupies — which cost the search pill its
   LOCATION / CHECK IN / GUEST labels and clipped every filter chip to a bit
   over half its height. Split view has had the right value all along (see
   .sr-view-map below), which is why only the grid looked wrong. */
.sr-page .sr-sticky-header {
    position: sticky;
    top: var(--sre-header-h);
    z-index: 400;
    background: var(--sb-bg);
    border-bottom: 1px solid var(--sb-border);
}

.sr-page .sr-e-bar {
    display: flex;
    align-items: center;
    gap: 18px;
    padding: 18px var(--sre-pad);
    min-height: var(--sre-bar-h);
}

/* ── The search pill: one control for where / dates / guests ─────────────
   The button itself is the `.sr-pill[data-panel="panel-location"]` the view
   binds at 1809, and #panel-location is its sibling inside .sr-pill-wrap —
   so the dropdown opens under it and closes on an outside click exactly as
   the other chips do (the .sr-pill-wrap / .sr-panel contract). */
.sr-page .sr-e-searchwrap {
    position: relative;
    flex: 0 0 560px;
    min-width: 0;
}

/* Three classes deep on purpose: the shared chip shape in this same section
   also matches .sr-pill, and would otherwise win on source order and squash
   the pill to a 40px chip. */
.sr-page .sr-pill.sr-e-searchpill {
    display: flex;
    align-items: center;
    gap: 0;
    width: 100%;
    height: 56px;
    min-height: 56px;
    padding: 0;
    --sre-bw: 1px;
    --sre-bc: var(--sb-border);
    border-radius: var(--sb-r-pill);
    background: var(--sb-surface);
    box-shadow: var(--sb-shadow-1);
    overflow: hidden;
    text-align: left;
    color: var(--sb-text);
    transition: box-shadow var(--sb-dur-fast) var(--sb-ease),
                border-color var(--sb-dur-fast) var(--sb-ease);
}
.sr-page .sr-pill.sr-e-searchpill.panel-open,
.sr-page .sr-pill.sr-e-searchpill:hover { box-shadow: var(--sb-shadow-2); --sre-bc: var(--sb-border-strong); background: var(--sb-surface); }

.sr-page .sr-e-seg {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
    flex: 1 1 0;
    min-width: 0;
    height: 100%;
    justify-content: center;
    padding: 0 20px;
}
.sr-page .sr-e-seg--where  { flex-grow: 1.5; }
.sr-page .sr-e-seg--guests { flex-grow: 0.9; }

.sr-page .sr-e-seg .sr-sb-label {
    display: block;
    max-width: 100%;
    font-family: var(--sb-font-meta);
    font-size: 10px;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    line-height: 1;
    margin: 0;
    color: var(--sb-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
/* 14px, not 15: this is a utility control the eye passes over on the way to the
   results, not a headline. At 15 the location ran the full width of its segment
   and the bar read as the loudest thing on the page. */
.sr-page .sr-e-seg .sr-sb-val {
    display: block;
    max-width: 100%;
    font-size: 14px;
    font-weight: 500;
    line-height: 1.25;
    color: var(--sb-text);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.sr-page .sr-e-seg .sr-sb-val.sr-e-placeholder { color: var(--sb-muted); }
/* The dates + guests summary only appears once the pill collapses to a single
   segment on a phone (section 14). It must be hidden at the SAME specificity as
   the .sr-sb-val rule above — the element carries both classes, so a two-class
   selector loses to that three-class one and the summary showed on desktop,
   under a Location value that already sat beside its own Dates and Guests
   segments. */
.sr-page .sr-e-seg .sr-sb-val.sr-e-segsub {
    display: none;
    font-family: var(--sb-font-meta);
    font-size: 12px;
    font-weight: 400;
    color: var(--sb-muted);
}

.sr-page .sr-e-segrule {
    flex: 0 0 auto;
    width: 1px;
    height: 26px;
    background: var(--sb-border);
}

.sr-page .sr-e-searchgo {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    margin-right: 8px;
    margin-left: 8px;
    border-radius: var(--sb-r-pill);
    background: var(--sb-primary-strong);
    color: #FFFFFF;
    transition: background var(--sb-dur-fast) var(--sb-ease);
}
.sr-page .sr-pill.sr-e-searchpill:hover .sr-e-searchgo { background: var(--sb-primary-hover); }

/* ── Chip rail ──────────────────────────────────────────────────────────── */
.sr-page .sr-filter-bar {
    position: relative;
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 1 1 0;
    min-width: 0;
    margin-left: auto;
    padding: 0;
    border: 0;
    background: transparent;
    justify-content: flex-end;
}
.sr-page .sr-filter-label { display: none; }

.sr-page .sr-filter-scroll {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
    padding: 4px 0;
    overflow-x: auto;
    overflow-y: visible;
    scrollbar-width: none;
    -ms-overflow-style: none;
    -webkit-overflow-scrolling: touch;
    scroll-padding-inline: 16px;
}
.sr-page .sr-filter-scroll::-webkit-scrollbar { display: none; }

/* A gradient over the scroller's trailing edge, so a chip that is cut off
   reads as "there is more" instead of as a rendering fault. It is a painted
   overlay rather than a mask on the scroller itself, because a mask would
   make .sr-filter-scroll the containing block for the position:fixed
   .sr-panel dropdowns nested inside it. */
.sr-page .sr-filter-fade-right {
    display: block;
    position: absolute;
    top: 0;
    bottom: 0;
    right: 0;
    width: 44px;
    pointer-events: none;
    background: linear-gradient(90deg, rgba(255, 253, 251, 0) 0%, var(--sb-bg) 78%);
}
.sr-page.sr-view-map .sr-filter-fade-right { display: none; }

.sr-page #sr-cat-bar {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 0 0 auto;
    padding: 0;
    border: 0;
    background: transparent;
}

/* One chip shape for the category pills, the filter pills and More filters. */
.sr-page .sr-cat-pill,
.sr-page .sr-pill,
.sr-page .sr-e-chip {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex: 0 0 auto;
    height: 40px;
    min-height: 40px;
    padding: 0 16px;
    --sre-bw: 1px;
    --sre-bc: var(--sb-border);
    border-radius: var(--sb-r-pill);
    background: var(--sb-surface);
    color: var(--sb-text);
    font-family: var(--sb-font-body);
    font-size: 14px;
    font-weight: 500;
    letter-spacing: 0;
    line-height: 1;
    white-space: nowrap;
    text-transform: none;
    transition: background var(--sb-dur-fast) var(--sb-ease),
                color var(--sb-dur-fast) var(--sb-ease),
                border-color var(--sb-dur-fast) var(--sb-ease);
}
.sr-page .sr-cat-pill:hover,
.sr-page .sr-pill:hover,
.sr-page .sr-e-chip:hover { --sre-bc: var(--sb-border-strong); background: var(--sb-surface-2); color: var(--sb-text); }

.sr-page .sr-cat-pill.active,
.sr-page .sr-pill.panel-open,
.sr-page .sr-pill.sr-pill-active,
.sr-page .sr-e-chip.is-on {
    background: var(--sb-ink);
    color: var(--sb-bg);
    --sre-bc: var(--sb-ink);
}
.sr-page .sr-cat-pill.active .sr-e-ic,
.sr-page .sr-pill.panel-open .sr-e-ic { color: currentColor; }

.sr-page .sr-pill .sr-pill-chevron,
.sr-page .sr-cat-pill i,
.sr-page .sr-pill i { font-size: 12px; color: inherit; opacity: 0.75; }

.sr-page .sr-pill .sr-pill-dot,
.sr-page .sr-pill-more .sr-pill-dot {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    padding: 0 5px;
    border-radius: var(--sb-r-pill);
    background: var(--sb-primary-strong);
    color: #FFFFFF;
    font-family: var(--sb-font-meta);
    font-size: 11px;
    font-weight: 500;
    top: auto;
    right: auto;
    position: static;
}

.sr-page .sr-e-ic { flex: 0 0 auto; }

.sr-page .sr-e-barrule {
    flex: 0 0 auto;
    width: 1px;
    height: 28px;
    margin: 0 4px;
    background: var(--sb-border);
}

/* ── View toggle (grid ⇄ map). Reuses #sr-view-grid / #sr-view-list so the
   view's own handlers still flip #mapCol and refetch with ignoreMapBounds. ── */
/* The element carries .sr-e-viewtoggle AND the page's old .sr-view-toggle, so
   this is written three classes deep — a plain `.sr-page .sr-view-toggle` rule
   would tie and the old one would win, dissolving the box and letting the
   buttons shrink to a clipped 34px. */
.sr-page .sr-e-viewtoggle.sr-view-toggle,
.sr-page .sr-e-viewtoggle {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 0 0 auto;
    border: 0;
    background: transparent;
    padding: 0;
}

.sr-page .sr-e-vbtn {
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
    gap: 8px;
    width: auto;          /* the old .sr-view-btn pins these to a 32px square */
    height: 44px;
    min-height: 44px;
    padding: 0 16px;
    --sre-bw: 1px;
    --sre-bc: var(--sb-border);
    border-radius: var(--sb-r-pill);
    background: var(--sb-surface);
    color: var(--sb-text);
    font-size: 14px;
    font-weight: 500;
    white-space: nowrap;
    transition: background var(--sb-dur-fast) var(--sb-ease);
}
.sr-page .sr-e-vbtn:hover { background: var(--sb-surface-2); --sre-bc: var(--sb-border-strong); }
.sr-page.sr-view-grid .sr-e-vbtn--grid { display: none; }
.sr-page.sr-view-map  .sr-e-vbtn--map  { display: none; }


/* ==========================================================================
   5. Hero — the place, framed
   ========================================================================== */

.sr-page .sr-e-hero {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 40px;
    padding: 44px var(--sre-pad) 28px;
}

.sr-page .sr-e-heroText {
    display: flex;
    flex-direction: column;
    gap: 12px;
    max-width: 640px;
    min-width: 0;
}

.sr-page .sr-e-eyebrow {
    font-family: var(--sb-font-meta);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    line-height: 1.2;
    color: var(--sb-muted);
}
.sr-page .sr-e-eyebrow:empty { display: none; }

.sr-page .sr-e-title {
    font-family: var(--sb-font-display);
    font-size: 46px;
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.08;
    color: var(--sb-ink);
    text-wrap: balance;
}

.sr-page .sr-e-lede {
    font-family: var(--sb-font-meta);
    font-size: 16px;
    font-weight: 400;
    line-height: 1.55;
    color: var(--sb-muted);
    text-wrap: pretty;
}
.sr-page .sr-e-lede:empty { display: none; }

/* Sort — a native <select> wearing the board's pill, so it stays keyboard and
   screen-reader native. #sr-sort-select keeps its id and its four values. */
.sr-page .sr-e-sort {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    flex: 0 0 auto;
    height: 44px;
    padding: 0 14px 0 16px;
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-r-pill);
    background: var(--sb-surface);
    color: var(--sb-text);
}
.sr-page .sr-e-sort:hover { border-color: var(--sb-border-strong); }
.sr-page .sr-e-sort .sr-e-sortLabel {
    font-family: var(--sb-font-meta);
    font-size: 14px;
    color: var(--sb-muted);
}
.sr-page .sr-e-sort .sr-sort-select {
    appearance: none;
    -webkit-appearance: none;
    height: 42px;
    padding: 0 22px 0 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    background-image: none;
    font-family: var(--sb-font-body);
    font-size: 14px;
    font-weight: 500;
    color: var(--sb-text);
    cursor: pointer;
}
.sr-page .sr-e-sort .sr-e-sortChevron {
    position: absolute;
    right: 14px;
    pointer-events: none;
    color: var(--sb-text);
}


/* ==========================================================================
   6. "Browse by" collection rail
   ========================================================================== */

.sr-page .sr-e-browse {
    display: flex;
    flex-direction: column;
    gap: 14px;
    padding: 0 var(--sre-pad) 34px;
}
.sr-page .sr-e-browseTitle {
    font-size: 15px;
    font-weight: 500;
    color: var(--sb-ink);
}

.sr-page .sr-e-rail {
    display: flex;
    gap: 16px;
    padding: 2px 0;
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
    -webkit-overflow-scrolling: touch;
    scroll-snap-type: x proximity;
}
.sr-page .sr-e-rail::-webkit-scrollbar { display: none; }

.sr-page .sr-e-tile {
    position: relative;
    display: block;
    flex: 0 0 auto;
    width: var(--sre-tile-w);
    height: var(--sre-tile-h);
    border-radius: 16px;
    overflow: hidden;
    color: #FFFFFF;
    scroll-snap-align: start;
    /* No invented photography: each collection gets a warm ground drawn from
       the palette plus its own icon. A tile only ever shows a photograph if a
       real listing supplies one. */
    background:
        radial-gradient(120% 130% at 12% 8%, rgba(255, 255, 255, 0.18) 0%, rgba(255, 255, 255, 0) 55%),
        linear-gradient(145deg, var(--sre-tile-a, #2A2320) 0%, var(--sre-tile-b, #14100E) 100%);
    transition: transform var(--sb-dur) var(--sb-ease-out);
}
.sr-page .sr-e-tile:nth-child(4n + 1) { --sre-tile-a: #3A2D28; --sre-tile-b: #14100E; }
.sr-page .sr-e-tile:nth-child(4n + 2) { --sre-tile-a: #4A2B2C; --sre-tile-b: #1B1210; }
.sr-page .sr-e-tile:nth-child(4n + 3) { --sre-tile-a: #2E3330; --sre-tile-b: #13100F; }
.sr-page .sr-e-tile:nth-child(4n + 4) { --sre-tile-a: #43352A; --sre-tile-b: #17110E; }

.sr-page .sr-e-tile img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
}
.sr-page .sr-e-tileShade {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, rgba(15, 13, 12, 0) 38%, rgba(15, 13, 12, 0.82) 100%);
}
/* Over a gradient the top of the tile is already dark, so the shade can start
   transparent. Over a photograph it cannot: the icon sits at the top-left at
   72% white and would dissolve into a bright sky or a pale wall. .has-photo is
   set by the Blade only when a listing actually supplied a picture. */
.sr-page .sr-e-tile.has-photo .sr-e-tileShade {
    background: linear-gradient(180deg,
        rgba(15, 13, 12, 0.46) 0%,
        rgba(15, 13, 12, 0.10) 40%,
        rgba(15, 13, 12, 0.88) 100%);
}
.sr-page .sr-e-tileIcon {
    position: absolute;
    left: 16px;
    top: 14px;
    color: rgba(255, 255, 255, 0.72);
}
.sr-page .sr-e-tileName {
    position: absolute;
    left: 16px;
    right: 16px;
    bottom: 14px;
    font-size: 15px;
    font-weight: 500;
    color: #FFFFFF;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

@media (hover: hover) and (pointer: fine) {
    .sr-page .sr-e-tile:hover { transform: translateY(-2px); }
}


/* ==========================================================================
   7. Result count row  (#pagination — keeps the id the loader/JS toggle)
   ========================================================================== */

.sr-page .sr-results-meta {
    display: block;
    padding: 0 var(--sre-pad) 20px;
    margin: 0;
    border: 0;
    background: transparent;
}
.sr-page .sr-results-top {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
    padding: 0;
    border: 0;
}
.sr-page .sr-pagination-count {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 8px;
    font-size: 17px;
    font-weight: 500;
    color: var(--sb-ink);
}
.sr-page .sr-e-countCtx {
    font-family: var(--sb-font-meta);
    font-size: 15px;
    font-weight: 400;
    color: var(--sb-muted);
}
.sr-page .sr-results-controls { display: none; }


/* ==========================================================================
   8. The grid and the card
   ========================================================================== */

.sr-page #properties_show { padding: 0 var(--sre-pad) 56px; }

.sr-page .sr-e-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--sre-row-gap) var(--sre-col-gap);
    margin: 0;
}

.sr-page .sr-e-card {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 14px;
    min-width: 0;
    color: var(--sb-text);
}

.sr-page .sr-e-media {
    position: relative;
    display: block;
    width: 100%;
    aspect-ratio: 33 / 20;         /* 413 × 250 at 1440, the board's ratio */
    border-radius: var(--sre-card-radius);
    overflow: hidden;
    background: var(--sb-surface-2);
}
.sr-page .sr-e-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    border-radius: inherit;
    transition: transform var(--sb-dur-slow) var(--sb-ease-out);
}
@media (hover: hover) and (pointer: fine) {
    .sr-page .sr-e-card:hover .sr-e-media img { transform: scale(1.03); }
}

/* Full-card link. Sits under the heart and the badges so both stay clickable. */
.sr-page .sr-e-cardLink {
    position: absolute;
    inset: 0;
    z-index: 2;
    border-radius: var(--sre-card-radius);
}
.sr-page .sr-e-cardLink:focus-visible { outline-offset: -3px; }

.sr-page .sr-e-badges {
    position: absolute;
    left: 14px;
    top: 14px;
    z-index: 3;
    display: flex;
    gap: 6px;
    pointer-events: none;
}
.sr-page .sr-e-badge {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    height: 26px;
    padding: 0 10px;
    border-radius: var(--sb-r-pill);
    background: rgba(255, 255, 255, 0.92);
    color: #14100E;
    font-size: 12px;
    font-weight: 500;
    white-space: nowrap;
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
}
.sr-page .sr-e-badge--ink { background: #14100E; color: #FFFFFF; }

.sr-page .sr-e-heart,
.sr-page .sr-card-heart {
    position: absolute;
    top: 12px;
    right: 12px;
    z-index: 4;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    padding: 0;
    --sre-bw: 0;
    border-radius: var(--sb-r-pill);
    background: rgba(20, 16, 14, 0.42);
    color: #FFFFFF;
    font-size: 15px;
    line-height: 1;
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    transition: background var(--sb-dur-fast) var(--sb-ease),
                transform var(--sb-dur-press) var(--sb-ease);
}
.sr-page .sr-e-heart:hover { background: rgba(20, 16, 14, 0.62); }
.sr-page .sr-e-heart:active { transform: scale(0.94); }
.sr-page .sr-e-heart.liked { color: var(--sb-primary); }
/* A 36px visual on a 44px hit area — the target rule without the bulk. */
.sr-page .sr-e-heart::after {
    content: "";
    position: absolute;
    inset: -4px;
}

.sr-page .sr-e-body {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}

.sr-page .sr-e-metaRow {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    min-width: 0;
}
.sr-page .sr-e-area {
    font-family: var(--sb-font-meta);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--sb-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.sr-page .sr-e-rating {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    flex: 0 0 auto;
    font-size: 13px;
    color: var(--sb-text);
}
.sr-page .sr-e-rating .sr-e-ic { color: var(--sb-primary-strong); }
.sr-page .sr-e-ratingVal { font-weight: 500; }
.sr-page .sr-e-ratingCnt { font-family: var(--sb-font-meta); color: var(--sb-muted); }
.sr-page .sr-e-new { font-family: var(--sb-font-meta); font-size: 13px; color: var(--sb-muted); }

.sr-page .sr-e-name {
    font-family: var(--sb-font-display);
    font-size: 19px;
    font-weight: 500;
    letter-spacing: -0.005em;
    line-height: 1.3;
    color: var(--sb-ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sr-page .sr-e-facts {
    font-family: var(--sb-font-meta);
    font-size: 14px;
    font-weight: 400;
    color: var(--sb-muted);
}

.sr-page .sr-e-priceRow {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;          /* the stay note drops to its own line rather than
                                 running out of a narrow card */
    gap: 2px 10px;
    margin-top: 6px;
    padding-top: 12px;
    border-top: 1px solid var(--sb-border);
}
.sr-page .sr-e-price {
    font-size: 18px;
    font-weight: 700;
    color: var(--sb-ink);
    white-space: nowrap;
}
.sr-page .sr-e-priceUnit {
    font-family: var(--sb-font-meta);
    font-size: 13px;
    font-weight: 400;
    color: var(--sb-muted);
}
.sr-page .sr-e-nights {
    font-family: var(--sb-font-meta);
    font-size: 12px;
    color: var(--sb-muted);
    white-space: nowrap;
}
/* Long form by default; the split panel at two columns takes the short one. */
.sr-page .sr-e-nightsShort { display: none; }
.sr-page.sr-view-map:not(.sr-map-cols-1) .sr-e-rcard .sr-e-nightsLong { display: none; }
.sr-page.sr-view-map:not(.sr-map-cols-1) .sr-e-rcard .sr-e-nightsShort { display: inline; }

/* Card ↔ pin pairing (Map First, and harmless in the grid). */
.sr-page .sr-e-card.is-paired .sr-e-media,
.sr-page .sr-e-rcard.is-paired {
    box-shadow: 0 0 0 2px var(--sb-primary-strong);
}


/* ==========================================================================
   9. Skeletons, empty state, pagination
   ========================================================================== */

.sr-page .sr-e-skel { pointer-events: none; }
.sr-page .sr-e-skelBar,
.sr-page .sr-e-skelMedia {
    background: var(--sb-surface-2);
    border-radius: var(--sb-r-sm);
    position: relative;
    overflow: hidden;
}
.sr-page .sr-e-skelMedia {
    width: 100%;
    aspect-ratio: 33 / 20;
    border-radius: var(--sre-card-radius);
}
.sr-page .sr-e-skelBar { height: 12px; }
.sr-page .sr-e-skelBar--sm   { width: 34%; }
.sr-page .sr-e-skelBar--md   { width: 68%; height: 16px; }
.sr-page .sr-e-skelBar--lg   { width: 52%; }
.sr-page .sr-e-skelMedia::after,
.sr-page .sr-e-skelBar::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(90deg,
        rgba(255, 255, 255, 0) 0%,
        rgba(255, 255, 255, 0.45) 50%,
        rgba(255, 255, 255, 0) 100%);
    transform: translateX(-100%);
    animation: sr-e-shimmer 1400ms var(--sb-ease-in-out) infinite;
}
body.dark-mode .sr-page .sr-e-skelMedia::after,
body.dark-mode .sr-page .sr-e-skelBar::after {
    background: linear-gradient(90deg,
        rgba(255, 255, 255, 0) 0%,
        rgba(255, 255, 255, 0.09) 50%,
        rgba(255, 255, 255, 0) 100%);
}
@keyframes sr-e-shimmer { to { transform: translateX(100%); } }

.sr-page .sr-e-empty {
    grid-column: 1 / -1;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 14px;
    max-width: 560px;
    padding: 48px 0 24px;
}
.sr-page .sr-e-emptyTitle {
    font-family: var(--sb-font-display);
    font-size: 27px;
    font-weight: 700;
    letter-spacing: -0.012em;
    color: var(--sb-ink);
}
.sr-page .sr-e-emptyText {
    font-family: var(--sb-font-meta);
    font-size: 16px;
    line-height: 1.55;
    color: var(--sb-muted);
}
.sr-page .sr-e-emptyFilters {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 2px 0 4px;
    padding: 0;
    list-style: none;
}
.sr-page .sr-e-emptyFilters li {
    display: inline-flex;
    align-items: center;
    height: 30px;
    padding: 0 12px;
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-r-pill);
    background: var(--sb-surface-2);
    font-family: var(--sb-font-meta);
    font-size: 13px;
    color: var(--sb-text);
}
.sr-page .sr-e-emptyClear {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 44px;
    padding: 0 20px;
    --sre-bw: 0;
    border-radius: var(--sb-r-pill);
    background: var(--sb-ink);
    color: var(--sb-bg);
    font-size: 15px;
    font-weight: 500;
}
.sr-page .sr-e-emptyClear:hover { background: var(--sb-ink-soft); }

/* Old empty block, still used by the legacy fallback renderer. */
.sr-page .sr-empty { padding: 48px 0; color: var(--sb-muted); }
.sr-page .sr-empty p { font-family: var(--sb-font-meta); color: var(--sb-muted); }

.sr-page .sr-e-pagerwrap {
    display: flex;
    justify-content: center;
    padding: 0 var(--sre-pad) 64px;
}
.sr-page .sr-e-pagerwrap[hidden] { display: none; }

.sr-page .pager.pagination {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 6px;
    margin: 0;
    padding: 0;
    list-style: none;
}
.sr-page .pager .page-item { margin: 0; }
.sr-page .pager .page-link {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    height: 44px;
    padding: 0 14px;
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-r-pill);
    background: var(--sb-surface);
    color: var(--sb-text);
    font-size: 14px;
    font-weight: 500;
}
.sr-page .pager .page-link:hover { background: var(--sb-surface-2); border-color: var(--sb-border-strong); color: var(--sb-text); }
.sr-page .pager .page-item.active .page-link {
    background: var(--sb-ink);
    border-color: var(--sb-ink);
    color: var(--sb-bg);
}

.sr-page #loader { padding: 24px 0 48px; text-align: center; }
.sr-page #loader.display-off { display: none; }


/* ==========================================================================
   10. Map First — glass rail, rail cards, map chrome
   ========================================================================== */

.sr-page.sr-view-map .sr-e-bar {
    padding: 0 32px;
    min-height: 84px;
    gap: 16px;
}
.sr-page.sr-view-map .sr-e-searchwrap { flex: 0 0 520px; }

/* Every chip in the bar turns to glass over the map. */
.sr-page.sr-view-map .sr-cat-pill,
.sr-page.sr-view-map .sr-pill,
.sr-page.sr-view-map .sr-e-chip,
.sr-page.sr-view-map .sr-e-vbtn,
.sr-page.sr-view-map .sr-pill.sr-e-searchpill {
    background: var(--sre-glass);
    color: var(--sre-glass-ink);
    --sre-bc: var(--sre-glass-line);
    -webkit-backdrop-filter: var(--sre-glass-blur);
    backdrop-filter: var(--sre-glass-blur);
    box-shadow: none;
}
.sr-page.sr-view-map .sr-cat-pill:hover,
.sr-page.sr-view-map .sr-pill:hover,
.sr-page.sr-view-map .sr-e-vbtn:hover { background: var(--sre-glass-strong); color: var(--sre-glass-ink); }
.sr-page.sr-view-map .sr-cat-pill.active,
.sr-page.sr-view-map .sr-pill.panel-open,
.sr-page.sr-view-map .sr-pill.sr-pill-active {
    background: var(--sb-ink);
    color: var(--sb-bg);
    --sre-bc: var(--sb-ink);
}
.sr-page.sr-view-map .sr-e-seg .sr-sb-label { color: var(--sre-glass-muted); }
.sr-page.sr-view-map .sr-e-seg .sr-sb-val { color: var(--sre-glass-ink); }
.sr-page.sr-view-map .sr-e-seg .sr-sb-val.sr-e-placeholder { color: var(--sre-glass-muted); }
.sr-page.sr-view-map .sr-e-segrule { background: var(--sre-glass-line); }
.sr-page.sr-view-map .sr-e-barrule { background: var(--sre-glass-line); }

/* ── Rail head: count + sort, on the glass ─────────────────────────────── */
/* Split view keeps the hero, scaled down to suit a half-width panel. It stays
   a normal flex row: the sort control used to be position:absolute here, so a
   long place name ("Lekki Phase 1, Lekki, Nigeria") ran underneath it. */
.sr-page.sr-view-map .sr-e-hero {
    position: static;
    flex-direction: row;
    align-items: flex-end;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 10px 20px;
    padding: 20px var(--sre-pad-map, 20px) 12px;
}
.sr-page.sr-view-map .sr-e-heroText { max-width: none; gap: 4px; min-width: 0; flex: 1 1 260px; }
.sr-page.sr-view-map .sr-e-eyebrow { display: none; }
.sr-page.sr-view-map .sr-e-title {
    font-size: 21px;
    font-weight: 700;
    letter-spacing: -0.012em;
    line-height: 1.22;
    color: var(--sb-ink);
    text-wrap: balance;
}
.sr-page.sr-view-map .sr-e-lede {
    font-size: 13px;
    line-height: 1.45;
    color: var(--sb-muted);
}
.sr-page.sr-view-map .sr-e-heroAside {
    position: static;
    right: auto;
    top: auto;
    flex: 0 0 auto;
    align-self: flex-end;
}
/* The panel is a light surface now, so the sort control drops the glass fill
   and white text it wore over the full-bleed map. */
.sr-page.sr-view-map .sr-e-sort {
    height: 34px;
    padding: 0 8px 0 12px;
    border-color: var(--sb-border);
    background: var(--sb-surface);
    color: var(--sb-text);
}
.sr-page.sr-view-map .sr-e-sort .sr-e-sortLabel { display: none; }
.sr-page.sr-view-map .sr-e-sort .sr-sort-select { height: 32px; font-size: 13px; color: var(--sb-text); }
.sr-page.sr-view-map .sr-e-sort .sr-sort-select option { color: #14100E; }
.sr-page.sr-view-map .sr-e-sort .sr-e-sortChevron { right: 8px; color: var(--sb-muted); }

/* The collection rail belongs to the grid only. The count row stays — it is
   #pagination, which show_loader()/hide_loader() toggle with inline styles, so
   hiding it here would be overridden anyway. It becomes the rail head's second
   line and carries the rule under it. */
.sr-page.sr-view-map .sr-e-browse { display: none; }

.sr-page.sr-view-map .sr-results-meta {
    padding: 0 20px 16px;
    border-bottom: 1px solid var(--sre-glass-line-2);
}
.sr-page.sr-view-map .sr-pagination-count {
    gap: 6px;
    font-family: var(--sb-font-meta);
    font-size: 13px;
    font-weight: 400;
    color: var(--sre-glass-muted);
}
.sr-page.sr-view-map .sr-pagination-count strong { color: var(--sre-glass-ink); font-weight: 500; }
.sr-page.sr-view-map .sr-e-countCtx { font-size: 13px; color: var(--sre-glass-muted); }

.sr-page.sr-view-map #properties_show { padding: 16px 20px 20px; }
.sr-page.sr-view-map .sr-e-pagerwrap { padding: 0 20px 24px; }
.sr-page.sr-view-map .pager .page-link {
    border-color: var(--sre-glass-border);
    background: var(--sre-glass-card);
    color: var(--sre-glass-ink);
    min-width: 40px;
    height: 40px;
}
.sr-page.sr-view-map .pager .page-item.active .page-link { background: var(--sb-ink); border-color: var(--sb-ink); color: var(--sb-bg); }

/* ── Rail card ─────────────────────────────────────────────────────────── */
.sr-page .sr-e-raillist {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

/* Split view: the rail list IS the results grid. The map-view card template
   (.sr-e-rcard) was written for a 376px rail, so it stacks; beside a map at
   half the page it gets the horizontal shape the Split Map board shows, and
   the column count the visitor picked. */
.sr-page.sr-view-map .sr-e-raillist {
    display: grid;
    grid-template-columns: repeat(var(--sre-map-cols), minmax(0, 1fr));
    gap: 14px;
    align-content: start;
}
.sr-page.sr-view-map .sr-e-rcard {
    flex-direction: row;
    gap: 13px;
    align-items: stretch;
}
.sr-page.sr-view-map .sr-e-rcard .sr-e-media {
    flex: 0 0 auto;
    width: 132px;
    aspect-ratio: auto;
    align-self: stretch;
    min-height: 116px;
    border-radius: 12px;
    overflow: hidden;
}
.sr-page.sr-view-map .sr-e-rcard .sr-e-media img {
    width: 100%; height: 100%; object-fit: cover;
}
.sr-page.sr-view-map .sr-e-rcard .sr-e-body {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 3px;
    padding: 2px 2px 2px 0;
}
.sr-page.sr-view-map .sr-e-rcard .sr-e-name { font-size: 15px; }
.sr-page.sr-view-map .sr-e-rcard .sr-e-price { font-size: 16px; }
/* In the split panel the body is only ~200px across at two columns, so the
   price and the stay note cannot share a line. The note takes its own, and the
   price keeps the emphasis. */
.sr-page.sr-view-map .sr-e-rcard .sr-e-priceRow {
    margin-top: auto;
    justify-content: flex-start;
    align-items: baseline;
}
.sr-page.sr-view-map .sr-e-rcard .sr-e-price { min-width: 0; }
.sr-page.sr-view-map:not(.sr-map-cols-1) .sr-e-rcard .sr-e-nights { flex: 1 0 100%; }
/* One column has room for the taller photograph again. */
.sr-page.sr-view-map.sr-map-cols-1 .sr-e-rcard .sr-e-media { width: 168px; min-height: 132px; }
.sr-page.sr-view-map .sr-e-rcard:hover,
.sr-page.sr-view-map .sr-e-rcard.is-paired { box-shadow: var(--sb-shadow-2); }

/* Pairing has to look different from plain hover, or the two halves of the
   split view read as unrelated widgets. The generic .is-paired rule up in §8 is
   (0,3,0); the two rules above and below it are (0,4,0) and match :hover and
   .is-paired alike — so in the ONE view where pairing matters, a card lit from
   a pin was byte-for-byte identical to a card under the cursor, and the red
   ring never painted. This re-states it above that weight.

   The 2px lift is deliberately half the pin's 4px: the pin is what the eye is
   on, the card is the confirmation. */
.sr-page.sr-view-map .sr-e-rcard.is-paired {
    box-shadow: 0 0 0 2px var(--sb-primary-strong), var(--sb-shadow-2);
    transform: translateY(-2px);
}

.sr-page .sr-e-rcard {
    position: relative;
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 12px;
    border: 1px solid var(--sre-glass-border);
    border-radius: 18px;
    background: var(--sre-glass-card);
    color: var(--sre-glass-ink);
    transition: border-color var(--sb-dur-fast) var(--sb-ease),
                box-shadow var(--sb-dur-fast) var(--sb-ease),
                transform var(--sb-dur-fast) var(--sb-ease);
}
.sr-page .sr-e-rcard:hover,
.sr-page .sr-e-rcard.is-paired { border-color: var(--sre-glass-ink); }

.sr-page .sr-e-rcard .sr-e-media { aspect-ratio: 2 / 1; border-radius: 12px; background: var(--sre-glass-fill); }
.sr-page .sr-e-rcard .sr-e-body { gap: 4px; padding: 0 4px 4px; }
.sr-page .sr-e-rcard .sr-e-area { text-transform: none; letter-spacing: 0; font-size: 12px; color: var(--sre-glass-muted); }
.sr-page .sr-e-rcard .sr-e-name { font-size: 16px; color: var(--sre-glass-ink); }
.sr-page .sr-e-rcard .sr-e-facts { font-size: 13px; color: var(--sre-glass-muted); }
.sr-page .sr-e-rcard .sr-e-rating { color: var(--sre-glass-ink); }
.sr-page .sr-e-rcard .sr-e-ratingCnt,
.sr-page .sr-e-rcard .sr-e-new { color: var(--sre-glass-muted); }
.sr-page .sr-e-rcard .sr-e-priceRow { margin-top: 6px; padding-top: 0; border-top: 0; }
.sr-page .sr-e-rcard .sr-e-price { font-size: 17px; color: var(--sre-glass-ink); }
.sr-page .sr-e-rcard .sr-e-priceUnit,
.sr-page .sr-e-rcard .sr-e-nights { color: var(--sre-glass-muted); }
.sr-page .sr-e-rcard .sr-e-skelMedia { aspect-ratio: 2 / 1; background: var(--sre-glass-fill); }
.sr-page .sr-e-rcard .sr-e-skelBar { background: var(--sre-glass-fill); }

.sr-page.sr-view-map .sr-e-empty { color: var(--sb-text); padding: 24px 0; }
.sr-page.sr-view-map .sr-e-emptyTitle { color: var(--sre-glass-ink); font-size: 21px; }
.sr-page.sr-view-map .sr-e-emptyText { color: var(--sre-glass-muted); font-size: 14px; }
.sr-page.sr-view-map .sr-e-emptyFilters li {
    background: var(--sre-glass-card);
    border-color: var(--sre-glass-border);
    color: var(--sb-text);
}
.sr-page.sr-view-map .sr-e-emptyClear { background: var(--sb-ink); color: var(--sb-bg); }

/* ── Filter strip scroll arrows ─────────────────────────────────────────────
   See the markup for why these exist. They sit on top of the fade, are only
   rendered when there is overflow in that direction, and never appear on touch
   where swiping already works. */
.sr-page .sr-filter-bar { position: relative; }

.sr-page .sr-filter-arrow {
    position: absolute;
    top: 50%;
    z-index: 3;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    justify-content: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 1px solid var(--sb-border);
    border-radius: 50%;
    background: var(--sb-surface);
    color: var(--sb-text);
    box-shadow: var(--sb-shadow-1);
    cursor: pointer;
    transition: background 160ms var(--sb-ease-out), transform 160ms var(--sb-ease-out);
}
.sr-page .sr-filter-arrow:hover { background: var(--sb-surface-2); }
.sr-page .sr-filter-arrow:active { transform: translateY(-50%) scale(0.92); }
.sr-page .sr-filter-arrow[hidden] { display: none; }
.sr-page .sr-filter-arrow--l { left: -6px; }
.sr-page .sr-filter-arrow--r { right: -6px; }

/* A left arrow needs a fade to sit on, the same as the right one has. */
.sr-page .sr-filter-bar::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: 44px;
    z-index: 2;
    pointer-events: none;
    opacity: 0;
    background: linear-gradient(to left, transparent, var(--sb-bg));
    transition: opacity 160ms var(--sb-ease-out);
}
.sr-page .sr-filter-bar.is-scrolled::before { opacity: 1; }

@media (hover: none) {
    /* Swiping already works; an arrow would just cover a chip. */
    .sr-page .sr-filter-arrow { display: none !important; }
}

/* ── The price pins ─────────────────────────────────────────────────────────
   Real DOM, rendered by the OverlayView in js/search-redesign.js §9b. The old
   pins were data-URI SVG images on google.maps.Marker: Arial (a data-URI SVG
   cannot load a webfont), a hardcoded red, no hover beyond swapping the whole
   picture, no focus ring, and no way to animate anything.

   TWO TRANSFORM LAYERS, and the split is load-bearing:
     .sr-pin        position only, written by draw() on every frame of a pan.
                    It must NEVER carry a transition — one here makes every pin
                    lag the map and float free of the ground it is pinning.
     .sr-pin-inner  everything else. All state, all motion, owned by CSS. */

.sr-pinlayer {
    position: absolute;
    inset: 0;
    /* The root must not take pointer events or it swallows map drags — and
       with them the dragend refetch. Only the pins themselves are live. */
    pointer-events: none;
}

.sr-page .sr-pin {
    position: absolute;
    top: 0;
    left: 0;
    width: 0;
    height: 0;
    padding: 0;
    border: 0;
    background: none;
    pointer-events: auto;
    cursor: pointer;
    /* No transition. See above. */
}

.sr-page .sr-pin-inner {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    height: 32px;
    padding: 0 12px;
    transform: translate(-50%, -100%);
    transform-origin: 50% 100%;
    border-radius: var(--sb-r-pill);
    background: var(--sb-primary-strong);
    color: #FFFFFF;
    box-shadow: var(--sb-shadow-1);
    font-family: var(--sb-font-body);
    font-size: 13px;
    font-weight: 500;              /* Ubuntu 500 is loaded; 600 is not */
    line-height: 1;
    white-space: nowrap;
    transition: background 180ms var(--sb-ease-out),
                color 180ms var(--sb-ease-out),
                box-shadow 180ms var(--sb-ease-out),
                transform 180ms var(--sb-ease-out);
}

/* The tail, inheriting the parent's background so both states stay in step. */
.sr-page .sr-pin-inner::after {
    content: "";
    position: absolute;
    left: 50%;
    bottom: -3px;
    width: 10px;
    height: 10px;
    transform: translateX(-50%) rotate(45deg);
    border-radius: 2px;
    background: inherit;
    box-shadow: inherit;
    z-index: -1;
}

/* Hover, keyboard focus and card-pairing all share one treatment: invert, lift,
   and come to the front. z-index is free now that pins are DOM — the old
   setZIndex(12) dance is gone. */
.sr-page .sr-pin:hover,
.sr-page .sr-pin:focus-visible,
.sr-page .sr-pin.is-active { z-index: 40; }

.sr-page .sr-pin:hover .sr-pin-inner,
.sr-page .sr-pin:focus-visible .sr-pin-inner,
.sr-page .sr-pin.is-active .sr-pin-inner {
    background: var(--sb-surface);
    color: var(--sb-primary-strong);
    box-shadow: 0 0 0 2px var(--sb-primary-strong), var(--sb-shadow-2);
    transform: translate(-50%, -100%) translateY(-4px) scale(1.08);
}
.sr-page .sr-pin:active .sr-pin-inner {
    transform: translate(-50%, -100%) translateY(-4px) scale(0.96);
}
.sr-page .sr-pin:focus-visible {
    outline: 3px solid var(--sb-focus);
    outline-offset: 2px;
    border-radius: var(--sb-r-pill);
}

/* Entrance — only for pins whose listing was not already on the map. A survivor
   moves; it does not reintroduce itself. The delay comes from JS, sorted by
   screen position so the sweep reads top-to-bottom like the results rail. */
@keyframes sr-pin-in {
    0%   { opacity: 0; transform: translate(-50%, -100%) translateY(-14px) scale(0.72); }
    62%  { opacity: 1; transform: translate(-50%, -100%) translateY(2px)   scale(1.04); }
    100% { opacity: 1; transform: translate(-50%, -100%) translateY(0)     scale(1); }
}
@keyframes sr-pin-out {
    to { opacity: 0; transform: translate(-50%, -100%) scale(0.82); }
}
.sr-page .sr-pin.is-new .sr-pin-inner {
    animation: sr-pin-in 420ms var(--sb-ease-out) both;
    animation-delay: var(--sr-pin-delay, 0ms);
}
.sr-page .sr-pin.is-out { pointer-events: none; }
.sr-page .sr-pin.is-out .sr-pin-inner {
    animation: sr-pin-out 160ms var(--sb-ease-out) both;
}

/* Reduced motion keeps every STATE — the inverted active pin, the ring, the
   pairing — and drops only the movement. */
@media (prefers-reduced-motion: reduce) {
    .sr-page .sr-pin,
    .sr-page .sr-pin-inner {
        transition: none;
        animation: none;
        animation-delay: 0s !important;
    }
    .sr-page .sr-pin:hover .sr-pin-inner,
    .sr-page .sr-pin:focus-visible .sr-pin-inner,
    .sr-page .sr-pin.is-active .sr-pin-inner {
        transform: translate(-50%, -100%);
    }
}

/* ── Map furniture ──────────────────────────────────────────────────────────
   One dock, one switch, one veil — all inside #mapCol, all built from design
   tokens. Google's own zoom cluster and camera pad are turned off in
   js/search-redesign.js, so nothing here competes with them.

   The old chrome floated in .sr-shell and centred itself with
   `calc(32px + var(--sre-rail-w) + …)` — an arithmetic left over from the
   abandoned full-bleed "Map First" layout whose 376px rail no longer exists.
   Against the split view's 44% map track that put the note ~195px left of
   centre. Everything below positions against #mapCol instead, so the map's own
   box is the reference and the maths disappears. */

.sr-map-veil {
    position: absolute;
    inset: 0;
    z-index: 4;
    pointer-events: none;          /* MANDATORY — otherwise it eats every drag */
    opacity: 0;
    background: var(--sb-bg);
    transition: opacity 320ms var(--sb-ease-out);
}

/* ── The dock ── */
.sr-page .sr-mapdock {
    position: absolute;
    right: 16px;
    bottom: 32px;                  /* clears Google's attribution strip */
    z-index: 6;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
}
.sr-page .sr-mapdock-grp {
    display: flex;
    flex-direction: column;
    border-radius: var(--sb-r-md);
    overflow: hidden;
    box-shadow: var(--sb-shadow-2);
}
.sr-page .sr-mapdock-grp .sr-mapdock-btn {
    border-radius: 0;
    box-shadow: none;
}
.sr-page .sr-mapdock-grp .sr-mapdock-btn + .sr-mapdock-btn {
    border-top: 1px solid var(--sb-border);
}
.sr-page .sr-mapdock-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    padding: 0;
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-r-md);
    background: var(--sb-surface);
    color: var(--sb-text);
    box-shadow: var(--sb-shadow-2);
    cursor: pointer;
    transition: background 180ms var(--sb-ease-out),
                color 180ms var(--sb-ease-out),
                transform 180ms var(--sb-ease-out);
}
.sr-page .sr-mapdock-btn:hover { background: var(--sb-surface-2); }
.sr-page .sr-mapdock-btn:active { transform: scale(0.94); }

/* The close button keeps its id — view:2134 and js:555 both bind the view state
   to it — but has moved into the dock. The legacy stylesheet still pins
   .sr-map-close to position:absolute; top:12px; left:12px, which pulled it out
   of the flex column and dropped it on top of the zoom group. */
.sr-page .sr-mapdock .sr-map-close {
    position: static;
    top: auto;
    left: auto;
    right: auto;
    width: 44px;
    height: 44px;
    z-index: auto;
}

/* ── "Search as I move the map", now a real switch ── */
.sr-page .sr-e-mapnote {
    position: absolute;
    left: 50%;
    top: 16px;
    z-index: 6;
    transform: translateX(-50%);
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 42px;
    padding: 0 18px;
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-r-pill);
    background: var(--sb-surface);
    color: var(--sb-text);
    box-shadow: var(--sb-shadow-2);
    font-family: var(--sb-font-body);
    font-size: 14px;
    font-weight: 500;
    white-space: nowrap;
    cursor: pointer;
    transition: background 180ms var(--sb-ease-out), color 180ms var(--sb-ease-out);
}
.sr-page .sr-e-mapnote:hover { background: var(--sb-surface-2); }
.sr-page .sr-e-mapnote .sr-e-ic { color: var(--sb-success); }
/* Off: the tick goes quiet and the label stops claiming something is happening. */
.sr-page .sr-e-mapnote[aria-pressed="false"] { color: var(--sb-muted); }
.sr-page .sr-e-mapnote[aria-pressed="false"] .sr-e-ic { color: var(--sb-muted-2); opacity: 0.5; }
.sr-page.sr-view-grid .sr-e-mapnote { display: none; }

/* ── "Search this area", shown only while the switch is off ── */
.sr-page .sr-map-redo {
    position: absolute;
    left: 50%;
    top: 68px;
    z-index: 6;
    transform: translateX(-50%);
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 40px;
    padding: 0 18px;
    border: 0;
    border-radius: var(--sb-r-pill);
    background: var(--sb-ink);
    color: var(--sb-bg);
    box-shadow: var(--sb-shadow-2);
    font-family: var(--sb-font-body);
    font-size: 14px;
    font-weight: 500;
    white-space: nowrap;
    cursor: pointer;
    animation: sr-dock-in 240ms var(--sb-ease-out) both;
}
.sr-page .sr-map-redo[hidden] { display: none; }
.sr-page.sr-view-grid .sr-map-redo { display: none; }

/* Entering map view, the furniture arrives rather than being simply present. */
@keyframes sr-dock-in {
    from { opacity: 0; transform: translateY(8px) translateX(-50%); }
    to   { opacity: 1; transform: translateY(0)   translateX(-50%); }
}
@keyframes sr-dock-in-plain {
    from { opacity: 0; transform: translateY(8px); }
    to   { opacity: 1; transform: translateY(0); }
}
.sr-page.sr-view-map .sr-e-mapnote { animation: sr-dock-in 240ms var(--sb-ease-out) both; }
.sr-page.sr-view-map .sr-mapdock-grp { animation: sr-dock-in-plain 240ms 40ms var(--sb-ease-out) both; }
.sr-page.sr-view-map #srRecentre    { animation: sr-dock-in-plain 240ms 80ms var(--sb-ease-out) both; }
.sr-page.sr-view-map #closeMap      { animation: sr-dock-in-plain 240ms 120ms var(--sb-ease-out) both; }

/* Dark: --sb-surface (#1A1614) on midnight's #14100E ground is nearly invisible,
   so the dock steps up a surface and takes the stronger border. */
body.dark-mode .sr-page .sr-mapdock-btn,
body.dark-mode .sr-page .sr-e-mapnote {
    background: var(--sb-surface-2);
    border-color: var(--sb-border-strong);
    color: var(--sb-text);
}
body.dark-mode .sr-page .sr-mapdock-btn:hover,
body.dark-mode .sr-page .sr-e-mapnote:hover { background: var(--sb-surface-3); }
body.dark-mode .sr-page .sr-mapdock-grp .sr-mapdock-btn + .sr-mapdock-btn { border-top-color: var(--sb-border-strong); }

/* Google's own chrome. js/search-redesign.js turns every control off in favour
   of .sr-mapdock, and this is the belt to those braces.

   Worth keeping even though the options currently do the job: the Maps loader
   pins no `v=`, so it tracks the weekly channel, and an unrecognised
   MapOptions key is silently IGNORED rather than throwing. The day Google
   renames or adds a control, the option stops working with no error and the
   furniture reappears on top of the dock. Hiding by class survives that.

   Not .gmnoprint on its own — that class is also on the attribution strip,
   which must never be covered. */
.sr-page.sr-view-map .gm-fullscreen-control,
.sr-page.sr-view-map .gm-bundled-control,
.sr-page.sr-view-map .gm-bundled-control-on-bottom,
.sr-page.sr-view-map .gm-svpc,
.sr-page.sr-view-map .gm-style-mtc { display: none !important; }
.sr-page.sr-view-map .gm-style-cc,
.sr-page.sr-view-map .gmnoprint { z-index: 2; }


/* ==========================================================================
   11. #map-hover-card — appended to <body>, so no .sr-page prefix is possible
   ========================================================================== */

/* The card is a child of <body>, so it sits outside .sb-page and NONE of the
   design tokens reach it — nor does the page's reduced-motion block, which is
   scoped to `.sr-page *, .sr-overlays *`. Writing var(--sb-ease-out) here
   resolves to nothing and the whole declaration is dropped as invalid.

   So the tokens are re-declared ON THE CARD. That is a component redeclaring
   what it needs, not a write to :root. */
body #map-hover-card {
    --sb-ink:            #1A1614;
    --sb-muted:          #6B615A;
    --sb-surface:        #FFFFFF;
    --sb-primary-strong: #C8262B;
    --sb-star:           #B4761A;
    --sb-ease-out:       cubic-bezier(.23, 1, .32, 1);

    font-family: var(--sb-font-body, "Ubuntu", system-ui, sans-serif);
    background: var(--sb-surface);
    color: var(--sb-ink);
    border-radius: 16px;
    box-shadow: 0 8px 20px rgba(20, 16, 14, 0.18), 0 28px 60px rgba(20, 16, 14, 0.22);
    overflow: hidden;

    /* Visibility used to be display:none, which is why the inline
       `transition:opacity .12s` on this element had never once run — display
       is not animatable. */
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transform: translateY(6px);
    transform-origin: 50% 100%;      /* grows out of the pin tip */
    transition: opacity 160ms var(--sb-ease-out),
                transform 160ms var(--sb-ease-out),
                visibility 0s linear 160ms;
}
body #map-hover-card.is-below { transform-origin: 50% 0; transform: translateY(-6px); }

body #map-hover-card.is-in {
    opacity: 1;
    visibility: visible;
    pointer-events: auto;            /* or the invisible card eats clicks */
    transform: translateY(0);
    transition: opacity 160ms var(--sb-ease-out),
                transform 160ms var(--sb-ease-out),
                visibility 0s;
}
/* Exit is quicker and does not shrink — leaving should not draw the eye. */
body #map-hover-card:not(.is-in) { transition-duration: 120ms, 120ms, 0s; }

/* Laid out off-screen for one frame while its height is measured. */
body #map-hover-card.is-measuring { visibility: hidden; opacity: 0; }

body #map-hover-card .sr-hc-title {
    font-size: 13px;
    font-weight: 700;
    color: var(--sb-ink);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-bottom: 3px;
}
body #map-hover-card .sr-hc-addr {
    font-size: 11px;
    color: var(--sb-muted);
    margin-bottom: 6px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
body #map-hover-card .sr-hc-pin { color: var(--sb-primary-strong); font-size: 10px; }
body #map-hover-card .sr-hc-price { font-size: 13px; font-weight: 700; color: var(--sb-primary-strong); }
body #map-hover-card .sr-hc-unit { font-size: 11px; font-weight: 400; color: var(--sb-muted); }
body #map-hover-card .sr-hc-rating { font-size: 12px; color: var(--sb-star); margin-right: 6px; }
body #map-hover-card .sr-hc-badge {
    position: absolute;
    bottom: 8px;
    right: 8px;
    background: rgba(20, 16, 14, 0.62);
    color: #FFFFFF;
    font-size: 13px;
    font-weight: 700;
    padding: 3px 9px;
    border-radius: 20px;
}

body.dark-mode #map-hover-card {
    --sb-ink:            #F5F0EB;
    --sb-muted:          #A99E95;
    --sb-surface:        #1A1614;
    --sb-primary-strong: #FF8A8D;    /* the lifted red; #C8262B is 3.86:1 here */
    --sb-star:           #FBBF24;
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.5), 0 28px 60px rgba(0, 0, 0, 0.55);
}

/* Its own guard: the page's reduced-motion block cannot reach this element. */
@media (prefers-reduced-motion: reduce) {
    body #map-hover-card,
    body #map-hover-card * { transition: none !important; animation: none !important; }
    body #map-hover-card { transform: none; }
}


/* ==========================================================================
   12. Filter panels, More-filters modal, toast, confirm — restyled, not moved
   ========================================================================== */

.sr-page .sr-panel,
.sr-overlays .sr-panel {
    border-radius: var(--sb-r-lg);
    border: 1px solid var(--sb-border);
    background: var(--sb-surface);
    box-shadow: var(--sb-shadow-3);
    font-family: var(--sb-font-body);
    color: var(--sb-text);
}
.sr-page .sr-panel-title {
    font-family: var(--sb-font-display);
    font-size: 15px;
    font-weight: 500;
    letter-spacing: 0;
    text-transform: none;
    color: var(--sb-ink);
}
.sr-page .sr-panel .sr-input,
.sr-overlays .sr-input {
    height: 48px;
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-r-md);
    background: var(--sb-surface);
    font-family: var(--sb-font-body);
    font-size: 15px;
    color: var(--sb-text);
}
.sr-page .sr-panel .sr-input:focus { border-color: var(--sb-border-strong); box-shadow: 0 0 0 4px var(--sb-primary-ring); }

/* ── The guest row is a field too ───────────────────────────────────────────
   The view styles it from the legacy palette — #f9fafb on #e5e7eb by day,
   #0f172a on #334155 at night — while the two fields above it were brought
   onto the design system in the rule just above. That left a cool grey box
   sitting between two warm ones, and after dark a navy one between two warm
   browns, three pixels shorter and on a tighter radius. Built like the others
   here: same height, border, radius and ground, so the three read as one set.
   ------------------------------------------------------------------------ */
.sr-page .sr-panel .sr-guest-stepper {
    min-height: 48px;
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-r-md);
    background: var(--sb-surface);
    padding: 6px 10px 6px 14px;
}
body.dark-mode .sr-page .sr-panel .sr-guest-stepper {
    background: var(--sb-surface);
    border-color: var(--sb-border);
}

/* "Guests" is this field's value, the way "lekki phase 1" is the one above's,
   so it takes that field's size, weight and colour instead of a heavier 14/500
   that read as a heading rather than as something you had filled in. */
.sr-page .sr-panel .sr-guest-label {
    font-family: var(--sb-font-body);
    font-size: 15px;
    font-weight: 400;
    color: var(--sb-text);
}
.sr-page .sr-panel .sr-guest-label i { color: var(--sb-muted); }
.sr-page .sr-panel .sr-guest-count {
    font-family: var(--sb-font-body);
    font-size: 15px;
    font-weight: 500;
    color: var(--sb-text);
}

/* The steppers keep their circle; only the palette changes. */
.sr-page .sr-panel .sr-guest-btn {
    border: 1px solid var(--sb-border-strong);
    background: var(--sb-surface);
    color: var(--sb-ink);
}
body.dark-mode .sr-page .sr-panel .sr-guest-btn {
    background: var(--sb-surface-2);
    border-color: var(--sb-border-strong);
    color: var(--sb-ink);
}
.sr-page .sr-panel .sr-guest-btn:hover,
body.dark-mode .sr-page .sr-panel .sr-guest-btn:hover {
    border-color: var(--sb-ink);
    background: var(--sb-surface-2);
}
.sr-page .sr-date-label {
    font-family: var(--sb-font-meta);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--sb-muted);
}

.sr-page .sr-btn-apply,
.sr-overlays .sr-btn-apply {
    min-height: 44px;
    padding: 0 20px;
    border: 0;
    border-radius: var(--sb-r-pill);
    background: var(--sb-primary-strong);
    color: #FFFFFF;
    font-family: var(--sb-font-body);
    font-size: 15px;
    font-weight: 500;
}
.sr-page .sr-btn-apply:hover,
.sr-overlays .sr-btn-apply:hover { background: var(--sb-primary-hover); }
.sr-page .sr-btn-clear,
.sr-overlays .sr-btn-clear {
    min-height: 44px;
    padding: 0 18px;
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-r-pill);
    background: var(--sb-surface);
    color: var(--sb-text);
    font-family: var(--sb-font-body);
    font-size: 15px;
    font-weight: 500;
}
.sr-page .sr-btn-clear:hover,
.sr-overlays .sr-btn-clear:hover { background: var(--sb-surface-2); }

.sr-overlays .sr-modal {
    border-radius: var(--sb-r-xl);
    border: 1px solid var(--sb-border);
    background: var(--sb-surface);
    box-shadow: var(--sb-shadow-3);
    font-family: var(--sb-font-body);
    color: var(--sb-text);
}
.sr-overlays .sr-modal-head h3 {
    font-family: var(--sb-font-display);
    font-size: 21px;
    font-weight: 700;
    letter-spacing: -0.012em;
    color: var(--sb-ink);
}
.sr-overlays .sr-modal-head,
.sr-overlays .sr-modal-footer { border-color: var(--sb-border); }
.sr-overlays .sr-modal-close-btn {
    width: 44px;
    height: 44px;
    border: 0;
    border-radius: var(--sb-r-pill);
    background: var(--sb-surface-2);
    color: var(--sb-text);
}
.sr-overlays .sr-section-title {
    font-family: var(--sb-font-meta);
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--sb-muted);
}
.sr-overlays .sr-amenity-check,
.sr-overlays .sr-check-item,
.sr-page .sr-check-item {
    min-height: 44px;
    font-family: var(--sb-font-body);
    font-size: 15px;
    color: var(--sb-text);
}
.sr-overlays .sr-select,
.sr-page .sr-select {
    height: 48px;
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-r-md);
    background-color: var(--sb-surface);
    font-family: var(--sb-font-body);
    font-size: 15px;
    color: var(--sb-text);
}
.sr-overlays .sr-show-more-btn {
    min-height: 44px;
    border: 0;
    background: transparent;
    font-family: var(--sb-font-body);
    font-size: 14px;
    font-weight: 500;
    color: var(--sb-primary-strong);
}

.sr-overlays .sr-confirm-box,
/* The toast is a CARD, and a card needs an edge. Without one it is
   --sb-surface on --sb-bg, which at night is #1A1614 on #0F0D0C — 1.08:1, so
   the text appeared to float on the page with nothing behind it, and the black
   drop shadow had nothing to fall on. */
.sr-overlays #sr-toast {
    border-radius: var(--sb-r-lg);
    background: var(--sb-surface);
    border: 1px solid var(--sb-border);
    box-shadow: var(--sb-shadow-3);
    font-family: var(--sb-font-body);
    color: var(--sb-text);
    /* The disc is 32px and a one-line message is 22px, so aligning to the top
       left the text sitting 5px above the disc's centre. These two sit side by
       side — centre them on each other. */
    align-items: center;
}

/* Status colours from the tokens, so they invert at night with everything
   else. They were hard-coded light-mode pinks: a bright #FDE8E8 disc on a
   near-black card, and a dark red tick on a SUCCESS message, which read as an
   error. The plain colour is the fallback for browsers without color-mix. */
/* Font Awesome's own `.fas` rule sets `display:inline-block; line-height:1`
   at the same weight as the base `.sr-toast-icon`, and won on source order —
   so the disc was not a flex container at all and the glyph sat in its
   top-left corner instead of its middle. Restated here, above FA. */
.sr-overlays #sr-toast .sr-toast-icon {
    display: flex;
    align-items: center;
    justify-content: center;
    line-height: 1;
    background: var(--sb-surface-3);
    color: var(--sb-text);
}

.sr-overlays #sr-toast.success .sr-toast-icon {
    background: var(--sb-surface-3);
    background: color-mix(in srgb, var(--sb-success) 18%, transparent);
    color: var(--sb-success);
}
.sr-overlays #sr-toast.error .sr-toast-icon {
    background: var(--sb-surface-3);
    background: color-mix(in srgb, var(--sb-error) 18%, transparent);
    color: var(--sb-error);
}
.sr-overlays #sr-toast.info .sr-toast-icon {
    background: var(--sb-surface-3);
    background: color-mix(in srgb, var(--sb-primary) 18%, transparent);
    color: var(--sb-primary-strong);
}
.sr-overlays .sr-confirm-title { font-family: var(--sb-font-display); color: var(--sb-ink); }
.sr-overlays .sr-confirm-sub,
.sr-overlays .sr-toast-sub { font-family: var(--sb-font-meta); color: var(--sb-muted); }
.sr-overlays .sr-confirm-yes {
    min-height: 44px;
    border: 0;
    border-radius: var(--sb-r-pill);
    background: var(--sb-primary-strong);
    color: #FFFFFF;
}
.sr-overlays .sr-confirm-no {
    min-height: 44px;
    border: 1px solid var(--sb-border);
    border-radius: var(--sb-r-pill);
    background: var(--sb-surface);
    color: var(--sb-text);
}


/* ==========================================================================
   13. Mobile "Show map" button  (#showMap — the view's own handler flips the
       map; this file only gives it the board's shape)
   ========================================================================== */

.sr-page .sr-e-fab {
    position: fixed;
    left: 50%;
    bottom: calc(62px + 22px + env(safe-area-inset-bottom, 0px));
    z-index: 1030;
    transform: translateX(-50%);
    display: none;
    align-items: center;
    gap: 9px;
    height: 48px;
    padding: 0 22px;
    border: 0;
    border-radius: var(--sb-r-pill);
    background: var(--sb-ink);
    color: var(--sb-bg);
    font-family: var(--sb-font-body);
    font-size: 15px;
    font-weight: 500;
    box-shadow: var(--sb-shadow-3);
}
.sr-page .sr-e-fab:hover { background: var(--sb-ink-soft); color: var(--sb-bg); }


/* ==========================================================================
   14. Responsive
   ========================================================================== */

/* ── 1280–1439: keep three up, tighten the gutter ──────────────────────── */
@media (max-width: 1439.98px) {
    .sr-page.sb-page { --sre-pad: 48px; }
    .sr-page .sr-e-title { font-size: 40px; }
}

/* ── 992–1279: two up ─────────────────────────────────────────────────── */
@media (max-width: 1279.98px) {
    .sr-page.sb-page { --sre-pad: 40px; }
    .sr-page .sr-e-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .sr-page .sr-e-searchwrap { flex-basis: 420px; }
    .sr-page .sr-e-title { font-size: 36px; }
    .sr-page .sr-e-hero { padding-top: 36px; }
}

/* ── Below 992: one up. 992 is the site's own switch (the header goes to its
   54px mobile bar and .pub-mob-nav appears), so the page follows it here
   rather than at the old 768 — that is what left the 769–991 band in a
   desktop shell under a mobile header. ─────────────────────────────────── */
@media (max-width: 991.98px) {
    .sr-page.sb-page { --sre-pad: 16px; --sre-header-h: 54px; }

    .sr-page .sr-shell {
        display: block;
        height: auto;
        min-height: 0;
        overflow: visible;
    }
    .sr-page .sr-results { display: block; }
    .sr-page .sr-results-inner {
        display: block;
        overflow: visible;
        min-height: 0;
        padding: 0;
    }

    .sr-page .sr-e-bar {
        flex-direction: column;
        align-items: stretch;
        gap: 12px;
        padding: 10px 16px 14px;
        min-height: 0;
    }
    .sr-page .sr-e-searchwrap { flex: 0 0 auto; width: 100%; }
    .sr-page .sr-pill.sr-e-searchpill { height: 48px; min-height: 48px; }
    .sr-page .sr-e-seg { padding: 0 16px; gap: 1px; }
    /* Three lines share a 48px pill on a phone — label, the place, then dates and
       guests underneath. At 10/14/12 they filled it edge to edge with nothing
       between them, which is what made the bar look cramped. A point off each
       gives the stack room to breathe without losing legibility. */
    /* line-height 1.25, not 1: the label span is overflow:hidden and Poppins'
       ascenders and descenders clip at a line box equal to the font size
       (measured scrollHeight > clientHeight). The pill has the room. */
    .sr-page .sr-e-seg .sr-sb-label { font-size: 10px; letter-spacing: 0.10em; line-height: 1.25; }
    .sr-page .sr-e-seg .sr-sb-val { font-size: 13px; line-height: 1.25; }
    .sr-page .sr-e-searchgo { width: 40px; height: 40px; }
    /* Dates and guests collapse into the "where" line on a phone, exactly as
       the mobile board shows: one pill, query on top, context underneath. */
    .sr-page .sr-e-seg--dates,
    .sr-page .sr-e-seg--guests,
    .sr-page .sr-e-segrule { display: none; }
    .sr-page .sr-e-seg--where { flex-grow: 1; }
    /* Same specificity as the desktop hide, or this never takes effect. */
    .sr-page .sr-e-seg .sr-sb-val.sr-e-segsub { display: block; font-size: 11px; line-height: 1.3; }

    /* The pill bar used to vanish below 768px, which also took More Filters
       with it — the only way into amenities, size and property type. It is a
       scrolling chip rail on a phone instead. */
    /* .sr-e-bar is a COLUMN here, so flex-basis is the height — the desktop
       `flex:1 1 0` would collapse this row to 0px and let its chips spill over
       the search pill. */
    .sr-page .sr-filter-bar {
        display: flex;
        flex: 0 0 auto;
        width: 100%;
        margin: 0;
        justify-content: flex-start;
    }
    .sr-page .sr-filter-scroll {
        flex: 1 1 auto;
        padding: 2px 16px 2px 0;
        margin-right: -16px;
    }
    .sr-page .sr-e-barrule { display: none; }
    /* Matches the desktop rule's specificity — a media query does not raise it. */
    .sr-page .sr-e-viewtoggle.sr-view-toggle,
    .sr-page .sr-e-viewtoggle { display: none; }
    .sr-page .sr-filter-fade-right { width: 28px; }

    .sr-page .sr-e-hero {
        flex-direction: column;
        align-items: stretch;
        gap: 8px;
        padding: 24px 16px 4px;
    }
    .sr-page .sr-e-heroText { gap: 8px; max-width: none; }
    .sr-page .sr-e-title { font-size: 32px; line-height: 1.12; }
    .sr-page .sr-e-lede { font-size: 14px; }
    .sr-page .sr-e-heroAside { align-self: flex-start; margin-top: 6px; }

    .sr-page .sr-e-browse { padding: 18px 16px 24px; gap: 12px; }
    .sr-page .sr-e-rail { margin-right: -16px; padding-right: 16px; }

    .sr-page .sr-results-meta { padding: 0 16px 16px; }
    .sr-page .sr-pagination-count { font-size: 15px; }
    .sr-page .sr-e-countCtx { font-size: 14px; }

    .sr-page #properties_show { padding: 0 16px 96px; }
    .sr-page .sr-e-grid { grid-template-columns: minmax(0, 1fr); gap: 32px; }
    .sr-page .sr-e-name { font-size: 18px; }
    .sr-page .sr-e-pagerwrap { padding: 0 16px 96px; }

    /* Show map, as a centred pill above the site's bottom nav. */
    .sr-page.sr-view-grid .sr-e-fab { display: inline-flex !important; }
    .sr-page.sr-view-map  .sr-e-fab { display: none !important; }

    /* ── Map First on a phone: the map fills the screen, results ride in a
       bottom sheet that scrolls sideways (MapFirstMobile board). ────────── */
    .sr-page.sr-view-map .sr-shell {
        position: fixed;
        left: 0;
        right: 0;
        top: var(--sre-header-h);
        bottom: 0;
        height: auto;
        z-index: 900;
    }
    .sr-page.sr-view-map .sr-results {
        left: 0;
        right: 0;
        top: auto;
        /* clears .pub-mob-nav (62px, z-index 1040 — it sits above this sheet) */
        bottom: calc(62px + env(safe-area-inset-bottom, 0px));
        width: auto;
        max-height: 54%;
        border-radius: 24px 24px 0 0;
        border-bottom: 0;
        border-left: 0;
        border-right: 0;
        background: var(--sre-glass-strong);
    }
    /* The sheet is short: the place and the count earn their space, the lede
       does not. */
    .sr-page.sr-view-map .sr-e-lede { display: none; }
    .sr-page.sr-view-map .sr-results-meta { padding: 0 16px 12px; border-bottom: 0; }
    .sr-page.sr-view-map .sr-sticky-header { padding-top: 12px; }
    .sr-page.sr-view-map .sr-e-bar { padding: 0 16px; gap: 10px; }
    .sr-page.sr-view-map .sr-e-searchwrap { width: auto; flex: 1 1 auto; }
    .sr-page.sr-view-map .sr-filter-bar { flex: 0 0 auto; }
    .sr-page.sr-view-map .sr-filter-scroll { max-width: 44vw; }
    /* On a phone the results sheet covers the bottom of the map, so the dock
       moves up clear of it and drops the close button — the sheet has its own
       control for that. */
    .sr-page.sr-view-map .sr-mapdock { right: 12px; bottom: auto; top: 64px; }
    /* #closeMap is the ONLY way back to the list on a phone: the header's view
       toggle is display:none at this width and .sr-e-fab hides itself in map
       view, so hiding this one too left the map a dead end — you could get in
       and not out. It keeps its id, which js:555 binds the view state to. */
    .sr-page.sr-view-map .sr-mapdock #closeMap {
        display: inline-flex;
        background: var(--sb-surface);
        color: var(--sb-ink);
        box-shadow: var(--sb-shadow-2);
    }
    .sr-page.sr-view-map .sr-e-mapnote { display: none; }
    .sr-page.sr-view-map .sr-map-redo { top: 16px; }
    .sr-page.sr-view-map .sr-e-hero { padding: 14px 16px 8px; }
    .sr-page.sr-view-map .sr-e-title { font-size: 17px; }
    .sr-page.sr-view-map .sr-e-heroAside { position: absolute; right: 16px; top: 12px; }
    .sr-page.sr-view-map #properties_show { padding: 12px 16px 20px; }
    .sr-page.sr-view-map .sr-e-raillist {
        /* Split view makes this a grid on desktop; the phone sheet needs it
           back as a horizontal flex carousel. */
        display: flex;
        flex-direction: row;
        gap: 12px;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        scrollbar-width: none;
        padding-bottom: 4px;
    }
    .sr-page.sr-view-map .sr-e-raillist::-webkit-scrollbar { display: none; }
    /* A drag along the rail scrolls the rail; a drag on the map pans the map.
       Without this the map, which is directly underneath, took both. */
    .sr-page.sr-view-map .sr-e-raillist { touch-action: pan-x; }
    .sr-page.sr-view-map .sr-e-rcard { touch-action: pan-x; }

    /* The strip is capped at 44vw for the old layout, where the results were a
       narrow panel beside the map. The bar spans the screen now, so the cap
       left the chips crammed into the left third with the rest unreachable. */
    .sr-page.sr-view-map .sr-filter-scroll { max-width: none; }

    .sr-page.sr-view-map .sr-e-rcard {
        flex: 0 0 auto;
        width: 280px;
        flex-direction: row;
        gap: 12px;
        border-radius: 16px;
        padding: 10px;
        scroll-snap-align: start;
    }
    .sr-page.sr-view-map .sr-e-rcard .sr-e-media {
        flex: 0 0 96px;
        width: 96px;
        aspect-ratio: 1 / 1;
        border-radius: 10px;
    }
    .sr-page.sr-view-map .sr-e-rcard .sr-e-body { flex: 1 1 auto; min-width: 0; gap: 3px; padding: 0; }
    .sr-page.sr-view-map .sr-e-rcard .sr-e-area { font-size: 11px; }
    .sr-page.sr-view-map .sr-e-rcard .sr-e-name { font-size: 15px; }
    .sr-page.sr-view-map .sr-e-rcard .sr-e-facts { font-size: 12px; }
    .sr-page.sr-view-map .sr-e-rcard .sr-e-priceRow { margin-top: auto; }
    .sr-page.sr-view-map .sr-e-rcard .sr-e-price { font-size: 16px; }
    .sr-page.sr-view-map .sr-e-rcard .sr-e-heart { width: 32px; height: 32px; top: 6px; right: 6px; }
    .sr-page.sr-view-map .sr-e-rcard .sr-e-badges { left: 6px; top: 6px; }
    .sr-page.sr-view-map .sr-e-pagerwrap { padding: 0 16px 16px; }
}

/* ── 575 and under: the smallest phones ───────────────────────────────── */
@media (max-width: 575.98px) {
    .sr-page .sr-e-title { font-size: 29px; }
    .sr-page .sr-e-price { font-size: 17px; }
    .sr-page .sr-e-nights { display: none; }
}


/* ==========================================================================
   15. Motion, print
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
    .sr-page *,
    .sr-overlays * {
        animation-duration: 1ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 1ms !important;
        scroll-behavior: auto !important;
    }
    .sr-page .sr-e-skelMedia::after,
    .sr-page .sr-e-skelBar::after { display: none; }
    .sr-page .sr-e-card:hover .sr-e-media img { transform: none; }
}

@media print {
    .sr-page .sr-sticky-header,
    .sr-page .sr-e-browse,
    .sr-page .sr-e-fab,
    .sr-page .sr-map-panel { display: none !important; }
    .sr-page .sr-shell { height: auto; display: block; }
    .sr-page .sr-e-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}


/* ==========================================================================
   16. Dark mode — re-asserting the editorial palette

   The page's own <style> block ships ~70 `body.dark-mode .sr-x { … }` rules
   in the old slate-blue palette. Those are (0,2,1) selectors, so they outrank
   the (0,2,0) rules above and would repaint the redesign blue after dark.
   Everything here is therefore written one class deeper — `body.dark-mode
   .sr-page .x` / `body.dark-mode .sr-overlays .x` — and re-states only the
   properties those rules hardcode. The VALUES are still tokens, which
   softbnb-ds.css has already flipped, so there is no second palette to keep
   in step.
   ========================================================================== */

body.dark-mode .sr-page .sr-shell,
body.dark-mode .sr-page .sr-results,
body.dark-mode .sr-page .sr-sticky-header,
body.dark-mode .sr-page .sr-search-bar { background: var(--sb-bg); }

body.dark-mode .sr-page .sr-sticky-header { border-bottom-color: var(--sb-border); }

body.dark-mode .sr-page .sr-filter-bar,
body.dark-mode .sr-page #sr-cat-bar { background: transparent; border-color: var(--sb-border); }

body.dark-mode .sr-page .sr-filter-fade-right {
    background: linear-gradient(90deg, rgba(15, 13, 12, 0) 0%, var(--sb-bg) 78%);
}

/* Chips, the sort control and the view toggle */
body.dark-mode .sr-page .sr-cat-pill,
body.dark-mode .sr-page .sr-pill,
body.dark-mode .sr-page .sr-pill-more,
body.dark-mode .sr-page .sr-view-btn,
body.dark-mode .sr-page .sr-e-vbtn,
body.dark-mode .sr-page .sr-sort-select,
body.dark-mode .sr-page .sr-pill.sr-e-searchpill {
    background: var(--sb-surface);
    color: var(--sb-text);
    border-color: var(--sre-bc, var(--sb-border));
}
body.dark-mode .sr-page .sr-e-sort { background: var(--sb-surface); border-color: var(--sb-border); }
body.dark-mode .sr-page .sr-e-sort .sr-sort-select { background: transparent; border-color: transparent; }

body.dark-mode .sr-page .sr-cat-pill:hover,
body.dark-mode .sr-page .sr-pill:hover,
body.dark-mode .sr-page .sr-e-vbtn:hover {
    background: var(--sb-surface-2);
    border-color: var(--sb-border-strong);
    color: var(--sb-text);
}
body.dark-mode .sr-page .sr-cat-pill.active,
body.dark-mode .sr-page .sr-pill.panel-open,
body.dark-mode .sr-page .sr-pill.sr-pill-active,
body.dark-mode .sr-page .sr-view-btn.active {
    background: var(--sb-ink);
    color: var(--sb-bg);
    border-color: var(--sb-ink);
}

body.dark-mode .sr-page .sr-e-fab,
body.dark-mode .sr-page .sr-map-toggle-btn.sr-e-fab {
    background: var(--sb-ink);
    color: var(--sb-bg);
    border-color: transparent;
}

body.dark-mode .sr-page #loader { background: transparent; }

body.dark-mode .sr-page .sr-results-meta,
body.dark-mode .sr-page .sr-results-top { border-color: var(--sb-border); }
body.dark-mode .sr-page .sr-pagination-count { color: var(--sb-ink); }

/* Filter dropdowns */
body.dark-mode .sr-page .sr-panel,
body.dark-mode .sr-overlays .sr-panel {
    background: var(--sb-surface);
    border-color: var(--sb-border);
    box-shadow: var(--sb-shadow-3);
}
body.dark-mode .sr-page .sr-panel label,
body.dark-mode .sr-page .sr-check-label { color: var(--sb-text); }
body.dark-mode .sr-page .sr-check-item { border-color: var(--sb-border); }

/* Overlays: the modal, the confirm dialog and the toast */
body.dark-mode .sr-overlays .sr-modal,
body.dark-mode .sr-overlays .sr-modal-head,
body.dark-mode .sr-overlays .sr-modal-body,
body.dark-mode .sr-overlays .sr-confirm-box,
body.dark-mode .sr-overlays #sr-toast {
    /* A step lighter than the night surface, with the stronger border: the
       card has to separate from a --sb-bg of #0F0D0C. */
    background: var(--sb-surface-3);
    border-color: var(--sb-border-strong);
    color: var(--sb-text);
}
body.dark-mode .sr-overlays .sr-modal-head h3,
body.dark-mode .sr-overlays .sr-confirm-title,
body.dark-mode .sr-overlays .sr-toast-title { color: var(--sb-ink); }
body.dark-mode .sr-overlays .sr-section-title,
body.dark-mode .sr-overlays .sr-toast-sub { color: var(--sb-muted); }
body.dark-mode .sr-overlays .sr-modal-close-btn { background: var(--sb-surface-2); color: var(--sb-text); }
body.dark-mode .sr-overlays .sr-select,
body.dark-mode .sr-overlays .sr-input {
    background-color: var(--sb-surface);
    border-color: var(--sb-border);
    color: var(--sb-text);
}
body.dark-mode .sr-overlays .sr-amenities-grid label,
body.dark-mode .sr-overlays .sr-prop-type-grid label,
body.dark-mode .sr-overlays .sr-amenity-check { color: var(--sb-text); }
body.dark-mode .sr-overlays .sr-check-item { border-color: var(--sb-border); }
body.dark-mode .sr-overlays .sr-confirm-no { background: var(--sb-surface); border-color: var(--sb-border); color: var(--sb-text); }
body.dark-mode .sr-page .sr-empty p { color: var(--sb-muted); }

/* Map First stays dark-on-dark: these must outrank the block above, which is
   why they repeat the view class AND body.dark-mode. */
body.dark-mode .sr-page.sr-view-map .sr-cat-pill,
body.dark-mode .sr-page.sr-view-map .sr-pill,
body.dark-mode .sr-page.sr-view-map .sr-pill-more,
body.dark-mode .sr-page.sr-view-map .sr-e-vbtn,
body.dark-mode .sr-page.sr-view-map .sr-view-btn,
body.dark-mode .sr-page.sr-view-map .sr-pill.sr-e-searchpill {
    background: var(--sre-glass);
    color: var(--sre-glass-ink);
    border-color: var(--sre-glass-line);
}
body.dark-mode .sr-page.sr-view-map .sr-cat-pill.active,
body.dark-mode .sr-page.sr-view-map .sr-pill.panel-open,
body.dark-mode .sr-page.sr-view-map .sr-pill.sr-pill-active,
body.dark-mode .sr-page.sr-view-map .sr-view-btn.active {
    background: #FFFFFF;
    color: #14100E;
    border-color: #FFFFFF;
}
body.dark-mode .sr-page.sr-view-map .sr-results,
body.dark-mode .sr-page.sr-view-map .sr-sticky-header,
body.dark-mode .sr-page.sr-view-map .sr-shell { background: transparent; }
body.dark-mode .sr-page.sr-view-map .sr-results { background: var(--sre-glass); }
body.dark-mode .sr-page.sr-view-map .sr-e-sort { background: var(--sre-glass-fill); border-color: transparent; }
body.dark-mode .sr-page.sr-view-map .sr-e-sort .sr-sort-select { color: #FFFFFF; }
body.dark-mode .sr-page.sr-view-map .sr-pagination-count { color: var(--sre-glass-muted); }
body.dark-mode .sr-page.sr-view-map .sr-results-meta { border-bottom-color: var(--sre-glass-line-2); }

/* ── The search page's own dark ground ──────────────────────────────────────
   common/header.blade.php paints body and .site-topnav Tailwind slate-900
   (#0f172a) in dark mode, which every other page on the site is built around.
   This page is not: .sr-page is #0F0D0C and the results panel #1A1614, both
   warm. Slate against those is a 1.01:1 step — not a brightness change the eye
   reads as depth, but a HUE change, cool blue sitting directly above a warm
   panel and, in split view, directly above the map.

   So the override is scoped to this page via .sr-body (added by an inline
   script at the top of the view, so it lands before first paint) rather than
   changing the header, which would drag every other page with it. Literal hex
   throughout: <body> and .site-topnav sit OUTSIDE .sb-page, so the design
   system's tokens do not resolve on them.

   Both sides carry !important, so the win has to come from specificity:
   body.dark-mode.sr-body is 0-2-1 against the header's 0-1-1, and the topnav
   pair 0-4-1 against 0-3-1. */
body.dark-mode.sr-body {
    background-color: #0F0D0C !important;
    color: #F1EAE4 !important;
}
body.dark-mode.sr-body:not(.page-home) .site-topnav {
    background: #14100E !important;
    border-bottom-color: #332B26 !important;
}
body.dark-mode.sr-body .site-topnav .site-topnav__link { color: #D9D0C7; }
body.dark-mode.sr-body .site-topnav__user-btn,
body.dark-mode.sr-body .site-topnav__dm {
    background: #1A1614;
    border-color: #332B26;
    color: #D9D0C7;
}
/* Anything that opens out of the nav, or the navy would come back with it. */
body.dark-mode.sr-body .site-topnav__dropdown {
    background: #1A1614;
    border-color: #332B26;
}
body.dark-mode.sr-body .site-topnav__dropdown a,
body.dark-mode.sr-body .site-topnav__dropdown .site-topnav__link { color: #D9D0C7; }
/* The consent banner is a shared component hardcoded to #1a1a2e — navy again,
   and on this page it sits directly over the map. Scoped to .sr-body so every
   other page keeps the banner it has. Applies in both modes: the navy clashes
   with the warm cream ground by day just as much as with the warm black
   by night. */
body.sr-body .sbpop-banner {
    background: #14100E;
    box-shadow: 0 8px 40px rgba(20, 16, 14, 0.4);
}

body.dark-mode.sr-body .mob-site-top-bar {
    background: #14100E !important;
    border-bottom-color: #332B26 !important;
}


/* ==========================================================================
   17. Map view on a phone
   Below 992px the map panel is fixed, so the results column it used to sit
   beside ended up behind it: the search bar, the chips and every card were
   painted under an opaque map, and the screen below the map was empty. The
   column keeps its markup and becomes an overlay instead — search bar along
   the top, cards as a rail along the bottom, map filling everything between.
   The column itself does not take pointer events, so a tap between the two
   reaches the map; the two bands put them back.
   ========================================================================== */

@media (max-width: 991.98px) {
    .sr-page.sr-view-map .sr-map-panel,
    .sr-page.sr-view-map .sr-map-panel.hidden {
        position: fixed;
        inset: var(--sre-header-h) 0 0 0;
        /* Spelled out rather than left to top/bottom: the panel kept the 320px
           the old stacked layout gave it and would not stretch to the insets. */
        height: calc(100vh - var(--sre-header-h)) !important;
        z-index: 40;
    }
    /* .map-view only. A `.sr-map-panel > div` was here too, meant for the map's
       own wrapper — but that wrapper is `.map-view > div`, a grandchild, so the
       selector never matched it (Google Maps sizes it anyway). What it did match
       was .sr-mapdock, stretching the button column to the full height of the
       map: a 44px, touch-taking, z-60 strip down the right edge that swallowed
       every drag started there. Measured with it gone: map, wrapper, .gm-style,
       veil and tiles all unchanged; the dock collapses to its own height. */
    .sr-page.sr-view-map .map-view { height: 100% !important; }

    /* The bottom nav (.pub-mob-nav, 64px) owns the last strip of the screen. */
    .sr-page.sr-view-map .sr-results {
        position: fixed;
        inset: var(--sre-header-h) 0 64px 0;
        /* An earlier rule caps this column at 54% for the old bottom-sheet
           shape; the overlay spans the screen and lets its two bands sit apart. */
        max-height: none;
        z-index: 50;
        display: flex;
        flex-direction: column;
        height: auto;
        min-height: 0;
        pointer-events: none;
        /* It sits over the map now; the column's own page-coloured background
           would paint the map out completely. */
        background: transparent;
    }
    .sr-page.sr-view-map .sr-sticky-header {
        position: static;
        pointer-events: auto;
        flex: 0 0 auto;
    }
    /* Laid out rather than pushed with an auto margin, which an earlier rule
       for the old shape was resetting: the column fills the gap and its
       content rides the bottom edge, so the map keeps the middle of the
       screen to itself. */
    .sr-page.sr-view-map .sr-results-inner {
        display: flex;
        flex-direction: column;
        justify-content: flex-end;
        flex: 1 1 auto;
        min-height: 0;
        pointer-events: none;
        padding: 0;
        background: transparent;
        overflow: visible;
    }
    .sr-page.sr-view-map .sr-results-meta,
    .sr-page.sr-view-map .list-view { pointer-events: auto; }

    /* On a map, only the count and the cards are worth the space. */
    .sr-page.sr-view-map .sr-e-hero,
    .sr-page.sr-view-map .sr-e-browse,
    .sr-page.sr-view-map .sr-e-pagerwrap,
    .sr-page.sr-view-map .sr-e-density { display: none !important; }

    /* The count becomes a small plate on the map above the cards. */
    .sr-page.sr-view-map .sr-results-meta {
        align-self: flex-start;
        margin: 0 0 8px 16px;
        padding: 6px 12px;
        border-radius: 999px;
        background: var(--sb-surface);
        border: 1px solid var(--sb-border);
        box-shadow: var(--sb-shadow-1);
        font-size: 12px;
        width: auto;
        flex: 0 0 auto;
    }

    /* One card at a time, snapping, so a thumb can walk the results. */
    .sr-page.sr-view-map .sr-e-raillist {
        display: flex;
        flex-direction: row;
        align-content: initial;
        grid-template-columns: none;
        gap: 12px;
        overflow-x: auto;
        overflow-y: hidden;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        padding: 6px 16px 10px;
        scrollbar-width: none;
        overscroll-behavior-x: contain;
    }
    .sr-page.sr-view-map .sr-e-raillist::-webkit-scrollbar { display: none; }
    .sr-page.sr-view-map .sr-e-rcard {
        flex: 0 0 84%;
        max-width: 340px;
        scroll-snap-align: center;
        flex-direction: row;
        background: var(--sb-surface);
        border: 1px solid var(--sb-border);
        border-radius: 16px;
        box-shadow: var(--sb-shadow-2);
        padding: 10px;
    }
    .sr-page.sr-view-map .sr-e-rcard .sr-e-media {
        width: 108px;
        min-height: 96px;
    }

    /* Dark map view (section 14) makes the column glass over the map and the
       bar transparent on top of it. That reads correctly when the column is a
       panel beside the map; as a full-screen overlay it painted the map out
       completely and left the search bar with no ground. These carry the same
       weight as those rules and win by sitting after them in the file — which
       is the whole reason they live down here and not with the rest of the
       phone map rules further up. */
    body.dark-mode .sr-page.sr-view-map .sr-results { background: transparent; }
    body.dark-mode .sr-page.sr-view-map .sr-sticky-header { background: var(--sb-bg); }

    /* ── The rail owns the whole strip ──────────────────────────────────────
       .list-view carries 16px of side padding, but it is not an ancestor of
       the scroller — the rail is the scroller — so a swipe that began in those
       margins had nothing to move and simply died. The rail goes full-bleed
       and takes the padding itself, which makes every pixel of the strip a
       place you can push the carousel from.

       Mandatory snapping with 1.25 cards in view also meant a short swipe
       sprang straight back to the card it started on; proximity lets the rail
       run and settle near a card instead. Together with touch-action: pan-x
       above, a drag along the strip moves the cards and never the map, and a
       drag anywhere else on the screen moves the map.
       -------------------------------------------------------------------- */
    /* .list-view IS #properties_show, and its side padding is set through that
       id — a class selector here never reached it. */
    .sr-page.sr-view-map #properties_show { padding-inline: 0; }
    .sr-page.sr-view-map .sr-e-raillist {
        padding-inline: 16px;
        scroll-padding-inline: 16px;
        scroll-snap-type: x proximity;
        overscroll-behavior: contain;
    }

    /* Back to the list: the ✕ is the only route out at this width. The dock
       starts below the floating search bar, or the zoom buttons sit behind it. */
    .sr-page.sr-view-map .sr-mapdock {
        z-index: 60;
        top: 127px;
        left: auto;
        right: 12px;
        width: 44px;
    }
}

/* The card the rail has settled on, matching the pin lit on the map. */
@media (max-width: 991.98px) {
    .sr-page.sr-view-map .sr-e-rcard.is-paired {
        border-color: var(--sb-ink);
        box-shadow: var(--sb-shadow-2);
    }
}

@media (max-width: 575.98px) {
    .sr-page.sr-view-map .sr-e-rcard { flex-basis: 88%; }
}

/* ==========================================================================
   18. Map view on a phone — the cards take the touch, the header is whole
   --------------------------------------------------------------------------
   Measured with real touch events at 390px (not mouse drags): a swipe along
   the card carousel panned the MAP about 19 km and never moved the cards, and
   because the map had moved, the search re-ran and the carousel emptied.
   elementFromPoint anywhere on the strip returned the map. The overlay column
   takes no pointer events so the map between the bands can be dragged; the
   cards were meant to take them back through `.list-view`, but in map view
   #properties_show does not carry that class, so the whole strip inherited
   `pointer-events: none` and every touch fell through to the map below.

   #listCol is also a Bootstrap column: its 15px gutters left a strip of live
   map down both edges of the search bar, so it never read as a header, and
   narrowed the carousel to 360px. And the page's own header — the area,
   "Stays & Shortlets", the from-price — was hidden in map view; it comes back
   as one compact band under the search bar.

   Kept after section 17 on purpose: see the dark-mode note there.
   ========================================================================== */
@media (max-width: 991.98px) {
    .sr-page.sr-view-map #listCol {
        padding-left: 0 !important;
        padding-right: 0 !important;
    }

    /* The strip is a band like the search bar: it takes its own touches.
       By id as well, because a class selector never reached #properties_show. */
    .sr-page.sr-view-map #properties_show,
    .sr-page.sr-view-map .sr-e-raillist,
    .sr-page.sr-view-map .sr-e-rcard { pointer-events: auto; }

    /* A drag on the cards only ever moves the cards sideways. Anything else
       started on them (a vertical flick) is simply ignored — it is neither a
       page scroll nor a map pan. The map, everywhere above the strip, keeps
       every gesture of its own. */
    .sr-page.sr-view-map .sr-e-raillist,
    .sr-page.sr-view-map .sr-e-rcard { touch-action: pan-x; }
    .sr-page.sr-view-map .sr-e-raillist { overscroll-behavior: contain; }

    /* The page header, as a compact band under the search bar. The column
       lays its content along the bottom edge; the auto margin keeps this one
       band at the top, directly under the bar, and the map between them. */
    .sr-page.sr-view-map .sr-e-hero {
        display: flex !important;
        flex: 0 0 auto;
        flex-direction: row;
        flex-wrap: nowrap;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        margin: 0 0 auto;
        padding: 10px 16px 11px;
        background: var(--sb-bg);
        border-bottom: 1px solid var(--sb-border);
        pointer-events: auto;
    }
    .sr-page.sr-view-map .sr-e-heroText { flex: 1 1 auto; gap: 2px; min-width: 0; }
    .sr-page.sr-view-map .sr-e-eyebrow { display: block; font-size: 10.5px; letter-spacing: 0.12em; }
    .sr-page.sr-view-map .sr-e-eyebrow:empty,
    .sr-page.sr-view-map .sr-e-lede:empty { display: none; }
    .sr-page.sr-view-map .sr-e-title {
        font-size: 18px;
        line-height: 1.2;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .sr-page.sr-view-map .sr-e-lede {
        display: block;   /* an older phone rule (section 14) hid it */
        font-size: 12.5px;
        line-height: 1.35;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    /* An older phone rule floated the sort control to the top of the screen,
       where it sat hidden behind the search bar. In the band it is in flow. */
    .sr-page.sr-view-map .sr-e-heroAside { position: static; top: auto; right: auto; flex: 0 0 auto; align-self: center; }
    .sr-page.sr-view-map .sr-e-sort { height: 36px; padding: 0 10px 0 12px; gap: 4px; }
    .sr-page.sr-view-map .sr-e-sort .sr-e-sortLabel { display: none; }
    .sr-page.sr-view-map .sr-e-sort .sr-sort-select { height: 34px; font-size: 13px; }

    /* The zoom / locate / close dock sits just below the search bar and this
       band, whatever their height (js: phoneMapChrome measures it). */
    .sr-page.sr-view-map .sr-mapdock { top: calc(var(--sr-phone-map-chrome, 190px) + 12px); }
}


/* ==========================================================================
   19. Focus on the search fields — without the red
   ==========================================================================
   The page carried three separate red focus treatments: the global
   `.sr-page :focus-visible` outline (3px solid --sb-focus, which resolves to
   the brand red), the --sb-primary-ring halo on panel inputs, and a red
   border-color from the view's own <style> block. Together they put a red
   stroke around the search pill and around every text field the instant a
   caret landed in one, which reads as an error state rather than as focus.

   A text input matches :focus-visible on a plain mouse click, not only on
   Tab, so :focus alone was not enough to clear — both have to go here.

   Scoped to this page's text fields, selects and the search pill. Buttons,
   links, cards, map pins and the overlays keep the global keyboard ring, so
   tabbing through the page can still be followed. A focused field still shows
   its caret and its own neutral border. */
.sr-page .sr-input:focus,
.sr-page .sr-input:focus-visible,
.sr-page .sr-panel .sr-input:focus,
.sr-page .sr-panel .sr-input:focus-visible,
.sr-page input[type="text"]:focus,
.sr-page input[type="text"]:focus-visible,
.sr-page input[type="search"]:focus,
.sr-page input[type="search"]:focus-visible,
.sr-page .sr-select:focus,
.sr-page .sr-select:focus-visible,
.sr-page .sr-sort-select:focus,
.sr-page .sr-sort-select:focus-visible,
.sr-page .sr-pill:focus,
.sr-page .sr-pill:focus-visible,
.sr-page .sr-e-searchpill:focus,
.sr-page .sr-e-searchpill:focus-visible {
    outline: none;
    box-shadow: none;
}

/* The border those fields turned red on focus. Neutral rather than removed,
   so an active field is still distinguishable from an idle one. */
.sr-page .sr-input:focus,
.sr-page input[type="text"]:focus,
.sr-page input[type="search"]:focus,
.sr-page .sr-select:focus,
.sr-page .sr-sort-select:focus {
    border-color: var(--sb-border-strong);
}

/* The guest stepper lights up from the input nested inside it. */
.sr-page .sr-guest-stepper:focus-within {
    border-color: var(--sb-border-strong);
    box-shadow: none;
}

/* Night needs its own pass: the view's `body.dark-mode .sr-input:focus`
   (0,3,1) outranks a plain `.sr-page .sr-input:focus` (0,3,0), so without
   these the red came back after dark. */
body.dark-mode .sr-page .sr-input:focus,
body.dark-mode .sr-page .sr-input:focus-visible,
body.dark-mode .sr-page .sr-panel .sr-input:focus,
body.dark-mode .sr-page input[type="text"]:focus,
body.dark-mode .sr-page input[type="search"]:focus,
body.dark-mode .sr-page .sr-select:focus,
body.dark-mode .sr-page .sr-sort-select:focus {
    outline: none;
    box-shadow: none;
    border-color: var(--sb-border-strong);
}

/* The pill is left to its own --sre-bc border machinery (§ the .sr-pill hover
   rule); only the outline and the ring are cleared, so a focused pill still
   looks exactly like a hovered one rather than gaining an extra edge. */
body.dark-mode .sr-page .sr-pill:focus,
body.dark-mode .sr-page .sr-pill:focus-visible,
body.dark-mode .sr-page .sr-e-searchpill:focus,
body.dark-mode .sr-page .sr-e-searchpill:focus-visible {
    outline: none;
    box-shadow: none;
}
body.dark-mode .sr-page .sr-guest-stepper:focus-within {
    border-color: var(--sb-border-strong);
    box-shadow: none;
}

/* ==========================================================================
   20. The search fields read as one set; phone type and map chrome
   --------------------------------------------------------------------------
   Measured in Safari's engine (iPhone 12, 390×664) and Chrome, day and night,
   list and map view, with the pill closed and open:

   · The pill's three values were two colours. "Anywhere" and "Any dates"
     carry .sr-e-placeholder while empty and were drawn muted; "1 Guest"
     never does, so it was the only value in full ink. On a phone the
     "Any dates · 1 Guest" line was muted in list view but full ink in map view.
   · Opening the pill handed it the filter chips' inverted "active" fill:
     cream at night under cream values (1.05:1), white in map view at night
     (1.13:1), near-black in map view by day under near-black values (1.00:1).
     The values vanished the moment the panel opened.
   · In the panel, "Search location…" was #B0B8C4 by day (2.0:1) and a slate
     #475569 at night (2.37:1), from the view's own <style>. Its icon was red
     while the guest row's is muted (the guest-row block above), and the
     guest text started 5px left of the location text.
   Kept last so it follows the dark-mode sections it corrects.
   ========================================================================== */

/* One ink for all three values, set or not, in both views. */
.sr-page .sr-e-seg .sr-sb-val.sr-e-placeholder,
.sr-page .sr-e-seg .sr-sb-val.sr-e-segsub,
.sr-page.sr-view-map .sr-e-seg .sr-sb-val,
.sr-page.sr-view-map .sr-e-seg .sr-sb-val.sr-e-placeholder,
.sr-page.sr-view-map .sr-e-seg .sr-sb-val.sr-e-segsub { color: var(--sb-text); }

/* The pill keeps its own ground while its panel is open — the inverted fill
   is the filter chips' "on" state, not this control's. Each selector is one
   class deeper than the .sr-pill.panel-open rule it answers. */
.sr-page .sr-pill.sr-e-searchpill.panel-open,
.sr-page.sr-view-map .sr-pill.sr-e-searchpill.panel-open,
body.dark-mode .sr-page .sr-pill.sr-e-searchpill.panel-open,
body.dark-mode .sr-page.sr-view-map .sr-pill.sr-e-searchpill.panel-open {
    background: var(--sb-surface);
    color: var(--sb-text);
    --sre-bc: var(--sb-border-strong);
    border-color: var(--sb-border-strong);
}

/* Panel hints readable on both grounds; the location field's hint in the
   same ink as the dates and guests beside it. */
.sr-page .sr-panel .sr-input::placeholder,
.sr-overlays .sr-input::placeholder { color: var(--sb-muted); opacity: 1; }
.sr-page #panel-location .sr-input::placeholder { color: var(--sb-text); }

/* The location and guest icons match, and sit on the same line: icon at
   13px, text at 39px from the field's edge, as .sr-input-icon-wrap does. */
.sr-page #panel-location .sr-input-icon-wrap > i { color: var(--sb-muted); }
.sr-page .sr-panel .sr-guest-stepper { padding-left: 12px; }
.sr-page .sr-panel .sr-guest-label { gap: 13px; }
.sr-page .sr-panel .sr-guest-label i {
    flex: 0 0 13px;
    width: 13px;
    font-size: 13px;
    text-align: center;
}

/* Google's suggestion list hangs off <body>, outside .sr-page, so it takes
   the tokens it needs the way #map-hover-card does. At night it kept the old
   slate navy; the typed part of each line was #777 (3.27:1 after dark), and
   600 is not a Poppins weight this page loads. `html` outranks the header
   partials' !important rules, which load after this file. */
body .pac-container {
    --sb-text:  #1A1614;
    --sb-muted: #6B615A;
}
body.dark-mode .pac-container {
    --sb-surface:   #1A1614;
    --sb-surface-2: #221D1A;
    --sb-border:    #332B26;
    --sb-text:      #F1EAE4;
    --sb-muted:     #A99E95;
}
html body .pac-container .pac-matched { color: var(--sb-muted) !important; font-weight: 500; }
html body .pac-container .pac-item-query { font-weight: 500 !important; }
html body.dark-mode .pac-container {
    background: var(--sb-surface) !important;
    border-color: var(--sb-border) !important;
}
html body.dark-mode .pac-container .pac-item,
html body.dark-mode .pac-container .pac-item-query { color: var(--sb-text) !important; border-color: var(--sb-border) !important; }
html body.dark-mode .pac-container .pac-item:hover,
html body.dark-mode .pac-container .pac-item-selected { background: var(--sb-surface-2) !important; }
/* Google's attribution is a dark-on-white image; after dark it takes the
   variant Google publishes for other grounds, so it stays legible. */
html body.dark-mode .pac-container.pac-logo::after {
    background-image: url(https://maps.gstatic.com/mapfiles/api-3/images/powered-by-google-on-non-white3_hdpi.png);
}

/* List-view title on phones, sized to the screen: 22px at 320, ~24px at 390,
   32px from 720 (the old tablet rung). The ladder stopped at 29px for every
   phone, twice the lede. :not(.sr-view-map) leaves the map band alone. */
@media (max-width: 991.98px) {
    .sr-page:not(.sr-view-map) .sr-e-title { font-size: clamp(22px, 14px + 2.5vw, 32px); }
}
@media (max-width: 575.98px) {
    .sr-page:not(.sr-view-map) .sr-e-title {
        line-height: 1.15;
        letter-spacing: -0.012em;
        overflow-wrap: break-word;
    }
    .sr-page:not(.sr-view-map) .sr-e-hero { padding-top: 20px; }
    .sr-page:not(.sr-view-map) .sr-e-heroText { gap: 6px; }
}

/* Map view on a phone: the All / Stays / Boat & Yacht chips sat on the
   header's bottom edge (2px under them, 13px over). They rise 8px and the
   header keeps its height, so nothing below it moves. */
@media (max-width: 991.98px) {
    .sr-page.sr-view-map .sr-e-bar { gap: 2px; padding-bottom: 8px; }
}

/* A short phone screen — Safari with its toolbars leaves an iPhone 12 664px —
   has no room for a 196px column of map buttons between the header band and
   the cards: the dock ran over the results count and under the first card.
   Laid in a row it is 44px tall and clears both. */
@media (max-width: 991.98px) and (max-height: 760px) {
    .sr-page.sr-view-map .sr-mapdock { flex-direction: row; width: auto; }
    .sr-page.sr-view-map .sr-mapdock-grp { flex-direction: row; }
}
/* Shorter still — an iPhone SE in Safari leaves 375×553 — and the count plate
   rides up into that same row: it sits over three of the four buttons (all
   four at 320×568, where its text wraps to two lines), and #listCol (z 50)
   paints above #mapCol (z 40), so they could be neither seen nor tapped. With
   about 75px of map left, the count is the part to give up; the band still
   names the search and the cards are all there. !important because the view
   shows and hides #pagination inline around every fetch. */
@media (max-width: 991.98px) and (max-height: 620px) {
    .sr-page.sr-view-map .sr-results-meta { display: none !important; }
}

/* Which parts of the card strip take a touch. Section 18 gave the whole
   #properties_show box pointer-events:auto, but that box is a transparent
   12px taller than the rail on top and 20px below it, so the map showing
   through those bands took no drag at all. The box now lets touches through
   and what it holds takes them back: the rail, or the empty state and its
   buttons (pointer-events inherits, so they need saying).

   Except a rail of placeholders while a search runs (js: showSkeletons, an
   .sr-e-raillist with aria-busy="true"). Those are taller than real cards,
   so for half a second to several seconds the strip rides up over the middle
   of the map, and section 18's auto on every .sr-e-rcard (the placeholders
   carry that class too, undoing .sr-e-skel's own none) turned a drag on the
   map into a scroll of empty cards. Nothing in a placeholder can be tapped. */
@media (max-width: 991.98px) {
    .sr-page.sr-view-map #properties_show { pointer-events: none; }
    .sr-page.sr-view-map #properties_show > :not([aria-busy="true"]) { pointer-events: auto; }
    .sr-page.sr-view-map .sr-e-raillist[aria-busy="true"],
    .sr-page.sr-view-map .sr-e-rcard.sr-e-skel { pointer-events: none; }
}

/* The search box on a phone. positionPanel() (view) measures the panel before
   placing it, and a fixed box with only `left` set is as wide as the screen
   lets it be — so it measured the whole screen, fell back to left:8px and
   ran into the right edge, out of line with the 16px pill above it. On a
   320px phone the 360px min-width (.sr-location-panel) pushed the guest "+",
   check-out and "Find a place" off the screen. On a phone it takes the pill's
   own edges; the script still sets its top. */
@media (max-width: 575.98px) {
    .sr-page #panel-location {
        left: 16px !important;
        right: 16px !important;
        width: auto;
        min-width: 0;
    }
}

/* "Show map" floats at z-index 1030 over the whole page, and the panels live
   inside the sticky header's stacking context, so their own 9000 never beats
   it: on a short phone (an iPhone SE in Safari leaves ~553px) the pill sat on
   the open search box, over "Find a place". It steps aside while a panel is
   open and comes back when it closes. */
.sr-page:has(.sr-panel.open) .sr-e-fab { visibility: hidden; }


/* ==========================================================================
   21. The search pill's field labels
   --------------------------------------------------------------------------
   The owner's call (29 Sep): LOCATION set 2px lower (it sat almost on the
   pill's top edge on a phone), bold and smaller, behind a location pin in
   black. Bold is Ubuntu 700 — this page loads Poppins at 400/500 only, and
   a browser-faked Poppins bold is the trap the type system warns about.
   CHECK IN and GUEST take the same cut, so on desktop the three labels still
   share one line. The pin is --sb-ink: black by day, and it inverts after
   dark so it does not vanish into the night pill.
   ========================================================================== */
.sr-page .sr-e-seg .sr-sb-label {
    position: relative;
    top: 2px;
    font-family: var(--sb-font-display);
    font-size: 9px;
    font-weight: 700;
    line-height: 1.25;
}
/* The pin sits in the label's own left padding, out of the text flow, so
   the LOCATION line box is exactly the CHECK IN and GUEST one beside it. */
.sr-page .sr-e-seg--where .sr-sb-label { padding-left: 12px; }
.sr-page .sr-e-seg--where .sr-sb-label::before {
    content: "\f3c5";                      /* Font Awesome map-marker-alt */
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    font-size: 10px;
    line-height: 1;
    letter-spacing: 0;
    color: var(--sb-ink);
}


/* ==========================================================================
   22. Map view on a phone — the title band is one row
   --------------------------------------------------------------------------
   The owner's call (29 Sep): on a phone the band under the search bar took
   77px of the map — logo bar 54 + search 115 + band 77 = 246px before any
   map at all. It keeps what orients: the title (the place searched, or the
   kind of stay) and the sort, on one row. The eyebrow repeated the pill's
   place, and the price line gives way to the prices on the cards and pins.
   About 45px, so the map gains ~32px; the dock follows it (js:
   phoneMapChrome measures the band).
   ========================================================================== */
@media (max-width: 991.98px) {
    .sr-page.sr-view-map .sr-e-hero { padding-top: 6px; padding-bottom: 6px; }
    .sr-page.sr-view-map .sr-e-eyebrow,
    .sr-page.sr-view-map .sr-e-lede { display: none; }
    .sr-page.sr-view-map .sr-e-title { font-size: 17px; line-height: 1.25; }
    .sr-page.sr-view-map .sr-e-heroAside { margin-top: 0; }   /* a 6px left from the list layout */
    .sr-page.sr-view-map .sr-e-sort { height: 32px; }
    .sr-page.sr-view-map .sr-e-sort .sr-sort-select { height: 30px; }
}


/* ==========================================================================
   23. The search pill on a phone is one row
   --------------------------------------------------------------------------
   The owner's call (29 Sep): location, dates and guests side by side on one
   line instead of stacked three deep, in one type and with room between
   them — the way the desktop pill already reads. The phone's combined
   "Any dates · 1 Guest" line gives way to the real dates and guests
   segments (js: paintSearchPill keeps all of them current), each value in
   Ubuntu 500, split by the desktop's hairline rules.

   The LOCATION caption does not fit beside them on a phone — at 390px it
   would cut "Anywhere" to "Anyw…", and at 430px "Lekki Phase 1" — so
   there the black pin marks the location on its own, and the caption comes
   back from 576px, where the place still reads whole beside it.
   ========================================================================== */
@media (max-width: 991.98px) {
    .sr-page .sr-e-seg {
        flex-direction: row;
        align-items: center;
        justify-content: flex-start;
    }
    .sr-page .sr-e-seg--where { flex: 1 1 auto; min-width: 0; gap: 8px; padding: 0 10px 0 14px; }
    .sr-page .sr-e-seg--dates,
    .sr-page .sr-e-seg--guests { display: flex; flex: 0 0 auto; padding: 0 10px; }
    .sr-page .sr-e-segrule { display: block; height: 20px; }
    .sr-page .sr-e-seg .sr-sb-val.sr-e-segsub,
    .sr-page .sr-e-seg--dates .sr-sb-label,
    .sr-page .sr-e-seg--guests .sr-sb-label { display: none; }

    .sr-page .sr-e-seg .sr-sb-val {
        font-family: var(--sb-font-body);
        font-size: 14px;
        font-weight: 500;
        line-height: 1.25;
        letter-spacing: 0;
    }
    .sr-page .sr-e-seg--where .sr-sb-val { flex: 1 1 auto; min-width: 0; }

    /* The caption shrinks to its pin: the word stays in the markup (and the
       button keeps its aria-label), only its type is taken to zero. */
    .sr-page .sr-e-seg--where .sr-sb-label {
        flex: 0 0 auto;
        top: 0;
        width: 8px;
        height: 14px;
        padding-left: 8px;
        font-size: 0;
        overflow: visible;
    }
}
@media (min-width: 576px) and (max-width: 991.98px) {
    .sr-page .sr-e-seg--where .sr-sb-label {
        width: auto;
        height: auto;
        padding-left: 12px;
        font-size: 9px;
        overflow: hidden;
    }
}
/* A 320px phone: a little less air, so "Anywhere" still reads whole. */
@media (max-width: 359.98px) {
    .sr-page .sr-e-seg--where { gap: 6px; padding: 0 8px 0 12px; }
    .sr-page .sr-e-seg--dates,
    .sr-page .sr-e-seg--guests { padding: 0 8px; }
    .sr-page .sr-e-seg .sr-sb-val { font-size: 13px; }
    .sr-page .sr-e-searchgo { width: 36px; height: 36px; margin-left: 4px; margin-right: 6px; }
}
