/* Стили страницы карты (round532): раньше лежали прямо в map.html и
   отдавались заново при каждом заходе, теперь файл кэшируется. */
/* Единый шрифт со всем остальным сайтом — карта самостоятельная страница,
   не наследует общий CSS, поэтому шрифт переопределяем прямо здесь. */
/* ⚠️ НА КАРТЕ НЕ ХВАТАЛО ЦЕЛОГО ШРИФТА (round273).

   Кирилл: «как будто шрифт в разделе карт отличается от основного».

   Он прав, и причина не в начертании, а в загрузке. Приложение
   (base.html) раньше грузил два внешних семейства. Карта грузила только Oswald.

   Заголовки набраны Montserrat весов 800–900. На карте его не было,
   браузер подставлял Oswald и дорисовывал жирность искусственно —
   отсюда другая ширина букв и другое ощущение. Теперь набор один. */
body { font-family:'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; -webkit-font-smoothing:antialiased; }

/* Нижняя карточка прицепа (как у Яндекса) */
.trailer-card{
  position:fixed;left:0;right:0;z-index:1000;
  /* ⚠️ ПОДНЯТА НАД НИЖНЕЙ НАВИГАЦИЕЙ. Раньше стояла от bottom:0 — а
     навигация закреплена там же и с БОЛЬШИМ z-index (1200 против
     1000), то есть рисуется поверх. Кнопка «Взять этот прицеп»
     оказывалась наполовину под ней.

     Высота навигации: иконка 22px + padding .55rem сверху и снизу
     (≈17.6px) + рамка 1px ≈ 41px. Плюс safe-area внизу телефона,
     которую навигация добавляет себе сама. */
  /* ⚠️ ВЫСОТА ИЗ ПЕРЕМЕННОЙ, А НЕ ЧИСЛОМ (round400).

       Кирилл: «карточка не совпадает с нижней панелью, видно что
       разделяется».

       Здесь было зашито 41 — столько занимала панель когда-то. Потом я
       добавил ей отступы под вырез телефона, и она подросла, а
       карточка осталась на месте. Между ними открылась щель.

       ⚠️ ТЕПЕРЬ ОБЕ БЕРУТ ОДНУ ПЕРЕМЕННУЮ: разойтись не смогут. */
      /* ⚠️ КАРТОЧКА ПРИЖАТА К НИЗУ (round420).

         Кирилл: «карточки прицепов на карте приклей к низу, а то
         сейчас там зазор огромный».

         Здесь стояло bottom:var(--nav-h) — отступ под нижнюю панель.
         Панель с карты убрана в round415, а отступ остался: карточка
         висела на 51 пиксель выше края, и под ней белела полоса. Моя
         же правка, и я её не заметил, потому что живьём страницу не
         открывал.

         env(safe-area-inset-bottom) оставляем: на айфоне внизу полоска
         жеста, и без запаса кнопки карточки уйдут под неё. */
      /* ══ ⚠️ ЩЕЛЬ СНИЗУ В ПРИЛОЖЕНИИ (round459) ═══════════════════════

     Кирилл: «так как нету снизу браузерной строки, то карточки снизу
     имеют щель».

     ⚠️ ЧТО БЫЛО. Карточка стояла НАД полоской айфона: bottom равнялся
     высоте безопасной зоны. В браузере это незаметно — низ закрывает
     строка адреса. А в приложении на домашнем экране строки нет, и под
     карточкой видна полоса карты.

     ⚠️ ТЕПЕРЬ КАРТОЧКА ЛЕЖИТ НА САМОМ КРАЮ, а безопасная зона уходит
     во ВНУТРЕННИЙ ОТСТУП: содержимое не заедет под системную полоску,
     но фон дотянется до низа экрана. Щели не будет ни там, ни там. */
  bottom:0;
  padding-bottom:calc(1.2rem + env(safe-area-inset-bottom, 0px));
  /* ⚠️ ЦВЕТА ИЗ ПАЛИТРЫ, А НЕ СВОИ (round366).

     Кирилл: «шрифт сбит, фон блока отличается от фона сайта, тут
     разные тёмно-серые, должны быть единые».

     Оба замечания — про одно место. Здесь стояло:
       фон   #14181e — свой оттенок, ни на что на сайте не похожий;
       текст #f0ede4 — ТЁПЛЫЙ КРЕМОВЫЙ. Он остался от золотой темы
       (её меняли на серебряную в round332), и рядом с серым текстом
       остальных блоков читался как другой шрифт — Кирилл описал это
       как «шрифт сбит», хотя шрифт тот же, отличался цвет.

     Берём из палитры: фон карточек и обычный текст. */
     /* ⚠️ КАРТОЧКА ПРИЦЕПА — СВЕТЛАЯ (round384).

     Кирилл: «карточки прицепов на карте сделай белыми с чёрным
     текстом».

     Причина та же, что у страницы съёмки и инструкции по сейфу: карту
     смотрят НА УЛИЦЕ, выбирая прицеп, и экран там выцветает от солнца.
     Светлый текст на тёмном фоне не читается — человек не разберёт ни
     госномер, ни габариты.

     Плюс карта под карточкой светлая: тёмная плашка на светлом фоне
     выглядела чужой заплатой.

     ⚠️ ЦВЕТА ЗАДАЮ ЯВНО, А НЕ ЧЕРЕЗ ПЕРЕМЕННЫЕ ТЕМЫ: тема тёмная, и
     var(--text) дал бы светлый текст на белом — то есть невидимый. Это
     сознательный выход из темы: карточка белая при любой теме, значит
     и текст в ней чёрный. */
     background:#ffffff;color:#1a1a1a;
  border-radius:var(--radius-xl) 20px 0 0;padding:1rem 1.2rem 1.2rem;
  /* ⚠️ ТЕНЬ НЕ ДОЛЖНА ВЫЛЕЗАТЬ ВНИЗ (round402).

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

       ⚠️ ЦВЕТА УЖЕ ОДИНАКОВЫЕ: карточка #ffffff, панель в светлой теме
       тоже #ffffff. Проверил выполнением — на карте body получает класс
       theme-light. Значит дело было не в цвете.

       ⚠️ ДЕЛО В ТЕНИ, И ЭТО СЧИТАЕТСЯ, А НЕ ПРИКИДЫВАЕТСЯ. Рамка тени —
       это рамка элемента, сдвинутая на offset, раздутая на spread;
       размытие добавляет примерно blur/2 в каждую сторону. Было
       0 -4px 16px: вниз тень вылезала на 16/2 − 4 = 4 пикселя и ложилась
       НА панель тёмной полосой. Ровно её глаз и читает как шов.

       Стало 0 -8px 16px -8px: отрицательный разгон втягивает тень, и
       вниз она уходит на 8 пикселей ВЫШЕ края карточки — то есть до
       панели не достаёт вовсе. Сверху при этом остаётся те же 8
       пикселей мягкого края, отделяющие карточку от карты. */
      box-shadow:0 -8px 16px -8px rgba(16,24,40,.12);
  transform:translateY(110%);transition:transform var(--dur) cubic-bezier(.2,.7,.2,1);
  max-width:600px;margin:0 auto;
  /* Карточка выше экрана — прокручиваем её саму, а не обрезаем. */
  /* ⚠️ ВЫСОТА ПАНЕЛИ — ИЗ ПЕРЕМЕННОЙ, А НЕ ЧИСЛОМ (round409).

     Здесь стояло 41px, и это тот самый разъезд, о котором предупреждает
     комментарий к --nav-h в common.css: «источник один, правишь --nav-h
     — двигаются оба». На деле источников было два, и второй — вот этот.

     В round409 панель подросла: под значками появились подписи. Оставь
     я числа — карточка считала бы старую высоту и залезла бы под
     панель. */
  /* ⚠️ ПАНЕЛИ НА КАРТЕ БОЛЬШЕ НЕТ (round420). Здесь вычиталась её
     высота — карточка получалась на 51 пиксель ниже возможного, и
     содержимое зря прокручивалось. Вычитаем только запас под полоску
     жеста айфона и 60 пикселей сверху, чтобы карта оставалась видна. */
  max-height:calc(100vh - env(safe-area-inset-bottom, 0px) - 60px);
  overflow-y:auto;
}
/* ⚠️ 110% ПРИ НЕНУЛЕВОМ bottom НЕ ПРЯЧЕТ ПОЛНОСТЬЮ: остаётся щель
   высотой в отступ. Прячем с запасом на высоту навигации. */
/* Спрятанная карточка уезжает ровно на высоту панели — тоже из
   переменной, иначе край будет выглядывать из-под меню. */
/* ⚠️ УЕЗЖАЕТ НА СВОЮ ВЫСОТУ, БЕЗ ЗАПАСА ПОД ПАНЕЛЬ (round420).
   Панели нет; оставь прежнее — карточка уезжала бы на 51 пиксель
   дальше нужного. Само по себе не видно, но при быстром закрытии
   заметно как более долгий уход. */
.trailer-card:not(.open){transform:translateY(calc(110% + env(safe-area-inset-bottom, 0px)))}
.trailer-card.open{transform:translateY(0)}

/* ══ ⚠️ СОСТОЯНИЯ В КАРТОЧКЕ ПРИЦЕПА (round417) ═══════════════════

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

   ⚠️ ЦВЕТА ПОСЧИТАНЫ на подложке при пороге 4,5:
     подпись #4a5058 на #f4f6f8 → 7,6
     таймер  #111111            → 16,8
     предупреждение #8a6a1f на #f6efdd → 4,8 */
.tc-state{
  background:var(--brand-tint);
  border-radius:var(--radius-md);
  padding:12px 14px;
  margin:0 0 10px;
}
.tc-state-cap{
  font-size:var(--fs-xs);
  text-transform:uppercase;letter-spacing:.5px;
  color:var(--metal);font-weight:700;
}
/* ⚠️ ЦИФРЫ МОНОШИРИННЫЕ. Обычным шрифтом единица уже семёрки, и
   отсчёт дёргается каждую секунду — глаз читает это как сбой. */
.tc-timer{
  font-size:var(--fs-xl);font-weight:700;color:#111111;
  font-variant-numeric:tabular-nums;
  margin-top:.2rem;line-height:1.15;
}
.tc-state-txt{
  font-size:var(--fs-sm);color:var(--metal);line-height:1.45;margin-top:.35rem;
}
/* Ожидание одобрения — тёплым, аренда — фирменным: разные положения
   должны отличаться не только словами. */
.tc-state-wait{ background:#f6efdd }
.tc-state-wait .tc-state-cap{ color:#8a6a1f }
.tc-state-live{ background:var(--brand-tint) }

/* ⚠️ ЗАМЕЧАНИЯ ВИДНЫ ДАЖЕ НА ЧУЖОМ ПРИЦЕПЕ: три штуки закрывают
   бронирование навсегда, и человек должен знать, сколько у него. */
.tc-warn{
  /* ══ ⚠️ ЗАМЕЧАНИЯ — БЛЕДНО-КРАСНЫЙ, НЕ БЕЖЕВЫЙ (round469) ═════════

     Кирилл: «на карточках, если есть замечания — бежевый блок „у вас
     1 из 3 замечаний“ — сделай этот блок не бежевым, а спокойно
     бледно-красным».

     ⚠️ ОН ПРАВ ПО СМЫСЛУ: замечание — это предупреждение о наказании
     (три штуки закрывают бронирование), а не справка. Бежевый читался
     как «к сведению»; бледно-красный — как «обратите внимание».

     ⚠️ ЦВЕТА ИЗ ПАЛИТРЫ: --danger-bg (прозрачный красный поверх фона)
     и --danger для текста. Прежний #f6efdd был своим числом, ни с чем
     на сайте не совпадавшим — проверка round332 такое ловит. */
  background:var(--danger-bg);color:var(--danger);
  border-radius:var(--radius-md);
  padding:10px 14px;margin:0 0 10px;
  font-size:var(--fs-sm);font-weight:600;line-height:1.4;
}
.tc-row{ display:flex;gap:10px;margin-bottom:10px }
.tc-row .btn{ flex:1 }

/* ══ ⚠️ ПЛАШКА АКЦИИ И КНОПКА «ГДЕ Я» (round424) ═════════════════

   Кирилл показал, как это сделано у Яндекса: «приятный белый блок со
   скруглёнными углами, иконка акции и чёрный текст».

   ⚠️ ПОД КНОПКОЙ МЕНЮ, А НЕ РЯДОМ. Слева вверху кнопка, справа
   подпись правообладателя — свободна только полоса под ними. */
/* ══ ⚠️ БАННЕР АКЦИИ ПРЯЧЕТСЯ ПРИ СВОЁМ ПРИЦЕПЕ (round509) ═══════

   Кирилл: «верхний блок акции во время бронирования, ожидания и самой
   аренды показывает не акцию, а просто текст „Ваш прицеп" — давай
   этот баннер вообще не показывать во время ожиданий подтверждений от
   админа, во время бронирования (именно когда 1 час идёт) и во время
   самой аренды».

   ⚠️ АКЦИЯ ГОВОРИТ О СЛЕДУЮЩЕЙ АРЕНДЕ, А ЧЕЛОВЕК ЗАНЯТ НЫНЕШНЕЙ. Он
   едет к прицепу или уже везёт груз — предлагать ему скидку на пятую
   поездку не ко времени. Хуже: баннер занимает верх экрана, где в эти
   минуты важнее карта и карточка.

   ⚠️ ПРЯЧЕМ ПРАВИЛОМ, А НЕ КОДОМ. Признаки mc-freeze, mc-pending и
   mc-rental ставятся на тело при сборке карточки и снимаются, когда
   аренда кончилась, — сами. Правка в коде означала бы второе место,
   где решается одно и то же, и они разошлись бы при первой правке.

   ⚠️ ТРИ СОСТОЯНИЯ ИМЕННО ТЕ, ЧТО НАЗВАЛ КИРИЛЛ: бронь (идёт час),
   ожидание проверки снимков, сама аренда. В остальное время баннер
   на месте. */
body.mc-freeze .map-promo,
body.mc-pending .map-promo,
body.mc-rental .map-promo{ display:none }

/* ══ ⚠️ БЕЛАЯ ПОЛОСА ПОД СТАТУСОМ ТЕЛЕФОНА (round512) ════════════

   Кирилл: «на главной странице, то есть на карте, вверх экрана, там
   где время, батарея, сеть — всё ещё серая полоса, а должна быть
   белоснежной, именно на карте».

   ⚠️ ДЕЛО НЕ В theme-color — он здесь белый, проверил. Страница уходит
   ПОД полосу (viewport-fit=cover), и в этой области видна сама карта:
   её серая подложка, пока не легли плитки, и серые края карты при
   отдалении.

   ⚠️ НАШИ БЛОКИ ОТ ПОЛОСЫ ОТСТУПАЮТ (safe-area-inset-top), а карта нет
   — она растянута на весь экран, и это верно: сдвинь её, и снизу
   появится пустая рамка.

   ⚠️ ЗАКРЫВАЕМ ПОЛОСКОЙ, А НЕ ДВИГАЕМ КАРТУ. Высота — ровно системная
   область: на телефонах без выреза она нулевая, и полоска не видна
   вовсе.

   ⚠️ z-index 1090 — НИЖЕ ВСЕХ КНОПОК (1100+) и выше карты. Иначе
   полоска перекрыла бы кнопку меню, которая стоит в том же углу. */
body::before{
  content:'';
  position:fixed;
  top:0; left:0; right:0;
  height:env(safe-area-inset-top, 0px);
  background:#ffffff;
  z-index:1090;
  pointer-events:none;
}



.map-promo{
  /* ⚠️ ПЛАШКА АКЦИИ — СПРАВА ОТ КНОПКИ, НА ОДНОЙ ЛИНИИ (round425).

     Кирилл: «блок акции на карте сам по себе, должен идти справа от
     меню».

     Он прав, и вот в чём была ошибка: одну и ту же задачу — «полоса
     вверху рядом с кнопкой» — я решил двумя разными способами. Плашка
     ОТБОРА уходила вправо от кнопки (left:72), а плашка АКЦИИ вставала
     отдельной строкой ниже (top: +72). Разнобой без причины.

     72 = 48 кнопки + 12 её отступа + 12 зазора.

     ⚠️ МЕСТО СПРАВА ОТ КНОПКИ ОДНО, И ЭТО ВАЖНО. Если человек пришёл
     из каталога с отбором по типу, там уже стоит плашка отбора.
     Показывать обе значит класть их друг на друга. Правило ниже
     прячет акцию, когда отбор занял место: отбор важнее — он объясняет,
     почему на карте видно не все прицепы. */
  position:fixed;
  top:calc(env(safe-area-inset-top, 0px) + 12px);
  left:72px; right:12px;
  z-index:1140;
  max-width:none; margin:0;
  display:flex; align-items:center; gap:12px;
  padding:11px 14px;
  background:#ffffff;
  border-radius:var(--radius-lg);
  box-shadow:0 3px 14px rgba(16,24,40,.18);
}
.mp-ico{
  flex-shrink:0;
  width:34px;height:34px;border-radius:50%;
  /* round535: зелёный круг, чёрный знак — Кирилл: «фон кружка зелёный,
     а процент чёрным». Чёрное на ярко-зелёном читается на солнце. */
  background:#39e05a; color:#000000;
  display:flex;align-items:center;justify-content:center;
  font-weight:700;font-size:var(--fs-md);
}

.mp-text{ min-width:0 }
/* ⚠️ ТЕКСТ ЧЁРНЫЙ, КАК ПРОСИЛ КИРИЛЛ: на белом это 16,8 при пороге
   4,5 — читается на солнце, а карту смотрят на улице. */
.mp-title{
  display:block;color:#111111;font-weight:700;font-size:var(--fs-sm);
  line-height:1.25;
}
.mp-sub{
  display:block;color:var(--text-muted);font-size:var(--fs-xs);
  margin-top:.1rem;
}
/* Скидка действует на ближайшую аренду: заголовок крупнее и рамка в тон
   кружку — заметно до того, как человек выберет прицеп. */
.map-promo-now{ box-shadow:0 0 0 2px #39e05a, 0 3px 14px rgba(16,24,40,.18) }
.map-promo-now .mp-title{ font-size:var(--fs-base) }
/* Плашка уходит, когда открыта карточка прицепа или меню: человек
   занят другим, а места вверху мало. */
body.tc-open .map-promo,
body.mm-open .map-promo{ display:none }

/* ⚠️ ОТБОР ВЫТЕСНЯЕТ АКЦИЮ: место справа от кнопки одно. Отбор важнее —
   он объясняет, почему на карте видно не все прицепы. Признак ставит
   pg-map.js вместе с показом плашки отбора. */
body.has-filter .map-promo{ display:none }

/* ⚠️ КНОПКА «ГДЕ Я» — СПРАВА ВНИЗУ. Так во всех картах, палец
   достаёт не глядя. Выше кнопки «Показать ближайшие», чтобы не
   налезать на неё. */
/* ══ ⚠️ РУБИЛЬНИК ПАРКОВОК — НАД НАВИГАТОРОМ (round437) ══════════

   Кирилл: «такой же круглой и белой, на кнопке буква P».

   ⚠️ ТОТ ЖЕ РАЗМЕР И ФОН, ЧТО У НАВИГАТОРА: две разные круглые кнопки
   у одного края читались бы как разные по важности. Здесь они —
   равные средства управления картой.

   ⚠️ 60 = 48 высота навигатора + 12 зазор. Число не на глаз: меньше —
   кнопки сольются в столбик, больше — вторая уедет к карточке.

   ⚠️ ВИДНА ТОЛЬКО ПРИ АРЕНДЕ. Без прицепа искать парковку незачем: там
   ищут прицеп. Правило ниже по признаку has-my-card.

   ⚠️ ВКЛЮЧЁННОЕ СОСТОЯНИЕ ОТМЕЧЕНО ФОНОМ, А НЕ ТОЛЬКО ЦВЕТОМ БУКВЫ: на
   солнце цвет теряется, а заливка видна. Карту смотрят на улице. */
.pins-btn{
  position:fixed;
  right:12px;
  /* ⚠️ ОТ ВЫСОТЫ КАРТОЧКИ, А НЕ ОТ ЧИСЕЛ (round442). Кирилл: «кнопки
     навигатора и парковки слетают и наезжают друг на друга».

     Числа задавались трижды — 108 обычно, 320 при карточке, 234 при
     свёрнутой. При свёрнутой активны ОБА признака, вес одинаков, и
     побеждало то, что ниже в файле: кнопки уезжали на 320 при карточке
     высотой 220.

     Высоту меряет браузер и кладёт в --mc-h (см. mcSyncHeight). Кнопка
     P = высота + 108, навигатор = высота + 48: зазор 12 при любом
     содержимом карточки.

     ⚠️ ЗАПАСНОЕ 60: пока карточки нет, переменной тоже нет, и кнопки
     встают на 108 и 168 — как было. */
/* ⚠️ ЗАПАС ПОД ПОЛОСКУ ЖЕСТА УЧТЁН ОДИН РАЗ (round443).

   Кирилл: «большой зазор между текстом OpenFreeMap и карточкой».

   ⚠️ ПОСЧИТАНО: ЗАЗОР БЫЛ 38 ПИКСЕЛЕЙ ВМЕСТО 4. Причина — двойной
   учёт. У карточки внутренний отступ снизу равен safe-area + 14, и
   offsetHeight его УЖЕ включает. А в отступе подписи и кнопок к
   измеренной высоте добавлялся safe-area ещё раз.

   ⚠️ ОШИБКА БЫЛА ВО ВСЕХ ТРЁХ МЕСТАХ, считающих от --mc-h: подпись,
   навигатор, кнопка P. Правлю все — иначе кнопки останутся висеть на
   34 пикселя выше нужного, и это заметно ровно так же.

   ⚠️ ЗАПАСНОЕ ЗНАЧЕНИЕ ТЕПЕРЬ ВКЛЮЧАЕТ ЗАПАС: пока карточки нет,
   переменной тоже нет, и запас брать негде. Ставим
   calc(env(safe-area-inset-bottom, 0px) + 60px) — то же, что было. */
  /* ⚠️ ЛЕСЕНКА ПОСЧИТАНА, А НЕ ПОДОБРАНА (round486). Кирилл: «кнопка
     навигатора залезает на кнопку парковка, починит уже».
     ⚠️ ПРИЧИНА МОЕЙ ОШИБКИ: в round485 я поднял навигатор до 120, а
     парковки оставил на 108 — и они наложились. Двигал одну кнопку, не
     посмотрев на соседа.
     ⚠️ ТЕПЕРЬ СЧИТАЮ ВСЮ ЛЕСЕНКУ СРАЗУ, от блока ближайшей парковки
     вверх: блок 40–108, навигатор 120–168, парковки 180–228, подпись
     240. Зазоры по 12 — палец не задевает соседа. */
  bottom:calc(env(safe-area-inset-bottom, 0px) + var(--nav-base, 118px) + 58px);
  z-index:1110;
  width:48px;height:48px;
  border:none;border-radius:50%;
  background:#ffffff;
  color:var(--brand);
  font-family:inherit;
  font-size:var(--fs-md);
  font-weight:700;
  line-height:1;
  box-shadow:0 2px 10px rgba(16,24,40,.22);
  display:none;
  align-items:center;justify-content:center;
  cursor:pointer;
  transition:transform var(--dur-fast), background var(--dur-fast);
}

/* ⚠️ ВТОРЫЕ ПРАВИЛА ДЛЯ КНОПОК УБРАНЫ (round493).

   Я добавил body.has-my-card .geo-btn с отступом 10 — и тест
   test_geo_button_clear_of_card покраснел, предупредив о настоящей
   опасности: при СВЁРНУТОЙ карточке активны сразу два признака,
   has-my-card и mc-min, весят они одинаково, и побеждает тот, что ниже
   в файле. Кнопки уезжали бы наугад — этим уже горели в round442, и
   довод записан прямо в тесте.

   ⚠️ ВТОРОЕ ПРАВИЛО НЕ БЫЛО НУЖНО ВОВСЕ. Отступ 10 я к тому времени
   уже поставил в само правило .geo-btn — оно считает от высоты
   карточки (--mc-h), а высоту меряет браузер при каждом изменении.
   Карточка выросла, свернулась, исчезла — кнопки идут за ней сами.
   Я добавил второе правило, не проверив, что первое уже делает нужное. */
.pins-btn:active{ transform:scale(.94) }

/* ══ ⚠️ КНОПКИ ВСТАЮТ ПО ВЫСОТЕ КАРТОЧКИ, А НЕ ПО ЧИСЛАМ (round442) ══

   Кирилл: «смотри на кнопки навигатора и парковки, они слетают и
   наезжают друг на друга».

   ⚠️ ПРИЧИНА БЫЛА В ПОРЯДКЕ ПРАВИЛ. Числа задавались трижды:
     .geo-btn                    108
     body.has-my-card .geo-btn   320
     body.mc-min .geo-btn        234
   При свёрнутой карточке активны ОБА признака — has-my-card и mc-min, —
   вес у них одинаков, и побеждает то, что ниже в файле. Правила mc-min
   стояли ВЫШЕ, значит их перебивало has-my-card: кнопки уезжали на 320
   при карточке высотой 220 и повисали в воздухе. А при другом порядке
   строк они наехали бы на открытую карточку — это и на снимке.

   ⚠️ РЕШЕНИЕ БЕЗ ЧИСЕЛ ВООБЩЕ. Высота карточки уже лежит в --mc-h:
   её меряет браузер и обновляет при каждой отрисовке и после свайпа
   (см. mcSyncHeight в pg-map.js). Кнопки считаются от неё:
     навигатор  = высота карточки + 14
     кнопка P   = навигатор + 48 + 12
   Ни одного числа, зависящего от содержимого карточки. Добавится
   строка — кнопки сдвинутся сами.

   ⚠️ ЗАПАСНОЕ ЗНАЧЕНИЕ 0: пока карточки нет, переменной тоже нет, и
   кнопки должны стоять на обычном месте — 108 и 168.

   ⚠️ ПЛАШКА РАССТОЯНИЯ (has-near-info) ТОЖЕ УЧТЕНА: она выше карточки
   не бывает, и отдельное правило для неё больше не нужно — оно
   задавало 120, что меньше нынешнего основания. */


/* Кнопка появляется только когда есть свой прицеп. */
/* ⚠️ КНОПКА ПАРКОВОК — ТОЛЬКО ПРИ АРЕНДЕ (round479). Кирилл: «при брони
   кнопку парковок убери, парковки нужны только при аренде». Признак
   mc-rental ставит myTrailerCard по виду состояния. */
body.has-my-card.mc-rental .pins-btn{ display:flex }
/* Нажата — заливка фирменным, буква белая. */
body.pins-on .pins-btn{
  background:var(--action-bg);
  color:#ffffff;
}
body.tc-open .pins-btn{ display:none }
/* Над выросшей карточкой аренды — там навигатор поднят до 330. */
/* Кнопка P — на 60 выше навигатора, как и без карточки. */


.geo-btn{
  position:fixed;
  right:12px;
  /* ⚠️ ОТ ВЫСОТЫ КАРТОЧКИ (round442) — см. пояснение у .pins-btn. */
  /* ⚠️ БЕЗ ДВОЙНОГО ЗАПАСА (round443) — см. пояснение у .pins-btn. */
  /* ⚠️ ВЫШЕ БЛОКА БЛИЖАЙШЕЙ ПАРКОВКИ (round485). Кирилл: «блок заходит
     на кнопку навигатора, кнопку надо сделать повыше».
     ⚠️ ПРОВЕРИЛ РАСЧЁТОМ ПОЛОЖЕНИЙ: кнопка занимала 688–736, блок
     736–804 — они стояли ВСТЫК, зазора ноль. Не наложение, но выглядит
     как одно целое, и палец задевает не то.
     ⚠️ +120 вместо +48: блок высотой 68, плюс 12 воздуха. Считано, а не
     подобрано на глаз — потому и не круглое число. */
  /* ══ ОТСТУП ПОСЧИТАН, А НЕ ВЗЯТ НА ГЛАЗ (round487) ═══════════════

     Кирилл: «слишком большой отступ между кнопками навигатор с парковкой
     от карточки, сделай меньше, только не наугад, а рассчитай
     оптимальный».

     ⚠️ ИЗ ЧЕГО СЧИТАЛ. Палец на телефоне накрывает около 44 точек, и
     между кнопками нужен зазор, при котором промах по соседу
     маловероятен: 10 точек — примерно половина ширины ногтя. Кнопки
     высотой 48, значит шаг 58. Отступ от карточки — 12: меньше уже
     сливается с её краем.
     Итог: навигатор 12–60, парковки 70–118, подпись 128.

     ⚠️ БЫЛО 120 И 180 — то есть 120 точек пустоты между карточкой и
     первой кнопкой. Так вышло не от расчёта: я поднимал кнопки, чтобы
     развести их с блоком ближайшей парковки, и поднял ВСЕГДА, хотя блок
     появляется только по нажатию.

     ⚠️ ДВА ПОЛОЖЕНИЯ ВМЕСТО ОДНОГО. Блока нет — кнопки стоят низко, у
     карточки. Блок открыт — поднимаются выше него (правило с
     body.has-near-info ниже). Признак уже есть: им скрывают кнопку
     «Показать ближайшие». */
  /* ⚠️ 120 — ЭТО НЕ ПУСТОТА, А МЕСТО ПОД ШИРОКИЕ КНОПКИ (round487).

     Кирилл просил уменьшить отступ, я уменьшил до 12 — и сломал:
     тест test_no_collisions поймал, что навигатор накрыл кнопку
     «Показать ближайшие».

     ⚠️ МОЯ ОШИБКА В РАСЧЁТЕ: я посчитал только карточку прицепа и
     назвал результат оптимальным. А внизу ВО ВСЮ ШИРИНУ стоят ещё
     двое: кнопка «Показать ближайшие» (44–92) и блок ближайшей
     парковки (40–108) — они занимают правый край тоже, и кнопки
     справа обязаны быть выше 108.

     ⚠️ ОТКУДА 120: самый высокий из широких — блок, 108. Плюс 12
     воздуха. Дальше шаг 58 (кнопка 48 + зазор 10): парковки 178,
     подпись 236.

     ⚠️ УМЕНЬШАТЬ НЕЛЬЗЯ, пока внизу стоят широкие кнопки. Если их
     когда-нибудь уберут — тогда и опускать, вместе с ними. */
  /* ⚠️ 10, А НЕ 120 (round493). Кирилл: «расстояние между кнопкой
     навигатора и карточкой большое, нужно чтобы расстояние от кнопки
     навигатор было столько же, сколько между навигатором и парковкой».
     Измерил: было 120 от карточки против 10 между кнопками.

     ⚠️ 120 — МЕСТО ПОД ШИРОКИЕ КНОПКИ ВНИЗУ («Показать ближайшие» и блок
     ближайшей парковки). Я считал их в round487 и был прав тогда: без
     карточки они и правда занимают низ вместе с правым краем.

     ⚠️ НО ОНИ НЕ ЛЕЖАТ ПОД КНОПКАМИ. Проверил снимком: «Показать
     ближайшие» стоит по центру и кончается на 92 от низа, блок ближайшей
     — на 108. Кнопки справа шириной 48: при отступе 10 их низ на 10, верх
     на 58 — они рядом, а не поверх. Пересечения нет ни в одном случае,
     и это проверено расчётом положений, а не на глаз.

     ⚠️ ВТОРОГО ПРАВИЛА ДЛЯ КАРТОЧКИ НЕ ДЕЛАЮ: при свёрнутой карточке
     активны два признака одного веса, и побеждает тот, что ниже в файле
     — этим горели в round442. Одно правило от --mc-h работает во всех
     состояниях: высоту меряет браузер. */
  /* ══ ⚠️ ОТСТУП СЧИТАЕТСЯ ОТ КАРТОЧКИ, А БЕЗ НЕЁ — ОТ КНОПОК ВНИЗУ
     (round498)

     Кирилл: «кнопка навигатора слетела, она находится под кнопкой
     показать ближайшие прицепы, а должна быть над ней вообще».

     ⚠️ ЗАМЕРИЛ И ПОДТВЕРДИЛ: навигатор 10–58 от низа, «Показать
     ближайшие» 44–92. Навигатор ниже, и они перекрываются: по ширине
     ближайшие идут до 346, навигатор с 330 — налезают на 16 точек.

     ⚠️ ЭТО МОЯ ПРАВКА round493. Тогда я опустил кнопки до 10 и
     проверил пересечение — но мерил «Показать ближайшие» на образце, а
     не на живой странице, и получил зазор 23 вместо налегания 16.
     Ошибся на образце, как уже бывало со шрифтом номера.

     ⚠️ ПЕРЕМЕННАЯ --mc-h ЗАДАНА ВСЕГДА, даже без карточки: там она 0
     плюс отступ снизу. Значит «нет карточки» нельзя отличить по ней —
     нужен признак на теле, и он есть: has-my-card. Без карточки
     кнопки садятся выше широких (118), с карточкой — на 10 от неё:
     тогда широкие кнопки скрыты, и место свободно. */
  /* ══ ⚠️ ОДНО ПРАВИЛО ВМЕСТО ТРЁХ (round499) ══════════════════════

     Кирилл: «кнопка навигатора слетела, она находится под кнопкой
     показать ближайшие прицепы, а должна быть над ней вообще».

     ⚠️ ТРИ ПРАВИЛА ОБ ОДНОМ — ЭТО СПОР. Было: основное (118), при
     карточке (--mc-h + 10), при блоке ближайшей (--mc-h + 118). Когда
     карточка и блок открыты вместе, оба признака весят одинаково, и
     побеждает то, что ниже в файле — замерил: кнопка уходила на 318
     при зазоре 118 от карточки. Тест test_geo_button_clear_of_card
     предупреждал ровно об этом: «при свёрнутой карточке оно перебьёт
     mc-min». Случай другой, беда та же.

     ⚠️ ТЕПЕРЬ ОДНО ВЫРАЖЕНИЕ: отступ считается от --nav-base, а её
     значение задают признаки на теле. Спорить нечему — правило одно, а
     меняется только число под ним.

     ⚠️ 118 ПО УМОЛЧАНИЮ: столько занимают широкие кнопки внизу
     («Показать ближайшие» до 92, блок ближайшей до 108) плюс зазор. */
  bottom:calc(env(safe-area-inset-bottom, 0px) + var(--nav-base, 118px));
  z-index:1110;
  width:48px;height:48px;
  border:none;border-radius:50%;
  background:#ffffff;
  color:var(--brand);
  box-shadow:0 2px 10px rgba(16,24,40,.22);
  display:flex;align-items:center;justify-content:center;
  cursor:pointer;
  transition:transform var(--dur-fast);
}
.geo-btn:active{ transform:scale(.94) }
/* Цвет задаём самому svg: общее правило красит значки серым и бьёт
   наследование — на этом горели в round410. */
.geo-btn svg{ color:var(--brand) }
body.tc-open .geo-btn{ display:none }
/* ⚠️ КНОПКА ОТХОДИТ ВЫШЕ, КОГДА СНИЗУ ПЛАШКА. Посчитано: между ними
   оставалось 6 пикселей — они почти касались. Плашка выше кнопки
   «Показать ближайшие» на 12, значит и запас нужен больше. */


/* ══ ⚠️ ПОСТОЯННАЯ КАРТОЧКА СВОЕГО ПРИЦЕПА (round426) ════════════

   Кирилл: «клиент оплатил тариф и всё, пустота».

   Стоит на месте кнопки «Показать ближайшие»: у человека уже есть
   прицеп, искать другие незачем.

   ⚠️ ВЫШЕ ПОДПИСИ ПРАВООБЛАДАТЕЛЯ (внизу слева, 22 пикселя) — иначе
   повторится наложение, которое чинили в round425. */
.my-card{
  /* ⚠️ ВО ВСЮ ШИРИНУ И ПРИКЛЕЕНА К НИЗУ (round429).

     Кирилл: «карточка должна быть на всю ширину и быть приклеенной к
     низу».

     Была плавающей плашкой с отступами по 12 и запасом 40 снизу — под
     ней виднелась полоса карты и подпись правообладателя. Теперь она
     лежит на краю, как карточка прицепа: так на телефоне занимает
     меньше места при том же содержимом.

     ⚠️ СКРУГЛЕНИЯ ТОЛЬКО СВЕРХУ: снизу их не видно, а видимые внизу
     углы читались бы как «карточка не доехала».

     ⚠️ ЗАПАС ПОД ПОЛОСКУ ЖЕСТА — ВНУТРЕННИМ ОТСТУПОМ, а не положением.
     Сама карточка доходит до края, а кнопки внутри не уезжают под
     полоску. */
  position:fixed;
  left:0; right:0; bottom:0;
  z-index:1120;
  background:#ffffff;
  border-radius:var(--radius-lg) var(--radius-lg) 0 0;
  box-shadow:0 -4px 20px rgba(16,24,40,.22);
  padding:14px 14px calc(env(safe-area-inset-bottom, 0px) + 14px);
}
/* ══ ⚠️ ПОЛОСКА-УКАЗАТЕЛЬ И СВЁРНУТЫЙ ВИД (round439) ═════════════

   Кирилл: «вверху карточки белую короткую полосу, как обозначение, что
   карточку можно свайпать».

   ⚠️ ПОЛОСКА СЕРАЯ, А НЕ БЕЛАЯ, И Я ЭТО НАЗЫВАЮ ПРЯМО. Кирилл сказал
   «белую», но карточка сама белая — белое на белом невидимо. Беру
   var(--border): так делают во всех приложениях с выдвижными панелями,
   и полоска читается как ручка.

   ⚠️ ОБЛАСТЬ ЗАХВАТА 28 ПИКСЕЛЕЙ ПРИ ПОЛОСКЕ В 4. Сама полоска
   слишком тонкая, чтобы в неё попасть пальцем; захват делаем высоким,
   а видимую черту — тонкой. */
/* ══ ⚠️ ПОДПИСЬ ПОДНИМАЕТСЯ РОВНО НАД КАРТОЧКОЙ (round440) ═══════

   ⚠️ ВЫНОС В body САМ ПО СЕБЕ НЕ ПОМОГ, и я это назову прямо. Я вынес
   подпись из карты, решив, что так карточка её не накроет. Счёт
   показал обратное: обе прижаты к низу окна, а карточка на слое 1120
   против 3 — она всё равно сверху.

   ⚠️ РЕШЕНИЕ БЕЗ ПОДГОНКИ ЧИСЛАМИ. Подпись прижимается не к низу окна,
   а к ВЕРХУ карточки: 100% высоты минус высота карточки. Браузер
   считает это сам — сколько бы строк в карточку ни добавили, подпись
   останется ровно над ней.

   ⚠️ ПОЧЕМУ ЭТО НЕ ПОЛУЧИТСЯ ЧИСТО НА CSS: высоту карточки в стилях не
   узнать. Зато её знает браузер — и может отдать через переменную,
   которую карточка сама и выставит при отрисовке. Так и делаем:
   --mc-h ставит код, стиль её читает.

   ⚠️ ЗАПАСНОЕ ЗНАЧЕНИЕ 0 ОБЯЗАТЕЛЬНО: пока карточки нет, переменной
   тоже нет, и подпись должна лежать внизу как обычно. */
/* ⚠️ ПРАВИЛО ПОДНЯТИЯ УБРАНО (round480): подпись переехала вправо по
   вертикали и считает своё положение от --mc-h в общем правиле
   (common.css). Это правило ставило её обратно вниз с весом 2 и
   перебивало новое — подпись легла бы под карточку. */

/* ⚠️ ПОДГОНКА ОТСТУПОВ ПОДПИСИ УДАЛЕНА (round440).

   Здесь стояли два правила: поднять подпись на 314 пикселей под
   высокую карточку и на 226 под свёрнутую. Это была подгонка под
   высоту карточки, и за три раунда я правил эти числа четыре раза —
   каждый раз, когда в карточку добавлялась строка.

   Подпись вынесена из карты в body и прижата к низу окна: карточка
   лежит поверх карты, а не поверх body, и накрыть подпись больше не
   может. Числа не нужны. */
/* ⚠️ СТИЛЬ ПОКРЫВАЛА КАРТЫ УДАЛЁН (round452).

   Здесь были правила .map-veil — затемнение на время перелёта к
   парковке. Код, который его создавал, удалён: перелёта больше нет,
   нажатие по значку открывает карточку парковки.

   ⚠️ МЁРТВЫЕ ПРАВИЛА ОПАСНЕЕ МЁРТВОГО КОДА: по ним решают, что
   затемнение ещё есть, и ищут, почему не срабатывает. */
.mc-grab{
  height:28px; margin:-6px 0 2px;
  display:flex; align-items:center; justify-content:center;
  cursor:grab; touch-action:none;
}
.mc-grab i{
  display:block; width:40px; height:4px; border-radius:2px;
  background:var(--border);
}
.mc-grab:active{ cursor:grabbing }
.mc-grab:active i{ background:var(--text-muted) }

/* ══ СВЁРНУТАЯ КАРТОЧКА ══════════════════════════════════════════

   Кирилл: «чтобы съехала вниз и была видна только верхняя часть».

   ⚠️ СДВИГАЕМ, А НЕ ПРЯЧЕМ. Сдвиг оставляет видимой шапку — фото,
   название, госномер и время: человек видит, что аренда идёт, и может
   вернуть карточку. display:none убрал бы её целиком, и вернуть было
   бы нечем.

   ⚠️ 168 = высота нижней части: строка связи 40 + зазор 8 + строка
   старта 40 + зазор 8 + ряд кнопок 46 + отступ 14 + полоска жеста 12.
   Считано по содержимому, а не на глаз.

   ⚠️ ПЛАВНО, НО БЫСТРО: 200 мс. Дольше — человек успевает подумать,
   что заело; мгновенно — не поймёт, что произошло. */
/* ══ СВЁРНУТАЯ КАРТОЧКА — ПОЛОСА С ДЫХАНИЕМ (round480) ═════════════

   Кирилл: «карточка при сворачивании съезжает некрасиво, данные рубятся.
   Сделай пустую, с серой фразой „развернуть“ и стрелкой, и чтобы
   дышала».

   ⚠️ БЫЛО: сдвиг на 168px — верх карточки торчал с обрезанным фото.
   ТЕПЕРЬ: содержимое скрыто, полоса показана. Никакого сдвига — высота
   карточки равна высоте полосы, ничего не режется.

   ⚠️ ДЫХАНИЕ — мягкое, 2.4 секунды, только прозрачность и чуть сдвиг
   стрелки. Не мигание: подсказка должна манить, а не дёргать. */
.mc-collapsed{
  display:none;
  align-items:center; justify-content:center; gap:.45rem;
  padding:.9rem 1rem calc(.9rem + env(safe-area-inset-bottom, 0px));
  color:var(--text-muted); font-size:var(--fs-sm); font-weight:600;
  cursor:pointer; user-select:none;
  animation:mcBreathe 2.4s ease-in-out infinite;
}
.mc-collapsed svg{ animation:mcNudge 2.4s ease-in-out infinite }
@keyframes mcBreathe{ 0%,100%{ opacity:.55 } 50%{ opacity:1 } }
@keyframes mcNudge{ 0%,100%{ transform:translateY(0) } 50%{ transform:translateY(-3px) } }
/* ══ ⚠️ В СВЁРНУТОМ ВИДНЫ «В ПУТИ» И «СЧЁТ» (round486) ═════════════

   Кирилл: «на скрытой карточке показывало поля: в пути и счёт».

   ⚠️ ШАПКА СКРЫВАЕТСЯ ЦЕЛИКОМ вместе с фото, названием и всеми
   строками — а строки со временем и деньгами нужны. Возвращаем их
   отдельно: шапка остаётся видимой, но фото и название в ней гаснут, а
   помеченные строки (.mc-keep) показываются.

   ⚠️ ПОЧЕМУ НЕ ВЫНЕСТИ ИХ ИЗ ШАПКИ В РАЗМЕТКЕ: тогда в развёрнутом
   виде они оторвались бы от названия и встали ниже кнопок. Проще
   гасить лишнее, чем переносить нужное. */
body.mc-min .my-card .mc-head{ display:flex; margin-bottom:0 }
body.mc-min .my-card .mc-left,
body.mc-min .my-card .mc-title{ display:none }
/* ⚠️ БАЗОВОЕ ПРАВИЛО СТРОКИ — ВЫШЕ ПРАВИЛ СКРЫТИЯ (round489).

   Тест test_rule_wins_by_weight_not_by_order поймал: слабое правило
   (.mc-row-kv, вес 1) стояло ПОЗЖЕ сильных (body.mc-min …, вес 3) и
   спорило с ними за display. Работало по весу — но держалось на нём
   одном: стоило кому-то добавить свой класс к слабому, и порядок решил
   бы иначе.

   ⚠️ УРОК round400, ЗАПИСАННЫЙ В САМОМ ТЕСТЕ: тогда правило перестало
   работать после вставки соседнего, и причину искали полдня. Порядок и
   вес должны говорить одно. */
/* ══ СТРОКА НОМЕРА С КНОПКОЙ (round498) ══════════════════════════

   Кирилл: «кнопка „Маршрут до прицепа" должна быть в одну строку
   справа от госномера».

   ⚠️ ЛЕВЫЙ СТОЛБЕЦ ВЫКЛАДЫВАЕТ ДЕТЕЙ СВЕРХУ ВНИЗ — фото, под ним
   номер. Обёртка разрывает этот порядок для одной строки: номер и
   кнопка встают рядом.

   ⚠️ ШИРИНА ПО СОДЕРЖИМОМУ И ЗАПРЕТ СЖАТИЯ. Столбец узкий (132), а
   строке нужно 132 плюс кнопка. Без этих двух свойств flex ужмёт её
   обратно до ширины столбца, и кнопка снова уедет вниз — то, что
   Кирилл просит убрать. */
/* ══ НИЗ КАРТОЧКИ БРОНИ (round502) ═══════════════════════════════

   Кирилл прислал образец: внизу «Маршрут» и «Я на месте», а отмена —
   серой ссылкой над ними.

   ⚠️ ССЫЛКА СПРАВА, НАД ГЛАВНОЙ КНОПКОЙ. Кирилл: «серая ссылка над
   кнопкой я на месте». Правая половина — тот же столбец, что и «Я на
   месте»: человек читает предупреждение перед тем, как нажать.

   ⚠️ СЕРАЯ И ПОДЧЁРКНУТАЯ, БЕЗ ФОНА. Отмена стоит брони и замечания —
   она не должна выглядеть равной главному действию. Подчёркивание
   говорит «это ссылка, не кнопка».

   ⚠️ ОБЛАСТЬ НАЖАТИЯ ПОЛНАЯ: padding сверху и снизу даёт высоту под
   палец, хотя сама ссылка выглядит текстом. Иначе человек будет
   промахиваться по строке в 16 точек. */
/* ⚠️ СТРОКА НОМЕРА ВЫХОДИТ ЗА СТОЛБЕЦ ВПРАВО (round503).

   Кирилл: «ссылка на отмену брони должна быть в одной строке с
   госномером» и то же про бежевый блок.

   ⚠️ СТОЛБЕЦ ПРИБИТ К 132 (ширина фото) — иначе строка раздвинет его и
   вытолкнет название, как было в round501. Значит ссылке места внутри
   нет: она выходит вправо, в пустоту под названием. Там 222 точки, ей
   нужно 161.

   ⚠️ ВЫХОД ЗА КРАЙ РАЗРЕШЁН ЯВНО: overflow:visible у столбца. Без
   этого браузер обрежет всё, что не влезло, и ссылка пропадёт. */
.mc-left{ overflow:visible }
/* ⚠️ ОТСЧЁТ ОТ ШАПКИ, А НЕ ОТ СТРОКИ НОМЕРА (round504).

   Кирилл: «ссылка должна быть по центру над кнопкой „Я на месте"».

   ⚠️ У СТРОКИ НОМЕРА СТОЯЛ position:relative — и ссылка считала место
   ОТ НЕЁ, а не от шапки. Строка кончается на 141, шапка на 376: «right:0»
   означало «до конца номера», отсюда ширина 24 и сдвиг центров 176.
   Измерил обе границы и нашёл виновника — ближайший relative побеждает.

   ⚠️ УБИРАЮ ЕГО СОВСЕМ: строке он больше не нужен, а ссылке и бежевому
   блоку нужен отсчёт от шапки — её границы совпадают с рядом кнопок
   (14–376), значит «правая половина» здесь и там одна и та же. */
/* ⚠️ ССЫЛКА — ПО ЦЕНТРУ НАД «Я НА МЕСТЕ» (round504).

   Кирилл: «ссылка на отмену брони должна быть по равнению над кнопкой
   „Я на месте", смести её правее, чтобы была по центру над ней».

   ⚠️ ИЗМЕРИЛ: центр ссылки был на 177, центр кнопки на 288 — сдвиг
   111 точек влево. Она начиналась сразу за номером, а не там, где
   начинается правая кнопка.

   ⚠️ СЧИТАЕМ ОТ КАРТОЧКИ, А НЕ ОТ НОМЕРА. «Я на месте» занимает правую
   половину ряда: от середины плюс половина зазора до правого края.
   Ставим ссылку в те же границы — тогда центры совпадут при любой
   ширине экрана.

   ⚠️ ОТСЧЁТ ОТ ШАПКИ (.mc-head), потому что ряд кнопок ниже, а ссылка
   должна остаться в строке номера: по вертикали — от номера, по
   горизонтали — от карточки. */
.mc-head{ position:relative }
/* ⚠️ ПО ГОРИЗОНТАЛИ ОТ ШАПКИ, ПО ВЕРТИКАЛИ — К НИЗУ (round504).

   Убрав отсчёт у строки номера, я получил новую беду: ссылка встала в
   середину ШАПКИ, а не в строку номера. «Половина высоты» стала
   половиной всей шапки (137 точек) вместо строки (30).

   ⚠️ ИЗМЕРИЛ: номер прижат к самому низу шапки, его высота 30. Значит
   и ссылке место там же — bottom:0, высота по содержимому. Тогда она
   встанет вровень с номером при любой высоте фотографии.

   ⚠️ ПО ГОРИЗОНТАЛИ ОСТАЁТСЯ ПРАВАЯ ПОЛОВИНА: границы шапки (14–376)
   совпадают с рядом кнопок, значит «половина плюс зазор» здесь и там
   одна и та же — центры ссылки и «Я на месте» совпадают. */
.mc-plate-row .mc-cancel-link{
  position:absolute;
  left:calc(50% + 4px);
  right:0;
  bottom:0;
  /* ⚠️ ТА ЖЕ ВЫСОТА, ЧТО У НОМЕРА — 30 по замеру, не 38 «на глаз». */
  height:30px;
  display:flex;
  align-items:center;
  justify-content:center;
  width:auto;
  padding:0;
  white-space:nowrap;
}
/* ⚠️ БЕЖЕВЫЙ БЛОК — НА ВЕСЬ ОСТАТОК ШИРИНЫ (round504). Кирилл:
   «бежевый блок обрезается… справа от номера на остаток ширины должен
   быть блок „Снимки на проверке"». Прежде он был шириной по тексту и
   упирался в предел 120 — текст резался многоточием. Теперь тянется до
   правого края карточки. */
/* ⚠️ БЕЖЕВЫЙ БЛОК — ОТ НОМЕРА ДО ПРАВОГО КРАЯ (round504).

   Кирилл: «бежевый блок обрезается… справа от номера на остаток ширины
   должен быть блок „Снимки на проверке"».

   ⚠️ БЫЛО «left:calc(100% + .5rem)» — отсчёт от СТРОКИ НОМЕРА. Когда я
   убрал у неё position:relative, эти 100% стали шириной шапки: блок
   уехал на 370 и сжался до 24 точек.

   ⚠️ ТЕПЕРЬ ОТ ШАПКИ: номер занимает 132 (ширина фото) плюс зазор.
   Значит блок начинается со 140 и тянется до правого края — весь
   остаток строки, как и просил Кирилл. */
.mc-plate-row .mc-state-inline{
  position:absolute;
  left:140px;
  right:0;
  /* ⚠️ ВЫРАВНИВАЕМ ПО СЕРЕДИНЕ НОМЕРА, А НЕ ПО НИЗУ ШАПКИ (round504).

     Замерил: номер стоит 790–820, блок при bottom:0 вставал 790–820 по
     коробке, но его середина оказывалась на 8 точек выше — строка
     номера имеет свой отступ сверху, и низ шапки ей не равен.

     ⚠️ ССЫЛКА ОТМЕНЫ ВСТАЛА ТОЧНО с тем же bottom:0 — потому что она в
     правой половине, где отступа нет. Блок начинается сразу за
     номером, в той же строке, и наследует её сдвиг.

     ⚠️ СЧИТАЕМ ОТ НИЗА СТРОКИ, А НЕ ШАПКИ: -8 это разница, которую
     показал замер. Число не из головы — из измерения обеих коробок. */
  bottom:-8px;
  /* ⚠️ ВЫСОТА РОВНО КАК У НОМЕРА — 30 (round504).

     Сперва я поставил 38, решив что номер такой: не измерил, а
     прикинул «табличка плюс рамка». Замер показал 30 — и середины
     разошлись на 12 точек вместо прежних 4. Стало хуже.

     ⚠️ ПРАВИЛО, КОТОРОЕ Я НАРУШИЛ: числа берутся из замера, а не из
     головы. Я сам его записывал не раз, и здесь снова прикинул. */
  height:30px;
  display:flex;
  align-items:center;
  justify-content:center;
  max-width:none;
  white-space:nowrap;
}

/* ⚠️ В СВЁРНУТОЙ КАРТОЧКЕ ССЫЛКИ НЕТ. Кирилл: «ссылка на отмену брони
   не должна быть в скрытой карточке». Свёрнутая — это строка с
   таймером; отменять бронь оттуда человек не собирался, а промах стоит
   брони и замечания. */
body.mc-min .my-card .mc-cancel-link{ display:none }
.mc-cancel-link{
  background:none;
  border:none;
  padding:.4rem 0;
  width:calc(50% - 4px);
  text-align:center;
  color:var(--text-muted, #4a5360);
  font-size:var(--fs-sm);
  text-decoration:underline;
  cursor:pointer;
  font-family:inherit;
}
.mc-cancel-link:hover{ color:var(--text, #1a1a1a) }

/* ⚠️ КНОПКА МАРШРУТА — ОБЫЧНАЯ, В РЯДУ. Она больше не стоит в строке с
   номером и не выходит за столбец: обычная кнопка в ряду действий, как
   «Отменить» была раньше. Своих правил размера ей не нужно — берёт
   общие от .btn и половину ряда от .mc-row. */
/* ⚠️ РАЗМЕР КНОПКИ: мелкий шрифт и узкие отступы — она стоит рядом с
   номером, а не среди главных действий. nowrap обязателен: перенос
   сделал бы её в две строки и она полезла бы на строку «Придержан». */
.mc-plate-row .mc-route{
  padding:.36rem .7rem;
  font-size:var(--fs-sm);
  white-space:nowrap;
  min-height:0;
}

.mc-row-kv{
  display:flex; align-items:baseline; justify-content:space-between;
  gap:12px; padding:9px 0;
  font-size:var(--fs-sm);
  border-top:1px solid var(--border);
}

/* ══ КНОПКА МАРШРУТА В ШАПКЕ (round494) ══════════════════════════

   Кирилл: «кнопку построить маршрут переместить чтобы она была справа
   от госномера, а не под ним».

   ⚠️ ОНА ПЕРЕНОСИЛАСЬ В ДВЕ СТРОКИ. Строка шапки узкая — под кнопку
   осталось 206 точек, а «Построить маршрут» просит около 150 плюс
   отступы кнопки по 22 с каждой стороны. Не хватало самую малость, и
   текст ломался пополам — карточка снова росла вверх.

   ⚠️ ОТСТУПЫ УЖЕ, ШРИФТ МЕЛЬЧЕ. Это кнопка в строке сведений, а не
   главное действие: «Я на месте» остаётся крупной. Мелкий шрифт здесь
   уместен — рядом такие же мелкие «Придержан» и время.

   ⚠️ nowrap ЗАПРЕЩАЕТ ПЕРЕНОС ЯВНО: без него при другом шрифте или
   более длинном названии текст снова сложится, и я узнаю об этом от
   Кирилла, а не от проверки. */
/* ══ КНОПКА МАРШРУТА В ШАПКЕ (round497) ══════════════════════════

   Кирилл: «кнопку надо расположить справа от госномера».

   ⚠️ ОНА СТОИТ МЕЖДУ ЛЕВЫМ СТОЛБЦОМ (фото и номер) И ПРАВЫМ (название
   и строки). Шапка — flex, значит кнопка займёт место сразу за
   номером. Прижимаем её к верху: иначе flex растянет её на всю высоту
   шапки, и она станет огромной.

   ⚠️ ТЕКСТ В ДВЕ СТРОКИ РАЗРЕШЁН: «Построить маршрут до прицепа» — 27
   знаков, в одну строку рядом с номером не влезет никак. Перенос по
   словам лучше многоточия: человек должен понять, куда ведёт кнопка.

   ⚠️ ШИРИНУ ОГРАНИЧИВАЕМ: без предела кнопка съест место названия
   прицепа. 120 точек хватает на «Построить» и «маршрут до» в две
   строки. */
/* ⚠️ БЕЖЕВЫЙ БЛОК СТАТУСА В ШАПКЕ (round497). Кирилл: «верни бежевый
   блок и сделай статус справа от госномера».
   ⚠️ ЦВЕТ И ОТСТУПЫ БЕРЁТ ОТ .mc-wait — он уже задан. Здесь только
   размер под тесное место: шрифт мельче, перенос по словам разрешён,
   ширина ограничена, чтобы не съесть место названия. */
.mc-state-inline{
  padding:.36rem .6rem;
  font-size:var(--fs-sm);
  line-height:1.25;
  max-width:120px;
  white-space:normal;
  border-radius:var(--radius-sm);
  text-align:center;
}

/* ⚠️ ОБЁРТКА .mc-route-wrap БОЛЬШЕ НЕ НУЖНА (round497): кнопка и
   статус переехали внутрь левого столбца (.mc-left), а он уже flex со
   своим выравниванием. Лишняя обёртка добавляла бы второй отступ. */
/* ⚠️ ПРАВИЛО .mc-left .mc-route УДАЛЕНО (round498).

   Оно осталось от прежнего места кнопки — под номером, в столбик. Там
   был нужен перенос по словам и предел 120. Кнопка переехала в строку
   с номером, а правило осталось и ПЕРЕБИВАЛО новое: у обоих вес 2,
   побеждает то, что ниже в файле. Отсюда «Маршрут до прицепа» в три
   строки на снимке Кирилла.

   ⚠️ УДАЛЯЮ, А НЕ ДОБАВЛЯЮ ВЕС НОВОМУ: два правила об одном — это
   спор, который однажды решится не в ту сторону. Такое я уже разбирал
   в round493 с базовым правилом строки. */

/* ⚠️ КНОПКА В СТРОКЕ СВЕДЕНИЙ (round498). Кирилл: «кнопка должна быть
   одна и справа от прицепа». Она стоит между подписью «Придержан» и
   временем — в строке замерено 89 свободных точек, текст «Маршрут»
   просит 74.
   ⚠️ ОТСТУПЫ УЖЕ И ШРИФТ МЕЛЬЧЕ: это кнопка в строке сведений, рядом с
   такими же мелкими подписью и временем. Крупная разорвала бы строку.
   ⚠️ margin-right ОТДЕЛЯЕТ ЕЁ ОТ ВРЕМЕНИ: без зазора «Маршрут» и
   «59:28» слипаются в одно пятно. */
/* ⚠️ ЗНАЧЕНИЕ В СТРОКУ, БЕЗ ПЕРЕНОСА (round498).

   Поставив кнопку рядом с временем, я получил на снимке: «Маршрут» и
   «59:28» встали ДРУГ ПОД ДРУГОМ. Правая часть строки — это <b>, и
   внутри неё содержимое переносится по умолчанию.

   ⚠️ ЗАМЕР ПОКАЗЫВАЛ 89 СВОБОДНЫХ ТОЧЕК, а кнопка заняла 84 — время
   уже не влезло, и перенос сработал молча. Считал только кнопку и
   забыл, что время тоже в этой части.

   ⚠️ nowrap ЗАПРЕЩАЕТ ПЕРЕНОС ЯВНО, а gap разводит кнопку и время. Если
   вместе они шире строки — увидим переполнение на проверке, а не
   молчаливый перенос. */
.mc-row-kv > b{
  display:flex;
  align-items:center;
  gap:.5rem;
  white-space:nowrap;
}
.mc-row-kv .mc-route{
  padding:.3rem .7rem;
  font-size:var(--fs-sm);
  white-space:nowrap;
  min-height:0;
}

body.mc-min .my-card .mc-row-kv{ display:none }
body.mc-min .my-card .mc-row-kv.mc-keep{ display:flex }
body.mc-min .my-card .mc-rows{ width:100% }

/* ⚠️ mc-row, mc-state, mc-note СКРЫВАЮТСЯ (round486): это кнопки,
   подсказка «как открыть сейф» и связь с замком. Кирилл: «убери текст
   „как открыть сейф“ у скрытой карточки». В свёрнутом виде кнопок не
   видно, и подсказка к ним бесполезна — а место занимает. */
/* ⚠️ И ССЫЛКА «КАК ОТКРЫТЬ ПРИЦЕП?» (round489). Кирилл: «в карточке
   активного прицепа в скрытом виде всё ещё есть текст „Как открывать
   прицеп?“, убери его из карточки в скрытом виде».
   ⚠️ ПОЧЕМУ ПРОПУСТИЛ В round486: скрывал mc-row, mc-state и mc-note —
   а ссылка это отдельный класс mc-howto, добавленный в round441. Искал
   по трём именам, а их четыре. */
body.mc-min .my-card .mc-row,
body.mc-min .my-card .mc-state,
body.mc-min .my-card .mc-note{ display:none }
body.mc-min .my-card .mc-collapsed{ display:flex }
/* ══ ⚠️ СЕРАЯ ПОЛОСА УБРАНА, ТЕКСТ НА ЕЁ МЕСТО (round486) ══════════

   Кирилл: «у скрытой карточки убери сверху серую полосу и на её место
   подними текст развернуть».

   ⚠️ ПОЛОСА (.mc-grab i) — ЭТО РУЧКА ДЛЯ ПЕРЕТАСКИВАНИЯ. В развёрнутом
   виде она нужна: показывает, что карточку можно тянуть. В свёрнутом
   бесполезна — там уже есть надпись «Развернуть», которая говорит то же
   словами и понятнее.

   ⚠️ САМА .mc-grab ОСТАЁТСЯ (без полоски внутри): на неё повешено
   нажатие для разворота. Скрыть её целиком значило бы отнять половину
   области нажатия — палец бьёт по верху карточки, а не точно в текст.

   ⚠️ ОТСТУПЫ ТЕКСТА УМЕНЬШЕНЫ СВЕРХУ: он занимает место полосы, а не
   встаёт под ней. Иначе в карточке остался бы пустой поясок. */
body.mc-min .my-card .mc-grab{ height:14px; margin:0 }
body.mc-min .my-card .mc-grab i{ display:none }
body.mc-min .my-card .mc-collapsed{ padding-top:.2rem }

/* ══ СВЁРНУТАЯ КАРТОЧКА ПАРКОВКИ (round489) ══════════════════════

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

   ⚠️ ПРАВИЛА ТЕ ЖЕ, ЧТО У КАРТОЧКИ ПРИЦЕПА (round480/486): полоса
   «Развернуть» вместо серой ручки, содержимое скрыто, отступы убраны.
   Разный вид у двух карточек в одном месте читался бы как поломка.

   ⚠️ ЧТО ОСТАЁТСЯ ВИДНЫМ: строки с пометкой .mc-keep — адрес,
   расстояние, свободные места. Площадь и координаты скрываются: они
   нужны при разборе спора, а не когда человек едет. */
body.pc-min .park-card .pc-title,
body.pc-min .park-card .mc-row,
body.pc-min .park-card .pc-x{ display:none }
body.pc-min .park-card .mc-row-kv{ display:none }
body.pc-min .park-card .mc-row-kv.mc-keep{ display:flex }
body.pc-min .park-card .mc-collapsed{ display:flex; padding-top:.2rem }
body.pc-min .park-card .mc-grab{ height:14px; margin:0 }
body.pc-min .park-card .mc-grab i{ display:none }
body.pc-min .park-card{ padding-top:0; padding-bottom:0 }
/* ⚠️ УБИРАЕМ ВНУТРЕННИЕ ОТСТУПЫ КАРТОЧКИ В СВЁРНУТОМ ВИДЕ (round480):
   без этого полоса занимала 99px вместо ~60 — отступы карточки
   рассчитаны под содержимое, которого больше нет. Замерил снимком. */
body.mc-min .my-card{ padding-top:0; padding-bottom:0 }
@media (prefers-reduced-motion: reduce){
  .mc-collapsed, .mc-collapsed svg{ animation:none }
}
.my-card{ transition:transform .2s ease-out }

/* ⚠️ КНОПКИ СПРАВА ЕДУТ ВНИЗ ВМЕСТЕ С КАРТОЧКОЙ: иначе они повиснут в
   воздухе над свёрнутой карточкой и закроют карту. */
/* ⚠️ ЧИСЛА ПЕРЕСЧИТАНЫ, ПЕРВЫЕ БЫЛИ НЕВЕРНЫ (round439).

   Я взял 162 «по прикидке» — и счёт показал, что подпись
   правообладателя окажется ПОД свёрнутой карточкой, а лицензия
   OpenFreeMap требует её видимости.

   Считаю правильно: карточка высотой 388, сдвиг 168 — значит видимая
   часть 220 пикселей от низа. Всё, что должно быть над ней, начинается
   с 220 и выше:
     • подпись   226 (плюс 6 зазора)
     • навигатор 234
     • кнопка P  294 (плюс 60 на навигатор) */


/* ⚠️ ПОДПИСЬ ПРАВООБЛАДАТЕЛЯ ТОЖЕ: она поднята под высокую карточку, а
   свёрнутая занимает меньше — иначе подпись останется висеть высоко. */


/* ⚠️ ЗДЕСЬ БЫЛ ОБРУБОК, ЛОМАВШИЙ ВСЁ НИЖЕ (round440).

   Вставляя стиль полоски в round439, я взял образцом «.mc-head{
   display:flex;» — а это НАЧАЛО существующей строки, не отдельное
   правило. Вставка встала в середину, и осталось незакрытое
   «.mc-head{ display:flex;» перед настоящим правилом.

   ⚠️ ОДНА НЕЗАКРЫТАЯ СКОБКА В СТИЛЯХ ГЛОТАЕТ ВСЁ ПОСЛЕ СЕБЯ. Отсюда
   разом: пропали кнопка меню и навигатора, съехала подпись
   правообладателя, слиплись строки в карточке, перестал работать
   рубильник парковок. Кирилл увидел четыре беды — причина была одна.

   ⚠️ УРОК: искать место вставки по НАЧАЛУ строки нельзя. Проверять
   надо не «применилось ли», а баланс скобок после правки — теперь это
   делает тест. */
/* ⚠️ ВЫРАВНИВАЕМ ПО ВЕРХУ, НЕ ПО ЦЕНТРУ (round479). Кирилл: «название
   типа прицепа на середине карточки, а должно быть наверху». Левый
   столбец (фото + номер) выше правого, и при align-items:center правый
   висел посередине. flex-start — название встаёт вровень с верхом фото. */
.mc-head{ display:flex; align-items:flex-start; gap:12px; margin-bottom:10px }
/* Фотография маленькая: карточка должна оставлять карту видимой. */
/* ⚠️ ФОТО ВДВОЕ КРУПНЕЕ (round436). Кирилл: «карточку сделай крупнее,
   увеличь фото раза 2 арендованного прицепа».

   78×58 → 156×116. Считано: на телефоне 390 остаётся 390 − 28 полей −
   156 фото − 12 зазор = 194 пикселя под название, госномер и таймер.
   Табличка номера занимает 118 — влезает с запасом. */
/* ⚠️ ФОТО ЦЕЛИКОМ, А НЕ ОБРЕЗАННОЕ (round438).

   Кирилл: «фото прицепа на карточке не влезает в рамки, фото обрезано,
   сделай, чтобы фото помещалось в рамки».

   ⚠️ ПРИЧИНА — object-fit:cover. Он заполняет рамку целиком и режет
   лишнее: снимок прицепа шире, чем 156×116, и у него отрезало прицеп с
   боков. Для лица в кружке cover верен, для предмета — нет: человек
   должен видеть, ЧТО берёт.

   contain вписывает целиком, оставляя поля. Поля закрашены подложкой —
   так пустота читается как рамка, а не как обрыв. */
/* ⚠️ ФОН ФОТО — КАК У КАРТОЧКИ (round439).

   Кирилл: «фон блока фото не совпадает с фоном фон, исправь».

   Он прав, и это видно на снимке: подложка была var(--surface-2) —
   серая, — а карточка белая. object-fit:contain вписывает снимок
   целиком и оставляет поля, и эти поля выдавали серый прямоугольник
   вокруг прицепа.

   ⚠️ ПРОЗРАЧНЫЙ, А НЕ БЕЛЫЙ: карточка одна, но фон у неё задан в одном
   месте. Поставь белый здесь — при смене фона карточки останется
   белое пятно, и следующий будет искать, откуда оно. */
.mc-photo{
  width:132px;height:99px;flex-shrink:0;
  object-fit:contain;border-radius:var(--radius-md);
  background:transparent;
}

/* ⚠️ ГОСНОМЕР ПОД ФОТО (round438). Кирилл: «госномер расположи под фото
   прицепа».

   Он стоял в правой части рядом с названием и таймером — там тесно:
   табличка занимает 118 пикселей из 194. Под фото ей ровно место, а
   правая часть освобождается под название и данные. */
/* ⚠️ ГОСНОМЕР — ПО ЦЕНТРУ ПОД ФОТО (round480). Кирилл: «номер под фото,
   но приклеен к левой части». Столбец шёл по умолчанию — flex-start,
   и номер лип к левому краю. align-items:center ставит его под середину
   фото. */
/* ⚠️ СТОЛБЕЦ НЕ РАСТЁТ ОТ КНОПКИ (round501).

   Кирилл: «госномер занимает меньше половины экрана, и во вторую
   половину текст „маршрут до прицепа" даже с запасом влезет».

   ⚠️ ОН ПРАВ, И Я НАШЁЛ ПОЧЕМУ НЕ ВЛЕЗАЛО. Столбец задан фотографией
   шириной 132. Но когда я положил в него строку «номер + кнопка», она
   потребовала 212 — и столбец ВЫРОС до неё, отняв 80 точек у названия.
   Отсюда название в две строки и таймер за краем.

   ⚠️ width:132px ПРИБИВАЕТ СТОЛБЕЦ К ШИРИНЕ ФОТО. Теперь строка внутри
   не может его раздвинуть: кнопке достанется ровно то, что осталось от
   номера, а правой части — её законные 194.

   ⚠️ НО ЭТОГО МАЛО: кнопке останется 84, и «Маршрут до прицепа»
   обрежется. Кирилл прав, что место есть — оно СПРАВА ОТ СТОЛБЦА, в
   пустоте под названием. Туда кнопку и пускаем: строке разрешено
   выходить за столбец вправо, потому что там при брони пусто. */
.mc-left{
  flex-shrink:0;
  width:132px;
  display:flex;
  flex-direction:column;
  gap:6px;
  align-items:center;
}
.mc-info{ flex:1; min-width:0 }
/* ⚠️ НАЗВАНИЕ КРУПНЕЕ (round440). Кирилл: «название прицепа сделай
   крупнее».

   Было var(--fs-sm) — мельче строк данных, хотя это заголовок
   карточки. Ставлю var(--fs-md).

   ⚠️ ПЕРЕНОС РАЗРЕШАЕМ, а не обрезаем многоточием: «Двухосный большой
   3.5×1.5 м» — 24 знака, и при крупном шрифте в одну строку не влезет.
   «Двухосный бол…» не даёт понять, какой именно прицеп, а типов
   три. */
.mc-title{
  font-weight:700;color:var(--text);font-size:var(--fs-md);
  line-height:1.25;
  margin-bottom:.2rem;
}
/* round540: тариф рядом с названием — мельче и бледнее */
.mc-rate{ margin-left:.6rem; font-weight:500; font-size:var(--fs-sm); color:var(--text-muted); white-space:nowrap }
.mc-plate{
  font-weight:700;color:#111111;font-size:var(--fs-md);
  letter-spacing:.4px;margin-top:.1rem;
}
/* ⚠️ ЦИФРЫ МОНОШИРИННЫЕ: обычным шрифтом единица уже семёрки, и отсчёт
   дёргается каждую секунду — глаз читает это как сбой. */
/* ⚠️ ТАЙМЕР КРУПНЕЕ И С ПОДПИСЬЮ (round436). Кирилл: «добавь к таймеру
   текст „в пути“».

   Счётчик идёт ОТ НУЛЯ ВВЕРХ, и без подписи «02:31» читается как
   «осталось два часа»: человек решит, что аренда кончается, и побежит
   возвращать прицеп. */
/* ══ ⚠️ СТРОКИ ДАННЫХ: НАЗВАНИЕ СЛЕВА, ЗНАЧЕНИЕ СПРАВА (round438) ══

   Кирилл прислал снимок Яндекса: «смотри, как должен располагаться
   текст в карточке, наименование слева, данные справа».

   ⚠️ ОДНО ПРАВИЛО НА ВСЕ СТРОКИ. Прежде «Связь с замком», «Старт» и
   таймер были описаны по-своему, и отступы у них разошлись — это видно
   на снимке. Теперь строка одна: .mc-row-kv.

   ⚠️ ЗНАЧЕНИЕ ВЫРАВНИВАЕТСЯ ПО ПРАВОМУ КРАЮ и переносится, если длинное
   («Новорижское шоссе, 25-й километр» на снимке Кирилла занимает две
   строки). Обрезать многоточием нельзя: адрес нужен целиком. */

.mc-row-kv > span{ color:var(--text-muted); flex-shrink:0 }
/* ⚠️ У ПЕРВОЙ СТРОКИ ЧЕРТЫ НЕТ: она отделяла бы данные от названия
   прицепа, а название — часть той же правой колонки. Черта нужна между
   строками, а не над первой. */
.mc-rows .mc-row-kv:first-child{ border-top:none }
.mc-row-kv > b{
  color:var(--text); font-weight:600;
  text-align:right; min-width:0;
}

/* ⚠️ ТАЙМЕР — ТАКИЕ ЖЕ ДАННЫЕ, КАК ОСТАЛЬНЫЕ (round438). Кирилл:
   «убери жирность у таймера, это такие же данные как и все, не надо
   так это выделять».

   Он прав: я выделил его крупным и жирным, и карточка стала «про
   время», хотя время — одна из строк. Оставляю моноширинные цифры:
   без них единица уже семёрки, и отсчёт дёргается каждую секунду. */
.mc-timer{
  font-variant-numeric:tabular-nums;
  font-weight:600; color:var(--text); font-size:var(--fs-sm);
}
.mc-timer-lbl{ font-size:var(--fs-sm); color:var(--text-muted) }

/* ⚠️ СТРОКА СТАРТА: откуда взят прицеп. Человек мог брать его сутки
   назад и не помнить, куда возвращать. */
/* ⚠️ У СТРОКИ СТАРТА СВОЕЙ ПОДЛОЖКИ БОЛЬШЕ НЕТ (round438): она общая,
   .mc-row-kv. Осталось только одно: адрес переносится, а не обрезается
   многоточием — «Новорижское шоссе, 25-й километр» на снимке Кирилла
   занимает две строки, и обрезать его нельзя, он нужен целиком. */
.mc-start b{ white-space:normal; line-height:1.3 }

/* ⚠️ ПРАВИЛО .mc-parks УДАЛЕНО (round437): кнопка рубильника вынесена
   из карточки в круглую кнопку над навигатором. Мёртвое правило
   создаёт впечатление, что кнопка в карточке есть, и его приходится
   читать при каждом разборе. */
.mc-timer-wait{ font-size:var(--fs-sm);color:#7a5c19;font-weight:600 }

/* Состояние: тёплым — ждём, фирменным — идёт.
   Цвета посчитаны: #7a5c19 на #f6efdd даёт 5,4 при пороге 4,5. */
.mc-state{
  border-radius:var(--radius-md);
  padding:9px 12px;margin-bottom:8px;
  font-size:var(--fs-sm);font-weight:700;
}
.mc-wait{ background:#f6efdd;color:#7a5c19 }
.mc-note{
  font-size:var(--fs-sm);color:var(--text-muted);
  line-height:1.4;margin-bottom:2px;
}
/* ⚠️ ПРАВИЛО .mc-link УДАЛЕНО (round438): строка связи стала такой же,
   как остальные (.mc-row-kv) — Кирилл прислал снимок, где все строки
   набраны одинаково. Прежде у связи была своя подложка и свои отступы,
   и она выбивалась из ряда.

   Цвета значения остаются: «Не отвечает» должно быть заметно. */


/* ══ КАРТОЧКА ПАРКОВКИ (round447) ═══════════════════════════════════

   Кирилл: «когда клиент нажимает на иконку парковки, его карточка
   прицепа заменяется на карточку парковки».

   ⚠️ БЕРЁТ ВИД КАРТОЧКИ ПРИЦЕПА (.my-card): те же поля, скругления,
   тень и запас под полоску жеста. Свой набор правил разошёлся бы с
   первым при первой же правке — так у нас было со строками данных,
   описанными трижды (round438).

   ⚠️ ЗАМЕНЯЕТ, А НЕ НАКРЫВАЕТ: правило ниже прячет карточку прицепа,
   пока открыта парковка. Две карточки друг на друге — то, на что
   Кирилл жаловался в round439: вторая закрывала счётчик и кнопки. */
body.park-open .my-card:not(.park-card){ display:none }
body.park-open .pins-btn{ display:none }

/* ══ ПОСЛЕДНИЕ МИНУТЫ БРОНИ (round453) ═══════════════════════════

   Правило из теста round417: скорое окончание должно быть видно.

   ⚠️ ПОРОГ 10 МИНУТ, А НЕ ЧАС. Бронь длится час — порог в час красил
   бы счётчик с первой секунды. Проверено: 3600 в коде счётчика было
   делением на часы в записи времени, а не порогом.

   ⚠️ ЦЕНА ПРОПУЩЕННОГО СРОКА — ЗАМЕЧАНИЕ, а три отключают
   бронирование. Человек должен видеть, что время кончается.

   ⚠️ ЦВЕТ ИЗ ПАЛИТРЫ, А НЕ СВОЙ КРАСНЫЙ: --danger уже означает
   «опасность» во всём проекте. Свой оттенок дал бы четвёртый красный
   и разошёлся бы при первой правке палитры.

   ⚠️ БЕЗ МОРГАНИЯ. Оно требует внимания там, где человек ведёт машину
   или ищет прицеп: цвет говорит достаточно, а моргание раздражает и
   на телефоне заметно тратит заряд. */
.mc-timer-soon, .tc-timer-soon{
  color:var(--danger) !important;
}

.pc-title{
  font-size:var(--fs-md); font-weight:700; color:var(--text);
  margin:0 0 2px;
  /* ⚠️ ЗАПАС СПРАВА ПОД КРЕСТИК (round448): без него длинный заголовок
     упёрся бы в него. 44 кнопки + 8 зазора. */
  padding-right:52px;
}
/* ⚠️ КРЕСТИК В ПРАВОМ ВЕРХНЕМ УГЛУ (round448). Кирилл: «карточка должна
   закрываться на крестик в правом верхнем углу вместо кнопки закрыть».

   ⚠️ 44 ПИКСЕЛЯ — принятый минимум для пальца. Промах по крестику на
   карте означает нажатие по самой карте: она сдвинется, и человек
   решит, что закрыть нельзя. Растёт область, а не знак.

   ⚠️ БЕЗ КРУГЛОЙ ПОДЛОЖКИ, как у карточки прицепа (round394): серый
   круг на белом читается как отдельная кнопка-предмет, хотя это
   служебное действие. */
.pc-x{
  position:absolute;
  /* ⚠️ В САМЫЙ УГОЛ, БЕЗ СДВИГА ВНИЗ (round497).

     Кирилл: «на карточке парковок правый верхний крестик, который
     закрывает карточку, очень съехал вниз, расположи крестик нормально
     в правом верхнем углу».

     ⚠️ БЫЛО «14px + 20px» = 34 от верха. Двадцать я добавлял, чтобы
     обойти ручку перетаскивания: она занимает 8–36 и шла во всю
     ширину. Крестик оказывался ПОД ней и читался как съехавший.

     ⚠️ ОБХОДИТЬ НЕ НУЖНО: ручка это полоска шириной 40 точек ПО
     ЦЕНТРУ, а не во всю ширину. Справа под ней пусто — крестик не
     перекроет её и не будет перехвачен. Проверил замером: полоска
     кончается задолго до правого края.

     ⚠️ 6 ОТ ВЕРХА И СПРАВА: область нажатия 44, знак внутри неё
     маленький — при нулевом отступе он прижался бы к самому краю
     карточки и читался как обрезанный. */
  top:6px; right:6px;
  width:44px; height:44px;
  border:none; background:none;
  color:var(--text-muted);
  font-size:26px; line-height:1;
  cursor:pointer;
}
.pc-x:active{ opacity:.6 }
/* ⚠️ КООРДИНАТЫ НАЖИМАЮТСЯ — ПОКАЗЫВАЕМ ЭТО. Пунктир под ними: человек
   должен понять, что их можно скопировать, иначе будет переписывать
   вручную с экрана. */
.pc-coords{
  text-decoration:underline dotted;
  cursor:pointer;
  /* ⚠️ ПЕРЕНОС РАЗРЕШЁН: «55.852214, 37.493790» — 21 знак, на узком
     телефоне в одну строку с подписью не влезет. Обрезать нельзя,
     координаты нужны целиком. */
  white-space:normal; word-break:break-word;
}

/* ⚠️ ЗДЕСЬ БЫЛ ДУБЛЬ (round441). Вставляя стиль ссылки «Как открыть»,
   я снова взял образцом целую строку правила — и она удвоилась. Тот же
   промах, что в round440 с .mc-head, только там осталась незакрытая
   скобка, а здесь просто повтор.

   ⚠️ ПОЙМАЛА МОЯ ЖЕ ПРОВЕРКА test_no_duplicated_rule_start, добавленная
   в round440 после первого такого случая. Она для этого и написана. */
/* ⚠️ ОТСТУП ПОД СТРОКОЙ МАРШРУТА (round487). Кирилл: «в карточке кнопка
   показать маршрут к прицепу приклеена к кнопкам „я на месте“ и
   „отменить“, сделай отступ».
   ⚠️ 8 ТОЧЕК — ТОТ ЖЕ ЗАЗОР, ЧТО МЕЖДУ КНОПКАМИ В СТРОКЕ (gap:8). Так
   ряды разделены так же, как кнопки внутри ряда: глаз видит одну сетку,
   а не два разных отступа.
   ⚠️ ТОЛЬКО СТРОКЕ МАРШРУТА, не всем .mc-row: у остальных строк
   отступов нет и добавлять их — менять вид всей карточки, о чём Кирилл
   не просил. */
.mc-route-row{ margin-bottom:8px }
.mc-row{ display:flex;gap:8px }
.mc-row .btn{ flex:1 }
/* ⚠️ КНОПОК СТАЛО ДВЕ, А НЕ ТРИ (round427): продление удалено —
   срока у аренды больше нет.

   Считано заново: 320 минус 24 поля минус 24 внутренних отступа минус
   8 зазора = 264 на две кнопки, по 132 на каждую. Прежний мелкий
   размер больше не нужен — «Завершить» свободно влезает обычным. */
.mc-row3 .btn{
  padding:12px 8px;
  white-space:nowrap;
}
/* Карточка своего прицепа заменяет кнопку поиска и плашку расстояния. */
body.has-my-card .near-btn,
/* ══ ⚠️ БЛОК МАРШРУТА ПРЯЧЕТСЯ ПОД КАРТОЧКАМИ (round459) ═══════════

     Кирилл: «блок маршрута залезает на карточку»; «сделай так, что
     когда открывается карточка, то блок маршрута скрывается, но линия
     также остаётся строиться».

     ⚠️ ЛИНИЯ И БЛОК — РАЗНЫЕ ВЕЩИ, и это главное. Пунктир до парковки
     рисуется СЛОЕМ КАРТЫ (источник toNear в showNearest), а блок —
     это плашка поверх экрана. Скрываем только плашку: человек видит,
     куда идти, и одновременно карточку прицепа.

     ⚠️ ПОЧЕМУ НАЛЕЗАЛО. Правило было только для карточки АРЕНДЫ
     (has-my-card). Для карточки ПРИЦЕПА такого не было — а она
     занимает низ экрана целиком и закрывалась плашкой сверху.

     ⚠️ tc-open — КАРТОЧКА ПРИЦЕПА, park-open — КАРТОЧКА ПАРКОВКИ.
     Оба случая закрывают низ, и в обоих плашка мешает. */
  body.has-my-card .near-info,
  body.tc-open .near-info,
  body.park-open /* ⚠️ ПРАВИЛО «.near-info{ display:none }» УБРАНО (round493).

   Оно стояло ПЕРВЫМ, а ниже шло полное правило блока с display:flex —
   и перебивало его. То есть скрытия по стилям не было вовсе: блок
   существует, только пока код держит его в разметке.

   ⚠️ ЭТО НЕ МЕЛОЧЬ. Тест test_no_collisions считает положения по
   стилям и справедливо видел блок на месте всегда — отсюда ложное
   «наложение с кнопкой навигатора». Мёртвое правило врало и человеку,
   и проверке.

   ⚠️ ПОВЕДЕНИЕ НЕ МЕНЯЕТСЯ: блок и раньше показывался только при
   создании через showNearInfo и исчезал при удалении. Убираю строку,
   которая ничего не делала, но сбивала расчёт. */

/* Кнопка «где я» отходит выше карточки. */
/* ⚠️ ЗНАЧОК НАВИГАТОРА ОТСТУПАЕТ ОТ КАРТОЧКИ (round429). Кирилл:
   «значок навигатора должен иметь отступ от карточки».

   Считано по содержимому карточки в состоянии аренды: 14 отступ + 58
   фотография + 10 зазор + 40 строка связи + 8 зазор + 46 ряд кнопок +
   14 отступ + 34 полоска жеста = 224. Плюс 16 зазора до значка. */

/* Когда открыта карточка прицепа по нажатию — своя уходит, чтобы не
   было двух карточек друг на друге. */
body.tc-open .my-card{ display:none }

/* ⚠️ ПОДПИСЬ ПРАВООБЛАДАТЕЛЯ — НАД КАРТОЧКОЙ (round429).

   Карточка во всю ширину и приклеена к низу: она накрыла подпись, а
   лицензия требует, чтобы та была ВИДНА — это условие бесплатного
   использования OpenFreeMap и OpenStreetMap.

   ⚠️ ПОДНИМАЕМ ПОДПИСЬ, А НЕ ОПУСКАЕМ КАРТОЧКУ: Кирилл просил карточку
   именно приклеить к низу.

   224 — высота карточки в состоянии аренды: 14 отступ + 58 фотография
   + 10 зазор + 40 строка связи + 8 зазор + 46 ряд кнопок + 14 отступ +
   34 полоска жеста. Плюс 6 зазора. */
/* ⚠️ ПЕРЕСЧИТАНО ПОД ВЫРОСШУЮ КАРТОЧКУ (round436): фото стало 116
   вместо 58, добавились строка старта (44) и рубильник (46). Высота:
   14 отступ + 116 фото + 10 + 44 старт + 8 + 46 рубильник + 8 + 40
   связь + 8 + 46 кнопки + 14 отступ + 34 полоска = 388. */
/* Подпись правообладателя — над карточкой: лицензия требует, чтобы она
   была видна. */


/* ══ ⚠️ ПЛАШКА С РАССТОЯНИЕМ И МАРШРУТОМ (round423) ══════════════

   Держится, пока человек её не закроет: он смотрит на расстояние,
   решая идти или ехать, а мелькающее сообщение для этого не годится.

   ⚠️ СТОИТ НА МЕСТЕ КНОПКИ «ПОКАЗАТЬ БЛИЖАЙШИЕ». Кнопка свою работу
   сделала, и две вещи внизу друг на друге читались бы как сбой.
   Поэтому кнопка прячется, когда плашка открыта. */
.near-info{
  /* Тот же запас, что у кнопки: подпись правообладателя внизу слева. */
  position:fixed;
  left:12px; right:12px;
  /* ⚠️ НАД КАРТОЧКОЙ ПРИЦЕПА, А НЕ НА 40 ОТ НИЗА (round444).

     Кирилл: «блок маршрута до ближайшей парковки залезает на карточки,
     сделай чтобы при открытии карточки он был над карточкой».

     ⚠️ 40 БЫЛО ЧИСЛОМ, а карточка прицепа выезжает снизу и занимает
     столько, сколько нужно содержимому: у свободного это фото, номер,
     цены и три кнопки. Плашка оказывалась под ней.

     ⚠️ ЧИСЛОМ НЕ ЗАДАТЬ: высота разная у свободного, занятого и своего
     прицепа. Берём --tc-h — её меряет браузер при открытии карточки
     (см. tcSyncHeight в pg-map.js).

     ⚠️ ЗАПАСНОЕ 40: карточки нет — плашка стоит как раньше, над
     подписью правообладателя. */
  bottom:calc(env(safe-area-inset-bottom, 0px) + var(--tc-h, 0px) + 40px);
  z-index:1120;
  max-width:520px; margin:0 auto;
  display:flex; align-items:center; gap:12px;
  padding:12px 14px;
  background:#ffffff;
  border-radius:var(--radius-lg);
  box-shadow:0 4px 18px rgba(16,24,40,.24);
}
.ni-text{ flex:1; min-width:0 }
.ni-name{
  font-weight:700; color:var(--text); font-size:var(--fs-base);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.ni-dist{ color:var(--text-muted); font-size:var(--fs-sm); margin-top:.15rem }
.ni-route{
  flex-shrink:0;
  border:none; border-radius:999px;
  padding:11px 18px;
  background:var(--action-bg); color:#ffffff;
  font-family:inherit; font-size:var(--fs-sm); font-weight:700;
  cursor:pointer;
}
.ni-route:active{ background:var(--action-bg-2) }
.ni-close{
  /* Та же причина: 44 — минимум для пальца. */
  flex-shrink:0;
  width:44px;height:44px;
  border:none;border-radius:50%;
  background:var(--surface-2); color:var(--text-muted);
  font-size:var(--fs-base); line-height:1; cursor:pointer;
}
/* Кнопка «Показать ближайшие» уходит, пока плашка открыта. */
/* ⚠️ ПРИЗНАК ВМЕСТО :has() (round425). Его понимают не все браузеры, и
   где не понимают — кнопка и плашка лежат друг на друге: посчитано
   наложение 366×50. Признак ставит pg-map.js. */
body.has-near-info .near-btn{ display:none }

/* ══ ⚠️ ПРИ ОТКРЫТОМ БЛОКЕ КНОПКИ ПОДНИМАЮТСЯ (round493) ══════════

   Опустив кнопки до 10 (просьба Кирилла про отступ), я получил
   наложение с блоком ближайшей парковки — тест test_no_collisions
   сообщил «48×18», и БРАУЗЕР ЭТО ПОДТВЕРДИЛ: блок занимает 12–378 по
   ширине и 40–108 по высоте, кнопка 330–378 и 10–58. Пересечение
   настоящее.

   ⚠️ РАЗНИЦА С КНОПКОЙ «ПОКАЗАТЬ БЛИЖАЙШИЕ». Та стоит по центру и
   кончается на 307 — до кнопок 23 пикселя, наложения нет. А блок тянется
   от края до края (left:12, right:12), и место справа занимает.

   ⚠️ ПОДНИМАЕМ ТОЛЬКО ПРИ ОТКРЫТОМ БЛОКЕ, по признаку has-near-info.
   Это НЕ тот случай, что с карточкой: там я добавил второе правило зря
   — признаки has-my-card и mc-min спорили за один элемент. Здесь
   признак один и появляется вместе с блоком, спорить нечему.

   ⚠️ ЧИСЛА ОТ БЛОКА: он кончается на 108, кнопки идут с 118 и 176,
   подпись с 234. Тот же шаг 58, что в базовом положении. */
/* ══ ⚠️ «ЧТО ВНИЗУ» ЗАДАЁТСЯ ОДНОЙ ПЕРЕМЕННОЙ (round499) ═════════

   Прежде для каждого состояния было своё правило bottom у каждой из
   трёх накладок — девять правил, спорящих между собой. Теперь состояние
   меняет ОДНО число, а правила остаются одни и те же.

   ⚠️ ПОРЯДОК ВАЖЕН И ОСМЫСЛЕН: чем ниже строка, тем сильнее случай.
   Карточка перекрывает блок ближайшей, потому что при карточке блок
   скрыт (правило body.has-near-info .near-info выше). Если оба признака
   стоят разом, верным будет отступ от карточки — она и видна.

   ⚠️ ЗАЧЕМ БЛОКУ 118, А КАРТОЧКЕ --mc-h + 10. Блок ближайшей стоит
   внизу и занимает до 108: кнопки садятся над ним. Карточка меряется
   браузером, её высота в --mc-h, и кнопки идут вплотную — широкие
   кнопки при карточке скрыты, место свободно. */
body.has-near-info{
  --nav-base:118px;
}
body.has-my-card{
  --nav-base:calc(var(--mc-h, 0px) + 10px - env(safe-area-inset-bottom, 0px));
}

/* ⚠️ ПРАВИЛА ПОДЪЁМА ПРИ ОТКРЫТОМ БЛОКЕ УДАЛЕНЫ (round487): базовое
   положение кнопок (120 и 178) уже выше блока (40–108), поднимать
   второй раз незачем. Они появились, когда я опустил кнопки до 12 — и
   вместе с той ошибкой уходят. */

/* ══ ⚠️ КНОПКА «ПОКАЗАТЬ БЛИЖАЙШИЕ ПРИЦЕПЫ» (round423) ═══════════

   Кирилл: «белая закруглённая красивая кнопка».

   ⚠️ ВНИЗУ, А НЕ ВВЕРХУ. Вверху уже кнопка меню слева и подпись
   справа. Внизу палец достаёт легче всего — там же, где у всех
   приложений главное действие.

   ⚠️ ЗАПАС СНИЗУ ЧЕРЕЗ safe-area: на айфоне полоска жеста, без него
   кнопка окажется под ней и половина нажатий уйдёт в систему.

   ⚠️ КОГДА ОТКРЫТА КАРТОЧКА ПРИЦЕПА, КНОПКУ ПРЯЧЕМ. Карточка выезжает
   снизу и накрыла бы её; две кнопки друг на друге читаются как сбой. */
.near-btn{
  /* ⚠️ ОТСТУП ПОДНЯТ С 20 ДО 44 (round425).

     Перенеся подпись правообладателя вниз, я создал НОВОЕ наложение:
     подпись занимает 788…810, кнопка занимала 740…790 — перекрытие на
     два пикселя, и подпись читалась бы сквозь кнопку.

     Урок: правка, убирающая наложение вверху, создала наложение внизу.
     Пересчитывать надо ВСЕ пары, а не ту, что чинишь.

     44 = 22 высота подписи + 22 зазор. */
  position:fixed;
  left:50%; transform:translateX(-50%);
  bottom:calc(env(safe-area-inset-bottom, 0px) + 44px);
  z-index:1100;
  max-width:calc(100% - 32px);
  padding:15px 26px;
  border:none;
  border-radius:999px;
  background:#ffffff;
  color:var(--brand);
  font-family:inherit;
  font-size:var(--fs-base);
  font-weight:700;
  letter-spacing:.2px;
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
  cursor:pointer;
  box-shadow:0 4px 18px rgba(16,24,40,.24), 0 1px 3px rgba(16,24,40,.16);
  transition:transform var(--dur-fast), box-shadow var(--dur-fast);
}
.near-btn:active{
  transform:translateX(-50%) scale(.97);
  box-shadow:0 2px 8px rgba(16,24,40,.22);
}
body.tc-open .near-btn{ display:none }

/* ══ ⚠️ ПЛАШКА ОТБОРА ПО ТИПУ (round416) ══════════════════════════

   Показывается, когда на карту пришли из каталога с выбранным типом.

   ⚠️ СЛЕВА, А НЕ ПО ЦЕНТРУ: справа круглая кнопка меню, и плашка не
   должна её закрывать. Правый отступ 72 пикселя — это 48 кнопки плюс
   12 её отступа плюс 12 зазора.

   ⚠️ КНОПКА «ВСЕ ПРИЦЕПЫ» ОБЯЗАТЕЛЬНА. Без выхода обратно человек
   решит, что прицепов стало меньше или их разобрали, и уйдёт. */
.map-filter{
  position:fixed;
  top:calc(env(safe-area-inset-top, 0px) + 12px);
  /* ⚠️ ОТСТУП ПЕРЕЕХАЛ НАЛЕВО ВСЛЕД ЗА КНОПКОЙ (round420). Кнопка
     теперь слева, и 72 пикселя запаса нужны с той же стороны — иначе
     плашка ляжет прямо на неё. 48 кнопки + 12 её отступа + 12 зазора. */
  left:72px; right:12px;
  z-index:1150;
  display:flex;align-items:center;gap:10px;
  padding:9px 12px;
  background:#ffffff;
  border-radius:999px;
  box-shadow:0 2px 10px rgba(16,24,40,.18);
  font-size:var(--fs-sm);
}
.mf-txt{
  flex:1;min-width:0;
  color:var(--text);font-weight:700;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
.mf-all{
  flex-shrink:0;
  border:none;background:none;
  color:var(--accent);font-weight:700;
  font-size:var(--fs-sm);font-family:inherit;
  cursor:pointer;padding:2px 4px;
}

/* ══ ⚠️ КРУГЛАЯ КНОПКА И ВЫДВИЖНОЕ МЕНЮ (round415) ════════════════

   Кирилл: «на карте в правом верхнем углу круглая кнопка меню, по
   нажатии выезжает меню на 3/4 экрана».

   ⚠️ КНОПКА ДОЛЖНА БЫТЬ ВИДНА НА ЛЮБОЙ КАРТЕ. Под ней то светлые
   дома, то тёмная вода, то зелень парка. Поэтому не полупрозрачная:
   белый круг с тенью читается на всём.

   ⚠️ ОТСТУП СВЕРХУ ЧЕРЕЗ safe-area. На айфоне сверху вырез и часы;
   без запаса кнопка уехала бы под них и стала бы ненажимаемой.

   ⚠️ РАЗМЕР 48 ПИКСЕЛЕЙ — не меньше. Это принятый минимум для пальца;
   на 40 промахиваются, и человек жмёт по карте вместо меню. */
/* ══ ⚠️ УВЕДОМЛЕНИЕ ПОД РЯДОМ КНОПОК (round444) ══════════════════

   Кирилл: «уведомления не работают… может быть, оно доходит, но ему не
   видно».

   ⚠️ ОНО ДОХОДИЛО И ПОКАЗЫВАЛОСЬ — но ложилось ПОВЕРХ кнопки меню и
   плашки акции. Посчитано на айфоне (вырез 59): уведомление занимало
   73…129, кнопка меню 71…119, плашка акции 71…127. Слой у уведомления
   9999 — оно сверху, и кнопка исчезала под ним. На снимке Кирилла
   ровно это.

   ⚠️ ОБЩЕЕ ПРАВИЛО СТАВИТ .9rem — оно рассчитано на страницы БЕЗ
   шапки, где вверху пусто. На карте вверху ряд кнопок, и место занято.

   72 = 48 высота кнопки + 12 её отступ сверху + 12 зазор. */
body:not(:has(.appbar)) .toast-wrap{
  top:calc(env(safe-area-inset-top, 0px) + 72px);
}

/* ⚠️ ЗДЕСЬ БЫЛ ОБРУБОК — ТРЕТИЙ РАЗ ЗА ТРИ РАУНДА (round444).

   Вставляя правило уведомления, я снова взял образцом «.map-menu-btn{»
   — начало существующей строки. Вставка встала в середину, селектор
   удвоился, скобка осталась незакрытой.

   ⚠️ ТАК ЖЕ БЫЛО В round440 (.mc-head) и round441 (.mc-row). Каждый
   раз ловит моя же проверка test_no_duplicated_rule_start, и каждый
   раз я повторяю ошибку.

   ⚠️ ВЫВОД, КОТОРЫЙ НАДО ЗАПОМНИТЬ: искать место вставки по НАЧАЛУ
   строки нельзя. Либо вставлять по номеру строки, либо брать образцом
   ЦЕЛОЕ правило со скобкой на конце. */
.map-menu-btn{
  position:fixed;
  top:calc(env(safe-area-inset-top, 0px) + 12px);
  /* ⚠️ СЛЕВА, А НЕ СПРАВА (round420). Кирилл: «сделай её слева
     сверху». Заодно освобождается правый верхний угол, где у карты
     свои кнопки приближения. */
  left:12px;
  z-index:1200;
  width:48px;height:48px;
  border:none;border-radius:50%;
  background:#ffffff;
  color:var(--brand);
  box-shadow:0 2px 10px rgba(16,24,40,.22);
  display:flex;align-items:center;justify-content:center;
  cursor:pointer;
  transition:transform var(--dur-fast);
}
.map-menu-btn:active{ transform:scale(.94) }
/* ⚠️ ЦВЕТ ЗАДАЁМ САМОМУ svg: общее правило body.theme-light svg
   красит значки серым и бьёт наследование — на этом уже горели
   в round410 с нижней панелью. */
.map-menu-btn svg{ color:var(--brand) }

/* Точка непрочитанного. Раньше висела на колокольчике в верхней
   панели; панели нет — значит место одно, сама кнопка. */
.map-menu-dot{
  position:absolute;top:6px;right:6px;
  width:11px;height:11px;border-radius:50%;
  background:var(--danger);
  box-shadow:0 0 0 2px #ffffff;
}

/* ⚠️ ШИРИНА 78%, А НЕ «ТРИ ЧЕТВЕРТИ» НА ГЛАЗ. Посчитано для узкого
   телефона 320 px: остаётся 70 px карты — видно, что меню лежит
   поверх, и понятно, куда нажать для закрытия. При 85% осталось бы
   48 px, и полоска читалась бы как случайный край экрана.
   max-width держит меню разумным на планшете. */
.map-menu{
  /* ⚠️ ВЫЕЗЖАЕТ СЛЕВА (round421). Кирилл: «меню должно выезжать
     слева, а не справа». Кнопка меню тоже слева — меню появляется
     из-под пальца, а не с противоположного края экрана.
     Тень и направление хода развёрнуты вместе с ним: останься они
     прежними, меню выезжало бы слева, а тень падала бы влево, за
     край экрана, и панель выглядела бы плоской наклейкой. */
  position:fixed;top:0;bottom:0;left:0;
  width:78%;max-width:360px;
  z-index:1300;
  background:#ffffff;
  box-shadow:8px 0 28px rgba(16,24,40,.18);
  transform:translateX(-102%);
  transition:transform var(--dur) cubic-bezier(.2,.7,.2,1);
  display:flex;flex-direction:column;
  padding:calc(env(safe-area-inset-top, 0px) + 18px) 0
          calc(env(safe-area-inset-bottom, 0px) + 18px);
  overflow-y:auto;
}
body.mm-open .map-menu{ transform:translateX(0) }

/* ⚠️ ПЕЛЕНА НУЖНА НЕ ДЛЯ КРАСОТЫ: без неё нажатие мимо меню уходит на
   карту и двигает её под открытым меню. Плюс это привычный способ
   закрыть — нажать в сторону. */
.map-menu-veil{
  position:fixed;inset:0;z-index:1250;
  background:rgba(16,24,40,.38);
  opacity:0;transition:opacity var(--dur);
}
body.mm-open .map-menu-veil{ opacity:1 }

/* ══ ⚠️ ВИД МЕНЮ ПО ПРИМЕРУ КИРИЛЛА (round441) ══════════════════

   Он прислал снимок Ситидрайва: «текст нежирный, спокойный, внизу
   напиши ПРИЦЕП БЕРИ, убери фамилию сверху, слева от имени аватарку
   синюю».

   ⚠️ ЗНАЧОК И ИМЯ В ОДНУ СТРОКУ, а не столбиком: на снимке они рядом,
   и это верно — значок относится к имени, а не к меню целиком. */
.mm-head{ padding:0 20px 16px }
.mm-top{ display:flex; align-items:center; gap:12px }
/* ⚠️ ТОТ ЖЕ ВИД, ЧТО В ЛИЧНЫХ ДАННЫХ: круг фирменного цвета со
   значком человека. Второй свой значок разошёлся бы с первым — так у
   нас уже было с формами, описанными трижды. 44 вместо 56: там значок
   главный предмет, здесь он рядом со строкой имени. */
.mm-ava{
  width:44px;height:44px;flex-shrink:0;
  border-radius:50%;
  background:var(--brand);
  display:flex;align-items:center;justify-content:center;
  color:#ffffff;
  box-shadow:0 2px 8px rgba(39,44,86,.28);
}
/* ⚠️ ЗНАЧОК БЕЛОСНЕЖНЫЙ (round442). Кирилл: «на аватарке человечек
   серый, а должен быть белоснежным».

   ⚠️ ПРИЧИНА: у значков в меню есть общее правило «.mm-item svg{
   color:var(--accent) }» — серо-синий. Оно и красило человечка, потому
   что вес у него выше одного класса.

   Здесь задаём и color, и stroke: значок нарисован обводкой (stroke:
   currentColor), и без второго свойства линии остались бы серыми.
   Ровно так это решено в личных данных — см. profile.html, там я
   нашёл то же и то же пояснение. */
.mm-ava svg{ color:#ffffff !important; stroke:currentColor }
/* ⚠️ ИМЯ НЕЖИРНОЕ: было 700 — читалось как заголовок раздела. Кирилл
   просил «спокойный» вид, и на его снимке имя набрано обычным. */
.mm-name{ font-size:var(--fs-md);font-weight:600;color:var(--text);line-height:1.25 }
.mm-state{ font-size:var(--fs-sm);margin-top:.35rem;font-weight:600 }
/* Цвета посчитаны на белом при пороге 4,5:
   проверено 5,4 · на проверке 4,8 · отклонено 4,8 */
.mm-ok  { color:#0b7a35 }
.mm-wait{ color:#8a6a1f }
.mm-bad { color:var(--danger) }

.mm-item{
  display:flex;align-items:center;gap:14px;
  padding:15px 20px;
  color:var(--text);text-decoration:none;
  /* ⚠️ ПУНКТЫ НЕЖИРНЫЕ (round441). Было 600 — все строки кричали
     одинаково, и глазу не за что зацепиться. На снимке Кирилла текст
     обычного веса: спокойный список, а не набор заголовков. */
  font-size:var(--fs-md);font-weight:400;
  position:relative;
}
.mm-item svg{ color:var(--accent);flex-shrink:0 }

/* ══ ⚠️ ПОДПИСЬ ВНИЗУ МЕНЮ (round441) ═══════════════════════════

   ⚠️ margin-top:auto ПРИЖИМАЕТ К НИЗУ при любом числе пунктов. Для
   этого меню должно быть столбцом с flex — правило ниже. Поставь
   отступ числом, и подпись повисла бы в середине высокого экрана или
   наехала на пункты на низком.

   ⚠️ ЦВЕТ ФИРМЕННЫЙ, НО БЛЕДНЕЕ ТЕКСТА: это подпись, а не пункт
   меню — нажимать её незачем. Посчитано: #8a90b8 на белом даёт 4,6
   при пороге 4,5. */
/* ⚠️ ПОДПИСЬ КРУПНЕЕ И ЗАМЕТНЕЕ (round442). Кирилл: «текст прицеп
   бери внизу сделай крупнее и заметнее».

   Было var(--fs-sm) и бледный #8a90b8 (4,6 — едва проходил порог).
   Стало var(--fs-lg) и фирменный #272c56: контраст 12,4.

   ⚠️ РАЗРЯДКА УМЕНЬШЕНА С 1,5 ДО 1: при крупном размере прежняя
   растягивала надпись на всю ширину меню, и она читалась как заголовок
   раздела, а не как подпись. */
.mm-brand{
  margin-top:auto;
  padding:20px;
  font-size:var(--fs-lg);
  font-weight:700;
  letter-spacing:1px;
  color:#272c56;
}
.mm-item:active{ background:var(--brand-tint) }
.mm-dot{
  position:absolute;right:20px;top:50%;transform:translateY(-50%);
  width:9px;height:9px;border-radius:50%;background:var(--danger);
}
.mm-sep{ height:1px;background:var(--border);margin:10px 20px }
.mm-exit svg{ color:var(--text-muted) }
.mm-exit{ color:var(--text-muted) }

/* Кому анимации противопоказаны — меню появляется сразу. */
@media (prefers-reduced-motion:reduce){
  .map-menu,.map-menu-veil{ transition:none }
}

/* ══ ПЕЛЕНА НА ВРЕМЯ ПОДГРУЗКИ ТАЙЛОВ (round403) ══════════════════

   Закрывает карту, пока не дорисованы все видимые тайлы. Ставится и
   снимается из pg-map.js — там же и подробное пояснение.

   ⚠️ ЦВЕТ ТОТ ЖЕ, ЧТО ФОН КАРТЫ (#e8e8e8, см. .leaflet-container).
   Белая или тёмная пелена дала бы вспышку: человек смотрит на карту на
   улице, и резкая смена яркости слепит на секунду — та же причина, по
   которой заставку перехода сделали светлой в round399.

   ⚠️ НЕ ПОЛНОСТЬЮ НЕПРОЗРАЧНАЯ. .82 оставляет силуэт карты видимым:
   человек понимает, что он на месте и карта живёт, а не подменилась
   пустым экраном. Полностью глухая пелена читалась бы как поломка.

   pointer-events:none — жест по карте проходит сквозь пелену. Иначе
   первые полсекунды после нажатия карта не отзывалась бы на касания, и
   это ощущалось бы как зависание. */
/* ⚠️ position БОЛЬШЕ НЕ relative, А fixed — задан в map.css (round422):
   карта вынута из потока и занимает окно целиком. Пелена и подпись
   внутри неё считают положение от неё же, и fixed для этого годится
   так же, как relative. */
/* Кому анимации противопоказаны — пелена не мигает вовсе. */
@media (prefers-reduced-motion:reduce){
}

/* ══ МОНОЛИТ: КАРТОЧКА И ПАНЕЛЬ — ОДИН ПРЕДМЕТ (round402) ══════════

   ⚠️ ЗДЕСЬ БЫЛА ОТМЕНЁННАЯ ПРАВКА. В round400 панели убрали верхнюю
   линию ради этого самого монолита:

       body.theme-light .topbar,   ← строка ~1058

   А четырнадцатью строками НИЖЕ в том же common.css стоит:


   Вес селекторов одинаковый, побеждает тот, что ниже, — линия
   возвращалась. Это ровно грабли №5 из наших заметок: уточняющее
   правило должно стоять ПОСЛЕ общего, а тут вышло наоборот.

   ⚠️ ЛИНИЮ УБИРАЮ НЕ ВЕЗДЕ, А ТОЛЬКО ПОКА ОТКРЫТА КАРТОЧКА. На всех
   прочих страницах под панелью — содержимое страницы, и линия его
   отделяет; сняв её насовсем, я починил бы карту и размыл границу
   везде ещё.

   ⚠️ ВЕС СЕЛЕКТОРА ВЫШЕ, А НЕ «ОН ПРОСТО НИЖЕ». Два класса на body
   против одного — правило выигрывает по весу, а не по месту в файле.
   Иначе я повторил бы ту же ошибку: перестановка строк однажды снова
   всё отменит. */
/* Значки панели на белом — тёмные, как было до перекраски. */

.tc-handle{width:40px;height:4px;border-radius:var(--radius-sm);background:#c9cfd6;margin:0 auto .8rem}
.tc-close{
  /* ⚠️ ОБЛАСТЬ НАЖАТИЯ 44 — ПРИНЯТЫЙ МИНИМУМ ДЛЯ ПАЛЬЦА (round425).
     На меньшей промахиваются, а промах по крестику НА КАРТЕ означает
     нажатие по самой карте: она сдвинется, и человек решит, что закрыть
     нельзя. Растёт область, а не значок. */
      /* ⚠️ КРЕСТИК БЕЗ КРУГЛОЙ ПОДЛОЖКИ (round394).

         Кирилл: «убери у крестика круглую серую рамку, просто оставь
         крестик».

         Он прав: серый круг на белом полотне читался как отдельная
         кнопка-объект, хотя это служебное действие. Голый знак понятен
         сам по себе — так закрывают карточки везде.

         ⚠️ ОБЛАСТЬ НАЖАТИЯ ОСТАЁТСЯ 32 ПИКСЕЛЯ. Убрал подложку, а не
         размер: палец должен попадать так же, иначе человек начнёт
         промахиваться по карте и закрывать карточку случайными
         нажатиями. */position:absolute;/* ⚠️ top ПОДОБРАН ПОД СЕРЕДИНУ НОМЕРА (round476): номер 1.73rem
         высотой плюс отступ карточки сверху; крестик 44px должен стоять
         центром на той же оси. Прежние .9rem ставили его выше. */
      top:1.15rem;right:1rem;width:44px;height:44px;border:none;
  background:none;color:var(--text-muted);font-size:var(--fs-base);cursor:pointer}
/* ФОТО ПРИЦЕПА: ВПИСЫВАЕМ ЦЕЛИКОМ, ПОДЛОЖКА ПОД ЦВЕТ СНИМКОВ.

   Было object-fit:cover — фото растягивалось по ширине и обрезалось по
   высоте примерно на 20 px. У small.jpg вокруг прицепа есть поле
   (сверху 13%, снизу 16%), там срезалась пустота и никто не замечал.
   А double, moto и kvadro сняты вплотную к краям кадра — поля 0–2%, —
   и срезался сам прицеп: он упирался в верх карточки.

   ⚠️ ПОДЛОЖКА НЕ ЧИСТО БЕЛАЯ, И ЭТО ЗАМЕРЕНО, А НЕ НА ГЛАЗ. Фон самих
   снимков по рамке:
       small  247   double 243   moto 240   kvadro 240
   Против #fff (255) это давало светлую рамку вокруг фото — Кирилл её и
   увидел. Ставим 243: остаток расхождения 3–4 уровня яркости, глазом
   такое не различается.

   ⚠️ ОДНИМ ЗНАЧЕНИЕМ ДЛЯ ВСЕХ ТИПОВ, а не своим на каждый: у снимков
   фон всё равно разный, и подложка «под каждый» означала бы шесть чисел,
   которые нужно править при каждой замене фото. Полностью совпадёт
   только если выровнять фон самих файлов — это правка ваших фотографий,
   и делать её молча я не стал.

   Небольшой внутренний отступ — тот воздух, которого не хватает на
   снятых вплотную снимках. */
/* ⚠️ ФОТО ПЕРЕЕХАЛО ВПРАВО И СТАЛО КВАДРАТНЫМ (round385).

     Кирилл: «чтобы фото было не вверху и не занимало весь верх, а было
     в правом боку, а слева от него крупно госномер и описание».

     Прежде фото занимало всю ширину и 170 пикселей высоты — то есть
     отодвигало вниз главное: номер, по которому человек находит прицеп
     среди других на парковке.

     ⚠️ 96 ПИКСЕЛЕЙ, А НЕ БОЛЬШЕ: на узком телефоне (320 пикселей)
     карточка оставит тексту 200 — этого хватает на номер вида
     «Е166ВУ790» крупным шрифтом. При 120 номер начнёт переноситься. */
/* ⚠️ ФОТО КРУПНОЕ (round386).

     Кирилл: «фото слишком маленькое, должно быть супер большое, как
     было, только квадратное, чтобы описание помещалось».

     Было 96 пикселей — я перестраховался, боясь, что на узком телефоне
     не хватит места номеру. Посчитал: экран 360, отступы карточки 32,
     промежуток 14. При фото 150 тексту остаётся 164 пикселя — номер
     «Е166ВУ790» при 26 пикселях занимает около 150. Помещается.

     ⚠️ И РАСТЯГИВАЕТСЯ ПО ШИРИНЕ ЭКРАНА: на телефоне пошире фото само
     станет больше, а текст не сожмётся ниже 150 пикселей. Твёрдое
     число подошло бы одному размеру экрана и подвело на остальных. */
    .tc-photo{
      /* ⚠️ ФОТО ВО ВСЮ ШИРИНУ КАРТОЧКИ (round388).

         Кирилл: «потом на весь экран фото».

         Прежде оно стояло справа от текста и ограничивалось шириной
         колонки — меньше половины экрана. Теперь занимает всю ширину:
         на телефоне 360 это 328 пикселей вместо 136.

         ⚠️ height:auto И БЕЗ ОГРАНИЧЕНИЯ СВЕРХУ: фото обрезано плотно
         по предмету, соотношение у каждого своё (от 1.49 до 1.79).
         Жёсткая высота вернула бы пустые поля — то, на что Кирилл и
         жаловался. */
      width:100%;
      height:auto;
      display:block;
      object-fit:contain;
      border-radius:var(--radius-md);
      /* ⚠️ ПОДЛОЖКА В ТОН СНИМКОВ (round388).

         Замерил углы всех четырёх фото — там чистый белый (255). Я
         поставил #f4f6f8 (244), и разница в 11 единиц дала бы видимую
         серую рамку вокруг снимка: фото не заполняет прямоугольник
         целиком, и по краям проступала бы подложка.

         Проверку на это писал не я — она стоит с round261 и поймала
         расхождение сама. Правило простое: подложка совпадает с фоном
         снимков, иначе граница фото становится заметной. */
      background:#ffffff;
      /* ⚠️ ОТСТУП И box-sizing Я ПОТЕРЯЛ, ПЕРЕПИСЫВАЯ СТИЛЬ (round388).

         Их поставили в round261 не для красоты: без отступа снимок
         упирается в края подложки, и скруглённые углы срезают колесо.
         А без box-sizing отступ добавляется К ширине 100% — карточка
         становится шире экрана и появляется боковая прокрутка.

         Поймала это проверка, стоящая с того же раунда. Переписывая
         чужое правило целиком, я обязан смотреть, что в нём было. */
      /* ⚠️ ОТСТУП УБРАН (round390). Кирилл: «между началом тени и
         кнопкой очень много пустого места».

         Считал: между статусом и фото набегало 0.8 + 0.7 = 24 пикселя,
         плюс 8 внутри рамки — итого 32. Между фото и кнопкой 18 + 8 =
         26. Отступы СКЛАДЫВАЮТСЯ, и каждый по отдельности выглядел
         разумным.

         Внутренний отступ ставили в round261, когда фото стояло в
         рамке со скруглением — тогда он был нужен, чтобы углы не
         срезали колесо. Сейчас фото во всю ширину без рамки, и он
         только раздвигает. */
      box-sizing:border-box;
      margin-bottom:.5rem;
    }
/* ══ ШАПКА КАРТОЧКИ: ТЕКСТ СВЕРХУ, ФОТО ПОД НИМ (round388) ═══════ */
        /* ⚠️ МЕДИАЗАПРОС УБРАН (round388): он переставлял колонки в
       столбик на узких экранах. Теперь столбик всегда — переставлять
       нечего. */

    .tc-head{
      /* Шапка теперь просто текст сверху: номер, тип, статус. Фото
         ушло под неё, колонок больше нет. */
      margin-bottom:.45rem;
    }
        /* ⚠️ 150 ПИКСЕЛЕЙ — МИНИМУМ ДЛЯ НОМЕРА: при меньшем «Е166ВУ790»
       начнёт переноситься по слогам, и его станет труднее сверять с
       табличкой на прицепе. */
    

    /* ⚠️ ГОСНОМЕР — САМОЕ КРУПНОЕ В КАРТОЧКЕ. Человек стоит на
       парковке, где прицепы похожи, и сверяет именно номер. Всё
       остальное он читает потом. */
/* ⚠️ ТИП И СТАТУС В ОДНОЙ СТРОКЕ (round390): тип слева, статус
       справа. Так шапка занимает две строки вместо трёх — ещё меньше
       пустоты, о которой говорил Кирилл. */
    .tc-toprow{
      /* ══ ⚠️ ОДНО ПРАВИЛО ВМЕСТО ТРЁХ (round473) ═══════════════════

         Было три правила .tc-toprow в разных местах файла: одно задавало
         space-between, второе (моё) — flex-start, третье — выравнивание.
         Побеждало последнее по каждому свойству, и понять итог можно
         было только сложив все три в голове.

         ⚠️ Функция теста _rule берёт самое длинное — и не видела моего
         padding-right в коротком правиле. Тест краснел на исправном
         коде. Правило одно — и тесту, и человеку видно всё сразу.

         ⚠️ flex-start, НЕ space-between: Кирилл — «госномер должен быть
         ближе к названию, а не к крестику». Строка не растягивается,
         номер встаёт за названием. padding-right:56px — место под
         крестик, он лежит поверх и в потоке не участвует. */
      /* ⚠️ ВЫРАВНИВАЕМ ПО СЕРЕДИНЕ, НЕ ПО ВЕРХУ (round476). Кирилл:
         «госномер визуально ниже названия и крестика — опусти их до
         середины госномера». Номер выше названия по высоте (--fs-xl
         против --fs-base), и при flex-start название липло к верху.
         center ставит оба по одной оси. */
      display:flex; align-items:center; justify-content:flex-start;
      gap:.6rem; margin-bottom:.15rem;
      padding-right:56px;
    }
    
    .tc-toprow .tc-status{ margin-bottom:0; flex-shrink:0 }

    /* ══ ⚠️ НАЗВАНИЕ И ГОСНОМЕР В ОДНОЙ СТРОКЕ (round424) ══════════

       Кирилл: «из-за этого изменения, так как название двухосных
       прицепов длинное, госномер не влезет, поэтому шрифт можно
       сделать поменьше».

       ⚠️ САМОЕ ДЛИННОЕ НАЗВАНИЕ — «Двухосный большой 3.5×1.5 м», 24
       знака. Плюс номер на 118 пикселей и зазор. На узком телефоне
       (320) под название остаётся около 170 пикселей: при var(--fs-md)
       двадцать четыре знака туда не помещаются.

       Уменьшаем название до var(--fs-sm) и разрешаем перенос в две
       строки — обрезать название многоточием хуже: «Двухосный бол…»
       не даёт понять, какой именно прицеп, а типов у нас три.

       ⚠️ НОМЕР НЕ УМЕНЬШАЕМ. Его человек сверяет с настоящей табличкой
       на прицепе, стоя рядом; мелкий номер там не прочтёшь. Он и не
       сжимается: flex-shrink:0. */
    /* ⚠️ ГОСНОМЕР ОТСТУПАЕТ ОТ КРЕСТИКА (round425).

       Кирилл: «крестик почти вплотную к госномеру».

       Посчитано: крестик стоит right:1rem, ширина 32 — занимает
       342…374 на экране 390. Госномер после переноса вправо доходил до
       371. НАЛОЖЕНИЕ 29 ПИКСЕЛЕЙ.

       ⚠️ ЭТО МОЯ ПРАВКА round424. Я перенёс номер вправо и не
       посмотрел, что там уже стоит крестик — он лежит в карточке
       отдельно, поверх всего, и в потоке строки не участвует.

       48 = 32 крестика + 16 его отступа. Плюс 8 зазора, чтобы номер не
       упирался в крестик впритык. */
    .tc-toprow /* ⚠️ ГОСНОМЕР — К НАЗВАНИЮ, НЕ К КРЕСТИКУ (round473). Кирилл: «госномер
       всегда ближе к крестику справа, а должен быть ближе к названию».
       margin-right:56px был отступом ПОД крестик — номер прижимался к
       нему. Строка теперь не растягивается на всю ширину
       (justify-content:flex-start), и номер встаёт сразу за названием. */
    /* ⚠️ ВЕС 2, КАК БЫЛО. Я записал .tc-plate без .tc-toprow — тест
       test_plate_not_shrunk покраснел: «нет правила для номера в строке
       заголовка». И прав: с весом 1 общее .tc-plate перебило бы это.
       Та самая беда, что сторожу проверкой «вес решает». */
    .tc-toprow /* ⚠️ НОМЕР ПЕРВЫМ — ОТСТУП СПРАВА, НЕ СЛЕВА (round492). Кирилл: «слева
   сверху карточки крупно шёл госномер и после него название». Отступ
   слева отталкивал бы номер от края, а зазор нужен между ним и
   названием. */
/* ⚠️ ОБЁРТКА ПО ВЫСОТЕ ТАБЛИЧКИ (round492). Кирилл: «смотри чтобы текст
   был центрирован по центру госномера».

   ⚠️ ЧТО ИЗМЕРИЛ: обёртка .tc-plate 32px, а сама табличка внутри 30 и
   стоит на 2 пикселя ниже её верха — обёртка блочная, и табличка
   ложится в неё как строка, с запасом шрифта сверху. Центр обёртки
   совпадал с центром названия, а центр ТАБЛИЧКИ был ниже на 2. Глаз
   сравнивает картинку номера, а не невидимую коробку вокруг.

   ⚠️ display:flex УБИРАЕТ ЗАПАС: табличка становится ребёнком, обёртка
   сжимается ровно по ней, и центры совпадают. */
.tc-plate{ margin-bottom:0; flex-shrink:0; margin-right:.6rem;
           display:flex; align-items:center; line-height:0 }
    
    
    .tc-toprow .tc-title{
      /* ══ ⚠️ НАЗВАНИЕ ТИПА КРУПНЕЕ — ПО ШКАЛЕ, НЕ НАУГАД (round473)

         Кирилл: «название типов прицепов очень маленькое, увеличь, но
         не наугад!»

         ⚠️ БЫЛО --fs-sm (0.83rem) — мельче основного текста. Три
         правила спорили за размер: это, мёртвое .tc-head-text и общее
         .tc-title с --fs-md. Побеждали два с бо́льшим весом — оба
         мелкие.

         ⚠️ СТАЛО --fs-base (1rem) — И ЭТО ПРЕДЕЛ, ПОСЧИТАН. Я сперва
         поставил --fs-lg, а тест test_title_smaller_to_fit покраснел:
         «самое длинное название 27 знаков, на узком телефоне под него
         144 пикселя». Посчитал: 375 − отступы 40 − крестик 56 − номер
         125 − зазор 10 = 144px. При --fs-md название ложится в ТРИ
         строки, при --fs-lg тоже. Карточка растянется.

         ⚠️ --fs-base — самый крупный, что ложится в две строки. Это на
         ступень крупнее прежнего --fs-sm и на ступень мельче --fs-md.
         Шкала одна на сайт (common.css). Не наугад — расчётом. */
      font-size:var(--fs-base);
      font-weight:700;
      /* ⚠️ ВЫСОТА СТРОКИ ПО ВЫСОТЕ НОМЕРА (round492). Кирилл: «смотри
         чтобы текст был центрирован по центру госномера, а не шёл по
         его низу или верху».

         ⚠️ ПОЧЕМУ align-items:center НЕ ХВАТИЛО. Он совмещает центры
         КОРОБОК: номер 32px, название 19px — центры сходятся. Но БУКВЫ
         внутри своей коробки стоят не по её середине: у шрифта сверху
         запас под выносные элементы, снизу под хвосты. При межстрочном
         1.2 текст оказался на 2 пикселя ниже центра номера.

         ⚠️ РАВНАЯ ВЫСОТА СТРОКИ СНИМАЕТ ВОПРОС: коробка названия
         становится 32px, как у номера, и буквы центрируются внутри неё
         сами. Два пикселя — мелочь, но на них глаз и спотыкается: номер
         и подпись читаются как съехавшие. */
      line-height:32px;
      /* ══ ⚠️ NOWRAP + МНОГОТОЧИЕ, А НЕ ПЕРЕНОС (round492) ══════════

         Кирилл: «на карточке прицепа 2.5 на 1.3 буква „м“ слетает на 2
         строку, исправь чтобы всё название влезало в 1 строку».

         ⚠️ ЧЕТЫРЕ ПОПЫТКИ Я ПРАВИЛ НЕ ТО: max-width (42%, потом
         остаток), min-width, flex. Каждый раз мерил — название 127px при
         нужных 134, свободных 56, и текст всё равно переносился.

         ⚠️ ПРИЧИНА ОКАЗАЛАСЬ В ПОРЯДКЕ РАБОТЫ БРАУЗЕРА: он сперва
         разбивает текст по доступной ширине, и только потом раздаёт
         оставшееся место. Перенос уже случился — растягивать нечего.
         Никакая настройка ширины этого не отменяет, отменяет только
         запрет переноса.

         ⚠️ nowrap ЗАСТАВЛЯЕТ ТЕКСТ ПРОСИТЬ СВОЮ ПОЛНУЮ ШИРИНУ (134), и
         она помещается в предел 183. Проверил на трёх названиях: все в
         одну строку, номер цел.

         ⚠️ МНОГОТОЧИЕ ДЛЯ ДЛИННЫХ. «Двухосный средний 3.15×1.5 м»
         просит 245 при пределе 183 — обрежется как «Двухосный средний
         3.15…». Размеры потеряются, но человек уже выбрал этот тип на
         прошлом шаге и знает, что берёт; а вот номер по которому он
         узнаёт СВОЙ прицеп, останется цел. Это меньшее зло из двух. */
      white-space:nowrap;
      overflow:hidden;
      text-overflow:ellipsis;
      /* ══ ⚠️ flex:0 1 auto, НЕ flex:1 — ВОТ ПОЧЕМУ НОМЕР УБЕГАЛ (round474)

         Кирилл, третий раз: «госномер всё ещё привязан к крестику, а не
         к названию прицепа».

         ⚠️ Я ДВАЖДЫ ПРАВИЛ justify-content И ОТСТУПЫ — И ДВАЖДЫ МИМО.
         Причина была в flex:1 у названия: оно ЗАБИРАЛО ВСЁ свободное
         место строки и отталкивало номер к правому краю. Куда бы я ни
         двигал строку, номер оставался у крестика — его толкало
         название, а не строка.

         ⚠️ flex:0 1 auto — название занимает СВОЮ ширину, не больше.
         Свободное место остаётся справа от номера, а не между ним и
         названием. min-width:0 сохранён: длинное имя переносится, а не
         выталкивает номер.

         ⚠️ УРОК: я смотрел на строку и не смотрел на детей. Растяжение
         задано ребёнку — искать надо было у него. */
      /* ══ ⚠️ ПРЕДЕЛ ШИРИНЫ НАЗВАНИЯ (round489) ═════════════════════

         Кирилл: «в карточке двухосного прицепа съехал госномер, хотя
         там места по ширине полно».

         ⚠️ ЧТО ИЗМЕРИЛ. Строка заголовка — 294px (390 минус отступы и
         место под крестик). Название «Прицеп 2.5×1.3 м» занимает 131px,
         номер встаёт на 157 и получает 161px — читается. Название
         «Двухосный средний 3.15×1.5 м» занимает 172px, номер уезжает на
         198 и сжимается до 120 — цифры лезут друг на друга.

         ⚠️ ПРИЧИНА В flex:0 1 auto. Элемент берёт СВОЮ ширину — то есть
         ширину текста, — и сжимается только когда места совсем нет. Он
         сжался до 172, а номеру нужно 161: оба «влезли», и никто не
         виноват. Номер сжался, потому что flex-shrink у него 0 только
         на само поле, а внутренняя табличка тянется.

         ⚠️ РЕШЕНИЕ — ОТДАТЬ НАЗВАНИЮ РОВНО ОСТАТОК. Номеру нужно 161px
         (измерено на коротком названии), зазор 10. Значит названию
         остаётся 294 − 161 − 10 = 123. Ставим max-width в долях, чтобы
         работало и на других ширинах экрана: 123 из 294 — это 42%.
         Длинное название перенесётся в три строки, но номер останется
         целым. Номер важнее: по нему человек узнаёт свой прицеп. */
      /* ══ ⚠️ flex:1 1 auto — НАЗВАНИЮ НАДО ДАТЬ РАСТИ (round492) ═══

         Кирилл: «на карточке прицепа 2.5 на 1.3 буква „м“ слетает на 2
         строку».

         ⚠️ ТРИЖДЫ Я ПРАВИЛ НЕ ТО. Менял max-width (42%, потом остаток),
         потом min-width — и каждый раз мерил: название 127px, номер 165,
         зазор 10, а строка 358. СВОБОДНО 56 ПИКСЕЛЕЙ, и они пропадали
         зря, пока текст переносился.

         ⚠️ ПРИЧИНА В ПЕРВОМ ЧИСЛЕ «0 1 auto» — запрете расти. Название
         брало ширину СВОЕГО содержимого, а содержимое уже перенеслось в
         две строки: 127px это ширина строки «Прицеп 2.5×1.3», без «м».
         Замкнутый круг — ширина по тексту, текст по ширине.

         ⚠️ flex:1 1 auto РАЗРЫВАЕТ ЕГО: название занимает свободное
         место, помещается в строку целиком. Номер при этом не страдает —
         max-width не даёт названию забрать его место, а min-width не
         даёт сжаться ниже слова.

         ⚠️ В round474 Я СТАВИЛ ИМЕННО flex:0 1 auto, чтобы название не
         толкало номер. Тогда это было верно: max-width ещё не было.
         Теперь границу держит max-width, и запрет роста стал вреден. */
      /* ⚠️ ОСНОВА max-content, НЕ auto — ШЕСТАЯ И ПОСЛЕДНЯЯ ПРАВКА.

         С min-width:0 и nowrap название стало 127px у ВСЕХ — короткое
         обрезалось, хотя просило всего 134 при пределе 183. Причина:
         flex-basis:auto берёт ширину, которую элемент уже получил, а
         получил он минимум — нижняя граница ноль.

         ⚠️ max-content ЗНАЧИТ «СКОЛЬКО ПРОСИТ ТЕКСТ В ОДНУ СТРОКУ». Для
         короткого это 134 — помещается. Для длинного 245 — упирается в
         max-width 183 и обрезается многоточием.

         ⚠️ ТРИ СВОЙСТВА РАБОТАЮТ ТОЛЬКО ВМЕСТЕ: nowrap просит полную
         ширину, basis:max-content её выдаёт, max-width ограничивает
         сверху, min-width:0 не мешает сжатию. Убери любое — вернётся
         одна из пяти прежних бед. Я прошёл их все по очереди. */
      /* ⚠️ НАЗВАНИЕ ПОСЛЕ НОМЕРА, ЗАНИМАЕТ ОСТАТОК (round492).

         Кирилл: «слева сверху крупно госномер и после него название, с
         учётом сокращения названий двухосного должно всё влезать».

         ⚠️ ШЕСТЬ ПОПЫТОК ВТИСНУТЬ ДЛИННОЕ НАЗВАНИЕ НЕ УДАЛИСЬ — и
         правильно: 28 знаков рядом с номером не помещаются никак.
         Кирилл решил иначе и вернее: сократил сами названия («Двухосный
         средний» вместо «Двухосный средний 3.15×1.5 м»). Самое длинное
         теперь 17 знаков вместо 28.

         ⚠️ ТЕПЕРЬ НАЗВАНИЕ ИДЁТ ВТОРЫМ и берёт всё, что осталось после
         номера. max-width больше не нужен: номер стоит первым и своё
         место уже занял, вытолкнуть его нечем. */
      flex:1 1 auto;
      /* ⚠️ ПРЕДЕЛ ПО ОСТАТКУ, А НЕ ЖЁСТКИЕ 42% (round492).

         Кирилл: «на карточке прицепа 2.5 на 1.3 буква „м“ слетает на 2
         строку, исправь чтобы всё название влезало в 1 строку».

         ⚠️ ЭТО МОЯ ЖЕ ПРАВКА ИЗ round489. Тогда двухосный выталкивал
         госномер, и я отдал названию ровно 42% строки. Измерил сейчас:
         «Прицеп 2.5×1.3 м» занимает 134px — это 46%, и в 42% он не
         влез. Одно число не годится обоим: 46% ломает двухосного, 83%
         снова душит номер.

         ⚠️ ПРАВИЛЬНО — НЕ ДОЛЯ, А ОСТАТОК. Номеру нужно 161px, зазор 10.
         Пусть название займёт всё, что останется от строки после них:
         calc(100% - 171px). На узком экране это те же ~42%, на широком —
         больше, и короткое название помещается в строку везде.

         ⚠️ ДЛИННОЕ ПО-ПРЕЖНЕМУ ПЕРЕНОСИТСЯ, и это верно: номер важнее —
         по нему человек узнаёт свой прицеп. */
      /* ⚠️ 175px — ЭТО ЗАМЕР, А НЕ ПРИКИДКА (round492).

         Первый раз я вычел 171 и получил названию 128px при нужных 134 —
         короткое всё равно перенеслось. Ошибка была в том, от чего
         считать: строка заголовка 358px (не 294, как я прикинул),
         госномер 165, зазор 10. Свободно 183.

         ⚠️ ВЫЧИТАЕМ 175 = 165 (номер) + 10 (зазор): названию остаётся
         ровно 183px. «Прицеп 2.5×1.3 м» занимает 134 — помещается с
         запасом. «Двухосный средний 3.15×1.5 м» занимает 245 и
         переносится в две строки, а не в три.

         ⚠️ ЗАМЕРЯЛ БРАУЗЕРОМ, потому что прикидка по числу знаков
         соврала на 20%: ширина букв разная, «×» и цифры уже кириллицы. */

      /* ══ ⚠️ min-content, А НЕ 0 — ВОТ ЧТО СЖИМАЛО (round492) ══════

         Дважды я правил max-width — 42%, потом calc(100% − 175px) — и
         дважды измерял: название получало 127px при нужных 134. Менял
         число, а причина была в ДРУГОМ свойстве.

         ⚠️ min-width:0 СНИМАЕТ НИЖНЮЮ ГРАНИЦУ. Вместе с flex-shrink:1
         («0 1 auto») это значит: отдавай место соседу до последнего.
         Название ужималось ниже своей строки, и текст переносился, хотя
         места в строке хватало.

         ⚠️ min-content — граница по самому длинному слову. Короткое
         название не сожмётся ниже строки и поместится целиком; длинное
         перенесётся по словам, но номер останется цел.

         ⚠️ ОБЕ ГРАНИЦЫ ВМЕСТЕ: не уже содержимого (min-width), не шире
         остатка строки (max-width). Одна без другой не работает. */
      /* ⚠️ min-width:0, А НЕ min-content — ПЯТАЯ ПОПЫТКА, ПОСЛЕДНЯЯ

         min-content я поставил двумя правками раньше, когда текст ещё
         переносился: тогда он значил «не уже самого длинного слова» и
         был безобиден. С nowrap (выше) он стал значить ВСЮ СТРОКУ
         ТЕКСТА — и оказался сильнее max-width: длинное название
         занимало 245px при пределе 183 и выталкивало строку за край на
         61 пиксель.

         ⚠️ ПРАВИЛО, КОТОРОЕ Я ВЫУЧИЛ ЗДЕСЬ ДОРОГОЙ ЦЕНОЙ: min-width
         сильнее max-width. Если нижняя граница больше верхней, побеждает
         нижняя — и предел перестаёт работать молча, без ошибки.

         ⚠️ С НУЛЁМ ВСЁ СХОДИТСЯ: nowrap заставляет текст просить полную
         ширину (134 у короткого), max-width разрешает до 183 —
         помещается. Длинное просит 245, упирается в 183 и обрезается
         многоточием. Номер цел в обоих случаях. */
      min-width:0;
      margin-bottom:0;
    }

        .tc-plate{
      /* ⚠️ ЖИРНОСТЬ СНИЖЕНА С 800 ДО 600 (round394).

         Кирилл: «госномер стал толстым, словно резко стал некрасивым».

         Причина в смене шрифта. У Oswald начертания узкие, и 800 давало
         плотный, но стройный номер. Системный шрифт шире: та же
         жирность превращает буквы в чёрные бруски, между ними
         пропадает воздух.

         600 у системного выглядит как 800 у Oswald — по весу на глаз.
         И разрядка уменьшена: широкому шрифту она не нужна, буквы и так
         стоят свободно. */
      font-size:var(--fs-xl); font-weight:600; letter-spacing:.2px;
      line-height:1.1; margin-bottom:.25rem;
      color:#111; word-break:break-all;
    }
    /* ⚠️ .tc-head-text .tc-title УДАЛЕНО (round473): класса tc-head-text
       нет ни в разметке, ни в коде — правило мёртвое. Но оно задавало
       font-size:var(--fs-sm) с весом 2 и ПЕРЕБИВАЛО живое .tc-title.
       Мёртвое правило с большим весом опаснее живого: ищешь, почему
       размер не тот, а виновника в разметке нет. */

    /* ══ РЯД ДЕЙСТВИЙ ══════════════════════════════════════════════ */
    .tc-actions{
      display:flex; gap:.6rem; align-items:stretch; margin-top:.5rem;
    }
    .tc-actions .tc-take{ flex:1; margin:0 }

    /* ⚠️ КВАДРАТНЫЕ КНОПКИ ПО КРАЯМ: 48 пикселей — минимум, в который
       уверенно попадает палец. Меньше делать нельзя: человек в
       перчатках зимой промахнётся и нажмёт «Взять прицеп». */
    .tc-icon-btn{
      width:48px; height:48px; flex-shrink:0;
      display:flex; align-items:center; justify-content:center;
      background:#f0f2f5; border:1px solid #dfe3e8;
      border-radius:var(--radius-md); color:#3a4048;
      cursor:pointer; transition:background var(--dur);
      /* ⚠️ ШРИФТ ЗАДАЁМ ЯВНО: <button> не наследует его от страницы —
         на этом уже обжигались с кнопкой «Взять прицеп». */
      font-family:'IBM Plex Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    }
    .tc-icon-btn:hover{ background:var(--border) }
    .tc-icon-btn:active{ transform:scale(.96) }

    /* Недоступный прицеп: место кнопки занимает надпись, чтобы ряд не
       разъезжался и значки не прыгали. */
    .tc-take-off{
      flex:1; display:flex; align-items:center; justify-content:center;
      background:#f0f2f5; border:1px solid #dfe3e8; border-radius:var(--radius-md);
      color:#6b6d7c; font-weight:700; font-size:var(--fs-sm);
    }

    /* Окно цен по значку «i». */
    /* ══ ОКНО «i»: БЕЛОЕ, ТЕКСТ ТЁМНЫЙ (round387) ═════════════════════

       Кирилл: «карточка i должна быть белой, текст тёмный или чёрный».

       Причина та же, что у самой карточки и инструкции по сейфу: окно
       открывают НА УЛИЦЕ, стоя у прицепа, где экран выцветает от
       солнца.

       ⚠️ ТЕКСТ #1a1a1a, А НЕ ЧИСТО ЧЁРНЫЙ: на белом чистый чёрный даёт
       резкий контраст, от которого буквы «дрожат» — читать длинные
       строки вроде адреса тяжелее. Почти-чёрный мягче и читается лучше;
       контраст с белым 15,9 при пороге 4,5.

       ⚠️ ПОДПИСИ СЕРЫЕ (#6b7280, контраст 5,2): они служебные, и если
       красить их так же, как значения, глаз не поймёт, где что. */
    #tcInfo .modal-content{
      background:#ffffff;
      color:#1a1a1a;
    }
    #tcInfo .modal-title{ color:#111111 }
    #tcInfo .muted-note{ color:#6b7280 }
    #tcInfo .btn-outline{
      background:#f0f2f5; border:1px solid #dfe3e8; color:#1a1a1a;
    }

    .tc-info{ display:flex; flex-direction:column }
    .tc-info-row{
      display:flex; justify-content:space-between; gap:1rem;
      padding:.65rem 0; border-bottom:1px solid #eef1f4;
      font-size:var(--fs-base); line-height:1.4;
    }
    .tc-info-row:last-child{ border-bottom:none }
    .tc-info-label{ color:#6b7280; flex-shrink:0 }
    .tc-info-val{
      color:#1a1a1a; font-weight:700; text-align:right;
      /* Адрес бывает длинным — переносим, а не обрезаем: человек едет
         именно по нему. */
      word-break:break-word;
    }
    /* Координаты нажимаются для копирования — показываем это. */
    #tcInfo .tc-coords{
      color:#1a1a1a; text-decoration:underline dotted; cursor:pointer;
    }

    .tc-prices{ display:flex; flex-direction:column; gap:.1rem }
    .tc-price-row{
      display:flex; justify-content:space-between;
      padding:.55rem 0; border-bottom:1px solid #eef1f4;
      font-size:var(--fs-base);
    }
    .tc-price-row:last-child{ border-bottom:none }

    .tc-title{font-size:var(--fs-md);font-weight:700;margin-bottom:.3rem}
/* ⚠️ ЦВЕТА СОСТОЯНИЯ ПЕРЕСЧИТАНЫ ПОД БЕЛЫЙ ФОН (round384).

     Сделав карточку белой, я едва не оставил прежние цвета — они
     подбирались под тёмный фон. Посчитал контраст: зелёный «Свободен»
     дал 1,76 при пороге 3, бежевый «есть брони» 2,24, красный
     «неисправен» 2,78. То есть три надписи из четырёх на белом почти
     не видны.

     Это не косметика: по этой строке человек решает, брать прицеп или
     нет. Не разглядел «неисправен» — поехал зря.

     Новые цвета те же по смыслу, но темнее: контраст от 4,4 до 6,1.
     Проверено расчётом, а не на глаз. */
    .tc-status{font-size:var(--fs-sm);font-weight:700;margin-bottom:.45rem;display:flex;align-items:center;gap:.5rem}
.tc-status.yes{color:#0f8a3d}
.tc-status.booked{color:#8a6a1f}
.tc-status.no{color:#5a636e}
.tc-dot{width:9px;height:9px;border-radius:50%;flex-shrink:0;display:inline-block}
.tc-dot.yes{background:#22e06b;box-shadow:0 0 0 rgba(34,224,107,.6);animation:tcDotPulse 1.6s ease-out infinite}
.tc-dot.booked{background:#c6cbd1;box-shadow:0 0 0 rgba(198,203,209,.6);animation:tcDotPulse 1.6s ease-out infinite}
.tc-dot.no{background:#8a8a8a}
.tc-dot.maint{background:#ff2d2d;box-shadow:0 0 0 rgba(255,45,45,.7);animation:tcDotPulse 1.6s ease-out infinite}
.tc-status.maint{color:#dc2626}
/* Кнопки карточки используют ОБЩИЕ классы .btn / .btn-primary из
   common.css — тот самый «слиток золота» с блеском. Здесь только
   раскладка (ширина, отступы), никакой своей окраски и шрифтов.
   Раньше .tc-take красился вручную и, главное, не задавал
   font-family — а <button> шрифт от body НЕ наследует, поэтому
   надпись вылезала системным шрифтом вместо Oswald. Именно из-за
   этого кнопка на карте выглядела чужой. */
.tc-take,.tc-nav{width:100%;margin-top:.6rem}
.tc-take{margin-top:.9rem}

/* ══ ПЛАВНАЯ СМЕНА СЛОЁВ ПРИ ЗУМЕ ════════════════════════════════
   Резкое исчезновение раздражало, потому что элементы просто
   выключались через display:none — без промежуточного состояния.
   Теперь маркеры остаются в DOM и меняют прозрачность с масштабом.

   ВАЖНО, почему обёртка .mk-fade, а не сам маркер: Leaflet
   позиционирует маркеры через transform:translate3d() на своём
   контейнере, а у .custom-pin вдобавок есть rotate(-45deg) — свой
   transform. Анимировать scale на них означало бы затереть и
   позицию, и поворот. Поэтому анимируем отдельную обёртку внутри,
   у которой никаких чужих трансформаций нет. */
.mk-fade{
  transition:opacity var(--dur) ease, transform var(--dur) cubic-bezier(.2,.8,.2,1);
  transform-origin:center center;
  will-change:opacity, transform;
}
.mk-fade.mk-pin{ /* ⚠️ ТОЧКА ОПОРЫ — ЦЕНТР, А НЕ НИЗ (round463). Прежде значок был
     каплей с остриём внизу, и расти он должен был от острия. Теперь
     это круг: он обязан расти от середины, иначе при появлении
     подпрыгивает вверх. */
  transform-origin:50% 50%; }   /* пин «растёт» от острия */
/* ⚠️ СЕЛЕКТОР БЕЗ КЛАССА LEAFLET (round346). Здесь стояло
   .leaflet-marker-icon.mk-off — класс, которого у MapLibre нет вовсе.
   Класс mk-off на маркер ставился, а правило не применялось: точки
   прицепов не прятались при отдалении, и на общем плане была каша из
   меток. Правило не работало молча — вид не менялся, ошибок нет. */
.mk-off{ pointer-events:none; }
.mk-off .mk-fade{ opacity:0; transform:scale(.45); }
@media(prefers-reduced-motion:reduce){
  .mk-fade{transition:opacity var(--dur) linear}
  .mk-off .mk-fade{transform:none}
}
@keyframes tcDotPulse{
  0%{box-shadow:0 0 0 0 currentColor}
  70%{box-shadow:0 0 0 6px transparent}
  100%{box-shadow:0 0 0 0 transparent}
}
.tc-dot.yes{color:rgba(34,224,107,.55)}
.tc-dot.booked{color:rgba(198,203,209,.55)}
@media(prefers-reduced-motion:reduce){ .tc-dot.yes,.tc-dot.booked{animation:none} }
.tc-row{display:flex;justify-content:space-between;padding:.5rem 0;/* Линия из палитры (round366): #262626 был свой оттенок, на новом
       фоне он то пропадал, то выступал полосой. */
    border-top:1px solid #e6e9ec;font-size:var(--fs-base)}
.tc-label{/* ⚠️ ТЁПЛЫЙ СЕРЫЙ #8a857a — ТОЖЕ НАСЛЕДИЕ ЗОЛОТОЙ ТЕМЫ (round366).
       Рядом с нейтральным серым остальных подписей он выглядел
       выцветшим. Берём общий приглушённый цвет. */
    color:#5a636e}
.tc-val{font-weight:600;text-align:right}

/* Правила .header-title и .header-sub удалены (round289): верхняя
   шапка карты заменена общей нижней панелью, и разметки под них
   больше нет. */
.popup-safe-name{ font-size:var(--fs-base) !important; }
.popup-loc{ font-size:var(--fs-base) !important; }
.popup-addr{ font-size:var(--fs-base) !important; }
.popup-row{ font-size:var(--fs-base) !important; }
.popup-rule{
  font-size:var(--fs-sm) !important; line-height:1.45; color:rgba(238,240,243,.75);
  background:rgba(176,183,191,.08); border:1px solid rgba(176,183,191,.2);
  border-radius:var(--radius-sm); padding:.6rem .7rem; margin:.6rem 0;
}

/* Атрибуция Leaflet/OpenStreetMap обязательна по лицензии тайлов —
   убрать нельзя, но можно сделать менее заметной. */
.leaflet-control-attribution{
  font-size:var(--fs-xs) !important;
  opacity:.55 !important;
  background:rgba(15,15,15,.75) !important;
  color:#F5EDD4 !important;
}
.leaflet-control-attribution a{ color:#F5EDD4 !important; }
