/**
 * Browse / search-results page layout.
 * Covers both desktop states from Figma — map hidden (4-up grid) and map shown
 * (3-up grid beside a sticky 561px panel) — plus the mobile list and map overlay.
 */

/* ============================================================
   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 at all — `63:5401` draws none — 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);
}

/* Figma `93:9521`: a 963px row of 300 / 300 / 115 / 200 on 16px gaps, and the whole
   control set steps down from the 56px default to 50px. */
/* Alignment is left on the base rule's flex-end. This bar renders the field labels, so
   centring 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;
  grid-template-columns: 1fr;
  gap: var(--space-8);
  align-items: start;
  padding-block: var(--space-10) var(--space-16);
}

/* With the map open the layout leaves the container and runs to the right edge of the
   window, which is what Figma `75:8508` draws: 80px of margin, a 1225px results column,
   a 50px gap, then the 565px panel hard against 1920. Keeping the panel inside the 1760
   container instead would cost the results column 80px and take the cards from 395 down
   to 368.

   The left inset is worked out from a percentage of the full width rather than from vw,
   so the scrollbar is not counted twice and nothing overflows sideways. */
.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);
}

/* The toggle sits at the FOOT of the heading block, not the top. Figma `63:5416` is a
   129px block and puts the 44px button at y=85, level with the last line of the intro.
   Aligned to the top it drifts as far above the cards as the intro is tall, and our intro
   is a city write-up rather than the frame's two lines. */
.browse__heading {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-8);
  /* The frame's rhythm throughout: the heading ends at 169 and the cards start at 199. */
  margin-bottom: 30px;
}


/* A flex item's automatic minimum is its content, and the intro is editor copy of any
   length, so without this the column refuses to shrink and pushes the toggle off the row. */
.browse__heading-copy {
  min-width: 0;
}

/* Figma `63:5418`: Bricolage Medium 30px in pure black, untracked. The base h1 is a
   weight heavier, on a hero-sized line, and carries -0.02em. */
.browse__heading h1 {
  font-size: 30px;
  line-height: normal;
  font-weight: var(--weight-medium);
  letter-spacing: normal;
  color: var(--color-black);
}

/* 1309px is the frame's own measure (Figma `63:5419`), which leaves the toggle its place
   at the right of the row. A narrower column is easier to read but makes the block taller,
   and the block's height is what pushes the toggle up the page. */
.browse__intro {
  max-width: 1309px;
  margin-top: 15px;
  font-size: 20px;
  line-height: 26px;
  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 two rules style what comes out rather than a structure. */
.browse__intro p + p {
  margin-top: var(--space-3);
}

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

/* Figma `63:5420` and `75:8578` draw the same 44px button either way: 20px inline
   padding, a 10px gap, 0.35px tracking and a two-layer shadow. The .btn defaults are
   wider, tighter on the gap and tracked at 0.1em, so both instances restate it. */
.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;
}

/* The in-panel Hide Map button only exists while the map is on screen. Figma `75:8578`
   sits it 43/25 in from the panel's top-right corner. */
.browse__map-hide {
  position: absolute;
  top: 43px;
  right: 25px;
  z-index: 500;
}

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

/* Figma `93:9526` is a bare 24px line of text with 30px under it — no rule and no
   padding. The sort control and the filter panel that used to live here are gone: the
   frame draws neither, on this page or anywhere else.

   The map toggle rides at the right of this line. On a row of its own it owned 74px of
   empty band between the search bar and the results, and the frame leaves no room for
   that — the count is at y=120 and the cards start at y=174. */
.browse__resultsbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: 30px;
}

/* Inter Medium 20px in black, with the city picked out in brand teal. */
.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
   ============================================================ */

/* Figma `63:5421`: four cards of 417.5 across 1760 with 30px between them, and the rows
   pitched 530 against a 500px card, so 30px both ways. */
.browse__grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 30px;
}

/* Figma `75:8521`: three cards of 395 across 1225, and the column gap tightens to 20px
   to pay for it. The rows stay at 30. */
.browse[data-map-visible='true'] .browse__grid {
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 30px 20px;
}

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

.browse__pagination {
  display: flex;
  justify-content: center;
  margin-top: var(--space-12);
}


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

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

  /* The design draws a 900px panel. 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) --- */

/* Figma `75:8546`: a 24px teal pill with 10px inline padding and Inter SemiBold 14/24.
   The overlay wrapper is left unsized, so the pill centres itself on the anchor point. */
.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 (Figma `401:18709`) --- */

/* 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);
}

/* The design's 28x14 tail, pointing down at the pin. */
.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;
}

/* Static photo indicator sitting 12px off the foot of the shot. */
.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
   ============================================================ */

/* Figma `78:8798`: the same mint wash the home locations band uses, over a 680 / 808
   split at a 64px gutter. */
.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%;
  }
}

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

  .browse[data-map-visible='true'] .browse__grid {
    grid-template-columns: repeat(2, 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: 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) {
  /* `281:22008` hides the city write-up on the phone. This is a real SEO cost — it is the
     copy the page ranks on and mobile-first indexing crawls the mobile page — and it is
     the design's decision rather than ours. Recorded on RE-1630. */
  .browse__intro {
    display: none;
  }

  /* The frame's floating SHOW MAP pill. */
  .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);
  }

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

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