/* ============================================================
   Search bar
   ============================================================ */

/* The map panel sits below this bar and must clear it. The bar is opaque and sticky, so
   any part of the map under it is painted over — and the map, which knows nothing about
   the bar, opens popups into that band. 116px is the bar with field labels; browse.js
   replaces the value with the measured height. */
.browse {
  --searchbar-height: 116px;
}

/* The city page has no search bar, so the map panel sticks straight under the header. */
.browse[data-mode='location'] {
  --searchbar-height: 0px;
}

.browse__searchbar {
  position: sticky;
  top: var(--header-height);
  z-index: var(--z-sticky);
  background: var(--color-white);
  border-bottom: 1px solid var(--border-subtle);
}

.browse__searchbar-inner {
  padding-block: var(--space-5);
}

/* Alignment is left on the base rule's flex-end. This bar renders the field labels, so
   centering the row would center the button against label-plus-field and lift it off the
   line the fields sit on. */
.browse__search .search-form__inner {
  max-width: 963px;
}

.browse__search .search-form__field {
  flex: 0 0 300px;
}

.browse__search .search-form__field--narrow {
  flex: 0 0 115px;
}

.browse__search .search-form__field .field {
  height: 50px;
}

.browse__search .search-form__submit {
  width: 200px;
  min-height: 50px;
  font-size: 18px;
  letter-spacing: 1.26px;
}

/* ============================================================
   Layout: results column plus optional map panel
   ============================================================ */

.browse__layout {
  display: grid;
  /* minmax, not `1fr` — see the 640px note: the automatic minimum let wide
     min-content push the whole results column past the viewport. */
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-8);
  align-items: start;
  padding-block: var(--space-10) var(--space-16);
}

/* With the map open the layout runs to the window's right edge. The left inset is a
   percentage of the full width rather than vw, so the scrollbar is not counted twice. */
.browse[data-map-visible='true'] .browse__layout {
  max-width: none;
  margin-inline: 0;
  padding-left: max(var(--gutter), calc((100% - var(--container-wide)) / 2));
  padding-right: 0;
  grid-template-columns: minmax(0, 1fr) var(--map-panel-width);
  gap: var(--map-panel-gap);
}

.browse__heading {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-8);
  margin-bottom: 30px;
}


/* A flex item's automatic minimum is its content, so without this a long city name
   refuses to shrink and pushes the toggle off the row. */
.browse__heading-copy {
  min-width: 0;
}

.browse__heading h1 {
  font-size: 30px;
  line-height: normal;
  font-weight: var(--weight-medium);
  letter-spacing: normal;
  color: var(--color-black);
}

.browse__subtitle {
  max-width: 900px;
  margin-top: var(--space-3);
  font-size: var(--text-body);
  color: var(--color-grey-secondary);
}

.browse__intro {
  max-width: 1309px;
  margin-top: var(--space-16);
  padding-top: var(--space-12);
  border-top: 1px solid var(--border-subtle);
  font-size: 18px;
  line-height: 30px;
  color: var(--color-grey-secondary);
}

/* The city page fills this from Location.Description, which is editor copy, so the tags
   inside it are theirs — these rules style what comes out rather than a structure. The
   editors use <h2> for sub-heads, and the global 50px h2 would dwarf the copy. */
.browse__intro > * {
  max-width: 880px;
}

.browse__intro p + p {
  margin-top: var(--space-4);
}

.browse__intro h2,
.browse__intro h3 {
  margin-top: var(--space-10);
  margin-bottom: var(--space-3);
  font-size: 28px;
  line-height: 36px;
  letter-spacing: -0.3px;
}

.browse__intro > :first-child {
  margin-top: 0;
}

.browse__intro a {
  color: var(--color-green-primary);
}

.browse__map-toggle,
.browse__map-hide {
  gap: 10px;
  padding-inline: var(--space-5);
  letter-spacing: 0.35px;
  box-shadow:
    0 10px 7.5px rgba(0, 0, 0, 0.1),
    0 4px 3px rgba(0, 0, 0, 0.1);
}

.browse__map-toggle {
  flex: none;
}

/* Once the panel is open its own overlaid button owns the toggle, so the heading
   copy of it would be a second identical control. */
.browse[data-map-visible='true'] .browse__map-toggle {
  display: none;
}

.browse__map-hide {
  position: absolute;
  top: 43px;
  right: 25px;
  z-index: 500;
}

/* ============================================================
   Results count
   ============================================================ */

.browse__resultsbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: 30px;
}

.browse__count {
  font-size: var(--text-lead);
  line-height: normal;
  font-weight: var(--weight-medium);
  color: #000000;
}

.browse__count-city {
  color: var(--color-green-primary);
}

/* ============================================================
   Card grid
   ============================================================ */

.browse__grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 30px;
}

.browse[data-map-visible='true'] .browse__grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 30px 20px;
}

/* ---- Travel promo tile ---- */

.promo-card {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: var(--space-5);
  padding: 40px 30px;
  border-radius: var(--radius-control-lg);
  background: linear-gradient(151deg, var(--color-green-primary) 13.494%, #001a1d 199.79%);
  color: var(--text-inverse);
  text-align: center;
}

.promo-card__copy {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

/* base.css colors every heading explicitly, so one on a dark ground has to take the
   color back. */
.promo-card__title {
  font-size: 45px;
  /* Not `normal`: Bricolage's own line gap spaces a wrapped title 96px apart. */
  line-height: 1.2;
  letter-spacing: -0.5px;
  color: inherit;
}

/* Literal sizes, not --text-lead: that token steps down to 16px on mobile, and this
   paragraph stays at 18px. */
.promo-card__copy p {
  font-size: 20px;
  line-height: 32px;
  letter-spacing: -0.2px;
}

.promo-card__cta {
  align-self: center;
  min-height: 60px;
  max-width: 100%;
  padding-inline: 49px;
  font-size: 20px;
  letter-spacing: 1.4px;
  box-shadow: 0 10px 7.5px rgba(140, 60, 103, 0.2);
  /* The .btn nowrap must yield here: under OS text scaling the one-line label is
     wider than a phone column, and a wrapped pill beats a sideways-scrolling page. */
  white-space: normal;
}

.browse__empty {
  padding: var(--space-16) 0;
  text-align: center;
  color: var(--text-muted);
}


/* ============================================================
   Map panel
   ============================================================ */

.browse__map {
  position: sticky;
  top: calc(var(--header-height) + var(--searchbar-height));

  /* An open popup lives inside the map *container*, not
     inside the window, so any part of the panel the visitor cannot see is
     a band the popup can open into unseen. The panel is therefore never taller than the
     gap the header and the search bar leave, less 24px of breathing room. */
  height: min(
    900px,
    calc(100vh - var(--header-height) - var(--searchbar-height) - var(--space-6))
  );
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-grey-light);
}

.browse[data-map-visible='false'] .browse__map {
  display: none;
}

.browse__map-canvas {
  width: 100%;
  height: 100%;
}

/* --- Price pins (shared by the Google overlays and the static fallback) --- */

.map-pin {
  position: absolute;
  translate: -50% -50%;
  display: flex;
  align-items: center;
  height: 24px;
  padding-inline: 10px;
  border-radius: 20px;
  background: var(--color-green-primary);
  color: var(--text-inverse);
  font-size: var(--text-sm);
  line-height: 24px;
  font-weight: var(--weight-semibold);
  white-space: nowrap;
  transition: scale var(--duration-fast) var(--ease-out),
    background var(--duration-fast) var(--ease-out);
}

.map-pin-wrap.is-hovered .map-pin,
.map-pin.is-hovered {
  scale: 1.12;
  background: #a82a6e;
  z-index: 600;
}

/* The selected pin drops the price for a 46px disc carrying the home glyph. The details
   page plots one property and uses the same disc from the start. */
.map-pin.is-active,
.map-pin--marker {
  justify-content: center;
  width: 46px;
  height: 46px;
  padding: 0;
  border: 3px solid var(--color-white);
  border-radius: var(--radius-pill);
  background: var(--color-grey-secondary);
  filter: drop-shadow(0 3px 4px rgba(0, 0, 0, 0.25));
}

/* Located, not selectable: the details pin marks a place and takes no click. */
.map-pin--marker {
  background: var(--color-green-primary);
  cursor: default;
}

.map-fallback {
  position: relative;
  background:
    repeating-linear-gradient(0deg, #e8edf0 0 1px, transparent 1px 42px),
    repeating-linear-gradient(90deg, #e8edf0 0 1px, transparent 1px 42px),
    #f3f6f8;
}

.map-fallback__empty {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: var(--text-muted);
  font-size: var(--text-sm);
}

/* --- Map popup --- */

/* Our own overlay, not a Google InfoWindow.

   The InfoWindow sizes its wrapper from what it measures when the window opens, before
   the card's width and photo height apply, so the wrapper ends up larger than the card
   and its own background shows as a band down the right edge and along the bottom. The
   API also injects its stylesheet after ours. Neither is reachable from here with any
   reliability, so js/googleMap.js positions a plain element instead and this styles it. */
.map-popup {
  position: absolute;
  width: 380px;

  /* Anchored on the pin's coordinate: lift it clear of the 24px pill and the 14px tail. */
  translate: -50% calc(-100% - 26px);
}

.map-popup::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 50%;
  translate: -50% 0;
  border: 14px solid transparent;
  border-bottom: 0;
  border-top-color: var(--color-white);
}

.map-popup-card {
  display: flex;
  flex-direction: column;
  border-radius: var(--radius-control-lg);
  overflow: hidden;
  background: var(--color-white);
  filter: drop-shadow(0 8px 14px rgba(0, 0, 0, 0.16));
}

.map-popup-card__head {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 14px var(--space-4);
}

.map-popup-card__title {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 5px;
}

.map-popup-card__name {
  font-family: var(--font-display);
  font-variation-settings: var(--display-axes);
  font-size: var(--text-h3);
  line-height: 24px;
  font-weight: var(--weight-semibold);
  color: var(--color-grey-dark);
  text-transform: capitalize;
}

.map-popup-card__address {
  font-size: var(--text-sm);
  line-height: 20px;
  color: var(--color-grey-secondary);
}

.map-popup-card__close {
  flex: none;
  width: 28px;
  height: 28px;
  border-radius: var(--radius-control-lg);
  font-size: 18px;
  line-height: 1;
  color: #8c9499;
}

/* The photo gives way so the whole card always fits the map panel. panIntoView can only
   pan a card into view if there is room for it — on a short window there is not, and the
   panel's own overflow then clips the building name off the top.

   The panel is 100vh less the header, the search bar and 24px. The card's text is a fixed
   140px (68 head, 72 foot) and the tail and its clearance take about 40px — 204px all
   told — so what is left over is the photo's, capped at the design's 200px. Above a 660px
   window that cap always wins and nothing changes. */
.map-popup-card__media {
  position: relative;
  height: clamp(
    80px,
    calc(100vh - var(--header-height) - var(--searchbar-height) - 204px),
    200px
  );
  overflow: hidden;
}

.map-popup-card__dots {
  position: absolute;
  left: 50%;
  bottom: 12px;
  translate: -50% 0;
  display: flex;
  gap: 5px;
}

.map-popup-card__dot {
  width: 7px;
  height: 7px;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.55);
}

.map-popup-card__dot.is-active {
  background: var(--color-white);
}

.map-popup-card__info {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: 14px var(--space-4) var(--space-4);
}

.map-popup-card__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.map-popup-card__price {
  display: flex;
  align-items: baseline;
  gap: var(--space-1);
  font-size: var(--text-body);
  line-height: 24px;
  color: var(--color-grey-secondary);
  white-space: nowrap;
}

.map-popup-card__price strong {
  font-family: var(--font-display);
  font-variation-settings: var(--display-axes);
  font-size: 25px;
  line-height: 24px;
  font-weight: var(--weight-bold);
  color: var(--color-green-primary);
}

.map-popup-card__sqft {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-display);
  font-variation-settings: var(--display-axes);
  font-size: var(--text-body);
  line-height: 18px;
  font-weight: var(--weight-medium);
  letter-spacing: -0.8px;
  color: var(--color-rose);
  white-space: nowrap;
}

.map-popup-card__more {
  font-size: var(--text-body);
  line-height: 24px;
  color: var(--color-grey-secondary);
  text-decoration: underline;
  text-transform: capitalize;
  white-space: nowrap;
}

/* ============================================================
   Pocket guide
   ============================================================ */

.pocket-guide {
  padding-block: var(--space-22);
  background: linear-gradient(180deg, var(--surface-mint) 0%, var(--surface-page) 41.091%);
}

.pocket-guide__inner {
  display: grid;
  grid-template-columns: minmax(0, 680fr) minmax(0, 808fr);
  gap: var(--space-16);
  align-items: center;
}

.pocket-guide__copy {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}

.pocket-guide__eyebrow {
  font-size: 13px;
  line-height: 16px;
  font-weight: var(--weight-semibold);
  letter-spacing: 2px;
  text-transform: uppercase;
  color: var(--color-green-primary);
}

.pocket-guide__copy h2 {
  font-size: 40px;
  line-height: 48px;
  color: var(--color-grey-dark);
}

/* Excludes the eyebrow, which is also a <p> and would otherwise inherit the body size. */
.pocket-guide__copy p:not(.pocket-guide__eyebrow) {
  width: 640px;
  max-width: 100%;
  font-size: 18px;
  line-height: 30px;
  color: #526163;
}

.pocket-guide__collage {
  display: grid;
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 252px 252px;
  gap: var(--space-4);
  height: 520px;
}

/* A grid item's automatic minimum size is its intrinsic height, so without min-height:0
   these photos push the rows past the collage's fixed height and spill into the footer. */
.pocket-guide__collage img {
  min-height: 0;
  border-radius: 20px;
}

.pocket-guide__collage img:first-child {
  grid-row: span 2;
}

/* ============================================================
   Mobile map overlay
   ============================================================ */

.browse__map-fab {
  display: none;
  position: fixed;
  left: 50%;
  bottom: var(--space-6);
  translate: -50% 0;
  z-index: var(--z-sticky);
  box-shadow: var(--shadow-float);
}

.map-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  background: var(--color-white);
}

.map-overlay__canvas {
  position: absolute;
  inset: 0;
}

.map-overlay__search {
  position: absolute;
  top: var(--space-4);
  left: var(--gutter);
  right: var(--gutter);
  z-index: 500;
}

.map-overlay__search .field {
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-float);
  border-color: transparent;
}

/* Holds the same popup card the desktop map opens, so the surface, the corners and the
   close control come from the card and this only places it. */
.map-overlay__popup {
  position: absolute;
  left: var(--gutter);
  right: var(--gutter);
  top: 76px;
  z-index: 500;
}

.map-overlay__list {
  position: absolute;
  left: 50%;
  bottom: var(--space-8);
  translate: -50% 0;
  z-index: 500;
  box-shadow: var(--shadow-float);
}

/* ============================================================
   Responsive
   ============================================================ */

/* Four controls in a row need about 1024px. Below that the filter bar wraps its fields
   onto a second line rather than overflowing — the generic stacking breakpoint at 900px
   is too late for this variant, which carries a guests field the others do not. */
@media (max-width: 1024px) {
  .browse__searchbar .search-form__inner {
    flex-wrap: wrap;
  }

  .browse__searchbar .search-form__field {
    flex: 1 1 220px;
  }

  .browse__searchbar .search-form__field--narrow {
    flex: 1 1 120px;
  }

  .browse__searchbar .search-form__submit {
    flex: 1 0 100%;
  }
}

/* Below 1600px three cards beside the map get too narrow to keep size and price on one row. */
@media (max-width: 1600px) {
  .browse[data-map-visible='true'] .browse__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 1440px) {
  .browse__grid {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* The panel is a fixed 567px, so every pixel the window loses comes off the results
   column. Two cards of about 300px is the floor for legibility, and that needs 1280px of
   window. Below it the split view collapses and the map moves behind the mobile overlay
   instead. This was 1100px while the panel width was derived from the cards. */
@media (max-width: 1280px) {
  /* The bleed above only holds while the panel is there to take the right margin. The
     state outlives the panel — the toggle is hidden here but data-map-visible is never
     reset — so a window narrowed with the map open kept padding-right: 0 and ran the
     cards off the right edge. Back to the plain container. */
  .browse[data-map-visible='true'] .browse__layout {
    grid-template-columns: minmax(0, 1fr);
    max-width: calc(var(--container-wide) + 2 * var(--gutter));
    margin-inline: auto;
    padding-inline: var(--gutter);
    gap: var(--space-8);
  }

  .browse__map {
    display: none !important;
  }

  .browse__map-toggle {
    display: none;
  }

  .browse__map-fab {
    display: inline-flex;
  }
}

@media (max-width: 1100px) {
  .browse__grid,
  .browse[data-map-visible='true'] .browse__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* `1fr` keeps an automatic minimum, and the copy paragraph is 640px wide, so the
     track stretched past the viewport. */
  .pocket-guide__inner {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-8);
  }

  .pocket-guide__copy,
  .pocket-guide__collage {
    min-width: 0;
  }

  /* The desktop rows are a fixed 252px each; inside the shortened collage they
     overflowed the box and spilled the photos into the footer. */
  .pocket-guide__collage {
    grid-template-rows: 1fr 1fr;
    height: 340px;
  }

  .pocket-guide__collage img {
    width: 100%;
    height: 100%;
    object-fit: cover;
  }
}

@media (max-width: 900px) {
  /* Hiding the city write-up on phones was the design's call, and it costs SEO: this is
     the copy the page ranks on, and mobile-first indexing crawls it. See RE-1630. */
  .browse__intro {
    display: none;
  }

  .browse__map-fab {
    min-height: 56px;
    padding-inline: var(--space-8);
    font-size: var(--text-body);
  }

  .browse__searchbar {
    position: static;
  }

  /* The desktop 300/300/115/200 basis would become a fixed row *height* once
     .search-form__inner turns into a column. */
  .browse__search .search-form__field,
  .browse__search .search-form__field--narrow {
    flex: 0 0 auto;
    width: 100%;
  }

  .browse__search .search-form__submit {
    width: 100%;
  }

  /* Stacked, the row's flex-end would right-align the heading and the button. */
  .browse__heading {
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-4);
  }

  .promo-card__title {
    font-size: 42px;
  }

  .promo-card__copy p {
    font-size: 18px;
  }

  .faq-grid {
    grid-template-columns: 1fr;
    gap: 0;
  }
}

@media (max-width: 640px) {
  /* minmax, not a bare `1fr`: `1fr` keeps an automatic min-content minimum, and with
     the phone's OS text scaling the promo tile's nowrap CTA grew past the viewport —
     the whole page scrolled sideways on device while no emulator showed it. */
  .browse__grid,
  .browse[data-map-visible='true'] .browse__grid {
    grid-template-columns: minmax(0, 1fr);
  }
}
