/* ============================================================
   «Поводок» на телефоне — оболочка приложения
   ============================================================
   Подключается ПОСЛЕ main.css: правила здесь перебивают базовые при равной
   специфичности, поэтому дублировать селекторы весом не нужно.

   Что делает файл. Портал на телефоне перестаёт быть уменьшенной десктопной
   страницей: снизу появляется панель вкладок, шапка сжимается и уезжает при
   прокрутке, все всплывающие слои выезжают листом снизу, а списки-справочники
   пересобираются в плотные строки. Порог — 880px, тот же, на котором десктопное
   меню уже сворачивалось в бургер: две разные границы «мобильного» в одном
   проекте расходятся при первой же правке.

   Порядок разделов:
     1. Касание и прокрутка (общее, без медиазапроса)
     2. Раскладка страницы: место под панель вкладок
     3. Шапка
     4. Панель вкладок
     5. Лист «Ещё» и общий механизм листов
     6. Всплывающие слои → нижние листы
     7. Каталог клиник
     8. Каталог врачей
     9. Страница клиники и врача
    10. Контентные страницы, подвал, мелочи
   ============================================================ */

/* ============================================================
   0. Телефонные правила компонентов (переехали из main.css)
   ============================================================
   Здесь лежит то, что раньше было объявлено в main.css медиазапросами
   на 400/560/700/880 — то есть внутри диапазона, за который отвечает
   этот файл. Пока они жили там, у каждого компонента было два адреса:
   базовый вид в main.css, телефонный — там же ниже по файлу, и ещё раз
   в mobile.css. Сто сорок восемь селекторов были объявлены в обоих файлах.

   Переезд заодно снимает ловушку каскада: безусловное правило, стоящее
   в main.css НИЖЕ телефонного медиазапроса, перебивало его при равной
   специфичности — телефонное правило молча не срабатывало. В этом файле
   такого не бывает: он подключается последним целиком.

   Блоки идут в исходном порядке и стоят перед остальными правилами
   файла — там же, где были относительно них раньше.
   ============================================================ */

@media (max-width: 560px) {
  /* Карточка растягивалась на всю ширину контейнера, и уголок снова стоял
     на отступе от края — своём, третьем по счёту. Теперь ширина одна на все
     экраны: карточка висит под кнопкой города, а та на узком экране и так
     у правого края. Остаётся не дать ей вылезти влево на самых узких. */
  .city-hint { max-width: calc(100vw - var(--space-lg) * 2); }
}

/* На узком экране столбец сжимается до ~145px, и «Санкт-Петербург» переносится
   на вторую строку — тогда столбцы перестают совпадать по строкам и список
   выглядит разъехавшимся. Отыгрываем ширину на полях и кегле. Блок стоит
   ПОСЛЕ правил кнопки: специфичность равная, побеждает то, что ниже. */
@media (max-width: 400px) {
  .city-modal-card { padding: 18px 14px 14px; }
  .city-list { column-gap: var(--space-xs); }
  .city-list button { gap: 4px; padding: 10px 8px; font-size: var(--text-sm); }
  /* У активного города жирность и галочка съедали те самые 10px, из-за которых
     «Санкт-Петербург» уезжал на вторую строку. Состояние всё равно читается
     подложкой и галочкой — не только цветом. */
  .city-list button.active { font-weight: 500; }
  .city-list button svg { width: 14px; height: 14px; }
}

/* Порог бургера. Держать в паре с медиазапросом ховера у .nav-menu::before:
   наведение включается ровно там, где меню развёрнуто в строку. */
@media (max-width: 880px) {
  .header-in { gap: 14px; }
  .city-btn { padding: 8px 13px; font-size: var(--text-xs); }
  .city-btn-label {
    max-width: 110px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }
  .burger { margin-left: 0; }
  .nav {
    display: none;
    position: absolute;
    top: var(--header-h);
    left: 0;
    right: 0;
    flex-direction: column;
    align-items: stretch;
    background: var(--card);
    border-bottom: 1px solid var(--line);
    padding: 10px 16px 16px;
    box-shadow: var(--shadow-md);
  }
  /* В бургер-меню группы раскрываются не панелью поверх, а гармошкой внутри
     списка: панель на всю ширину экрана перекрыла бы остальные пункты. */
  .nav-item { position: static; }
  .nav-link,
  .nav-trigger {
    display: flex;
    width: 100%;
    padding: 12px 14px;
    border-radius: var(--r-sm);
  }
  .nav-trigger { justify-content: space-between; }
  .nav-menu {
    position: static;
    margin: var(--space-2xs) 0 var(--space-sm) 15px;
    padding: 0 0 0 var(--space-md);
    border: 0;
    /* Вертикальная линия вместо рамки — вложенность видна, лишней коробки нет */
    border-left: 2px solid var(--border);
    border-radius: 0;
    box-shadow: none;
  }
  .nav-menu a { padding: 11px 12px; font-size: var(--text-base); }
  .nav.open { display: flex; }
  .burger { display: block; }
}

/* На узких экранах логотип (193px, flex-shrink: 0) вместе с кнопкой города и
   бургером не помещался в 390px — страница получала горизонтальную прокрутку.
   Уменьшаем логотип и подпись города, чтобы шапка укладывалась в ширину. */
@media (max-width: 560px) {
  .header-in { gap: 10px; }
  .city-btn { padding: 8px 11px; }
  .city-btn-label { max-width: 72px; }
  /* «Выберите город» в 72px превращалась в «Выберит…» — включаем короткую */
  .city-btn-label-full { display: none; }
  .city-btn-label-short { display: inline; }
}

@media (max-width: 560px) {
  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
}

@media (max-width: 560px) { .pros-cons { grid-template-columns: 1fr; } }

@media (max-width: 700px) { .footer-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

@media (max-width: 400px) { .footer-grid { grid-template-columns: minmax(0, 1fr); } }

/* На двух колонках бренд занимает строку целиком — иначе рядом с ним
   остаётся пустая половина. */
@media (max-width: 700px) { .footer-brand { grid-column: 1 / -1; } }

@media (max-width: 700px) {
  /* В одну колонку: рядом с названием на узком экране оценке не хватает
     ширины, а переносить её слова нельзя — «Очень хорошо» ломалось надвое. */
  .cl-head { grid-template-columns: minmax(0, 1fr); }
  .cl-head > *:not(.cl-score) { grid-column: 1; }
  .cl-score { grid-column: 1; grid-row: auto; margin-bottom: var(--space-md); }
}

@media (max-width: 560px) {
  /* На узком экране портрет и имя стоят в строке, а должность уходит под них
     во всю ширину: в колонке рядом с портретом остаётся 250px, и «Главный
     ветеринарный врач филиала Коньково и Крылатское, заведующая…» вытягивался
     в девять строк, а портрет висел в середине этого столбца.
     display: contents у обёртки — чтобы заголовок и должность стали
     самостоятельными ячейками сетки без второго блока в разметке. */
  .dr-top {
    display: grid;
    grid-template-columns: 88px minmax(0, 1fr);
    grid-template-areas:
      "photo name"
      "title title"
      "score score";
    align-items: center;
    column-gap: var(--space-lg);
    row-gap: var(--space-sm);
    margin-bottom: var(--space-lg);
  }
  .dr-ident { display: contents; }
  .dr-portrait { grid-area: photo; width: 88px; height: 88px; align-self: start; }
  .dr-ident h1 { grid-area: name; }
  .dr-title { grid-area: title; margin-top: 0; font-size: var(--text-base); }
  .dr-top .cl-score { grid-area: score; margin-left: 0; }
  /* Кнопки в строку не помещаются: номер и «оставить отзыв» рядом ужимались
     до двух строк текста каждая. */
  .dr-actions .btn { flex: 1 1 100%; justify-content: center; }
}

@media (max-width: 560px) {
  /* Рельс уезжает к левому краю, год встаёт над записью: колонка в 62px
     плюс зазор отнимали у текста треть экрана.
     Селектор с .dr-time-dated обязателен — правило с колонками специфичнее,
     и медиазапрос сам по себе его не перебивает. */
  .dr-time-dated .dr-time-row {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-2xs);
    padding-left: var(--space-xl);
  }
  .dr-time-dated .dr-time-year { text-align: left; }
  .dr-time-dated .dr-time-row::before { left: 3px; }
  .dr-time-dated .dr-time-row::after { left: 0; }
  .dr-time-year { font-size: var(--text-xs); }
}

/* От 720px и ниже .hc-side из столбика превращается в переносящийся ряд
   (правило выше по файлу, у мобильной раскладки карточки). Строка метро с
   width:100% из этого ряда выпадала: она одна занимала всю ширину и
   оказывалась единственной прижатой к левому краю — блок выглядел рваным.
   Переопределения стоят здесь, а не в том медиазапросе: он объявлен раньше
   компонента, и базовые правила его перебивали. */
@media (max-width: 700px) {
  .hc-metro { width: auto; align-items: center; }
  .hc-metro-item { width: auto; align-items: center; }
}

@media (max-width: 560px) {
  .hc { grid-template-columns: minmax(0, 1fr); gap: var(--space-lg); padding: var(--space-xl); }
  /* Столбик, как на десктопе: в строку фото, плашка оценки и ссылка отзыва
     не влезали — ссылка ломалась на две строки и всё съезжало. Меняется
     только размер снимка. */
  .hc-media { align-items: flex-start; }
  .hc-media img, .hc-media-stub { width: 120px; height: 120px; }
  .hc-rate { margin-left: var(--space-md); }
  .hc-side { grid-column: 1; }
  .agg-apply { flex: 1 1 100%; }
}

@media (max-width: 880px) {
  /* Фильтры сворачиваются под кнопку-сводку. details/summary, а не скрипт:
     панель обязана работать без JS, а «открыт по умолчанию на десктопе,
     свёрнут на мобильном» одним атрибутом не выражается — на широком экране
     содержимое показываем стилями независимо от [open]. */
  .agg-filters-toggle {
    display: inline-flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-md) var(--space-lg);
    border: 1px solid var(--border);
    border-radius: var(--r-sm);
    background: var(--surface);
    font-size: var(--text-sm);
    font-weight: 600;
    color: var(--text);
    cursor: pointer;
    list-style: none;
  }
  .agg-filters-toggle::-webkit-details-marker { display: none; }
  /* Число применённых фильтров — акцентом: это единственное, что отличает
     свёрнутую панель с выбором от свёрнутой панели без него. */
  .agg-filters-toggle .num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 20px;
    height: 20px;
    border-radius: var(--r-pill);
    background: var(--accent);
    color: var(--on-accent);
    font-size: var(--text-2xs);
  }
  .agg-filters:not([open]) .agg-filters-body { display: none; }
  .agg-filters[open] .agg-filters-body { margin-top: var(--space-md); }
  /* Кнопки фасетов узкие — в столбик их ставить незачем, встают рядом
     и переносятся по мере надобности. */
  .agg-selects { flex-wrap: wrap; }
  .agg-facet-menu { min-width: 240px; }
  /* Переключатель вида занимает строку целиком, значку сортировки хватает
     квадрата рядом: на 360px «Списком / На карте» вылезал за экран на два
     десятка пикселей. */
  .agg-head-tools { width: 100%; justify-content: space-between; flex-wrap: wrap; }
  .agg-view { flex: 1 1 auto; }
  .agg-view-btn { flex: 1 1 auto; justify-content: center; }
}

@media (max-width: 700px) { .sv-items { columns: 1; } }

@media (max-width: 700px) {
  .rv-summary { grid-template-columns: minmax(0, 1fr); gap: var(--space-lg); align-items: start; }
  /* Колонка «кто» уходит наверх строкой: 200px под имя на узком экране
     оставляют тексту отзыва треть ширины. */
  .rv-item { grid-template-columns: minmax(0, 1fr); gap: var(--space-md); }
  /* Перенос — страховка: длинное имя плюс контекст визита в одну строку
     на 360px не помещаются, и без него дата уходила за край. */
  .rv-who { flex-direction: row; align-items: center;
            justify-content: space-between; flex-wrap: wrap; }
}

@media (max-width: 560px) {
  .phone-modal { padding: var(--space-xl); }
  /* На узком экране три ответа в строку ужимаются до нечитаемого — в столбец */
  .phone-modal-btns .btn { flex: 1 1 100%; }
}

@media (max-width: 700px) {
  /* В одну колонку треугольной зоне негде жить: карта идёт чистой полосой
     под кнопками, а оценка возвращается под название — там она и стоит
     на узких экранах. Иначе балл падает прямо на карту. */
  .cl-card-map {
    position: static;
    width: calc(100% + var(--space-xl) * 2);
    height: 150px;
    margin: var(--space-lg) calc(var(--space-xl) * -1) calc(var(--space-xl) * -1);
    -webkit-mask-image: none;
    mask-image: none;
  }
  .cl-card:has(.cl-card-map) .cl-score { position: static; padding: 0; background: none;
    box-shadow: none; backdrop-filter: none; -webkit-backdrop-filter: none; }
  .cl-map-open { right: var(--space-lg); bottom: var(--space-lg); }
  .map-modal-foot { flex-direction: column; align-items: stretch; gap: var(--space-lg); }
}

@media (max-width: 880px) {
  .cl-cover { height: 240px; }
  .cl-card { padding: var(--space-xl) var(--space-xl) var(--space-xl); }
  .anchor-nav { padding: 0 var(--space-xl); }
  .cl-section { padding: var(--space-xl); }

  .cl-sticky-cta {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 40;
    display: flex;
    gap: var(--space-sm);
    padding: var(--space-md) var(--space-lg) calc(var(--space-md) + env(safe-area-inset-bottom));
    background: var(--surface);
    border-top: 1px solid var(--border);
    box-shadow: 0 -4px 16px rgba(17, 20, 31, 0.07);
    transform: translateY(110%);
    visibility: hidden;
    transition: transform var(--t-med) var(--ease-out), visibility var(--t-med);
  }
  .cl-sticky-cta.is-visible { transform: none; visibility: visible; }
  .cl-sticky-cta .btn { flex: 1; justify-content: center; }
  /* место под панель, чтобы она не накрывала конец страницы */
  body:has(.cl-sticky-cta) { padding-bottom: 76px; }
}

@media (max-width: 560px) {
  :root { --cl-card-overlap: 32px; }
  /* На узком экране три кадра превращались бы в нечитаемые полоски —
     оставляем первый во всю ширину, остальные открываются счётчиком. */
  .cl-cover { grid-template-columns: 1fr; height: 190px; }
  .cl-cover-cell:not(:first-child) { display: none; }
  .cl-cover-all { right: var(--space-md); padding: var(--space-xs) var(--space-md); }
  .cl-card { padding: var(--space-xl) var(--space-lg) var(--space-lg); }
  .anchor-nav { padding: 0 var(--space-lg); }
  /* 32px по бокам на экране 360px съедали пятую часть строки */
  .cl-section { padding: var(--space-xl) var(--space-lg); }
  .cl-section + .cl-section { margin-top: var(--space-sm); }
  /* Две плитки в ряд вместо одной: при minmax(160px) в колонку 288px влезала
     бы одна, и портрет 4:5 растянулся бы на пол-экрана в высоту. */
  /* Одна колонка: в списке две колонки по 180px рвут имена на три строки.
     Правило писалось под прежние плитки с портретом, там две помещались. */
  .doc-grid { grid-template-columns: minmax(0, 1fr); }
  /* nowrap на подписи требует запаса: 22px паддинга по бокам двум кнопкам
     в ряду на 360px не хватало — «На карте» упиралась в край. Значки из
     растяжения исключены: flex:1 раздувал их в широкие пилюли. */
  .cl-actions .btn:not(.cl-action-icon) { flex: 1; padding-inline: var(--space-lg); }
  /* Телефон занимает всю строку: номер с подписью «показать» рядом с другой
     кнопкой не помещался и давал горизонтальную прокрутку. */
  .cl-actions .cl-phone-btn { flex: 1 1 100%; padding-inline: var(--space-md); }
  .cl-phone-num { font-size: var(--text-sm); }
  .cl-section-head { flex-direction: column; align-items: flex-start; gap: var(--space-xs); }
}

@media (max-width: 560px) {
  .search-form input { padding-left: 14px; }
}

@media (max-width: 880px) {
  .bento { grid-template-columns: repeat(2, 1fr); }
  .bento-lg { grid-column: span 2; grid-row: auto; }
  /* 300, а не 220: в полосу 3.3:1 голова лабрадора не помещалась — от неё
     оставалась либо макушка, либо морда, смотря куда сдвинуть кадр. */
  .bento-lg a { min-height: 300px; }
}

@media (max-width: 560px) {
  /* Две колонки, а не одна. В одну колонку все шесть плиток становились
     одинаковыми прямоугольниками по 150px — идея разноразмерной сетки
     умирала, и получался столбик равных баннеров. Здесь ритм сохраняется:
     клиники во всю ширину и выше остальных, врачи и разделы контента —
     полосами, а две заглушки «Скоро» садятся в один ряд по половине ширины.
     Заглушкам половина и полагается: страниц за ними пока нет. */
  .bento { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .bento-lg, .bento-wide { grid-column: span 2; grid-row: auto; }
  .bento a { min-height: 150px; }
  .bento-lg a { min-height: 210px; }
  .bento-body { padding: 16px; }
  .bento-lg .bento-title { font-size: var(--text-lg); }
  /* В половинной плитке заголовок в две строки — норма, кегль не уменьшаем:
     мельче основного текста он читался бы как подпись, а не как раздел. */
  .bento-sm .bento-title { line-height: 1.25; }
}

@media (max-width: 560px) {
  .nav-cards { grid-template-columns: 1fr; }
}

@media (max-width: 560px) {
  /* На телефоне панель распрямляется во всю ширину: рамка вокруг формы,
     занимающей весь экран, только сужает поля ввода. */
  .auth-page {
    margin-top: var(--space-xl);
    padding: 0;
    background: none;
    border: none;
  }
}

/* На планшете карта уходит полосой под содержимое — отдать ей боковые 46%
   значит ужать факты до колонки в тридцать символов, а ряд кнопок сбросить
   на две строки. Ниже 700px то же самое делает правило ниже по файлу,
   поэтому диапазон здесь ограничен сверху и снизу. */
@media (min-width: 701px) and (max-width: 880px) {
  /* Селектор с двумя классами намеренно: общее правило .cl-card-map объявлено
     ниже по файлу, и при равной специфичности выигрывало бы оно. */
  .cl-card .cl-card-map {
    position: static;
    width: calc(100% + var(--space-3xl) * 2);
    height: 150px;
    margin: var(--space-xl) calc(var(--space-3xl) * -1) calc(var(--space-2xl) * -1);
    -webkit-mask-image: none;
    mask-image: none;
  }
  /* Карты под оценкой больше нет — значит, не нужны ни абсолют, ни стеклянная
     подложка: балл возвращается в поток шапки. */
  .cl-card:has(.cl-card-map) .cl-score {
    position: static;
    padding: 0;
    background: none;
    box-shadow: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
  }
}

/* ---------- 1. Касание и прокрутка ---------- */
/* Правила без медиазапроса: они безвредны на десктопе (там нет тач-событий)
   и должны действовать на любом тач-устройстве, включая ноутбуки с экраном. */

html {
  /* Safari в альбомной ориентации самовольно увеличивает кегль в узких
     колонках — текст в таблице вдруг крупнее соседнего абзаца. */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}

/* Серый прямоугольник, который Android рисует поверх нажатой ссылки, спорит
   с нашими состояниями :active. Отклик даём сами — ниже. */
a, button, summary, label, [role="button"] {
  -webkit-tap-highlight-color: transparent;
}

/* touch-action: manipulation убирает 300мс ожидания двойного тапа. Ставим
   точечно на интерактивном, а не на body: на body он запрещает и pinch-zoom
   внутри страницы, а увеличивать текст двумя пальцами человек вправе. */
a, button, summary, .chip, .agg-facet-btn, .agg-check, .tabbar-item {
  touch-action: manipulation;
}

@media (hover: none) {
  /* На тач-экране нажатие обязано откликнуться меньше чем за 100мс — иначе
     непонятно, попал палец или нет. Ховера здесь нет, поэтому весь отклик
     держится на :active. */
  .btn:active { transform: scale(0.97); }
  .card:active,
  .hc:active,
  .nav-card:active { background: var(--surface-1); }
  .row-link:active,
  .doc-card:active,
  .suggest-item:active,
  .city-list button:active,
  .ms-list a:active,
  .agg-facet-opt:active { background: var(--surface-2); }
  .chip:active,
  .agg-chip:active,
  .fchip:active { background: var(--surface-1); border-color: var(--accent-soft); }
}

/* ---------- Переходы между страницами ---------- */
/* Главное, что отличает приложение от сайта на телефоне, — между экранами нет
   белой вспышки. Браузер держит старую страницу, пока не готова новая, и
   сменяет их кадром. Работает только внутри одного домена и только там, где
   поддерживается; остальные браузеры просто переходят как раньше.

   Шапка и панель вкладок получают собственные имена: они одинаковы на всех
   страницах, поэтому не участвуют в смене кадра и остаются неподвижными —
   ровно так ведёт себя оболочка приложения. */
@view-transition { navigation: auto; }
.header { view-transition-name: pv-header; }
.tabbar { view-transition-name: pv-tabbar; }

@media (min-width: 881px) {
  /* На десктопе переходов нет: их заводили ради мобильной оболочки, а на
     широком экране смена страницы и так не мигает — там нет ни адресной
     строки, ни шва между экранами. */
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation-duration: 0s; }
}
@media (prefers-reduced-motion: reduce) {
  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation-duration: 0s; }
}

/* ---------- Компоненты оболочки на широком экране ---------- */
/* Панель вкладок, поиск-иконка в шапке и листы существуют в разметке всегда:
   показывать их скриптом значит мигать панелью при каждой загрузке страницы.
   На десктопе они просто выключены — там своя навигация в шапке. */
.tabbar,
.header-search,
.sheet { display: none; }

/* ============================================================
   Дальше — только телефон и планшет
   ============================================================ */
@media (max-width: 880px) {

/* ---------- 2. Раскладка страницы ---------- */

:root {
  /* Шапка ниже десктопной: 68px съедали седьмую часть экрана телефона, а
     кроме логотипа и города в ней ничего нет. Точки прилипания и отступы
     по всему проекту считаются от этого токена, поэтому меняем его, а не
     двадцать чисел. */
  --header-h: 54px;
  /* Точка прилипания вторых панелей (строка разделов, панель каталога).
     Отдельный токен, потому что при уехавшей шапке она меняется, а
     --header-h остаётся высотой самой шапки — на неё завязан её размер.

     Безопасная зона входит в расчёт: при viewport-fit=cover страница уходит
     под вырез, шапка отбивается от него своим padding-top, и её полная
     высота больше --header-h ровно на эту величину. Без слагаемого строка
     разделов на iPhone пряталась под шапкой. */
  --sticky-top: calc(var(--header-h) + var(--safe-t));
}
/* Уехавшая шапка освобождает место, но не вырез: прилипшая полоса должна
   встать под строкой состояния, а не под ней. */
body.hdr-hidden { --sticky-top: var(--safe-t); }

html {
  /* Якорный переход не должен нырять под шапку и прилипшую строку разделов */
  scroll-padding-top: calc(var(--header-h) + var(--safe-t) + 58px);
}

/* Место под панель вкладок забирает подвал, а не body: с полем у body между
   тёмным подвалом и панелью оставалась полоска фона страницы — шов, которого
   в приложении не бывает. Теперь подвал уходит под полупрозрачную панель
   и просвечивает сквозь неё, как и положено содержимому под баром. */
.footer { padding-bottom: calc(var(--space-2xl) + var(--tabbar-total)); }

/* Боковые поля контейнера считаются с безопасными зонами: в альбомной
   ориентации iPhone вырез съедает 44px слева, и текст упирался в него. */
.container {
  padding-left: max(var(--space-lg), var(--safe-l));
  padding-right: max(var(--space-lg), var(--safe-r));
}

/* ---------- 3. Шапка ---------- */

.header {
  /* Уезжает вверх при прокрутке вниз и возвращается при прокрутке вверх —
     как в приложении. Класс вешает mobile.js по направлению движения. */
  transition: transform var(--t-med) var(--ease-out);
  padding-top: var(--safe-t);
}
body.hdr-hidden .header { transform: translateY(calc(-100% - 1px)); }
/* Пока открыт лист или модалка, шапка не двигается: фон под слоем не должен
   ездить сам по себе. */
body.modal-open .header { transform: none; }

.header-in { gap: var(--space-md); }
/* Логотип в шапке 54px. Подпись остаётся: она набрана текстом и на девяти
   пикселях читается — в контурах на этой же высоте от неё оставалось два
   с половиной пикселя. Пропорции держит width: auto из main.css. */
.logo { gap: 8px; }
.logo-mark { height: 34px; }
.logo-word { height: 23px; }
.logo-lockup { gap: 2px; }
.logo-tagline { font-size: 9px; letter-spacing: 0; }

/* Поиск в шапке — иконка-кнопка: на телефоне до строки поиска на главной надо
   доскроллить, а из карточки клиники до неё не добраться вовсе. */
.header-search {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: none;
  width: var(--tap);
  height: var(--tap);
  margin-left: auto;
  border-radius: var(--r-pill);
  color: var(--accent-ink);
}
.header-search:active { background: var(--surface-1); }
/* Кнопка города встаёт после поиска, поэтому своё margin-left: auto снимаем */
.city-btn { margin-left: 0; min-height: 40px; }

/* Бургер больше не нужен: разделы живут в нижней панели и в листе «Ещё».
   Разметка остаётся — на десктопе она рабочая. */
.burger { display: none; }
.nav { display: none !important; }

/* ---------- 4. Панель вкладок ---------- */
/* Главная навигация приложения: четыре раздела, до которых чаще всего идут,
   плюс «Ещё». Внизу, а не сверху, — большой палец достаёт только нижнюю треть
   экрана, а именно там на портале раньше не было ничего. */

.tabbar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 60;
  display: flex;
  /* Панель во всю ширину, но сами вкладки не расползаются на планшете:
     на 880px пять пунктов встали бы через 170px друг от друга. */
  justify-content: center;
  padding-bottom: var(--safe-b);
  background: rgba(255, 255, 255, 0.92);
  backdrop-filter: saturate(1.5) blur(16px);
  -webkit-backdrop-filter: saturate(1.5) blur(16px);
  border-top: 1px solid var(--border);
  transition: transform var(--t-med) var(--ease-out);
}
/* Панель уезжает, когда её место занимает контекстное действие страницы
   (кнопка «Позвонить» на карточке клиники) или когда открыт лист: две
   полосы друг над другом съедали бы четверть экрана. */
body:has(.cl-sticky-cta.is-visible) .tabbar,
body.sheet-open .tabbar { transform: translateY(100%); }

.tabbar-item {
  display: flex;
  flex: 1 1 0;
  max-width: 128px;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 3px;
  min-height: var(--tabbar-h);
  padding: 6px 4px;
  border: 0;
  background: none;
  font: inherit;
  font-size: var(--text-2xs);
  font-weight: 500;
  line-height: 1;
  color: var(--text-muted);
  text-decoration: none !important;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.tabbar-ico { display: flex; }
.tabbar-label {
  /* Названия разделов длинные («Здоровье»), но переносить их нельзя — вкладка
     разъедется по высоте относительно соседей. */
  white-space: nowrap;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* Активная вкладка отличается цветом И весом: только цветом состояние
   передавать нельзя. */
.tabbar-item.is-on { color: var(--accent-strong); font-weight: 700; }
.tabbar-item:active .tabbar-ico { transform: scale(0.9); }
.tabbar-ico { transition: transform var(--t-fast) var(--ease-out); }
.tabbar-item:focus-visible { outline: 2px solid var(--focus); outline-offset: -3px; border-radius: var(--r-sm); }

/* ---------- 5. Листы ---------- */
/* Общий механизм всплывающих слоёв на телефоне: карточка выезжает снизу,
   тянется вниз пальцем, закрывается по фону, Esc и свайпу. Так ведут себя
   все слои портала — модалка города, телефон, форма отзыва, карта. */

.sheet {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: flex-end;
}
.sheet[hidden] { display: none; }
.sheet-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(39, 39, 108, 0.45);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  animation: sheet-fade var(--t-med) var(--ease-out) both;
}
.sheet-card {
  position: relative;
  display: flex;
  flex-direction: column;
  width: 100%;
  /* 88dvh, а не vh: на телефоне vh считается от окна без адресной строки,
     и лист вылезал за экран ровно на её высоту. */
  max-height: 88dvh;
  border-radius: var(--sheet-r) var(--sheet-r) 0 0;
  background: var(--surface);
  box-shadow: var(--shadow-lg);
  animation: sheet-up 280ms var(--ease-out) both;
  /* Ставит палец при перетаскивании (mobile.js); тут — исходное значение */
  --drag: 0px;
  transform: translateY(var(--drag));
}
.sheet.is-closing .sheet-card { animation: sheet-down 200ms var(--ease-out) both; }
.sheet.is-closing .sheet-backdrop { animation: sheet-fade 200ms var(--ease-out) reverse both; }
/* Пока палец держит лист, анимации выезда нет — иначе она спорит с перетаскиванием */
.sheet-card.is-dragging { animation: none; transition: none; }
.sheet-card.is-releasing { animation: none; transition: transform var(--t-med) var(--ease-out); }

@keyframes sheet-up { from { transform: translateY(100%); } to { transform: translateY(0); } }
@keyframes sheet-down { from { transform: translateY(0); } to { transform: translateY(100%); } }
@keyframes sheet-fade { from { opacity: 0; } to { opacity: 1; } }

/* Ручка: полоска сверху говорит «меня можно тянуть». Псевдоэлемент, а не
   отдельный узел, — она ничего не значит для скринридера. */
.sheet-head {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  padding: var(--space-xl) var(--space-xl) var(--space-md);
}
.sheet-head::before {
  content: "";
  position: absolute;
  top: 8px;
  left: 50%;
  width: 36px;
  height: 4px;
  margin-left: -18px;
  border-radius: var(--r-pill);
  background: var(--surface-3);
}
.sheet-title { margin: 0; font-size: var(--text-lg); font-weight: 700; }
.sheet-close {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 0;
  border-radius: var(--r-pill);
  background: var(--surface-1);
  color: var(--text-muted);
  cursor: pointer;
}
.sheet-close:active { background: var(--surface-2); }
.sheet-body {
  flex: 1 1 auto;
  padding: 0 var(--space-xl) calc(var(--space-xl) + var(--safe-b));
  overflow-y: auto;
  /* Прокрутка не уходит на страницу под листом: без этого страница уезжает,
     как только список внутри дошёл до конца. */
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
}

/* --- Лист «Ещё»: карта разделов портала --- */
.ms-group + .ms-group { margin-top: var(--space-xl); }
.ms-group-title {
  margin: 0 0 var(--space-sm);
  font-size: var(--text-2xs);
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-subtle);
}
.ms-list { list-style: none; margin: 0; padding: 0; }
.ms-list a {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  min-height: var(--tap);
  padding: var(--space-sm) 0;
  color: var(--text);
  font-size: var(--text-base);
  font-weight: 500;
}
.ms-list li + li a { border-top: 1px solid var(--border); }
.ms-ico { display: flex; flex: none; color: var(--accent); }
.ms-arrow { display: flex; margin-left: auto; flex: none; color: var(--surface-3); }
.ms-list a[aria-current] { color: var(--accent-strong); font-weight: 700; }
.ms-list a[aria-current] .ms-arrow { color: var(--accent-soft); }
/* Смена города — последней строкой листа: это настройка, а не раздел */
.ms-city {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  width: 100%;
  min-height: var(--tap);
  margin-top: var(--space-xl);
  padding: var(--space-md) var(--space-lg);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--surface-1);
  font: inherit;
  font-size: var(--text-sm);
  color: var(--text);
  text-align: left;
  cursor: pointer;
}
.ms-city b { margin-left: auto; color: var(--accent-ink); }
.ms-city svg { flex: none; color: var(--accent); }

/* ---------- 6. Всплывающие слои → нижние листы ---------- */

/* --- Модалка города --- */
.city-modal { align-items: flex-end; padding: 0; }
.city-modal-card {
  max-width: none;
  max-height: 84dvh;
  padding: var(--space-xl) var(--space-lg) calc(var(--space-xl) + var(--safe-b));
  border-radius: var(--sheet-r) var(--sheet-r) 0 0;
  box-shadow: var(--shadow-lg);
  animation: sheet-up 280ms var(--ease-out) both;
}
.city-modal.is-closing .city-modal-card { animation: sheet-down 200ms var(--ease-out) both; }
/* Ручка листа — тем же приёмом, что у .sheet-head */
.city-modal-head {
  position: relative;
  padding-top: var(--space-md);
  margin-bottom: var(--space-md);
}
.city-modal-head::before {
  content: "";
  position: absolute;
  top: -6px;
  left: 50%;
  width: 36px;
  height: 4px;
  margin-left: -18px;
  border-radius: var(--r-pill);
  background: var(--surface-3);
}
/* --- Модалка входа --- */
/* Те же правила, что у модалки города: на телефоне это нижний лист с ручкой,
   закрытием по фону, Esc и свайпу вниз. Селекторы перечислены отдельно, а не
   сведены в общий класс, — общий класс пришлось бы вводить в работающую
   разметку выбора города ради экономии десяти строк. */
.auth-modal { align-items: flex-end; padding: 0; }
.auth-modal-card {
  max-width: none;
  max-height: 88dvh;
  padding: var(--space-xl) var(--space-lg) calc(var(--space-xl) + var(--safe-b));
  border-radius: var(--sheet-r) var(--sheet-r) 0 0;
  box-shadow: var(--shadow-lg);
  animation: sheet-up 280ms var(--ease-out) both;
}
.auth-modal.is-closing .auth-modal-card { animation: sheet-down 200ms var(--ease-out) both; }
.auth-modal-head {
  position: relative;
  padding-top: var(--space-md);
  margin-bottom: var(--space-md);
}
.auth-modal-head::before {
  content: "";
  position: absolute;
  top: -6px;
  left: 50%;
  width: 36px;
  height: 4px;
  margin-left: -18px;
  border-radius: var(--r-pill);
  background: var(--surface-3);
}
/* Кнопки входа — во всю ширину листа и не мельче цели нажатия. */
.auth-provider, .auth-submit { min-height: var(--tap); }

/* Вход из шапки убран: в 54px уже стоят логотип, поиск и город, и шестой
   элемент выталкивал строку за правый край экрана на 360px. Точка входа
   на телефоне — лист «Ещё», там же, где выбор города; правило то же, по
   которому здесь нет бургера. */
.acc-login, .acc { display: none; }

/* Список городов в один столбец: на 390px в двух столбцах строка «Санкт-
   Петербург» ужималась до 13px и всё равно переносилась. В листе места
   по вертикали достаточно — он прокручивается. */
.city-list { grid-template-columns: minmax(0, 1fr); gap: 0; }
.city-list button { min-height: var(--tap); padding: var(--space-md) var(--space-md); font-size: var(--text-base); }
.city-list li + li button { border-top: 1px solid var(--border); }

/* --- Диалоги на <dialog>: телефон, отзыв, карта --- */
/* Одна геометрия на все три: лист снизу во всю ширину. Анимация — через
   @starting-style и allow-discrete, поэтому и открытие, и закрытие плавные
   без единой строки JS; в браузерах без поддержки слой просто появляется. */
dialog.phone-modal,
dialog.review-modal,
dialog.map-modal {
  position: fixed;
  inset: auto 0 0 0;
  width: 100%;
  max-width: none;
  max-height: 90dvh;
  margin: 0;
  border-radius: var(--sheet-r) var(--sheet-r) 0 0;
  transform: translateY(100%);
  transition: transform 280ms var(--ease-out),
              overlay 280ms var(--ease-out) allow-discrete,
              display 280ms var(--ease-out) allow-discrete;
}
dialog.phone-modal[open],
dialog.review-modal[open],
dialog.map-modal[open] { transform: translateY(var(--drag, 0px)); }
@starting-style {
  dialog.phone-modal[open],
  dialog.review-modal[open],
  dialog.map-modal[open] { transform: translateY(100%); }
}
dialog.phone-modal::backdrop,
dialog.review-modal::backdrop,
dialog.map-modal::backdrop {
  opacity: 0;
  transition: opacity 280ms var(--ease-out), overlay 280ms allow-discrete, display 280ms allow-discrete;
}
dialog.phone-modal[open]::backdrop,
dialog.review-modal[open]::backdrop,
dialog.map-modal[open]::backdrop { opacity: 1; }
@starting-style {
  dialog.phone-modal[open]::backdrop,
  dialog.review-modal[open]::backdrop,
  dialog.map-modal[open]::backdrop { opacity: 0; }
}
/* Пока лист тянут пальцем, плавность выключена: она спорит с перетаскиванием
   и лист отстаёт от пальца на длину перехода. */
dialog.phone-modal.is-dragging,
dialog.review-modal.is-dragging,
dialog.map-modal.is-dragging { transition: none; }

/* Ручка листа у диалогов — тем же псевдоэлементом; padding сверху под неё */
dialog.phone-modal { padding-top: var(--space-2xl); }
/* У формы отзыва отступ снят с самого листа и отдан шапке оболочки: padding
   на <dialog> уводил бы закреплённые шапку и низ в общую прокрутку. Место
   под ручку листа добавляется шапке. */
dialog.review-modal { padding-top: 0; }
dialog.review-modal .rf-head { padding-top: var(--space-2xl); }
dialog.phone-modal::before,
dialog.review-modal::before,
dialog.map-modal::before {
  content: "";
  position: absolute;
  top: 8px;
  left: 50%;
  z-index: 3;
  width: 36px;
  height: 4px;
  margin-left: -18px;
  border-radius: var(--r-pill);
  background: var(--surface-3);
}
dialog.map-modal::before { background: rgba(255, 255, 255, 0.9); }
/* Низ листа отбивается безопасной зоной: кнопки не должны попадать под
   полосу жеста, иначе свайп «домой» срабатывает вместо нажатия. */
dialog.phone-modal { padding-bottom: calc(var(--space-2xl) + var(--safe-b)); }
/* Безопасная зона — низу оболочки, а не листу: кнопки не должны попадать
   под полосу жеста, иначе свайп «домой» срабатывает вместо нажатия. */
dialog.review-modal .rf-foot { padding-bottom: calc(var(--space-lg) + var(--safe-b)); }
.map-modal-foot { padding-bottom: calc(var(--space-xl) + var(--safe-b)); }
/* Крестик уезжает ниже ручки листа */
dialog.phone-modal .lightbox-close { top: var(--space-xl); }


/* Карта в листе занимает ровно столько, сколько остаётся под адресом */
.map-modal-canvas { height: min(52dvh, 420px); }

/* Лайтбокс фото — во всю ширину экрана, крестик внутри кадра: снаружи ему
   негде поместиться, когда картинка занимает весь экран. */
.lightbox { max-width: 100vw; max-height: 100dvh; padding: 0; }
.lightbox-img { max-width: 100vw; max-height: 100dvh; border-radius: 0; }
.lightbox .lightbox-close,
.lightbox .lightbox-nav {
  width: var(--tap);
  height: var(--tap);
  justify-content: center;
  /* Снимок занимает экран целиком, и светлая полупрозрачная кнопка на светлом
     кадре пропадает: на телефоне органы управления тёмные. */
  background: rgba(17, 20, 31, 0.55);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.lightbox .lightbox-close {
  top: calc(var(--space-lg) + var(--safe-t));
  right: var(--space-lg);
}
/* Стрелки прижаты к краям: середина экрана остаётся снимку, листают свайпом,
   а кнопки нужны тем, кто о свайпе не догадывается. */
.lightbox .lightbox-nav { margin-top: calc(var(--tap) / -2); }
.lightbox .lightbox-prev { left: var(--space-sm); }
.lightbox .lightbox-next { right: var(--space-sm); }
.lightbox-meta { bottom: calc(var(--space-2xl) + var(--safe-b)); }

/* Пока открыт любой слой, страница под ним не скроллится вовсе. Одного
   overflow: hidden на iOS не хватает — фон уезжает вместе с листом, поэтому
   mobile.js снимает страницу из потока, запомнив положение прокрутки. */
body.is-locked {
  position: fixed;
  left: 0;
  right: 0;
  width: 100%;
  overscroll-behavior: none;
}

/* ---------- 7. Каталог клиник ---------- */

/* Шапка каталога сжимается: заголовок в одну ступень, а подзаголовок
   («Выберите место лечения для питомца в Москве») убран — он пересказывает
   заголовок другими словами и занимал две строки над самым нужным контролом.
   В разметке остаётся: на десктопе это подводка под заголовок по центру. */
.agg-hero { text-align: left; margin-bottom: var(--space-md); }
.agg-h1 { font-size: var(--text-xl); }
.agg-sub { display: none; }
/* Панель распускается: sticky прилипает только в пределах своего родителя,
   и внутри .agg-panel высотой в полторы сотни пикселей полоса инструментов
   отклеивалась сразу за первой карточкой. Через display: contents её
   родителем становится вся колонка выдачи. */
.agg-panel { display: contents; }

/* Полоса инструментов прилипает под шапкой: фильтр, сортировка и счётчик
   нужны в любой точке списка, а не только в его начале.

   Форма и строка счётчика становятся display: contents, поэтому поиск,
   «Фильтры», сортировка, переключатель вида и счётчик встают в одну сетку
   и раскладываются по строкам порядком (order). В разметке они лежат в трёх
   разных родителях — на десктопе это правильная группировка, а на телефоне
   нужна одна панель. Отрицательные боковые поля тянут подложку до краёв
   экрана, содержимое остаётся в контейнере. */
.agg-bar {
  display: flex;
  position: sticky;
  top: var(--sticky-top);
  z-index: 35;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
  margin: 0 calc(-1 * var(--space-lg)) var(--space-md);
  padding: var(--space-xs) var(--space-lg) var(--space-sm);
  background: var(--page);
  /* Хайрлайн отделяет панель от выдачи: подложка панели совпадает с фоном
     страницы, и прилипшая полоса без него сливалась с уезжающим под неё
     списком. */
  border-bottom: 1px solid var(--border);
  transition: top var(--t-med) var(--ease-out);
}
.agg-form, .agg-head, .agg-head-tools { display: contents; }
/* Две строки контролов вместо четырёх блоков:
     поиск ………………… [списком | картой]
     [Фильтры · N] ……………………………… [⇅]
   Три контрола в одну строку на 390px не помещались — «Фильтры» и полное
   название порядка сортировки вместе занимали больше ширины экрана; с тех пор
   сортировка ужалась до значка, но строки остались прежними: поиск с видом
   выдачи наверху, отбор с порядком под ними. */
.agg-search { order: 1; flex: 1 1 200px; }
.agg-search input {
  height: var(--tap);
  /* 16px обязательны: при меньшем кегле Safari на iOS увеличивает страницу
     при фокусе в поле и обратно уже не возвращает. */
  font-size: var(--text-base);
}
.agg-search .search-submit { width: 40px; height: 40px; justify-content: center; }
.agg-view { order: 2; flex: 0 0 auto; }
.agg-filters { order: 3; flex: 0 1 auto; min-width: 0; }
/* Без скрипта набор фасетов разворачивается прямо в панели (лист собирает
   mobile.js). Развёрнутый он шире экрана, и при flex-basis по содержимому
   страница получала горизонтальную прокрутку — отдаём ему строку целиком.
   Со скриптом это состояние недостижимо: <summary> открывает лист. */
.agg-filters[open] { flex: 1 1 100%; }
.agg-filters[open] .agg-filters-body { flex-wrap: wrap; }
/* Значок прижат к правому краю строки с «Фильтрами»: сам он ничего не
   рассказывает, и место в строке принадлежит отбору. */
.agg-sort { order: 4; flex: 0 0 auto; margin-left: auto; }
.agg-count { order: 5; flex: 0 0 100%; }
.agg-filters-toggle,
.agg-view-btn { min-height: 40px; }
/* На телефоне высоту не от кого наследовать — панель выравнивает контролы
   по центру, а не растягивает: задаём тот же квадрат в 40px, что у соседей. */
.agg-sort > summary { width: 40px; height: 40px; }

/* --- Фильтры листом --- */
/* Разворачивать набор фасетов прямо в потоке нельзя: на телефоне он выше
   экрана, и до кнопки «Показать» надо листать сквозь весь список станций.
   Скрипт переносит тело фильтров в лист (mobile.js), поэтому здесь описан
   только вид. Без JS набор по-прежнему разворачивается в потоке — это
   рабочий, хотя и менее удобный, запасной путь. */
body.sheet-open .agg-form { z-index: 101; }
.agg-sheet .sheet-body { padding-bottom: var(--space-md); }
.agg-sheet .agg-filters-body { display: block; }
/* Фасеты в листе — строки-гармошки во всю ширину, а не поповеры: выпадающее
   меню внутри листа открывалось бы поверх собственного заголовка. */
.agg-sheet .agg-selects { display: block; }
.agg-sheet .agg-facet { display: block; border-bottom: 1px solid var(--border); }
.agg-sheet .agg-facet-btn {
  display: flex;
  width: 100%;
  height: auto;
  min-height: var(--tap);
  padding: var(--space-md) 0;
  border: 0;
  border-radius: 0;
  background: none;
  font-size: var(--text-base);
  color: var(--text);
}
.agg-sheet .agg-facet-btn svg { margin-left: auto; }
.agg-sheet .agg-facet-title { flex: 0 1 auto; }
.agg-sheet .agg-facet-menu {
  position: static;
  width: auto;
  min-width: 0;
  max-width: none;
  padding: 0 0 var(--space-md);
  border: 0;
  border-radius: 0;
  box-shadow: none;
}
/* Внутренней прокрутки у списка значений нет: два вложенных скролла на
   телефоне неразличимы пальцем — палец попадает то в список, то в лист.
   Прокручивается лист целиком, длинные списки отсекает поиск над ними. */
.agg-sheet .agg-facet-list { max-height: none; overflow: visible; }
.agg-sheet .agg-facet-opt {
  min-height: var(--tap);
  padding: var(--space-sm) 0;
  /* Флажок крупнее десктопного (20px против 16), поэтому и колонка под него
     шире — иначе название наезжало на квадрат. */
  grid-template-columns: 20px auto minmax(0, 1fr) auto;
}
.agg-sheet .agg-facet-opt:not(:has(.hc-metro-dot)) { grid-template-columns: 20px minmax(0, 1fr) auto; }
.agg-sheet .agg-facet-opt input { width: 20px; height: 20px; }
.agg-sheet .agg-facet-search { height: var(--tap); font-size: var(--text-base); }
/* Кнопка в меню фасета не нужна: в листе есть общая «Показать» внизу */
.agg-sheet .agg-facet-apply { display: none; }
.agg-sheet .agg-check {
  display: flex;
  width: 100%;
  height: auto;
  min-height: var(--tap);
  margin-top: var(--space-md);
  padding: var(--space-md);
  border-style: solid;
  font-size: var(--text-base);
}
.agg-sheet .agg-check input { width: 20px; height: 20px; }
/* «Показать» прилипает ко дну листа: набирают фильтры сверху, а применяют
   отсюда, и тянуться за кнопкой через весь список не нужно. */
.agg-sheet .sheet-foot {
  flex: none;
  padding: var(--space-md) var(--space-xl) calc(var(--space-md) + var(--safe-b));
  border-top: 1px solid var(--border);
  background: var(--surface);
}
.agg-sheet .agg-apply {
  display: inline-flex;
  width: 100%;
  height: auto;
  min-height: 48px;
  font-size: var(--text-base);
}

/* --- Сортировка листом --- */
/* Выпадающее меню жило внутри полосы с горизонтальной прокруткой и обрезалось
   бы её краем. Выносим его к нижнему краю экрана — там же, где палец. */
.agg-sort { position: static; }
.agg-sort[open]::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: 1;
  background: rgba(39, 39, 108, 0.4);
  animation: sheet-fade var(--t-med) var(--ease-out) both;
}
.agg-sort[open] .agg-sort-menu {
  position: fixed;
  inset: auto 0 0 0;
  z-index: 2;
  min-width: 0;
  margin: 0;
  padding: var(--space-2xl) var(--space-lg) calc(var(--space-lg) + var(--safe-b));
  border: 0;
  border-radius: var(--sheet-r) var(--sheet-r) 0 0;
  box-shadow: var(--shadow-lg);
  animation: sheet-up 240ms var(--ease-out) both;
}
/* Ручка листа — та же, что у остальных слоёв */
.agg-sort[open] .agg-sort-menu::before {
  content: "";
  position: absolute;
  top: 8px;
  left: 50%;
  width: 36px;
  height: 4px;
  margin-left: -18px;
  border-radius: var(--r-pill);
  background: var(--surface-3);
}
/* Панель поднимается над шапкой и вкладками: и то и другое лежит выше её
   обычного z-index 35, и лист сортировки уходил под нижнюю панель.
   Селектор на .agg-bar, а не на .agg-form: форма и строка счётчика на телефоне
   display: contents и своего слоя не создают. */
.agg-bar:has(.agg-sort[open]) { z-index: 101; }
/* Панель вкладок уступает место листу — как и любому другому слою */
body:has(.agg-sort[open]) .tabbar { transform: translateY(100%); }
.agg-sort-menu a { display: flex; align-items: center; min-height: var(--tap); font-size: var(--text-base); }
/* В листе заголовок обязателен: значок остался за шторкой, и без строки
   «Сортировка» лист из четырёх ссылок ничем не отличается от листа фильтров. */
.agg-sort-title {
  display: block;
  margin: 0 0 var(--space-sm);
  padding: 0 var(--space-md);
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--text-muted);
}

/* Счётчик и чипы применённых фильтров — одной строкой под панелью */
.agg-head { gap: var(--space-sm); }
.agg-count { font-size: var(--text-sm); }
.agg-active {
  gap: var(--space-xs);
  margin-bottom: var(--space-md);
  padding-bottom: 2px;
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
}
.agg-active::-webkit-scrollbar { display: none; }
.agg-chip { flex: 0 0 auto; min-height: 34px; }

/* --- Карточка клиники: строка справочника вместо стопки блоков --- */
/* Было: фото 190px, ссылка «оставить отзыв», название, плашки, описание в две
   строки, «подробнее», факты и кнопка — 880px высоты на карточку, двадцать
   карточек давали 17 тысяч пикселей прокрутки. Стало: снимок 84px и суть
   рядом с ним, факты и кнопка ниже. Описание и «подробнее» убраны — на
   телефоне в карточку выдачи не читают, по ней выбирают. */
.hc {
  grid-template-columns: 84px minmax(0, 1fr);
  grid-template-areas:
    "media info"
    "side  side";
  gap: var(--space-md);
  padding: var(--space-lg);
  border-radius: var(--r-md);
}
.hc-media { grid-area: media; align-items: stretch; gap: var(--space-sm); }
.hc-info { grid-area: info; gap: var(--space-xs); min-width: 0; }
/* Столбик, а не переносящийся ряд: правило main.css для 720px раскладывало
   факты в строку со space-between, и часы работы вставали по центру карточки
   в отрыве от колонки значков. */
.hc-side {
  grid-area: side;
  flex-direction: column;
  align-items: stretch;
  justify-content: flex-start;
  text-align: left;
  gap: var(--space-sm);
  padding-top: var(--space-md);
}
.hc-media img, .hc-media-stub { width: 84px; height: 84px; border-radius: var(--r-sm); }
/* Оценка встаёт под снимком в его ширину: плашка «поверх нижнего края»
   рассчитана на снимок 190px и на 84px закрывала его целиком. */
.hc-rate {
  margin: 0;
  padding: 4px 6px;
  justify-content: center;
  gap: var(--space-xs);
  font-size: var(--text-xs);
  box-shadow: none;
}
.hc-rate-cnt svg { display: none; }
/* Ссылка «оставить отзыв» из карточки выдачи убрана: отзыв пишут со страницы
   клиники, а в списке она отнимала строку у названия. */
.hc-review, .hc-desc, .hc-more { display: none; }
.hc-name { font-size: var(--text-lg); }
.hc-badges { gap: var(--space-xs); }
.hc-badge { font-size: var(--text-2xs); padding: 3px 8px; }
.hc-fact { font-size: var(--text-sm); }
/* Кнопка звонка во всю ширину карточки — главное действие выдачи */
.hc-cta {
  width: 100%;
  min-height: var(--tap);
  margin-top: var(--space-xs);
}

/* Карта каталога во весь экран под панелью: половинчатая полоса в 320px
   на телефоне не карта, а картинка. */
.catalog-map {
  height: calc(100dvh - var(--header-h) - var(--tabbar-total) - 90px);
  min-height: 320px;
}

/* Пагинация — крупные цели: стрелка 38px промахивалась мимо пальца */
.pager-arrow { width: var(--tap); height: var(--tap); }

/* ---------- 9. Страница клиники и врача ---------- */

/* Полотно с фото — карусель с прилипанием кадра: раньше на телефоне
   показывался один снимок, остальные открывались только через счётчик. */
.cl-cover {
  display: flex;
  gap: 2px;
  height: 220px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.cl-cover::-webkit-scrollbar { display: none; }
.cl-cover-cell {
  flex: 0 0 100%;
  scroll-snap-align: start;
}
/* Следующий кадр выглядывает из-за правого края: без этого полоса выглядит
   как одна неподвижная картинка и листать её никто не пробует. Полоски
   прокрутки на телефоне нет, а подсказать надо. У единственного кадра
   выглядывать нечему — там снимок во всю ширину. */
.cl-cover:not(.cl-cover-one) .cl-cover-cell { flex: 0 0 92%; }
/* Правило из main.css прячет все кадры кроме первого на узком экране —
   в карусели они снова нужны. */
.cl-cover-cell:not(:first-child) { display: block; }
.cl-cover-all {
  bottom: calc(var(--cl-card-overlap) + var(--space-md));
  min-height: 40px;
  padding: var(--space-sm) var(--space-lg);
}

.cl-card { border-radius: var(--r-md) var(--r-md) 0 0; }
/* Строка разделов: прилипает под шапкой, тянется от края до края, активная
   вкладка сама подъезжает к середине (скрипт страницы клиники). */
.anchor-nav {
  top: var(--sticky-top);
  transition: top var(--t-med) var(--ease-out);
}
/* Прокрутка и её инерция принадлежат контейнеру вкладок: панель целиком
   больше не скроллер. */
.anchor-nav__tabs {
  gap: var(--space-lg);
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
}
.anchor-nav__tabs a {
  scroll-snap-align: center;
  padding-block: var(--space-md);
  /* Последний пункт упирался в правый край контейнера и выглядел обрезанным
     даже когда прокрутка была до конца. */
  min-height: var(--tap);
  display: inline-flex;
  align-items: center;
}
.anchor-nav__tabs a + a { margin-left: 0; }
/* Телефона в строке разделов на телефоне нет: там за него отвечает нижняя
   липкая панель, и два одинаковых действия появлялись бы одновременно. */
.cl-nav-phone { display: none; }

/* Липкая панель действий встаёт на место панели вкладок, а не над ней */
.cl-sticky-cta {
  z-index: 61;
  padding-bottom: calc(var(--space-md) + var(--safe-b));
}
.cl-sticky-cta .btn { min-height: var(--tap); }
/* Место под панель отбито подвалом — своё правило main.css здесь лишнее */
body:has(.cl-sticky-cta) { padding-bottom: 0; }

/* Кнопки в шапке карточки — в тач-размер и во всю ширину строки */
.cl-actions .btn { min-height: var(--tap); }
.cl-section { border-radius: var(--r-md); }

/* Прайс: цена не должна прижиматься к названию — на узкой строке между ними
   оставалось четыре пикселя. */
.sv-item { gap: var(--space-lg); }
.sv-group-head { min-height: var(--tap); }
.sv-search input { font-size: var(--text-base); }

/* Ссылки внутри строк фактов (станции метро, название клиники в карточке
   выдачи) — цели в 18–25px по высоте. Вертикальный паддинг у строчного
   элемента не меняет высоту строки, но увеличивает зону нажатия: палец
   перестаёт промахиваться мимо станции в плотной колонке. */
.hc-metro-link,
.metro-tag a,
.hc-name a,
/* Тот же приём для текстовых ссылок в сайдбарах, подписях и «все →»:
   в потоке они высотой в строку (17–23px) и мимо них промахиваешься.
   Вертикальный паддинг у строчного элемента не меняет высоту строки —
   ритм текста остаётся прежним, растёт только зона нажатия. */
.section-link,
.side-box li a,
.contact-list a,
.dr-peers li a,
.dr-peers-all,
.dr-help-link,
.eeat .person a,
.hc-more,
.cl-facts a,
.town-link,
.metro-near-list a { padding-block: 8px; }
.crumbs a { padding-block: 10px; }
.search-clear { width: 40px; height: 40px; }
.logo { min-height: var(--tap); }

/* Отзывы: имя и дата строкой, фото отзыва — лентой с прокруткой */
.rv-photos { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
.rv-photos::-webkit-scrollbar { display: none; }
.rv-photo { flex: 0 0 auto; }
.rv-sort {
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  margin-inline: calc(-1 * var(--space-lg));
  padding-inline: var(--space-lg);
}
.rv-sort::-webkit-scrollbar { display: none; }
.rv-sort .chip { flex: 0 0 auto; min-height: 40px; }

/* Форма отзыва: поля в тач-размер и без увеличения страницы при фокусе */
.review-form input[type="text"],
.review-form textarea { font-size: var(--text-base); min-height: var(--tap); }
.review-form textarea { min-height: 96px; }
/* Звёзды-радио: 2px паддинга давали цель 20×20 — промах через раз */
.rating-input label { padding: 7px 5px; }

/* ---------- 10. Контентные страницы, подвал, мелочи ---------- */

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

   Поле листа ужато: 40px по кругу на 360px экрана оставляют тексту 260 —
   при кегле 18 это 26 знаков в строке, и абзац читается лесенкой. С полем
   в 16px строка вырастает до 34 знаков — нижняя граница читаемой. Обложка
   следует за полем сама, она считается от --art-pad. */
.art-sheet {
  --art-pad: var(--space-lg);
  padding: var(--space-2xl) var(--art-pad) var(--space-3xl);
  border-radius: var(--r-md);
}
/* Кегль текста на телефоне — интерфейсные 16px, а не 18: в колонке шириной
   328px восемнадцатый даёт 28 знаков в строке, и абзац читается лесенкой
   из пяти слов. На шестнадцатом строка вырастает до 36 знаков — это уже
   нормальное чтение. */
.art-body, .art-lede { font-size: var(--text-base); }
.art-body .callout { font-size: var(--text-base); }
/* Врезка добавляет к полю листа своё: вместе они съедали у текста ещё
   сорок пикселей, и внутри неё строка была короче остальных на четверть. */
.art-body .callout { padding: var(--space-lg); }
.art-head { text-align: left; padding-bottom: var(--space-xl); }
/* Заголовок и автор по левому краю: центрированный заголовок в четыре
   строки на 360px читается как объявление, а не как статья. */
.art-by { justify-content: flex-start; }
/* Рубрика в надзаголовке — ссылка высотой в пятнадцать пикселей: отбиваем
   полем, как крошки и ссылки подвала. */
.art-kicker a { display: inline-block; padding-block: 8px; }
/* Обложка во всю ширину листа и в его поля: на 360px кадр 16:9 и так
   всего 180px высотой, сужать его дальше нечем. */
.art-cover {
  margin: 0 calc(var(--art-pad) * -1) var(--space-2xl);
}
.art-cover img { border-radius: 0; }
.art-cover figcaption { padding-inline: var(--art-pad); }
/* Оглавление в одну колонку: две по 130px рвут названия разделов пополам. */
.art-toc-list { columns: 1; }
/* Тач-цель набирается полем, а не min-height с центрированием: у пункта
   в две строки центрированный номер съезжал ко второй. baseline ставит
   его вровень с первой строкой названия. */
.art-toc-list a { padding-block: 11px; align-items: baseline; }
/* Полоса действия в столбик: кнопка во всю ширину — она тач-цель, а не
   подпись. */
.art-cta { display: grid; }
.art-cta-btn { justify-content: center; }

/* Строка симптома в одну колонку: правая колонка «когда срочно» на 360px
   ужалась бы до пяти знаков в строке. Признаки уходят под пояснение и
   отбиваются от него полем — порядок чтения тот же, что на широком экране. */
.sy-row {
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-md);
  padding-inline: var(--space-sm);
}
/* Обе строки держат читаемую длину: в одной колонке на 768px они иначе
   растягиваются на 90 знаков — глаз теряет начало следующей строки. */
.sy-tldr, .sy-urgent { max-width: 62ch; }
/* Соседние статьи — по одной в ряд: карточка с обложкой в половину
   трёхсотпиксельного экрана превращается в марку. */
.art-more { margin-top: var(--space-3xl); }
.art-more-grid { grid-template-columns: minmax(0, 1fr); }

/* Крошки — одной строкой с прокруткой: на телефоне цепочка из четырёх звеньев
   занимала три строки над заголовком. */
.crumbs {
  flex-wrap: nowrap;
  overflow-x: auto;
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 2px;
}
.crumbs::-webkit-scrollbar { display: none; }
.crumbs > * { flex: 0 0 auto; }
.crumbs a { padding-block: 6px; }

/* Строка поиска на главной не прилипает. Причин две.

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

   Вторая важнее: постоянный вход в поиск на телефоне уже есть — лупа в шапке,
   а шапка возвращается от любого движения вверх. Две строки поиска на экране
   разом — это не «удобнее», это просто минус 60px высоты на каждом из пяти
   экранов главной. На десктопе липкость остаётся: там шапка не уезжает и
   свободной высоты больше. */
.home-search { position: static; }
/* Класс вешает sticky-search.js независимо от раскладки; в отстыкованном
   состоянии его сжатие пилюли не нужно — гасим все его следы. */
.home-search.is-stuck .search-form {
  max-width: 100%;
  padding: 7px;
  box-shadow: var(--shadow-md);
}
.home-search.is-stuck .search-form input { padding: 10px 4px 10px 16px; font-size: var(--text-base); }
.home-search.is-stuck .search-form .search-submit { width: 44px; height: 44px; }
.search-form input { font-size: var(--text-base); }
.suggest { max-height: min(58dvh, 420px); }
.suggest-item { min-height: var(--tap); }

/* Ссылки в подвале — тач-цели: 21px по высоте, вплотную друг к другу */
.footer li a, .footer-bottom-links a {
  display: inline-block;
  padding-block: 6px;
}

/* Подвал сворачивается в гармошку. Четыре списка по семь ссылок занимали
   на телефоне два экрана из пяти с половиной — 37% высоты главной, — а те же
   разделы уже лежат в панели вкладок и в листе «Ещё». Здесь подвал остаётся
   полным (он нужен и поисковикам, и тем, кто ищет юридическое), но не
   загораживает собой конец страницы. */
/* Зазор сетки между колонками обнуляем: у свёрнутой гармошки 32px между
   строками выглядели так, будто содержимое не свернулось, а просто исчезло.
   Колонки теперь разделяет хайрлайн, а не воздух. */
.footer-grid { gap: 0; }
.footer-brand { margin-bottom: var(--space-2xl); }
.footer-legal { margin-top: var(--space-2xl); }
.footer-col { border-top: 1px solid rgba(255, 255, 255, 0.12); }
.footer-col:first-of-type { border-top: 0; }
.footer-col-head {
  justify-content: space-between;
  min-height: var(--tap);
  padding-block: var(--space-sm);
  cursor: pointer;
}
.footer-col-head h4 { margin: 0; }
.footer-col-head svg {
  display: block;
  flex: none;
  color: #9b96cc;
  transition: transform var(--t-fast) var(--ease-out);
}
.footer-col[open] .footer-col-head svg { transform: rotate(180deg); }
.footer-col-head:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }
.footer-col > ul { padding-bottom: var(--space-md); }
@media (prefers-reduced-motion: reduce) { .footer-col-head svg { transition: none; } }
.footer { margin-top: var(--space-5xl); padding-top: var(--space-4xl); }

/* Таблицы контентных страниц прокручиваются внутри своей рамки, а не тянут
   страницу вбок; тень у края говорит, что справа есть ещё колонки. */
.table-wrap {
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}

/* Плитка секции: 20px полей на 360px съедали девятую часть строки */
.side-box { padding: var(--space-lg); border-radius: var(--r-md); }
.card { padding: var(--space-lg); border-radius: var(--r-md); }
.hero { border-radius: var(--r-lg); }
.stub-hero { border-radius: var(--r-lg); }

.section { margin: var(--space-4xl) 0; }
.section-head { gap: var(--space-sm); }

/* --- Главная: первый экран --- */
/* Было 362px до первой плитки — 43% экрана на шапку, поиск и центрированный
   заголовок с подзаголовком. Текст по левому краю, а не по центру: три
   центрированные строки читаются хуже и это ровно тот «hero по центру»,
   который бан-лист системы называет признаком шаблона. */
.intro { margin-top: var(--space-2xl); text-align: left; }
.intro-head { margin-bottom: var(--space-xl); }
/* Перечисление разделов повторяет плитки под ним — на телефоне снимаем */
.intro-sub { display: none; }
.popular { margin: var(--space-4xl) 0; }
.popular-head { text-align: left; margin-bottom: var(--space-lg); }

/* --- Главная: свежие статьи --- */
.fresh { margin: var(--space-4xl) 0; }
.fresh-head { margin-bottom: var(--space-lg); }
/* Полоса остаётся полосой, меняется только сколько карточек в кадре:
   на планшете две, на телефоне одна с выглядывающей соседкой. Стрелки
   скрипт всё равно рисует, но пальцем листать привычнее — и попасть
   в 38px кнопку на ходу труднее, чем смахнуть. */
.fresh-list { --fresh-gap: var(--space-lg); --fresh-peek: 44px; }
.fresh-list > li { flex-basis: calc((100% - var(--fresh-gap) - var(--fresh-peek)) / 2); }
.fresh-tools { display: none; }
/* Выжимка на телефоне короче: карточка идёт во всю ширину, и три строки
   лида ниже заголовка превращают ленту из трёх статей в полтора экрана. */
.fresh-lead { -webkit-line-clamp: 2; }
.fresh-foot { margin-top: var(--space-lg); }

/* --- Главная: выход в каталог картой --- */
.citymap { margin: var(--space-4xl) 0; }
.citymap-head { margin-bottom: var(--space-lg); }
/* Полоса 2.5:1 на 360px — это 144px высоты: кнопка занимает её почти целиком
   и карты под ней не остаётся. Кадрируем в 3:2 (object-fit уже стоит). */
.citymap-bg { aspect-ratio: 3 / 2; max-height: 260px; }
.citymap-plate { border-radius: var(--r-md); }
/* Метки мельче: на узкой плите десяток тридцатипиксельных капель
   перекрывал сам рисунок карты. Остаются шесть, и все — выше или ниже
   полосы кнопки: на 360px кнопка занимает три четверти ширины плиты,
   и метки под ней выглядывали половинками из-под края. */
.citymap-pin { width: 26px; height: 26px; margin: -26px 0 0 -13px; }
.citymap-pin::after { top: 23px; height: 7px; }
.citymap-pin:nth-child(n + 7) { display: none; }
.citymap-pin:nth-child(1) { left: 12%; top: 24%; }
.citymap-pin:nth-child(2) { left: 38%; top: 16%; }
.citymap-pin:nth-child(3) { left: 66%; top: 26%; }
.citymap-pin:nth-child(4) { left: 22%; top: 84%; }
.citymap-pin:nth-child(5) { left: 55%; top: 76%; }
.citymap-pin:nth-child(6) { left: 86%; top: 86%; }

} /* /max-width: 880px */

/* ---------- Телефон: лист статьи во всю ширину экрана ---------- */
@media (max-width: 560px) {
  /* Поля контейнера вокруг статьи съедали сорок пикселей из трёхсот
     шестидесяти — восемь процентов ширины экрана уходило на воздух, которого
     на телефоне нет, а строка теряла четыре знака. Лист выходит в поля
     и становится самой страницей; скругление и боковые рамки там не нужны —
     их не на чем показать. */
  /* Поля берутся ТЕМ ЖЕ выражением, что у .container выше: там они считаются
     с безопасными зонами iPhone, и вычитание фиксированных 20px давало
     страницу шире экрана на четыре пикселя — горизонтальную прокрутку. */
  .art-sheet {
    margin-left: calc(max(var(--space-lg), var(--safe-l)) * -1);
    margin-right: calc(max(var(--space-lg), var(--safe-r)) * -1);
    border-inline: 0;
    border-radius: 0;
  }
}

/* ---------- Телефон: строка авторства в столбик ---------- */
@media (max-width: 560px) {
  /* «Елена Ветрова · Ветеринарный врач, терапевт · Обновлено 2 июля 2026» —
     это 66 знаков, на 360px они переносятся, и точка-разделитель оказывается
     первым знаком новой строки. Поэтому строка распадается в столбик,
     а разделители гаснут. */
  .art-by {
    display: grid;
    justify-items: start;
    gap: 2px;
  }
  .art-by-sep { display: none; }
  .art-by-person { margin-bottom: var(--space-2xs); }
}

/* ---------- Телефон: подписи, на которые не хватает ширины ---------- */
@media (max-width: 560px) {
  /* Переключатель вида — одни значки: «Списком» и «На карте» рядом с полем
     поиска занимали 160px из 358 доступных. Смысл кнопок остаётся в
     aria-label и в подсветке активной. */
  .agg-view-label { display: none; }
  .agg-view-btn { padding: var(--space-sm) var(--space-md); }
}

/* ---------- Большой телефон и планшет ---------- */
@media (min-width: 561px) and (max-width: 880px) {
  /* Снимок 84px рассчитан на 390px ширины; на 768 рядом с ним оставалось
     полстроки пустоты, и карточка выглядела недоделанной. */
  .hc { grid-template-columns: 140px minmax(0, 1fr); gap: var(--space-lg); }
  .hc-media img, .hc-media-stub { width: 140px; height: 140px; }
}

/* ---------- Телефон: карта в шапке карточки ---------- */
@media (max-width: 560px) {
  /* Правило main.css для 700px растягивает превью карты на ширину карточки
     плюс два поля --space-xl (20px), но ниже 560px у карточки поля --space-lg
     (16px) — карта уходила за край на 4px с каждой стороны, обрезалась
     overflow: hidden и не доставала до правого края. */
  .cl-card .cl-card-map {
    width: calc(100% + var(--space-lg) * 2);
    margin: var(--space-lg) calc(var(--space-lg) * -1) calc(var(--space-lg) * -1);
  }
}

/* ---------- Узкий телефон ---------- */
@media (max-width: 400px) {
  /* На 360px пять вкладок с подписями «Здоровье» и «Клиники» встают впритык:
     подписи мельче, значки те же. */
  .tabbar-item { font-size: 10px; padding-inline: 2px; }
  .agg-h1 { font-size: var(--text-lg); }
  .hc { grid-template-columns: 84px minmax(0, 1fr); }
  .hc-media img, .hc-media-stub { width: 84px; height: 84px; }


/* ---------- Форма отзыва: оболочка на телефоне ---------- */
/* Поля уже: на 360px тридцать два пикселя с каждой стороны съедали строку
   звёзд и заставляли её переноситься. */
/* Шапка занимала 169px из 576 на телефоне 360×640 — почти треть окна.
   Убрано лишнее: название в одну строку, обещание про модерацию снято
   (то же самое человек прочитает в ответе после отправки), место под
   ручку листа ужато до нужного. */
dialog.review-modal .rf-head {
  padding: var(--space-lg) 52px var(--space-sm) var(--space-lg);
}
dialog.review-modal .rf-title { -webkit-line-clamp: 1; font-size: var(--text-base); }
/* Подпись «Опубликуем после проверки модератором» остаётся и на телефоне:
   без неё ожидание модерации становится сюрпризом уже после отправки, а
   строка занимает ровно одну строку под заголовком. Скрывали её ради
   высоты — но высоту забирает не она, а вкладки с полями. */
dialog.review-modal .rf-note {
  margin-top: 2px;
  font-size: var(--text-xs);
  line-height: var(--leading-snug);
}
dialog.review-modal .rf-close { top: var(--space-md); right: var(--space-md); }

/* Строки критериев были по 65px: подпись и звёзды выстраивались в колонку,
   потому что в 328px они не расходились по краям. Кладём их в одну строку
   принудительно — пять строк это 180px вместо 326. */
dialog.review-modal .rv-crit-input { gap: 2px; grid-template-columns: 1fr; }
dialog.review-modal .rv-crit-row { flex-wrap: nowrap; gap: var(--space-sm); }
dialog.review-modal .rv-crit-label { flex: 1; min-width: 0; }

/* Плюсы и минусы на телефоне в столбик, но низкими полями: рядом они дают
   по 150px ширины на поле — писать в такое нельзя. А вот «с кем» и «повод»
   рядом остаются: это короткие списки, и в столбик они добавляли панели
   восемьдесят лишних пикселей. */
dialog.review-modal .rf-two-text { grid-template-columns: 1fr; gap: var(--space-sm); }
/* height, а не min-height: высоту textarea задаёт атрибут rows=3, и
   минимум её не уменьшает. Три строки на каждое из двух необязательных
   полей — это 220px из четырёхсот, которые есть у панели. */
dialog.review-modal .rf-two-text textarea { height: 56px; min-height: 56px; }
dialog.review-modal .rf-pane { padding: var(--space-md) var(--space-lg); }
dialog.review-modal .rf-foot { padding-left: var(--space-lg); padding-right: var(--space-lg); }
/* Полоса шагов вместо вкладок. Показывается только здесь: на широком
   экране шагов нет, все панели стоят одной колонкой. */
dialog.review-modal .rf-prog { display: flex; }

/* Пошаговый режим: на экране ровно одна панель, и она занимает всё,
   что осталось от шапки и подвала. Отсюда и главный выигрыш — поле
   получает высоту, а не три строки из четырёхсот пикселей. */
dialog.review-modal .rf-panes { flex-direction: row; overflow: hidden; }
dialog.review-modal .rf-pane { flex: 1; overflow-y: auto; }
dialog.review-modal .rf-pane + .rf-pane { padding-top: var(--space-md); }
dialog.review-modal .rf-text { flex: 1; display: flex; flex-direction: column; min-height: 0; }
dialog.review-modal .rf-text textarea { flex: 1; min-height: 120px; }
dialog.review-modal .rf-second textarea { min-height: 96px; }

/* Кнопки шагов: «Назад» узкой, действие — широкой. */
dialog.review-modal .rf-back { flex: 0 0 auto; }
dialog.review-modal .rf-next,
dialog.review-modal .rf-skip,
dialog.review-modal .rf-submit { flex: 1; }
/* Атрибут hidden проигрывает собственному display — правило на класс
   обязательно, иначе скрытые кнопки продолжают занимать место в ряду
   и выталкивают соседей за край. Та же ловушка, что с .rf-sign-line. */
dialog.review-modal .rf-actions button[hidden] { display: none; }

/* На телефоне колонок нет — панели снова идут шагами, по одной на экран. */
dialog.review-modal .rf-panes { display: flex; flex-direction: row; overflow: hidden; }
dialog.review-modal .rf-pane { grid-column: auto; grid-row: auto; border-left: 0; }
dialog.review-modal .rf-cons-block .rf-second textarea { min-height: 76px; }

/* Шаг с необязательным собирает четыре блока: поле, метки, область
   загрузки и два списка. На 360×780 они складываются в 480px при
   доступных 440 — ужимаем каждый понемногу, вместо того чтобы прятать
   что-то целиком. */
dialog.review-modal .rf-drop { padding: var(--space-sm); gap: 0; }
dialog.review-modal .rf-drop-icon svg { width: 18px; height: 18px; }
dialog.review-modal .rf-drop-note { font-size: 11px; line-height: 1.3; }
dialog.review-modal .rf-two-pick { gap: var(--space-sm); margin-top: var(--space-sm); }
dialog.review-modal .rf-two-pick label { font-size: var(--text-xs); margin-bottom: 2px; }
dialog.review-modal .rf-two-pick select { min-height: 38px; }

/* ---------- Форма отзыва: плотность на маленьком телефоне ---------- */
/* На 360×640 у панели остаётся 414px, а вкладке «Фото и детали» нужно
   почти пятьсот. Добираем тремя способами, ни один из которых не режет
   содержание: плотнее поля, теснее панель, выше лист. */
dialog.review-modal .rf-pane { padding: var(--space-sm) var(--space-lg); }
/* Шаг с необязательным — самый плотный из четырёх: подрезаем ему поля
   ещё на четыре пикселя сверху и снизу, этого хватает, чтобы блоки
   уместились без прокрутки на 360×780. */
dialog.review-modal .rf-pane[data-pane="bad"] { padding-top: var(--space-xs); padding-bottom: var(--space-xs); }
dialog.review-modal .rf-pane .field { margin-bottom: var(--space-sm); }
/* Подпись «отметьте, если было» над метками на телефоне снимается: место
   дороже, а сами метки говорят за себя. */
dialog.review-modal .rf-chips-cap { display: none; }
dialog.review-modal .rf-chips { gap: var(--space-xs); }
dialog.review-modal .rf-chip span { padding: 0 var(--space-sm); }
dialog.review-modal .rf-chip span { min-height: 34px; font-size: var(--text-xs); }

/* Подсказка «выберите оценку» рядом со звёздами на 360px не помещалась
   в строку и делала блок оценки двухэтажным. Раньше её здесь убирали
   совсем — но тогда обязательность оценки не сообщена нигде, и человек
   узнаёт о ней только по отказу отправить. Оставляем короткое слово:
   пять звёзд по 32px плюс «обязательно» мелким кеглем в строку влезают,
   а выбранная оценка это слово всё равно заменяет. */
dialog.review-modal .rf-rate-word { min-width: 0; }
dialog.review-modal .rf-rate-word:empty::after {
  content: "обязательно";
  font-size: var(--text-xs);
}

@media (max-height: 700px) {
  /* Короткий экран: полоска фона над листом всё равно ничего не показывает,
     а высота решает, поместится ли панель без прокрутки. */
  dialog.review-modal { max-height: 96dvh; }
}
}

/* ---------- Телефон в альбомной ориентации ---------- */
@media (max-width: 880px) and (orientation: landscape) and (max-height: 520px) {
  /* Экран в 380px высотой: панель вкладок и шапка вместе съедали бы четверть.
     Панель остаётся (это навигация), шапка уезжает и не возвращается до
     прокрутки вверх — правило то же, что в портрете, но лист ниже. */
  .sheet-card, .city-modal-card, .auth-modal-card { max-height: 92dvh; }
  dialog.phone-modal, dialog.review-modal, dialog.map-modal { max-height: 94dvh; }
  .map-modal-canvas { height: 46dvh; }
  .cl-cover { height: 160px; }
}

/* ---------- Уважение к настройке «меньше движения» ---------- */
@media (prefers-reduced-motion: reduce) {
  .header, .tabbar, .anchor-nav, .cl-nav-phone, .agg-form, .home-search { transition: none; }
  .sheet-card, .sheet-backdrop,
  .city-modal-card, .auth-modal-card,
  dialog.phone-modal, dialog.review-modal, dialog.map-modal { animation: none; transition: none; }
}

/* ---------- Правила списком: на телефоне в одну колонку ---------- */
@media (max-width: 700px) {
  /* 15rem под термин на 360px не оставляют объяснению ничего:
     складываем в колонку, зазор между термином и текстом меньше. */
  .rules-row { grid-template-columns: minmax(0, 1fr); gap: var(--space-xs); }
  /* Свежие статьи: на 390px карточка в полширины оставляет заголовку
     четыре слова в строку, и кламп обрывает его на середине названия.
     Одна карточка в кадре, соседка выглядывает — по ней и видно, что
     полосу листают. */
  .fresh-list > li { flex-basis: 86%; }
}

/* ---------- Карточка врача на телефоне ---------- */
/* Ниже 880px средняя колонка это ~250px, и строка «где принимает» флексом
   в ряд рвала названия клиник по слогам («Первый ветеринар. центр» в три
   строки), а высота карточки гуляла двенадцатью вариантами на двадцати
   карточках — список в таком виде не просматривают.

   Раскладка фиксированной высоты: имя максимум в две строки, дальше по
   одной строке на «кто», клинику и метро, каждая с многоточием. Стало три
   высоты вместо двенадцати, список 4647px вместо 5996. Что не поместилось,
   человек видит в профиле — на выдаче важнее ровный ритм. */
@media (max-width: 880px) {
  .hc-doc {
    grid-template-columns: 84px minmax(0, 1fr);
    grid-template-areas:
      "media info"
      "side  side";
    gap: var(--space-md);
    align-items: start;
    padding: var(--space-lg);
  }
  .hc-doc .hc-media-doc { grid-area: media; }
  .hc-doc .hc-info { grid-area: info; min-width: 0; gap: 4px; }
  .hc-doc .hc-side { grid-area: side; }
  .hc-doc .hc-media-doc img { width: 84px; height: 84px; }

  .hc-doc .hc-name {
    font-size: var(--text-base);
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
  /* Должность снимается: она длинная, а строки на телефоне дороже.
     Специализация и стаж отвечают на тот же вопрос короче. */
  .hc-doc-role { display: none; }
  /* «Кто это» остаётся в 14px: на десктопе строка выросла вместе с карточкой,
     а на телефоне лишние два пункта отнимают у специализации со стажем
     пару слов до многоточия. */
  .hc-doc-who { font-size: var(--text-sm); flex-wrap: nowrap; overflow: hidden; }

  .hc-doc-where {
    flex-direction: column;
    align-items: flex-start;
    gap: 2px;
  }
  .hc-doc-at,
  .hc-doc-where .hc-metro {
    max-width: 100%;
    min-width: 0;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .hc-doc-at { display: flex; }
  .hc-doc-at a { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  /* Время пешком снимается: на 390px оно вытесняло название второй станции,
     а станция для выбора важнее минут. */
  .hc-doc-where .hc-metro-min { display: none; }
  .hc-doc-call { width: 100%; margin-top: var(--space-md); }
}
