/*
 * Purpose: Search and collection page - search bar, filter sidebar and drawer,
 * results, map split and pagination.
 */

.rh-search {
  padding-bottom: var(--space-64);
}

/* ------------------------------------------------------------- SEARCH BAR */

/*
 * The search bar is always visible on Find a Room. It stops below the header
 * while the header is showing, and takes the top of the viewport when the
 * header hides. main.js keeps --rh-header-offset in step with that.
 *
 * The offset is read here, on the bar itself, and not through a sibling
 * selector. `.rh-header--sticky ~ .rh-search` never matched: the search markup
 * lives inside <main>, so it is not a sibling of the header, and the bar was
 * silently left at top: 0 - pinned underneath the header, which is why only the
 * header appeared on the way back up.
 *
 * The fallback is 0 rather than the header height: main.js publishes the offset
 * on every page that has a sticky header, so an unset variable means there is
 * no sticky header to sit below.
 */
.rh-search__bar {
  position: sticky;
  top: var(--rh-header-offset, 0px);
  z-index: var(--z-sticky);
  background-color: var(--rh-white);
  border-bottom: 1px solid var(--rh-border);
  padding-block: var(--space-12);
  /*
   * Same duration and easing as the header's transform, so the two travel
   * together instead of the bar snapping into place while the header slides.
   */
  transition: top var(--dur-base) var(--ease-out);
}

@media (prefers-reduced-motion: reduce) {
  .rh-search__bar {
    transition: none;
  }
}

.rh-search__form {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: var(--space-8);
  align-items: stretch;
}

/*
 * Buttons stand at --touch-target (44px) and inputs at --input-height (48px),
 * so the submit button sat visibly short of the field beside it. On this form
 * the button matches the field.
 */
.rh-search__form .rh-btn {
  min-height: var(--input-height);
}

.rh-search__field {
  position: relative;
  display: flex;
  align-items: center;
}

.rh-search__field .rh-icon {
  position: absolute;
  left: var(--space-12);
  width: 20px;
  height: 20px;
  color: var(--rh-text-secondary);
  pointer-events: none;
}

.rh-search__input {
  width: 100%;
  min-height: var(--input-height);
  padding: var(--space-12) var(--space-16) var(--space-12) var(--space-40);
  border: 1px solid var(--rh-border-input);
  border-radius: var(--r-input);
  font-size: var(--fs-body);
}

.rh-search__input:focus {
  outline: none;
  border-color: var(--rh-teal);
  box-shadow: 0 0 0 3px var(--rh-teal-light);
}

/* ---------------------------------------------------------------- LAYOUT */

.rh-search__layout {
  display: grid;
  gap: var(--space-32);
  padding-top: var(--space-24);
  grid-template-columns: 1fr;
}

@media (min-width: 1024px) {
  .rh-search__layout {
    grid-template-columns: 264px minmax(0, 1fr);
    gap: var(--space-40);
    align-items: start;
  }
}

.rh-search__main {
  min-width: 0; /* lets grid children shrink instead of forcing overflow */
}

/* ------------------------------------------------------------------ HEAD */

.rh-search__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-16);
  margin-bottom: var(--space-16);
}

.rh-search__title {
  font-size: var(--fs-h3);
  line-height: var(--lh-snug);
}

.rh-search__count {
  margin-top: var(--space-4);
  font-size: var(--fs-small);
  color: var(--rh-text-secondary);
}

.rh-search__controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-8);
}

.rh-search__filter-toggle {
  display: inline-flex;
}

@media (min-width: 1024px) {
  .rh-search__filter-toggle {
    display: none;
  }
}

.rh-search__filter-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding-inline: var(--space-4);
  border-radius: var(--r-pill);
  background-color: var(--rh-teal);
  color: var(--rh-text-inverse);
  font-size: var(--fs-12);
}

.rh-select--sm {
  min-height: 36px;
  padding-block: var(--space-4);
  font-size: var(--fs-small);
  width: auto;
}

.rh-search__view {
  display: inline-flex;
  border: 1px solid var(--rh-border-input);
  border-radius: var(--r-button);
  overflow: hidden;
}

.rh-search__view-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  min-height: 36px;
  padding: var(--space-4) var(--space-12);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--rh-text-secondary);
  background-color: var(--rh-white);
}

.rh-search__view-btn:hover {
  color: var(--rh-teal);
  text-decoration: none;
}

.rh-search__view-btn[aria-pressed="true"] {
  background-color: var(--rh-teal-12);
  color: var(--rh-teal);
}

/* -------------------------------------------------------- ACTIVE FILTERS */

.rh-active-filters {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-8);
  margin-bottom: var(--space-20);
}

.rh-active-filters__label {
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  color: var(--rh-text-secondary);
}

.rh-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
  min-height: 32px;
  padding: var(--space-4) var(--space-12);
  border: 1px solid var(--rh-border);
  border-radius: var(--r-pill);
  background-color: var(--rh-teal-light);
  color: var(--rh-teal);
  font-size: var(--fs-caption);
  font-weight: var(--fw-medium);
}

.rh-chip:hover {
  background-color: var(--rh-white);
  border-color: var(--rh-teal);
  text-decoration: none;
}

.rh-active-filters__clear {
  font-size: var(--fs-caption);
  font-weight: var(--fw-semibold);
  color: var(--rh-text-secondary);
  text-decoration: underline;
}

/* --------------------------------------------------------------- FILTERS */

.rh-filters__overlay {
  display: none;
}

.rh-filters__head {
  display: none;
}

@media (min-width: 1024px) {
  /*
   * Sticky, and only scrolls when the filter list is genuinely taller than the
   * viewport. The offset tracks the header the same way the map pane does -
   * it was pinned to the static --header-height, which drifted out of step once
   * the header started hiding on scroll.
   */
  .rh-filters {
    position: sticky;
    top: calc(var(--rh-header-offset, 0px) + var(--space-80));
    max-height: calc(100vh - var(--rh-header-offset, 0px) - var(--space-96));
    overflow-y: auto;
    border: 1px solid var(--rh-border);
    border-radius: var(--r-card);
    background-color: var(--rh-white);
  }

  .rh-filters__panel {
    display: block;
  }
}

/* Below desktop the filter panel is a full-height drawer. */
@media (max-width: 1023px) {
  .rh-filters {
    position: fixed;
    inset: 0;
    z-index: var(--z-drawer);
    visibility: hidden;
  }

  .rh-filters[data-open="true"] {
    visibility: visible;
  }

  .rh-filters__overlay {
    display: block;
    position: absolute;
    inset: 0;
    background-color: rgba(3, 38, 34, 0.5);
    opacity: 0;
    transition: opacity var(--dur-base) var(--ease-out);
  }

  .rh-filters[data-open="true"] .rh-filters__overlay {
    opacity: 1;
  }

  .rh-filters__panel {
    position: absolute;
    inset-block: 0;
    left: 0;
    display: flex;
    flex-direction: column;
    width: min(92vw, 380px);
    height: 100dvh;
    background-color: var(--rh-white);
    transform: translateX(-100%);
    transition: transform var(--dur-base) var(--ease-out);
  }

  .rh-filters[data-open="true"] .rh-filters__panel {
    transform: translateX(0);
  }

  .rh-filters__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-16);
    border-bottom: 1px solid var(--rh-border);
    flex-shrink: 0;
  }

  .rh-filters__form {
    display: flex;
    flex-direction: column;
    flex: 1;
    min-height: 0;
  }

  .rh-filters__body {
    flex: 1;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
  }
}

.rh-filters__title {
  font-size: var(--fs-h4);
}

.rh-filters__body {
  padding: var(--space-8) var(--space-16);
}

.rh-filter-group {
  border: 0;
  border-bottom: 1px solid var(--rh-border);
  margin: 0;
  padding: 0;
}

.rh-filter-group:last-child {
  border-bottom: 0;
}

.rh-filter-group__toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  min-height: var(--touch-target);
  padding: var(--space-12) 0;
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--rh-text-primary);
  text-align: left;
}

.rh-filter-group__toggle .rh-icon {
  flex-shrink: 0;
  color: var(--rh-text-secondary);
  transition: transform var(--dur-fast) var(--ease-out);
}

.rh-filter-group__toggle[aria-expanded="true"] .rh-icon {
  transform: rotate(180deg);
}

.rh-filter-group__body {
  padding-bottom: var(--space-12);
}


.rh-filter-range {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-12);
}

.rh-filters__foot {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  padding: var(--space-16);
  border-top: 1px solid var(--rh-border);
  background-color: var(--rh-white);
  flex-shrink: 0;
}

/*
 * "Clear all" was shrinking as a flex item and wrapping onto two lines. It
 * keeps its words together; the apply button takes whatever is left.
 */
.rh-filters__foot .rh-btn--ghost {
  flex-shrink: 0;
  white-space: nowrap;
}

.rh-filters__foot .rh-btn--block {
  flex: 1 1 auto;
  min-width: 0;
}

@media (max-width: 1023px) {
  .rh-filters__foot {
    padding-bottom: calc(var(--space-16) + env(safe-area-inset-bottom, 0px));
  }
}

/* --------------------------------------------------------------- RESULTS */

.rh-search__results {
  margin-bottom: var(--space-32);
}

/* Map view: results column beside the map on large screens. */
.rh-search__split {
  display: grid;
  gap: var(--space-16);
  grid-template-columns: 1fr;
  margin-bottom: var(--space-32);
}

/*
 * The map is the one pane that is always whole; everything else follows it.
 *
 * Giving all three columns their own height was the mistake. Filters, results
 * and map each got a cap and each cut its content off mid-item, so the page was
 * three separate scrollbars and nothing was ever fully readable.
 *
 * Now only the map is pinned: it sticks to the viewport and sizes itself to fit
 * inside it, so the map and its place list are visible the whole way down.
 * Results run at their natural height and scroll with the page, which is what
 * you want when reading a list. Filters do the same.
 */
@media (min-width: 1024px) {
  .rh-search__split {
    grid-template-columns: minmax(320px, 420px) minmax(0, 1fr);
    align-items: start;
  }

  .rh-search__results--compact {
    display: flex;
    flex-direction: column;
    gap: var(--space-16);
    margin-bottom: 0;
  }
}

.rh-search__results--compact {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
}

/*
 * Cards keep their natural height. Without this they are flex items with the
 * default flex-shrink: 1, and .rh-card's height: 100% resolves against the
 * column - which collapsed every card to a strip showing only its badges, with
 * the body clipped by the card's own overflow: hidden.
 */
.rh-search__results--compact > * {
  flex: 0 0 auto;
  height: auto;
}

/* ------------------------------------------------------------------- MAP */

.rh-map {
  border-radius: var(--r-card);
  overflow: hidden;
  border: 1px solid var(--rh-border);
  background-color: var(--rh-surface);
}

/*
 * The Leaflet container. It needs a height in CSS before the map is built -
 * Leaflet measures the element, and a zero-height container renders nothing.
 */
.rh-map__canvas {
  width: 100%;
  height: 320px;
  background-color: var(--rh-surface);
  z-index: 0;
}

/*
 * The map pane is the anchor: it sticks to the viewport and sizes itself to fit
 * inside it, so the map, the count and the place list are all on screen the
 * whole way down the results.
 *
 * It sits below the sticky search bar, which itself sits below the header, so
 * the offset is the header's published offset plus the bar. --rh-header-offset
 * is maintained by main.js and already accounts for the header hiding on scroll
 * and for the admin bar.
 */
@media (min-width: 1024px) {
  .rh-map {
    position: sticky;
    top: calc(var(--rh-header-offset, 0px) + var(--space-80));
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - var(--rh-header-offset, 0px) - var(--space-96));
    min-height: 0;
  }

  .rh-map__canvas {
    /* Fixed, so the list below it gets whatever height is left over. */
    flex: 0 0 auto;
    height: 340px;
  }

  .rh-map__head {
    flex: 0 0 auto;
  }

  /*
   * Takes the remaining height. It only scrolls when there are more places than
   * fit - with a handful of results the whole list is visible.
   */
  .rh-map__list {
    flex: 1 1 auto;
    min-height: 0;
    max-height: none;
    overflow-y: auto;
  }
}

/* Leaflet's own popup, restyled to match the cards beside it. */
.rh-map__popup {
  display: grid;
  gap: var(--space-4);
}

.rh-map__popup-name {
  font-weight: var(--fw-semibold);
  color: var(--rh-text-primary);
}

.rh-map__popup-price {
  font-weight: var(--fw-semibold);
  color: var(--rh-teal);
}

.rh-map__popup-meta {
  font-size: var(--fs-caption);
  color: var(--rh-text-secondary);
}

.rh-map__fallback {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-12);
  min-height: 320px;
  padding: var(--space-32);
  text-align: center;
  color: var(--rh-text-secondary);
  font-size: var(--fs-small);
}

/* Leaflet popup restyled to the design system. */
.rh-map .leaflet-popup-content-wrapper {
  border-radius: var(--r-card);
  padding: 0;
  overflow: hidden;
  box-shadow: var(--shadow-lg);
}

.rh-map .leaflet-popup-content {
  margin: 0;
  width: 232px !important;
}

.rh-map-popup {
  display: block;
  color: var(--rh-text-primary);
}

.rh-map-popup:hover {
  text-decoration: none;
}

.rh-map-popup__body {
  padding: var(--space-12);
}

.rh-map-popup__price {
  font-size: var(--fs-body);
  font-weight: var(--fw-bold);
}

.rh-map-popup__name {
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  margin-top: var(--space-4);
}

.rh-map-popup__meta {
  font-size: var(--fs-caption);
  color: var(--rh-text-secondary);
  margin-top: var(--space-4);
}

/* Price pin marker */
.rh-map-pin {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4) var(--space-8);
  border-radius: var(--r-pill);
  background-color: var(--rh-teal);
  color: var(--rh-text-inverse);
  font-size: var(--fs-12);
  font-weight: var(--fw-bold);
  white-space: nowrap;
  box-shadow: var(--shadow-md);
  border: 2px solid var(--rh-white);
}

.rh-map-pin--active {
  background-color: var(--rh-dark);
}

/* ------------------------------------------------------------ PAGINATION */

.rh-pagination {
  display: flex;
  justify-content: center;
  margin-top: var(--space-32);
}

.rh-pagination__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-4);
}

.rh-pagination__list .page-numbers {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--touch-target);
  height: var(--touch-target);
  padding-inline: var(--space-12);
  border: 1px solid var(--rh-border);
  border-radius: var(--r-button);
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--rh-text-primary);
  background-color: var(--rh-white);
}

.rh-pagination__list .page-numbers:hover {
  border-color: var(--rh-teal);
  color: var(--rh-teal);
  text-decoration: none;
}

.rh-pagination__list .page-numbers.current {
  background-color: var(--rh-teal-12);
  border-color: var(--rh-teal-20);
  color: var(--rh-teal);
  font-weight: var(--fw-semibold);
}

.rh-pagination__list .page-numbers.dots {
  border-color: transparent;
  background: none;
}

/* Empty results state gets a little more room to breathe. */
.rh-empty--results {
  padding-block: var(--space-64);
}

.rh-empty__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-8);
  margin-top: var(--space-8);
}

/* ------------------------------------------------- GOOGLE MAPS LIST VIEW */

.rh-map__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-12);
  padding: var(--space-16);
  border-bottom: 1px solid var(--rh-border);
  background-color: var(--rh-white);
}

.rh-map__title {
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
}

.rh-map__list {
  display: grid;
  gap: 0;
  background-color: var(--rh-white);
  overflow-y: auto;
}

/*
 * Stacked layout only. Above this the map pane owns the height and hands the
 * list whatever is left. The cap used to live on the base rule, where it sat
 * after the desktop rules and quietly won on source order.
 */
@media (max-width: 1023px) {
  .rh-map__list {
    max-height: 520px;
  }
}

.rh-map__item {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-12);
  padding: var(--space-12) var(--space-16);
  border-bottom: 1px solid var(--rh-border);
}

.rh-map__item:last-child {
  border-bottom: 0;
}

.rh-map__item-name {
  font-size: var(--fs-small);
  font-weight: var(--fw-semibold);
  color: var(--rh-text-primary);
}

.rh-map__item-name:hover {
  color: var(--rh-teal);
}

.rh-map__item-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
  margin-top: var(--space-4);
  font-size: var(--fs-caption);
  color: var(--rh-text-secondary);
}

.rh-map__item-price {
  color: var(--rh-teal);
  font-weight: var(--fw-semibold);
}

.rh-map__item-link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--touch-target);
  height: var(--touch-target);
  border-radius: var(--r-button);
  background-color: var(--rh-surface);
  color: var(--rh-teal);
  flex-shrink: 0;
}

.rh-map__item-link:hover {
  background-color: var(--rh-teal-light);
}

/*
 * Two more max-heights on this list used to sit here, both after the pane rules
 * above and so both winning on source order. Between them and the pane height
 * the list had three different caps and none of them matched the column, which
 * is why the last places were unreachable. The pane owns the height now, and
 * the only remaining cap is scoped to the stacked layout.
 */
