/* ============================================================================
   Map search (/keyword-search, v2) -- sport-agnostic.

   Everything is namespaced under .searchV2, which lives on the one <section> in
   search-results/v2/view.jsp. Nothing here can reach another page, so it can
   restate element defaults without having to know what style.css already did.
   Loaded from v2/head.jsp only -- not part of the global bundle.

   ONE COLOUR IS SITE-SPECIFIC: the accent, taken from --accent. That variable is
   declared on :root by the theme palette loaded last (default.css = blue,
   color-futsalvenues.css = red, color-picklevenues.css = blue). A new sport gets
   correct pins and buttons by declaring --accent and nothing else.

   ---------------------------------------------------------------------------
   WHY THIS LOOKS THE WAY IT DOES

   Booking.com and Domain were the references, and the parts worth copying are
   not decorative:

   1. THE MAP IS THE PAGE. It is the taller element, it does not scroll away,
      and the list scrolls against it. A map that scrolls off is a picture.

   2. THE LIST AND THE MAP ARE ONE CONTROL. Pointing at a card lights its pin;
      pointing at a pin lights its card. That correspondence is the entire
      reason both halves are on screen at once, so it gets a real hover state
      and a real selected state, not just a colour change.

   3. THE CARD CARRIES A PHOTO. Both references lead with an image because it
      is what makes a row scannable at a glance. Venues with no image of their
      own fall back to a shared court photo, so no row is ever a blank box.

   4. QUIET BASE MAP, LOUD PINS. Both references desaturate the underlying map
      so the pins carry the colour. That is done in map.jsp's style array, not
      here, but it is why the pins are the only saturated thing on screen.

   Where this deliberately DIVERGES from the dashboard's "NO CARDS" rule in
   dashboard.css: a dense list beside a map is a different problem from a
   sparse dashboard. Rows here still need a hit target and a hover state that
   reads at a glance while your eye is on the map, and a card is the honest
   shape for that. The rule stands where it was written; this is not that page.
   ========================================================================= */

.searchV2 {
  /* Accent: per-site. Everything below is shared. */
  --sv-accent:      var(--accent, #2196f3);
  --sv-accent-soft: color-mix(in srgb, var(--sv-accent) 10%, transparent);

  --sv-ink:       #17161a;
  --sv-ink-mid:   #56545c;
  --sv-ink-soft:  #8b8892;
  --sv-ink-faint: #b9b6c0;

  --sv-page:      #ffffff;
  --sv-panel:     #ffffff;
  --sv-hover:     rgba(23, 22, 26, 0.045);
  --sv-hairline:  rgba(23, 22, 26, 0.11);
  --sv-shadow-sm: 0 1px 2px rgba(23, 22, 26, 0.06);
  --sv-shadow-md: 0 2px 6px rgba(23, 22, 26, 0.10), 0 12px 28px -18px rgba(23, 22, 26, 0.35);

  /* The panel carries a thumbnail, a two-line name, a suburb, a booking pill and
     a distance, so it needs real width to stop the name wrapping every row.

     clamp, not a fixed width: the panel should grow with the window rather than
     leaving a 1920px monitor with a narrow column beside an ocean of map, while
     a 1280px laptop must not end up with a panel that crowds the map out.
       1280px -> 520px (the floor)
       1440px -> 520px
       1920px -> 653px
     The middle term is what to change if it wants to be wider or narrower; the
     floor and ceiling only stop it becoming silly at the extremes. */
  --sv-panel-w:   clamp(520px, 34vw, 780px);
  --sv-gap:       0px;

  /* The theme header measures 70px. Declared once because the split's height,
     the map's height and the panel's height all have to agree with it -- three
     places quietly holding the same magic number is how one of them drifts. */
  --sv-header-h:  70px;

  position: relative;
  background: var(--sv-page);
  font-family: 'Muli', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;

  /* style.css line 329 gives EVERY <section> "padding: 50px 0". That is right
     for a content band and wrong for a full-bleed map -- it was pushing the
     whole split half a screen down the page and leaving a white gap under the
     header. This page is the map, so it starts where the header ends. */
  padding: 0;
}

/* color-mix is recent; browsers without it fall back to a flat tint. */
@supports not (color: color-mix(in srgb, red 10%, transparent)) {
  .searchV2 { --sv-accent-soft: rgba(23, 22, 26, 0.05); }
}

/* --- the split ---------------------------------------------------------- */

/* The split is a FIXED-HEIGHT viewport region, not a block that grows with its
   content. That is what makes the panel a real scroll container: if the split
   were free to grow, the panel would grow with it, the list would never overflow
   anything, and the wheel would scroll the page instead. */
.searchV2 .searchSplit {
  display: flex;
  align-items: stretch;
  gap: var(--sv-gap);
  height: calc(100vh - var(--sv-header-h));
  min-height: 520px;
}

.searchV2 .searchPanel {
  width: var(--sv-panel-w);
  flex: 0 0 var(--sv-panel-w);
  /* Give a wide monitor's extra pixels to the results rather than to more empty
     ocean on the map. Caps so the panel never dominates. */
  max-width: 46vw;
  background: var(--sv-panel);
  border-right: 1px solid var(--sv-hairline);
  display: flex;
  flex-direction: column;
  height: 100%;
  /* THE BUG THIS FIXES: a flex item defaults to min-height:auto, meaning it
     refuses to shrink below its content. Without this the list child sizes
     itself to all 15 venues, overflows nothing, and every wheel event falls
     through to the document. min-width for the same reason horizontally. */
  min-height: 0;
  min-width: 0;
}

/* No longer sticky: the split itself is now viewport-height and does not scroll,
   so the map simply fills its half. Sticky was compensating for a page that
   scrolled underneath it -- that page no longer moves. */
.searchV2 .searchMap {
  flex: 1 1 auto;
  min-width: 0;
  height: 100%;
}

.searchV2 .searchMapShell,
.searchV2 .searchMapCanvas,
.searchV2 #map-canvas {
  width: 100%;
  height: 100%;
  background: #e9eaec;   /* what shows while tiles load */
}

/* --- controls floating over the map ------------------------------------- */

.searchV2 .searchMapShell { position: relative; }

/* "Search this area" -- appears only after the view has moved with auto-search
   off. Centred at the top, which is where Airbnb, Domain and Google Maps all
   put it, so it is found without being looked for. */
.searchV2 .searchAreaBtn {
  position: absolute;
  top: 14px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 4;
  border: 1px solid var(--sv-hairline);
  background: var(--sv-page);
  color: var(--sv-ink);
  font-family: 'Poppins', 'Muli', sans-serif;
  font-size: 12.5px;
  font-weight: 600;
  padding: 9px 18px;
  border-radius: 100px;
  cursor: pointer;
  box-shadow: var(--sv-shadow-md);
  white-space: nowrap;
}

.searchV2 .searchAreaBtn:hover { background: var(--sv-hover); }
.searchV2 .searchAreaBtn i { color: var(--sv-accent); margin-right: 4px; }

.searchV2 .searchMoveToggle {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 4;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin: 0;
  padding: 8px 13px;
  border-radius: 8px;
  background: var(--sv-page);
  border: 1px solid var(--sv-hairline);
  box-shadow: var(--sv-shadow-sm);
  font-size: 12px;
  font-weight: 600;
  color: var(--sv-ink-mid);
  cursor: pointer;
  user-select: none;
}

.searchV2 .searchMoveToggle input { margin: 0; cursor: pointer; accent-color: var(--sv-accent); }

/* Below tablet the map band is short and these two would cover most of it. The
   toggle goes; auto-search stays on, which is the behaviour the suburb pages
   already have on a phone. */
@media (max-width: 991px) {
  .searchV2 .searchMoveToggle { display: none; }
  .searchV2 .searchAreaBtn { top: 10px; font-size: 12px; padding: 8px 14px; }
}

/* --- panel header ------------------------------------------------------- */

.searchV2 .searchPanelTop {
  padding: 16px 18px 14px;
  border-bottom: 1px solid var(--sv-hairline);
  background: var(--sv-panel);
  position: sticky;
  top: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  gap: 11px;
}

/* ============================================================================
   THE SEARCH FIELD

   Built to the same rule as the Upcoming/Past/Cancelled control on My Bookings
   (my-bookings/v2/head.jsp), because that one is already right and the product
   should only have one idea about what a control looks like:

     - a fully-rounded track, radius 999px
     - NO border. A soft grey fill, rgba(23,22,26,0.05)
     - a solid accent pill sitting INSIDE the track
     - that pill carries a soft two-layer shadow, nothing else does

   WHY THE OLD ONE READ AS UNEVEN, AND WHY THIS CANNOT

   It was a bordered rectangle with the button welded into the right-hand end,
   so the button's corners had to match the box's corners minus the border
   width. Any drift -- a rounding, a 1px border, a font metric changing the
   height -- showed up as a hairline on one side only. The eye reads that
   asymmetry instantly even when it cannot name it.

   Here the button does not touch the edge at all. The track has even padding on
   every side, and the button is a circle inside it, so the gap above, below and
   to the right is ONE number (--sv-field-pad) rather than three that have to
   agree. There is no corner to match because the pill's corner is its own.
   Evenness is structural, not arithmetic.
   ========================================================================= */

.searchV2 {
  --sv-field-pad: 6px;    /* the even gap on every side of the button */
  --sv-field-h:   46px;   /* interior height; the button is this square */
}

.searchV2 .searchBox {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0;
  padding: var(--sv-field-pad);
  border: 0;
  border-radius: 999px;
  background: rgba(23, 22, 26, 0.05);
  transition: background-color .18s ease, box-shadow .18s ease;
}

/* Focus lifts the field off the panel rather than ringing it: the fill goes
   white and the accent becomes the edge. One ring, drawn by the track. The
   input's own outline is suppressed further down -- two rings on one control is
   what made the button look mis-sized before. */
.searchV2 .searchBox:focus-within {
  background: var(--sv-page);
  box-shadow: 0 0 0 2px var(--sv-accent),
              0 6px 18px -8px rgba(23, 22, 26, 0.45);
}

.searchV2 .searchBoxInput {
  flex: 1 1 auto;
  min-width: 0;
  height: var(--sv-field-h);
  border: 0;
  outline: 0;
  background: transparent;
  /* Left inset is larger than the track padding so the text starts on the
     straight part of the pill, not inside its curve. */
  padding: 0 12px 0 20px;
  font-family: 'Muli', sans-serif;
  font-size: 15px;
  line-height: var(--sv-field-h);
  color: var(--sv-ink);
}

.searchV2 .searchBoxInput::placeholder {
  color: var(--sv-ink-soft);
  opacity: 1;               /* Firefox dims placeholders by default */
}

/* A circle, not a slab. Square by construction -- width and height are the same
   variable -- so it can never render as a rounded rectangle if a font or a
   zoom level nudges the height. */
.searchV2 .searchBoxBtn {
  flex: 0 0 auto;
  width: var(--sv-field-h);
  height: var(--sv-field-h);
  border: 0;
  border-radius: 999px;
  background: var(--sv-accent);
  color: #fff;
  padding: 0;
  cursor: pointer;
  font-size: 15px;
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  /* The same two-layer shadow the active tab pill uses. */
  box-shadow: 0 1px 2px rgba(23, 22, 26, 0.20),
              0 2px 6px -2px rgba(23, 22, 26, 0.16);
  transition: transform .16s cubic-bezier(0.32, 0.72, 0, 1), filter .16s ease;
}

.searchV2 .searchBoxBtn:hover { filter: brightness(0.94); }
.searchV2 .searchBoxBtn:active { transform: scale(0.94); }

.searchV2 .searchPanelControls {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.searchV2 .searchGeoBtn {
  border: 0;
  background: none;
  padding: 0;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--sv-accent);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  letter-spacing: .01em;
}

.searchV2 .searchGeoBtn:hover { text-decoration: underline; }
.searchV2 .searchGeoBtn[disabled] { opacity: .5; cursor: default; text-decoration: none; }

.searchV2 .searchToggle {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--sv-ink-mid);
  cursor: pointer;
  margin: 0;
  user-select: none;
}

.searchV2 .searchToggle input { margin: 0; cursor: pointer; accent-color: var(--sv-accent); }

/* --- list heading ------------------------------------------------------- */

.searchV2 .searchListWrap {
  flex: 1 1 auto;
  /* Same min-height:0 story as the panel. This is the element that actually
     scrolls, so without it there is no scroll container anywhere in the column
     and the wheel goes to the page. */
  min-height: 0;
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
  /* Wheel over the list scrolls the list, and STOPS at its ends rather than
     handing the remaining scroll to the document underneath. */
  overscroll-behavior: contain;
}

.searchV2 .searchListHead {
  padding: 15px 18px 8px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.searchV2 .searchListLabel {
  font-family: 'Poppins', 'Muli', sans-serif;
  font-size: 18px;
  font-weight: 600;
  color: var(--sv-ink);
  letter-spacing: -.015em;
}

.searchV2 .searchListSub {
  font-size: 12.5px;
  color: var(--sv-ink-soft);
}

.searchV2 .searchList { padding: 4px 10px 18px; }

.searchV2 .searchListNote {
  margin: 4px 18px 20px;
  padding: 10px 12px;
  border-radius: 8px;
  background: var(--sv-hover);
  font-size: 12px;
  color: var(--sv-ink-mid);
  line-height: 1.5;
}

/* --- the card ----------------------------------------------------------- */

.searchV2 .searchRow {
  display: flex;
  align-items: flex-start;
  gap: 14px;
  padding: 14px 12px;
  border-radius: 10px;
  cursor: pointer;
  position: relative;
  transition: background-color .12s ease, box-shadow .12s ease;
}

.searchV2 .searchRow + .searchRow { margin-top: 2px; }

/* Hover AND the class map.jsp sets when you point at the matching pin. One
   appearance for both, because to the reader they are the same event. */
.searchV2 .searchRow:hover,
.searchV2 .searchRow.is-active {
  background: var(--sv-hover);
}

/* Selected: a pin was clicked. Stronger than hover and it persists. */
.searchV2 .searchRow.is-selected {
  background: var(--sv-page);
  box-shadow: var(--sv-shadow-md);
}

.searchV2 .searchRow.is-selected::before {
  content: '';
  position: absolute;
  left: 0;
  top: 10px;
  bottom: 10px;
  width: 3px;
  border-radius: 0 3px 3px 0;
  background: var(--sv-accent);
}

/* Thumbnail. Airbnb, Domain and Booking all lead a result with a picture at a
   size you can actually read -- that is what makes a list scannable rather than
   a table of names. Sized up substantially now that the number badge is gone
   and the panel is wider. Photo only: no lettered overlay. */
.searchV2 .searchRowThumb {
  flex: 0 0 auto;
  width: 116px;
  height: 92px;
  border-radius: 10px;
  overflow: hidden;
  background: linear-gradient(140deg, #e6e8ec, #d4d8de);
  position: relative;
}

.searchV2 .searchRowThumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Listing-only venues get a slightly muted photo, so the difference between
   "you can book this" and "this exists" is legible before you read a word. */
.searchV2 .searchRow.listingOnly .searchRowThumb img {
  filter: saturate(0.55);
  opacity: .85;
}

.searchV2 .searchRowBody {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.searchV2 .searchRowName {
  font-family: 'Poppins', 'Muli', sans-serif;
  font-size: 15px;
  font-weight: 600;
  color: var(--sv-ink);
  line-height: 1.3;
  letter-spacing: -.005em;
  text-decoration: none;
  /* Two lines then ellipsis -- venue names run long and a third line pushes
     the next card off a phone screen. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.searchV2 .searchRowName:hover { color: var(--sv-accent); text-decoration: none; }

.searchV2 .searchRow.listingOnly .searchRowName {
  font-weight: 500;
  color: var(--sv-ink-mid);
}

.searchV2 .searchRowWhere {
  font-size: 11.5px;
  color: var(--sv-ink-soft);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.searchV2 .searchRowBook {
  align-self: flex-start;
  margin-top: 4px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .02em;
  color: var(--sv-accent);
  text-decoration: none;
  border: 1px solid var(--sv-accent);
  border-radius: 100px;
  padding: 3px 10px;
  line-height: 1.4;
  transition: background-color .12s ease, color .12s ease;
}

.searchV2 .searchRowBook:hover,
.searchV2 .searchRow.is-selected .searchRowBook {
  background: var(--sv-accent);
  color: #fff;
  text-decoration: none;
}

/* The venue's own booking system, for venues we do not take bookings for.
   Deliberately QUIETER than .searchRowBook above: it is a real booking path and
   must be offered, but it sends the reader off-site, so it should not compete
   with the venue we can book directly. Outline in ink rather than accent.

   The old ".searchRowViewOnly" rule lived here and styled a "Listing only"
   badge. That badge is gone -- a venue with no booking path now gets no label
   at all, which is what tennisvenues.com.au has always done. */
.searchV2 .searchRowBookExternal {
  align-self: flex-start;
  margin-top: 4px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .02em;
  color: var(--sv-ink-mid);
  text-decoration: none;
  border: 1px solid var(--sv-hairline);
  border-radius: 100px;
  padding: 3px 10px;
}

.searchV2 .searchRowBookExternal:hover,
.searchV2 .searchRow.is-selected .searchRowBookExternal {
  color: var(--sv-ink);
  border-color: var(--sv-ink-soft);
  text-decoration: none;
}

/* Small and set off the label, so it reads as "leaves the site" rather than as
   part of the wording. */
.searchV2 .searchRowBookExternal .fa {
  font-size: 9px;
  margin-left: 4px;
  opacity: .75;
}

.searchV2 .searchRowDist {
  flex: 0 0 auto;
  font-size: 11px;
  color: var(--sv-ink-soft);
  font-variant-numeric: tabular-nums;
  padding-top: 3px;
  white-space: nowrap;
}

/* Shown instead of a distance when a venue has no coordinates, so "5 in the
   list, 3 on the map" reads as a fact about the data rather than a bug. */
.searchV2 .searchRowNoPin {
  flex: 0 0 auto;
  font-size: 10px;
  color: var(--sv-ink-faint);
  padding-top: 4px;
  white-space: nowrap;
  font-style: italic;
  cursor: help;
}

/* A row with no pin cannot be synced with the map, so it should not look
   clickable in the way the others do. */
.searchV2 .searchRow:has(.searchRowNoPin) { cursor: default; }

/* --- the autocomplete dropdown (shared markup with the classic page) ----- */

.searchV2 .searchBox .autocomplete-items {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 20;
  background: var(--sv-page);
  border: 1px solid var(--sv-hairline);
  border-radius: 8px;
  box-shadow: var(--sv-shadow-md);
  max-height: 320px;
  overflow-y: auto;
}

.searchV2 .searchBox .autocomplete-items:empty { display: none; }

.searchV2 .searchBox .autocomplete-items div {
  padding: 9px 12px;
  font-size: 13px;
  border-bottom: 1px solid var(--sv-hairline);
  cursor: pointer;
}

.searchV2 .searchBox .autocomplete-items div:last-child { border-bottom: 0; }
.searchV2 .searchBox .autocomplete-items div:hover { background: var(--sv-hover); }

/* --- the map's info card ------------------------------------------------ */
/* Google wraps InfoWindow content in its own chrome; this styles the node
   map.jsp builds, which sits inside it. */

/* THE BUBBLE'S OWN CHROME, ZEROED.

   Google draws the info window as .gm-style-iw-c with about 12px of padding and
   a scrolling .gm-style-iw-d inside it, and the close button is positioned
   against that padding. Left alone, the photograph sits in a white frame with a
   white margin all the way round -- which is what made this card look like a
   picture that had been dropped into a document rather than a card with a
   picture in it.

   The padding moves ONTO the content instead (see .searchInfoBody), so the
   photograph runs to the bubble's own rounded edge exactly as it does on a
   featured venue card, and the words below it are inset. Same object, one
   frame.

   !important throughout: these compete with inline styles the Maps SDK writes
   onto its own nodes, and there is nothing else on the page they can reach --
   every selector here is inside .gm-style. */
.gm-style .gm-style-iw-c {
  /* NO "position: relative" HERE, AND THAT LINE IS WHAT MADE THE CARD 648px
     WIDE.

     It was added so the close button, taken out of flow below, would be
     positioned against the bubble -- which it needed to be, and already was:
     the SDK draws this element position:ABSOLUTE, and an absolutely positioned
     element is a containing block for absolutely positioned descendants just as
     well as a relative one. The override bought nothing and cost the sizing.

     Because the other thing "position: absolute" does here is SHRINK-WRAP. Put
     back into flow as position:relative, the bubble becomes an ordinary block
     inside .gm-style-iw-t, which the SDK makes 9999px wide -- so instead of
     taking its width from the card, it filled the line and stopped at whatever
     max-width the SDK had computed from the size of the map. Measured on a
     1440px window: a 244px card in a 648px bubble, which is 400px of empty
     white with the close button stranded at the far end of it, and the tail
     pointing at the pin from somewhere off to the left. On a phone the same
     fault was only 20px wide, because the map is narrower -- so it read as a
     rendering quirk on the one viewport where anyone would have caught it.

     Nothing else in this block changes. The padding, the radius and the clip
     are all still needed and are all still fighting the SDK's inline styles;
     it is only the positioning that has to be left alone. */
  padding: 0 !important;
  border-radius: 14px !important;
  overflow: hidden !important;
  box-shadow: 0 2px 7px 1px rgba(0, 0, 0, 0.25);
}

/* THE SPACER ROW ABOVE THE CONTENT, which is the rest of the white strip.
   .gm-style-iw-c is a flex COLUMN with two children: a 17px div that holds the
   close button, and then .gm-style-iw-d with everything we render. Taking the
   button out of flow (below) empties that first div but does not remove it --
   measured, it still claimed 17px, and 17px of white above a full-bleed
   photograph is exactly as visible as 26 was.
   Collapsed rather than display:none, because the button lives inside it and is
   positioned against .gm-style-iw-c; hiding the parent would hide it too. */
.gm-style .gm-style-iw-c > div:not(.gm-style-iw-d) {
  height: 0 !important;
  min-height: 0 !important;
  overflow: visible !important;
}

.gm-style .gm-style-iw-d {
  padding: 0 !important;
  /* Google sets overflow:auto and a max-height inline. The card is short and
     fixed, so a scroller inside it only ever shows a stray scrollbar. */
  overflow: hidden !important;
  max-height: none !important;
}

/* THE CLOSE BUTTON HAS TO COME OUT OF FLOW, and this is what was putting a
   white strip across the top of the card.

   The bubble is a flex COLUMN: the button is a sibling above .gm-style-iw-d,
   not an overlay, so it takes a row of its own and pushes the content down by
   exactly its own height. Measured, .gm-style-iw-c started at 214px and the
   photograph at 240 -- 26px, which is the height set below, which is why it
   looked like a deliberate white band rather than a bug.

   Zeroing the padding (above) does nothing about it; top/right do nothing
   either while the button is still in flow. position:absolute is the fix, and
   then the offsets mean something. Over the photograph now, so it gets a white
   disc under it -- a plain grey glyph disappears on a dark image. */
.gm-style .gm-style-iw-c button.gm-ui-hover-effect {
  position: absolute !important;
  z-index: 2;
  top: 6px !important;
  right: 6px !important;
  width: 26px !important;
  height: 26px !important;
  border-radius: 50% !important;
  background: rgba(255, 255, 255, 0.92) !important;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.28);
  opacity: 1 !important;
}

.gm-style .gm-style-iw-c button.gm-ui-hover-effect > span {
  margin: 0 auto !important;
  width: 16px !important;
  height: 16px !important;
}

.searchInfoWindow {
  font-family: 'Muli', -apple-system, sans-serif;
  min-width: 150px;
  /* Wider than the 230 it was, because it now leads with a picture and a
     230px-wide photograph in a card with 4px of padding is a strip. 244 is
     what keeps the 16:10 thumbnail readable without the bubble covering the
     pins around the one that was clicked. */
  width: 244px;
  max-width: 244px;
  padding: 0;
  line-height: 1.4;
}

/* THE PHOTOGRAPH, above the name -- the same one the list row shows, copied
   from it at open time (see thumbForAlias in map.jsp).

   A FIXED ASPECT BOX, not a height on the img. The picture is whatever the
   venue uploaded; object-fit crops it to the frame rather than letting a
   portrait photograph make the bubble twice as tall as it should be, and the
   box holds its shape while the image decodes so the card does not resize
   under the pointer.

   Flush to every edge it can reach -- no radius of its own, because the bubble
   above already clips to 14px and a second radius inside a rounded clip is the
   notch this codebase has fixed once already on the featured cards. */
.searchInfoWindow .searchInfoThumb {
  margin: 0;
  overflow: hidden;
  background: #ececed;
  aspect-ratio: 16 / 10;
}

/* The words, and the only thing in the card that is inset. */
.searchInfoWindow .searchInfoBody {
  padding: 12px 14px 14px;
}

.searchInfoWindow .searchInfoThumb img {
  display: block;
  width: 100%;
  height: 100%;
  -o-object-fit: cover;
     object-fit: cover;
}

.searchInfoWindow a {
  font-family: 'Poppins', 'Muli', sans-serif;
  font-size: 14px;
  font-weight: 600;
  color: #17161a;
  text-decoration: none;
  display: block;
}

.searchInfoWindow a:hover { color: var(--accent, #2196f3); text-decoration: underline; }

.searchInfoWindow .searchInfoWhere {
  font-size: 11.5px;
  color: #8b8892;
  margin-top: 2px;
}

.searchInfoWindow .searchInfoBook {
  display: inline-block;
  margin-top: 8px;
  font-size: 11px;
  font-weight: 700;
  color: #fff;
  background: var(--accent, #2196f3);
  border-radius: 100px;
  padding: 4px 12px;
  text-decoration: none;
}

.searchInfoWindow .searchInfoBook:hover { color: #fff; text-decoration: none; filter: brightness(0.92); }

/* --- empty and error states --------------------------------------------- */

.searchV2 .searchListWrap .searchListHead:only-child .searchListLabel {
  color: var(--sv-ink-mid);
  font-weight: 500;
}

/* --- MOBILE: stack, do not squeeze -------------------------------------- */
/* A 400px panel beside a map does not survive a phone. Below 992px the map
   becomes a fixed band on top and the list flows underneath in normal page
   scroll -- the same arrangement every suburb page already uses, so there is
   nothing new for a visitor to learn. */

@media (max-width: 991px) {
  /* THE CARD IS NOT ALLOWED TO BE SHORTER THAN THE CARD.

     The SDK writes a max-height onto the bubble computed from the size of the
     MAP, so that an info window can never be taller than the thing it belongs
     to. On a desktop the map is full height and that cap never binds. On a
     phone the map is a fixed 260px band -- and the cap came out at 227px
     against a card that needs 267.

     The bubble is overflow:hidden, because that is what clips the photograph to
     its rounded corners, so the 40px did not scroll and did not overflow. It was
     simply cut off: a picture, a close button, and no name, no suburb and no
     "Book online" -- the three things the card exists to show. Nothing errored,
     and every check that looked at the CONTENT still passed, because the
     content was all there and just not on screen.

     So the cap is lifted here and the bubble takes its content's height. It can
     then extend past the map band and over the list below it, which is what an
     overlay anchored to a pin should do -- and it is still Google that keeps it
     on screen, because the info window auto-pans the map to fit itself. What is
     asserted is the outcome rather than the mechanism: RunnerMapCard checks that
     the last line of the card is inside the bubble AND that the bubble is inside
     the window, at a phone width. */
  .gm-style .gm-style-iw-c {
    max-height: none !important;
  }

  /* Stacked, and the PAGE scrolls again -- so the split goes back to growing
     with its content and the panel stops being a scroll container.

     THE ORDER MATTERS AND IS NOT THE DESKTOP ORDER. Wanted, top to bottom:
        search box  ->  map  ->  venue list
     An earlier column-reverse put the map first and dragged the search box down
     with the rest of the panel, so the page opened on a map with no visible way
     to search -- the search box started 444px down.

     display:contents dissolves .searchPanel on mobile so its two children become
     flex items of the split alongside the map, which is what makes them
     orderable independently. The panel's own background and border go with it;
     neither is wanted in a stacked layout anyway. */
  .searchV2 .searchSplit {
    flex-direction: column;
    height: auto;
    min-height: 0;
  }

  .searchV2 .searchPanel {
    display: contents;
  }

  .searchV2 .searchPanelTop { order: 1; }
  .searchV2 .searchMap      { order: 2; }
  .searchV2 .searchListWrap { order: 3; }

  .searchV2 .searchMap {
    width: 100%;
    height: auto;
  }

  .searchV2 .searchMapShell,
  .searchV2 .searchMapCanvas,
  .searchV2 #map-canvas {
    height: 44vh;
    min-height: 260px;
  }

  /* The panel is no longer its own scroll region, so its header should not
     stick to the viewport -- it would float over the page content. */
  .searchV2 .searchPanelTop { position: static; }
  .searchV2 .searchListWrap { overflow: visible; }
}

/* ROOM FOR THE SITE SWITCHER.

   Below 768px the switcher is a small tab hanging off the bottom-left of the
   header (custom.css.jsp), and on this page the panel starts at the header's
   bottom edge -- so with the stock 16px the tab sat on the top-left corner of
   the search field and swallowed taps meant for it. 34px clears the tab's 30px
   by a hair.

   767px and NOT the 991px block above, even though the stacked layout starts
   there: from 768px up the switcher is back beside the logo, inside the header,
   and this padding would be 18px of space with nothing in it. Measured against
   that tab; if its height changes, this follows. */
@media (max-width: 767px) {
  .searchV2 .searchPanelTop { padding-top: 34px; }
}

@media (max-width: 480px) {
  .searchV2 .searchPanelControls { flex-wrap: wrap; }
  .searchV2 .searchRowThumb { width: 92px; height: 74px; }
}

/* --- accessibility ------------------------------------------------------ */

.searchV2 a:focus-visible,
.searchV2 button:focus-visible,
.searchV2 input:focus-visible,
.searchV2 .searchRow:focus-visible {
  outline: 2px solid var(--sv-accent);
  outline-offset: 2px;
}

/* ...but NOT the search input or its button.

   The search box already shows focus as a whole, via :focus-within on the
   wrapper. Letting the input draw its own outline as well produced two red
   rectangles: the box's border, and a second ring floating 2px outside the
   INPUT only -- which stops where the button starts, so the button appeared to
   sit outside the field and at the wrong size. It was one control wearing two
   focus rings, not a sizing bug.

   Focus is still visible, and still visible for keyboard users: it is the
   ring drawn by .searchBox:focus-within, up where the field is defined. */
.searchV2 .searchBoxInput:focus,
.searchV2 .searchBoxInput:focus-visible,
.searchV2 .searchBoxBtn:focus-visible {
  outline: none;
}

/* NO SECOND :focus-within RULE HERE.

   There was one, and because it sat later in the file at the same specificity it
   silently beat the one that defines the field -- so the focus ring rendering
   was a 10% tint rather than the solid accent ring intended, and setting
   border-color did nothing at all once the border was removed. Two rules for one
   state is the collision worth avoiding; the field's own rule is the only one.
   :focus-within already covers the button, since the button is inside the box. */

/* The list is a live region; announce the count when the map moves without
   yanking focus. Visually identical. */
.searchV2 .searchListWrap:focus { outline: none; }

@media (prefers-reduced-motion: reduce) {
  .searchV2 * {
    transition: none !important;
    animation: none !important;
  }
}

/* --- "showing X, also found Y" ------------------------------------------ */
/* Sits under the filters, above the list. A search that matched more than one
   place goes to the nearest and names the others here rather than framing all
   of them at once -- see the note in map.jsp for why. */

.searchV2 .searchNote {
  margin: 0 18px 12px;
  padding: 9px 12px;
  border-radius: 8px;
  background: var(--sv-accent-soft);
  font-size: 12.5px;
  line-height: 1.5;
  color: var(--sv-ink-mid);
}

.searchV2 .searchNoteLead { font-weight: 700; color: var(--sv-ink); }

.searchV2 .searchNoteAlt {
  color: var(--sv-accent);
  font-weight: 600;
  text-decoration: none;
  border-bottom: 1px solid currentColor;
}

.searchV2 .searchNoteAlt:hover { color: var(--sv-accent); text-decoration: none; }
