/* Страница карты — по макетам «Карта / Десктоп 1920» (102:147) и
   «Карта / Телефон 390» (105:152).

   ⚠️ §8: карту нельзя пускать во всю ширину экрана. Весь сайт живёт
   в колонке, и карта без ограничения на мониторе 2560 растягивается до
   дыры в вёрстке. Высота тоже ограничена: 100dvh на высоком мониторе
   выдавливает вниз весь конверсионный низ страницы. */

.mp__in {
  max-width: calc(1872px + var(--side) * 0);
  margin: 0 auto;
  padding: 0 24px;
}
/* Полоса доверия и шапка живут в обычной колонке сайта, а не в широкой
   колонке карты: иначе они разъезжаются с остальными страницами. */
.mp__in--narrow { max-width: calc(1440px + var(--side) * 2); padding: 0 var(--side); }

/* ─── Шапка страницы ────────────────────────────────────────────────────── */

.mp__top { padding: 20px 0 12px; }
.mp__top .mp__in { display: flex; flex-direction: column; gap: 8px; }
.mp__crumbs { display: flex; gap: 6px; font-size: 12px; font-weight: 500; line-height: 16px; }
.mp__crumbs a { color: var(--accent-2); }
.mp__crumbs a:hover { text-decoration: underline; }
.mp__crumbs span { color: var(--ink-3); }
.mp__h1 { font-size: 34px; font-weight: 800; line-height: 46px; letter-spacing: -1.02px; color: var(--ink); }

/* ─── Основной блок (102:168) ─────────────────────────────────────────────
   Поля 16/24/24/24, зазор 20: список 480 слева, карта справа. */

.mp { padding: 0 0 24px; }
.mp .mp__in { display: grid; grid-template-columns: 480px minmax(0, 1fr); gap: 20px; }

/* ─── Список (102:169) ────────────────────────────────────────────────────
   480×860, поля 24, зазор 16. Прокручивается внутри себя: страница при
   этом остаётся обычной длины, а список не растягивает её на тридцать
   один экран. */

.mp__side {
  display: flex; flex-direction: column; gap: 16px;
  /* Снизу поля нет — так в макете: список уходит под край карточки, и
     это подсказывает, что он прокручивается дальше. */
  height: var(--map-h); padding: 24px 24px 0;
  background: #fff; border-radius: var(--r-card);
  box-shadow: var(--shadow);
}
/* Шапка и плашки не сжимаются: прокручивается только список. */
.mp__head { flex: 0 0 auto; display: flex; flex-direction: column; gap: 4px; }
.mp__count { font-size: 22px; font-weight: 800; line-height: 30px; letter-spacing: -0.44px; color: var(--ink); }
.mp__sub { font-size: 13px; font-weight: 500; line-height: 18px; font-style: normal; color: var(--ink-3); }

/* Плашки районов (104:155): лента с прокруткой — девять штук в 432 не
   помещаются, а перенос съедает половину списка. */
.mp__chips {
  flex: 0 0 auto;
  display: flex; gap: 8px; flex-wrap: nowrap;
  overflow-x: auto; scrollbar-width: none;
  margin: 0 -24px; padding: 0 24px;
}
.mp__chips::-webkit-scrollbar { display: none; }
.mp__chip {
  flex: 0 0 auto;
  display: inline-flex; align-items: center; gap: 6px;
  padding: 7px 12px; border-radius: var(--r-pill);
  box-shadow: inset 0 0 0 1px var(--line);
  font-size: 13px; font-weight: 600; line-height: 18px; color: var(--ink-2);
}
.mp__chip i { font-size: 12px; font-style: normal; color: var(--ink-3); }
.mp__chip.is-on { background: var(--accent-bg); box-shadow: none; color: var(--accent-2); }
.mp__chip.is-on i { color: var(--accent-2); }

/* min-height: 0 обязателен: без него flex-элемент не может стать ниже
   своего содержимого, список не прокручивается и выдавливает соседей. */
.mp__list { flex: 1 1 auto; min-height: 0; display: flex; flex-direction: column; gap: 12px; overflow-y: auto; scrollbar-width: thin; }

/* Строка списка 432×120: фото 96, поля 12, зазор 12 (104:163). */
.mi {
  display: flex; gap: 12px; padding: 12px; flex: 0 0 auto;
  border-radius: var(--r-fld); background: #fff;
  box-shadow: inset 0 0 0 1px var(--line);
}
/* 🔴 Та же беда, что была у карточек отзывов: `display: flex` выше отменял
   браузерное `[hidden] { display: none }`, потому что авторский стиль
   сильнее стилей браузера при любом весе селектора.

   Ценой был весь смысл списка рядом с картой: скрипт помечает `hidden` дома,
   которые уехали за края видимой области (map.js), а список всё равно
   показывал их все. Человек двигал карту на другой район и продолжал читать
   под ней дома, которых на экране уже нет. */
.mi[hidden] { display: none; }
.mi:hover, .mi.is-on { box-shadow: inset 0 0 0 1.5px var(--accent); }
.mi__photo { position: relative; flex: 0 0 auto; width: 96px; height: 96px; border-radius: 8px; overflow: hidden; background: var(--accent-bg); }
.mi__photo img { width: 100%; height: 100%; object-fit: cover; }
.mi__stub { position: absolute; inset: 0; background: var(--accent-bg); }
.mi__info { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.mi__name { font-size: 15px; font-weight: 800; line-height: 20px; color: var(--ink); }
.mi__price { font-size: 14px; font-weight: 600; line-height: 19px; font-style: normal; color: var(--accent-2); }
.mi__meta, .mi__flats { font-size: 12px; font-weight: 500; line-height: 16px; font-style: normal; color: var(--ink-3); }

.mp__nothing { display: flex; flex-direction: column; gap: 6px; padding: 16px 0; }
.mp__nothing[hidden] { display: none; }
.mp__nothing b { font-size: 15px; font-weight: 800; line-height: 20px; }
.mp__nothing p { margin: 0; font-size: 13px; font-weight: 500; line-height: 18px; color: var(--ink-3); }

.mp__empty { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.mp__empty b { font-size: 17px; font-weight: 800; line-height: 23px; }
.mp__reset { padding: 12px 18px; border-radius: var(--r-fld); background: var(--accent); font-size: 14px; font-weight: 600; color: #fff; }

/* ─── Карта (102:170) ─────────────────────────────────────────────────────
   Высота та же, что у списка: два столбца обязаны заканчиваться вместе. */

/* ⚠️ Высота карты считается от окна, но с потолком.

   Потолок обязателен (§8): 100dvh на высоком мониторе выдавливает вниз
   весь конверсионный низ страницы — полосу доверия и форму. Нижняя
   граница тоже обязательна: без вычета высоты шапки и заголовка карта
   уходит за край экрана и выглядит обрезанной, а не законченной.

   860 — высота из макета, 520 — предел, ниже которого карта перестаёт
   быть картой и становится картинкой. */
:root { --map-h: clamp(520px, calc(100dvh - 260px), 860px); }

.mp__map { position: relative; height: var(--map-h); border-radius: var(--r-card); overflow: hidden; }

/* 🔴 Кнопка связи поднимается над знаком «Яндекс Карты».

   Знак и ссылку на условия использования карта рисует в своём нижнем правом
   углу, и закрывать их нельзя — это требование условий использования API, а
   не вкусовщина. Плавающая кнопка связи (hero.css, .fab) стоит ровно в том
   же углу экрана.

   Объявляем переменную, а не bottom: тем же способом поднимают кнопку
   плашка о cookie и липкие полосы, а max() в .fab выбирает наибольшее из
   объявленного. Иначе правило из файла, загруженного позже, отменяло бы
   чужой подъём — и кнопка ныряла бы под плашку о cookie именно на карте. */
body:has(.mp__map) { --fab-map: 72px; }

/* Кнопка «Фильтры» и её флажок — только на телефоне: на десктопе панель
   помещается поверх карты, не мешая смотреть. */
.mp__tgl, .mp__tglbtn { display: none; }

/* Полоса фильтров поверх карты (107:157): поля 10/16/10/12, зазор 8. */
.mp__bar {
  position: absolute; left: 24px; top: 24px; right: 24px; z-index: 5;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  padding: 10px 16px 10px 12px; border-radius: var(--r-fld);
  background: #fff; box-shadow: var(--shadow);
}
/* Форма занимает всю свободную ширину полосы: без flex-grow она сжимается
   до самого узкого поля, и два выпадающих списка встают друг под другом. */
.mp__form { flex: 1 1 auto; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* Поле фильтра здесь ниже, чем в каталоге: полоса лежит поверх карты,
   и высокие поля закрывают собой то, ради чего страница открыта. */
/* min-height снимается явно: у .ff он задан в hero.css и без этого
   перебивает высоту, сколько бы её тут ни ставили. */
.mp__bar .ff--sm { height: 46px; min-height: 46px; padding: 6px 14px; flex: 0 1 200px; max-width: 200px; }
.mp__bar .ff--sm .ff__label { font-size: 11px; line-height: 15px; }
.mp__bar .ff--sm .ff__value { font-size: 14px; line-height: 19px; }
.mp__bar .fl__apply { height: 40px; }

.mp__res { margin-left: auto; font-size: 13px; font-weight: 800; line-height: 18px; color: var(--ink); }

.mp__canvas { position: absolute; inset: 0; background: var(--bg-soft); }

/* Подложка, пока карты нет: силуэт города вместо выдуманных дорог. */
.mp__stub { position: absolute; inset: 0; overflow: hidden; background: linear-gradient(155deg, #313d4d 0%, #1b222c 55%, #12161d 100%); }
.mp__sky {
  position: absolute; left: 0; right: 0; bottom: 0; height: 55%;
  background: url("/static/img/skyline.svg") bottom center / auto 100% no-repeat;
  opacity: .16;
}
.mp__stubtxt {
  position: absolute; left: 0; right: 0; bottom: 40px;
  display: flex; flex-direction: column; align-items: center; gap: 12px;
  color: #fff; text-align: center;
}
.mp__stubtxt b { font-size: 17px; font-weight: 800; line-height: 23px; }
.mp__open {
  padding: 13px 22px; border-radius: var(--r-fld);
  background: rgba(255,255,255,.14); box-shadow: inset 0 0 0 1px rgba(255,255,255,.28);
  font-size: 14px; font-weight: 600; color: #fff;
}
.mp__open:hover { background: rgba(255,255,255,.22); }

/* ─── Метка (по работающему сайту) ────────────────────────────────────────
   Круглая капля 36 с булавкой, под ней хвостик и подпись названием ЖК.
   В макете Figma метка другая — плашка с ценой (103:152); на живом сайте
   названия, и они узнаются быстрее цены. */

.mpin {
  position: relative;
  display: flex; flex-direction: column; align-items: center;
  line-height: 0; cursor: pointer;
  /* Метка стоит точкой на координате: сдвигаем её так, чтобы остриё
     хвостика приходилось на сам дом, а не центр кружка. */
  transform: translate(-50%, -100%);
}

.mpin__dot {
  display: flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: 50%; flex-shrink: 0;
  background: var(--accent); color: #fff;
  box-shadow: 0 0 0 2px rgba(255,255,255,.9), 0 3px 10px rgba(17,17,17,.32);
  transition: transform .22s cubic-bezier(.22,1,.36,1);
}
/* Хвостик — треугольник под каплей. */
.mpin__tail {
  width: 0; height: 0; margin-top: -1px;
  border-left: 5px solid transparent; border-right: 5px solid transparent;
  border-top: 7px solid var(--accent);
}
/* Подпись висит под меткой и не растягивает её: иначе соседние метки
   расталкивали бы друг друга по горизонтали. */
.mpin__label {
  position: absolute; top: calc(100% + 3px); left: 50%; transform: translateX(-50%);
  max-width: 140px; height: 22px; padding: 0 8px; border-radius: var(--r-pill);
  display: flex; align-items: center; justify-content: center;
  background: var(--accent); color: #fff;
  font-size: 10px; font-weight: 600; line-height: 22px;
  box-shadow: 0 2px 8px rgba(17,17,17,.2);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* Дом, не подошедший под фильтр: метка гаснет, но остаётся на карте — так
   видно, что рядом есть ещё дома, просто под другие условия; исчезнувшая
   метка этого не говорит, и человек решает, что в районе пусто.

   Приглушение снято с работающего сайта: прозрачность и приспущенная
   насыщенность, а не перекраска в серый. Метка остаётся той же самой —
   меняется только её вес на карте. */
.mpin.is-dim, .mclust.is-dim { opacity: .5; filter: saturate(.4); z-index: 0; }
/* Под курсором приглушение снимается: значит по метке можно нажать и
   посмотреть дом, просто он не подошёл под условия. */
.mpin.is-dim:hover, .mclust.is-dim:hover { opacity: 1; filter: none; }

/* Наведение и выбранная метка: приподнимаем каплю и темним фон. */
.mpin:hover .mpin__dot, .mpin.is-on .mpin__dot { transform: scale(1.08); }
.mpin.is-open .mpin__dot,
.mpin.is-open .mpin__label { background: var(--accent-2); }
.mpin.is-open .mpin__tail { border-top-color: var(--accent-2); }
/* Открытая метка поверх соседних — иначе её подпись уходит под чужую. */
.mpin.is-open { z-index: 3; }

/* Кластер — кружок 42 с числом домов (по работающему сайту). */
.mclust {
  display: flex; align-items: center; justify-content: center;
  width: 42px; height: 42px; border-radius: 50%;
  background: var(--accent); color: #fff;
  box-shadow: 0 0 0 2px #fff, 0 4px 12px rgba(17,17,17,.28);
  font-size: 15px; font-weight: 700; line-height: 42px;
  cursor: pointer; user-select: none;
  transform: translate(-50%, -50%);
  transition: transform .22s cubic-bezier(.22,1,.36,1);
}
.mclust:hover { transform: translate(-50%, -50%) scale(1.08); }

/* ─── Попап метки ─────────────────────────────────────────────────────────
   Размеры сняты с работающего сайта (ecn-nn.ru/map): ширина 272,
   скругление 18, фотография 16/9, содержание с полями 12/14/14.

   В макете Figma этот попап нарисован беднее (узел 103:172): без галереи,
   застройщика, этажности и кнопки. Живой вариант уже проверен людьми. */

.mpop {
  position: absolute; z-index: 10; width: 272px;
  display: flex; flex-direction: column;
  background: #fff; border-radius: 18px; overflow: hidden;
  box-shadow: 0 8px 32px rgba(48,48,54,.18), 0 2px 8px rgba(48,48,54,.10);
  /* Обводка внутренней тенью: обычная рамка добавила бы пиксель к ширине. */
  box-shadow: 0 8px 32px rgba(48,48,54,.18), 0 2px 8px rgba(48,48,54,.10), inset 0 0 0 1px var(--line);
  /* Карточка встаёт над меткой, а не поверх неё. */
  transform: translate(-50%, calc(-100% - 20px));
}
.mpop[hidden] { display: none; }

/* Фотография 16/9 (272×153). */
.mpop__photo { position: relative; display: block; aspect-ratio: 16 / 9; overflow: hidden; background: var(--bg-soft); }
/* Снимки домов приходят разных пропорций: основной кадр вписывается
   целиком, а поля закрывает он же — размытый и увеличенный. */
.mpop__blur { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; filter: blur(18px) brightness(.9); transform: scale(1.1); }
.mpop__img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; }
.mpop__stub { position: absolute; inset: 0; background: linear-gradient(155deg, #313d4d 0%, #1b222c 55%, #12161d 100%); }
/* Затемнение снизу — чтобы белое название читалось на любом снимке. */
.mpop__shade { position: absolute; inset: 0; pointer-events: none; background: linear-gradient(to top, rgba(0,0,0,.6) 0%, transparent 55%); }

.mpop__status {
  position: absolute; left: 10px; top: 10px;
  padding: 3px 8px; border-radius: var(--r-pill); background: #fff;
  font-size: 10px; font-weight: 700; line-height: 14px; font-style: normal;
  color: var(--ink); white-space: nowrap;
}

/* Круглые кнопки поверх фото: закрыть и листать. */
.mpop__btn {
  position: absolute; z-index: 2;
  width: 28px; height: 28px; display: flex; align-items: center; justify-content: center;
  border-radius: 50%; background: rgba(0,0,0,.45); backdrop-filter: blur(6px);
  color: #fff; cursor: pointer;
}
.mpop__btn:hover { background: rgba(0,0,0,.62); }
.mpop__btn[hidden] { display: none; }
.mpop__btn--close { right: 8px; top: 8px; }
.mpop__btn--prev { left: 8px; top: 50%; transform: translateY(-50%); }
.mpop__btn--next { right: 8px; top: 50%; transform: translateY(-50%); }

/* Название и застройщик — поверх снимка внизу. */
.mpop__title { position: absolute; left: 0; right: 0; bottom: 0; display: block; padding: 0 12px 10px; }
.mpop__name { display: block; font-size: 15px; font-weight: 700; line-height: 1.2; color: #fff; text-shadow: 0 1px 4px rgba(0,0,0,.4); }
.mpop__dev { display: block; margin-top: 2px; font-size: 11px; font-weight: 500; font-style: normal; color: rgba(255,255,255,.7); }

/* Содержание: поля 12/14/14. */
.mpop__info { display: block; padding: 12px 14px 14px; }
.mpop__row { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; margin-bottom: 4px; }
.mpop__pricebox { display: flex; align-items: baseline; gap: 3px; }
.mpop__from { font-size: 11px; font-style: normal; text-transform: uppercase; letter-spacing: .06em; color: var(--ink-3); }
/* tabular-nums: цифры одной ширины, и цены в разных попапах не пляшут. */
.mpop__price { font-size: 18px; font-weight: 800; line-height: 24px; color: var(--ink); font-variant-numeric: tabular-nums; }
.mpop__m2 { font-size: 11px; font-style: normal; color: var(--ink-3); font-variant-numeric: tabular-nums; white-space: nowrap; }
.mpop__line { display: block; margin-bottom: 12px; font-size: 12px; font-style: normal; color: var(--ink-3); }

.mpop__acts { display: flex; gap: 8px; }
.mpop__cta {
  flex: 1 1 0; display: flex; align-items: center; justify-content: center; gap: 6px;
  padding: 9px 14px; border-radius: var(--r-pill); background: var(--accent);
  font-size: 13px; font-weight: 700; line-height: 20px; color: #fff;
}
.mpop__cta:hover { background: var(--accent-2); }
.mpop__ask {
  flex: 0 0 auto; width: 38px; height: 38px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 50%; background: var(--accent-bg);
  box-shadow: inset 0 0 0 1.5px var(--accent); color: var(--accent);
}
.mpop__ask:hover { background: #FFE7DA; }

/* ─── Промежуточные ширины ─────────────────────────────────────────────── */

@media (max-width: 1280px) {
  /* Список уезжает под карту: в узком окне два столбца дают колонку,
     в которой не читается ни одна строка. */
  .mp .mp__in { grid-template-columns: minmax(0, 1fr); }
  .mp__side { height: auto; max-height: 640px; }
  .mp__map { height: clamp(420px, calc(100dvh - 320px), 560px); }
}

/* ─── Телефон, кадр 390 (105:152) ─────────────────────────────────────────
   Карта квадратная 390×390, под ней список. */

@media (max-width: 760px) {
  .mp__in { padding: 0 var(--side); }
  .mp__top { padding: 12px 0 8px; }
  .mp__h1 { font-size: 24px; line-height: 32px; letter-spacing: -0.48px; }

  .mp .mp__in { gap: 16px; }
  /* Карта идёт первой — так в макете: сначала показываем, потом
     перечисляем. Края ровные: она упирается в края экрана, и скруглять
     там нечего. */

  /* 🔴 Карта липкая, а под ней едет список.

     Захар: «хочу видеть снизу плашку со списком и одновременно сверху
     новостройки». Обычная карта уезжает вверх, стоит потянуть страницу, и
     человек выбирает вслепую: он листает дома, но уже не видит, где они.

     Карта прилипает под шапкой и занимает чуть больше половины экрана;
     оставшегося хватает на заголовок списка, полосу районов и первую
     карточку. Список прокручивается под ней сколько угодно — карта
     остаётся на глазах.

     Высота 390 из макета (105:163) не годилась: в макете на карте не
     нарисована панель фильтров, а живьём даже свёрнутой панелью 390 — это
     треть экрана под то, ради чего на страницу пришли. Нижний предел
     оставлен для коротких экранов, где доля от экрана вырождается.

     🔴 Липкость держится на том, что у body стоит overflow-x: clip, а не
     hidden: hidden завёл бы свою прокрутку и position: sticky перестал бы
     работать молча. */
  .mp__map {
    order: -1;
    position: sticky; top: var(--hdr-h); z-index: 1;
    height: 54dvh; min-height: 300px;
    margin: 0 calc(var(--side) * -1); border-radius: 0;
  }

  /* Кнопка, за которой прячутся фильтры. Стоит в углу карты и остаётся
     видимой, когда панель раскрыта, — ею же панель и закрывается.

     🔴 Оранжевая, а не белая. Белая пилюля на светлой карте читалась как
     подпись к местности, а не как то, что нажимают: Захар сказал «надо
     заметнее». Цвет тот же, которым на сайте помечено действие, — и он же
     у меток домов, так что карта не приобретает нового цвета. */
  .mp__tglbtn {
    display: inline-flex; align-items: center; gap: 8px;
    position: absolute; left: 12px; top: 12px; z-index: 6;
    padding: 11px 18px; border-radius: var(--r-pill);
    background: var(--accent); color: #fff; cursor: pointer;
    box-shadow: 0 6px 18px -2px rgba(237,99,33,.35), 0 2px 6px rgba(18,18,18,.12);
    font-size: 15px; font-weight: 700; line-height: 20.49px;
  }
  .mp__tglbtn:hover { background: var(--accent-2); }
  /* Бегунки значка закрашены цветом кнопки: иначе три белых кружка на белых
     дорожках сливаются в кашу. */
  .mp__tglico { flex: none; }
  .mp__tglico circle { fill: var(--accent); }
  .mp__tglbtn:hover .mp__tglico circle { fill: var(--accent-2); }
  /* Число выбранных условий — белым кружком поверх оранжевого. */
  .mp__tglbtn i {
    font-style: normal; font-size: 13px; font-weight: 700; line-height: 1;
    min-width: 20px; height: 20px; padding: 0 6px; border-radius: var(--r-pill);
    display: inline-flex; align-items: center; justify-content: center;
    background: #fff; color: var(--accent);
  }

  /* Панель раскрывается под кнопкой и только по нажатию. */
  .mp__bar {
    display: none;
    left: 12px; right: 12px; top: 60px; padding: 10px 12px; gap: 8px;
  }
  .mp__tgl:checked ~ .mp__bar { display: flex; }
  .mp__bar .ff--sm { flex: 1 1 140px; max-width: none; height: 42px; min-height: 42px; }
  .mp__res { width: 100%; margin-left: 0; }

  .mp__side { height: auto; max-height: none; padding: 16px; gap: 12px; }
  .mp__chips { margin: 0 -16px; padding: 0 16px; }
  .mp__count { font-size: 19px; line-height: 26px; }
  .mp__list { overflow: visible; }
  .mi__photo { width: 84px; height: 84px; }

  /* На телефоне попап выезжает листом снизу: над меткой карточка закрывает
     собой половину карты, а места по бокам всё равно нет. */
  .mpop {
    position: fixed; left: 0; right: 0; bottom: 0; top: auto;
    width: auto; transform: none;
    border-radius: 18px 18px 0 0;
  }

  /* Пока лист открыт, плавающая кнопка связи прячется.

     Лист занимает низ экрана целиком, и кнопка (hero.css, .fab — слой 30,
     угол справа внизу) легла бы прямо на его кнопки «открыть страницу дома»
     и «спросить цены». Своя кнопка связи у листа уже есть, так что прятать
     нечего жалеть: закроют лист — вернётся. */
  body:has(.mpop:not([hidden])) .fab { display: none; }
}
