/* ============================================================
   PddPro — листинг /schools/

   Источник — design2/assets/css/listing.css и раздел «Листинг
   и карточка листинга» design2/assets/css/main.css (строки
   874–1360). Значения перенесены как есть: токены --space-*,
   --radius-*, --color-*, --shadow-* уже лежат в tokens.css,
   поэтому переносятся только правила — и с заменой селекторов
   под ту разметку, которую печатает Messia_Listing_Tmpl_Pdd.

   Почему имена блоков не совпадают с прототипом один в один.
   Прототип зовёт карточку .card, строку — .card__row, услугу —
   .service. Всё это короткие общие имена, и во frontend.css
   (22 064 строки) с skin.css они уже заняты под другое. Поэтому
   у своих блоков приставка pdd- — ровно та же договорённость,
   что и на карточке школы (school.css). Классы движка, которые
   остались на месте (.card-item-ver-3, .list-item-v3,
   .working-hours-status, .rating, .buttons-new, .favorite),
   не переименованы намеренно: по ним ходит рабочий код движка,
   и наш CSS цепляется за них же.

   Почему карточка зовётся pdd-listing-card, а не pdd-card.
   Имя .pdd-card уже занято карточкой школы: school.css объявляет
   body.pdd .pdd-card { display: flex } и ещё 55 правил-потомков
   (.pdd-card .working-hours-status, .pdd-card .the_content,
   .pdd-card .category_tags и прочие). Специфичность у нас с ними
   одинаковая — (0,2,1), — а school.css подключается ПОСЛЕ
   listing.css (порядок ручек в functions.php), поэтому при
   совпадении имени выигрывал бы он: карточка листинга получала
   display:flex вместо grid и попутно тянула на себя оформление
   секций карточки школы. Проверено на живой странице: до
   переименования .pdd-card на листинге считался flex.
   Разъезжаться специфичностью здесь неправильно — правила
   соседнего потока не должны попадать на наши узлы вовсе,
   поэтому у листинга своё имя блока.

   Специфичность: всё от body.pdd, это (0,2,0) и выше. Самое
   тяжёлое чужое правило на этой странице —
   .page-template-newlisting .buttons-new button:not(.favorite)
   в skin.css, (0,3,1); под него заведён отдельный селектор
   с body.pdd.page-template-newlisting.

   Специфичностью обходится всё, кроме пяти элементов, которым
   движок задаёт размеры через !important, — они собраны в разделе 19
   в конце файла, вместе с дословным списком чужих правил. Больше
   !important в файле нет.
   ============================================================ */

/* ------------------------------------------------------------
   1. ПЕРЕМЕННЫЕ СТРАНИЦЫ

   Прототип держит их на .listing (обёртке списка). У нас той
   обёртки нет — движок печатает свой каркас, — поэтому они
   висят на карточке и на контейнере списка.
   ------------------------------------------------------------ */
body.pdd.page-template-newlisting {
	--card-inset: var(--space-6);

	/* Подмены базовых токенов — ровно те же, что прототип держит
	   на .listing (design2/assets/css/listing.css:13–58). Сверено
	   замером 14.08.2026: без них карточка выходила r12 без тени,
	   заголовок 15px вместо 18, строки 12px вместо 13, шаг ленты
	   8px вместо 12. */
	--grid-padding: var(--space-4);
	--grid-gap: var(--space-6);

	--radius-xl: 16px;
	--shadow-card: 0 1px 3px rgba(16, 18, 27, 0.07);

	--font-size-card-title: 18px;
	--font-size-caption: 13px;
	--font-size-price: 19px;
	--font-size-micro: 12px;

	/* --radius-xl выше стал 16px — скругление кадра держим прежним */
	--media-radius: 12px;

	/* Фото у карточки обычно одно.

	   В прототипе на его месте полоса из двух кадров 4:3 и краешка
	   третьего, но галерея crb_thumbnail_gallery заполнена у 9 объектов
	   из 8836 и у всех девяти пуста, а у 8738 объектов миниатюра — одна
	   и та же картинка-заглушка. Полоса листания из одного повторяющегося
	   кадра — обман, поэтому кадр один. Пропорция при этом взята
	   прототипская (--media-aspect: 3/1): высота полосы там же, где
	   в эталоне, и карточка не разъезжается по вертикали.

	   Кадров пришло несколько (фильтр messia_pddpro_listing_card_photos) —
	   включается лента, и работают три размера ниже. */
	--media-aspect: 3 / 1;
	--media-inset: 6px;

	/* Шаг ленты: два целых кадра и краешек третьего — он и говорит,
	   что полоса листается (design2/assets/css/listing.css:36–38). */
	--slide-gap: 8px;
	--peek: 24px;
	--slide-width: calc((100% - 2 * var(--slide-gap) - var(--peek)) / 2);

	/* Кадр на широком экране — фиксированный, из web.css прототипа */
	--web-photo-w: 240px;
	--web-photo-h: 220px;

	/* Колонки широкого экрана — замер эталона на 1440:
	   .app grid-template-columns = 60.14 | 276 | 864 | 171.86,
	   то есть панель фильтров 276, лента карточек 864, карта 188
	   (172 колонки + 16 поля .app), зазор 12. */
	--web-sidebar-width: 276px;
	--web-content-width: 864px;
	--web-map-width: 188px;

	/* Сдвиг всей левой части вправо (эталон: tokens.css:793–794,
	   включается в web.css:1528–1532, вариант v5).

	   До 1600px он нулевой — место под сдвиг отдаёт карта, а на
	   1280…1500 у неё этого места нет, карта ушла бы за край окна.
	   От 1600px левое поле страницы становится 16 + 300, и вместе
	   с ним вправо едет всё: шапка, сводка, панель фильтров, лента.

	   Без этого правила наша страница и эталон совпадали ровно
	   до 1440 и расходились выше — потому прошлые сессии этого
	   и не видели. Замер 1920: у нас padding-left 16 и фильтры
	   в x=213, в эталоне 316 и x=435. Колонки при этом объявлены
	   одинаково, расхождение давало только поле. */
	--web-content-shift: 0px;
	--web-content-shift-wide: 300px;

	--service-color: var(--color-text-secondary);
	--service-check: var(--color-rating-high);
	--service-divider: var(--color-border);

	--action-height: 38px;
	--action-font: 13px;
}

/* ------------------------------------------------------------
   2. КАРТОЧКА

   Движок задаёт ей плашку в двух местах:
       .card-item-ver-3   background #fff, padding 32px,
                          border-radius 24px, margin-bottom 16px,
                          box-shadow 0 4px 24px      frontend.css
       .card-item-ver-3   border-radius 20px,
                          box-shadow none !important  skin.css
       .card-item-ver-3   margin 0 0 16px             skin.css

   Padding снимается: у прототипа фото прижато к краям карточки,
   поля живут внутри .pdd-listing-card__body.

   Тень здесь объявлена, но НЕ доезжает: skin.css гасит её
   с !important (проверено замером — box-shadow у карточки был
   none). Рабочая тень стоит в разделе 19.
   ------------------------------------------------------------ */
body.pdd .pdd-listing-card {
	display: flex;
	flex-direction: column;

	/* система координат для плашки рейтинга: движок печатает её
	   в теле карточки, а лежать она должна на фото (см. раздел 5) */
	position: relative;
	padding: 0;
	margin: 0 0 var(--grid-gap);
	overflow: hidden;
	background: var(--color-surface);
	border: var(--border-width) solid var(--color-border);
	border-radius: var(--radius-xl);
	box-shadow: var(--shadow-card);
}

/* frontend.css в мобильной ширине раздаёт детям карточки order:
       .page-template-newlisting .buttons-new  { order: 10 }
       .page-template-newlisting .price        { order: 9 }
   Карточка стала flex-колонкой, и порядок блоков теперь наш,
   а не чужой. Сбрасываем явно — иначе ряд кнопок и прайс уезжают
   вниз мимо задуманного порядка. */
body.pdd .pdd-listing-card > *,
body.pdd .pdd-listing-card .pdd-listing-card__pricebox {
	order: 0;
}

/* ------------------------------------------------------------
   3. ФОТО

   Что перебиваем:
       .card-item-ver-3 .image-ver-3      max-width 232px,
                                          max-height 225px,
                                          margin-right 24px,
                                          flex-direction column
       .card-item-ver-3 .image-ver-3 img  height 225px,
                                          border-radius 12px / 17px
   ------------------------------------------------------------ */
/* width: auto — по той же причине, что у прайса: движок задаёт
   .card-item-ver-3 .image-ver-3 { width: 100% }, и кадр разъезжался
   на всю карточку поверх собственных полей (372 вместо 360 на 390). */
body.pdd .pdd-listing-card .pdd-listing-card__media {
	width: auto;
	position: relative;
	display: block;
	max-width: none;
	max-height: none;
	margin: var(--media-inset) var(--media-inset) 0;
	aspect-ratio: var(--media-aspect);

	/* Скругление и подложка — у кадров, а не у полосы.

	   Кадров в узкой ширине два с краешком третьего, и в просвете
	   между ними видна сама карточка: ни подложки, ни градиента
	   (.listing .card__media в design2/assets/css/listing.css, 95).
	   Движок красит .image-ver-3 серым градиентом — снимаем.
	   На широком экране кадр один, и там подложка возвращается
	   правилом раздела широкой ширины. */
	background: none;
	border-radius: 0;
	overflow: hidden;
}

body.pdd .pdd-listing-card .pdd-listing-card__media img {
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
	border-radius: 0;
}

/* ------------------------------------------------------------
   3.1. ЛЕНТА КАДРОВ

   Включается, когда кадров больше одного. Устройство — эталонное
   (design2/assets/css/main.css, 1200–1244 и listing.css, 95–154):
   горизонтальная прокрутка со snap по кадрам, точки поверх фото,
   счётчик в разметке есть, но скрыт — при двух видимых кадрах
   «1/6» только путает. Стрелки — ниже, в блоке широкого экрана.
   ------------------------------------------------------------ */
body.pdd .pdd-listing-card .pdd-listing-card__track {
	display: flex;
	gap: var(--slide-gap);
	height: 100%;
	overflow-x: auto;
	scroll-snap-type: x mandatory;
	scrollbar-width: none;
	-webkit-overflow-scrolling: touch;
}

body.pdd .pdd-listing-card .pdd-listing-card__track::-webkit-scrollbar {
	display: none;
}

/* у каждого кадра своё скругление: их два, и радиус карточки
   на них уже не работает */
/* кадр — ссылка на школу (см. скин), поэтому гасим цвет и
   подчёркивание ссылки: в эталоне на его месте div */
body.pdd .pdd-listing-card .pdd-listing-card__slide {
	flex: 0 0 var(--slide-width);
	height: 100%;
	overflow: hidden;
	color: inherit;
	text-decoration: none;
	border-radius: var(--media-radius);
	scroll-snap-align: start;
	scroll-snap-stop: always;
	background: var(--color-photo-stub);
}

/* Кадр один — во всю ширину полосы, без прокрутки.

   Пустых серых клеток рядом с ним больше нет: на узкой ширине
   они читались как незагрузившееся фото, а полоса скроллилась
   в пустоту (замер 23.08.2026 на 390: scrollWidth 496 при
   clientWidth 360). Три переменные — те же, что и в блоке
   широкого экрана: кадр 100%, ни зазора, ни краешка. */
body.pdd .pdd-listing-card .pdd-listing-card__media--solo {
	--slide-gap: 0px;
	--peek: 0px;
	--slide-width: 100%;
}

body.pdd .pdd-listing-card .pdd-listing-card__media--solo .pdd-listing-card__track {
	overflow-x: hidden;
	scroll-snap-type: none;
}

/* краешка следующего кадра тут нет — сердечко в углу */
body.pdd .pdd-listing-card .pdd-listing-card__media--solo .pdd-listing-card__track ~ .favorite {
	right: var(--space-4);
}

body.pdd .pdd-listing-card .pdd-listing-card__slide img {
	display: block;
	width: 100%;
	height: 100%;
	object-fit: cover;
	object-position: center;
	border-radius: 0;
}

/* точки по центру полосы попадали бы в стык кадров — уводим их
   в левый нижний угол первого фото */
body.pdd .pdd-listing-card .pdd-listing-card__dots {
	position: absolute;
	left: var(--space-4);
	bottom: var(--space-4);
	z-index: 3;
	display: flex;
	gap: var(--space-2);
	pointer-events: none;
}

body.pdd .pdd-listing-card .pdd-listing-card__dot {
	width: 5px;
	height: 5px;
	border-radius: var(--radius-pill);
	background: var(--color-surface);
	opacity: 0.55;
	box-shadow: var(--shadow-float);
	transition: opacity 0.15s ease;
}

body.pdd .pdd-listing-card .pdd-listing-card__dot.is-active {
	opacity: 1;
}

/* счётчик «1/3» при двух видимых кадрах только сбивает: он
   остаётся в разметке для вариантов, где кадр один */
body.pdd .pdd-listing-card .pdd-listing-card__count {
	display: none;
}

/* стрелки — только под мышью, на широком экране (см. ниже) */
body.pdd .pdd-listing-card .pdd-listing-card__arrow {
	display: none;
}

/* прозрачная ссылка на всю площадь фото: клик по карточке ведёт
   на школу, как в прототипе (listing.js, обработчик на .card).
   Ленте её не печатают: она перехватывала бы прокрутку. */
body.pdd .pdd-listing-card .pdd-listing-card__media-link {
	position: absolute;
	inset: 0;
	z-index: 2;
}

/* логотип поверх фото — только когда у объекта есть и обложка,
   и логотип; движок кладёт его в .logo-card-ver-3 */
body.pdd .pdd-listing-card .pdd-listing-card__logo {
	z-index: 3;
}

body.pdd .pdd-listing-card .pdd-listing-card__logo img {
	width: auto;
	height: auto;
}

/* сердечко избранного — из прототипа, поверх фото справа сверху.
   Движок печатает его кнопкой .favorite.bookmark внутри карточки. */
/* margin: 0 — движок отбивает кнопку закладки на 3px сверху и 5px
   слева, и сердечко съезжало с угла кадра (эталон .favorite —
   ровно --space-4 от обоих краёв). */
body.pdd .pdd-listing-card .pdd-listing-card__media .favorite {
	margin: 0;
	position: absolute;
	top: var(--space-4);
	right: var(--space-4);
	z-index: 4;
	display: grid;
	place-items: center;
	width: 30px;
	height: 30px;
	padding: 0;
	color: var(--color-icon-strong);
	background: var(--color-surface);
	border: none;
	border-radius: var(--radius-pill);
	box-shadow: var(--shadow-float);
}

body.pdd .pdd-listing-card .pdd-listing-card__media .favorite svg {
	width: 17px;
	height: 17px;
	transition: fill-opacity 0.15s ease;
}

/* Заливка и обводка заданы на path, а не на svg, нарочно.
   Движок красит именно path и именно в синий:
   .bookmark.active path { fill: #3293D6 } и то же на :hover
   (frontend.css, 8339 и 8354). Правило на svg он перебивал —
   и нажатое сердце выходило синим. */
body.pdd .pdd-listing-card .pdd-listing-card__media .favorite svg path,
body.pdd .pdd-listing-card .pdd-listing-card__media .favorite:hover svg path {
	fill: currentColor;
	/* контур виден всегда, заливка появляется в нажатом состоянии:
	   fill-opacity анимируется, в отличие от fill: none */
	fill-opacity: 0;
	stroke: currentColor;
	stroke-width: 1.9;
}

/* Нажатое состояние — сплошная красная кнопка с белым сердцем.
   Белый кружок с красным контуром читался как «недожатый»,
   решение 16.08.2026.

   Признака два: .active ставит движок, когда ответит сервер
   (frontend.js:969), aria-pressed — наш скрипт сразу по клику. */
body.pdd .pdd-listing-card .pdd-listing-card__media .favorite.active,
body.pdd .pdd-listing-card .pdd-listing-card__media .favorite[aria-pressed="true"] {
	color: var(--color-surface);
	background: var(--color-rating-low);
}

body.pdd .pdd-listing-card .pdd-listing-card__media .favorite.active svg path,
body.pdd .pdd-listing-card .pdd-listing-card__media .favorite.active:hover svg path,
body.pdd .pdd-listing-card .pdd-listing-card__media .favorite[aria-pressed="true"] svg path,
body.pdd .pdd-listing-card .pdd-listing-card__media .favorite[aria-pressed="true"]:hover svg path {
	fill: currentColor;
	fill-opacity: 1;
	stroke: currentColor;
}

/* на ленте сердечко съезжает влево — на второй, последний целый
   кадр: на обрезанном краю оно выглядело бы относящимся к нему
   (design2/assets/css/listing.css, 114–118). Правило идёт после
   блока выше: специфичность у них одинаковая, решает порядок */
body.pdd .pdd-listing-card .pdd-listing-card__track ~ .favorite {
	right: calc(var(--peek) + var(--slide-gap) + var(--space-3));
}

/* ------------------------------------------------------------
   4. ТЕЛО КАРТОЧКИ
   ------------------------------------------------------------ */
body.pdd .pdd-listing-card .pdd-listing-card__body {
	display: flex;
	flex-direction: column;
	flex: 1;
	min-width: 0;
	/* эталон: 12 12 6 12 (.listing .card__body — --card-inset сверху
	   и с боков, --space-3 снизу) */
	padding: var(--card-inset) var(--card-inset) var(--space-3);
}

/* заголовок: название слева, цена «от» справа.
   Движок красит .card-item-ver-3 .title-ver-3 a в #2a2a2a/21px
   (skin.css) и обнуляет margin через !important — margin не
   трогаем, он и так ноль. */
/* color задан явно: .card-item-ver-3 .title-ver-3 в skin.css красит
   заголовок в #2a2a2a, а в эталоне он того же цвета, что основной
   текст (#0b0b0b) */
/* padding: 0 — skin.css держит на .card-item-ver-3 .title-ver-3
   padding-right: 70px под старую карточку, где справа стояло
   сердечко. У нас сердечко на фото, и эти 70px просто резали
   название: замер 16.08.2026 дал ссылку в 268px при доступных
   348, «Поано Верхнесалдинская сп…» вместо полного имени. */
body.pdd .pdd-listing-card .pdd-listing-card__title {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	margin: 0;
	padding: 0;
	font-size: var(--font-size-card-title);
	font-weight: var(--font-weight-bold);
	line-height: var(--line-height-snug);
	letter-spacing: var(--letter-spacing-title);
	color: var(--color-text);
}

/* margin: 0 — frontend.css:.card-item-ver-3 .title-ver-3 a даёт
   ссылке margin-right 10px. Расстояние до галочки и до цены
   задаёт gap строки, второй отступ поверх него не нужен. */
body.pdd .pdd-listing-card .pdd-listing-card__title .pdd-listing-card__title-text {
	min-width: 0;
	margin: 0;
	overflow: hidden;
	font-size: inherit;
	font-weight: inherit;
	color: var(--color-text);
	text-overflow: ellipsis;
	white-space: nowrap;
}

body.pdd .pdd-listing-card .pdd-listing-card__title .pdd-listing-card__title-text:hover {
	color: var(--color-primary);
}

/* «от» и сумма стоят в строку с отбивкой 4, а весь блок отодвинут
   от заголовка на 8 — эталон .card__price-top */
body.pdd .pdd-listing-card .pdd-listing-card__price {
	display: flex;
	align-items: baseline;
	gap: var(--space-2);
	flex: 0 0 auto;
	margin-left: auto;
	padding-left: var(--space-4);
	font-size: var(--font-size-price);
	font-weight: var(--font-weight-bold);
	letter-spacing: var(--letter-spacing-title);
	white-space: nowrap;
}

body.pdd .pdd-listing-card .pdd-listing-card__price-from {
	font-size: var(--font-size-micro);
	font-weight: var(--font-weight-regular);
	color: var(--color-text-secondary);
}

/* ------------------------------------------------------------
   5. РЕЙТИНГ

   Движок печатает готовый сниппет get_object_rating_snippet():
   .rating > .rating_ball .points + .stars + .ratingCount, либо
   .no-rating, если отзывов нет. Разметка чужая — раскладку
   задаём снаружи, не влезая внутрь.
   ------------------------------------------------------------ */
body.pdd .pdd-listing-card .pdd-listing-card__stats {
	margin-top: var(--space-3);
}

/* Оценка — строкой под названием на всех ширинах.

   В эталоне на телефоне плашка «4,8 ★» лежит в левом верхнем углу
   полосы (design2/assets/js/listing.js, cardTemplate: .rating внутри
   .card__media) и уходит в поток только на широком экране
   (web.css, 923–941). Заказчик просил единообразия: 19.08.2026
   принято печатать оценку с количеством отзывов строкой под
   названием и на телефоне тоже — как на вебе и как в листинге
   messia. Фото остаётся чистым.

   Правило оставлено пустым намеренно: плашку печатает движок
   сниппетом в теле карточки, и без съёма из потока она уже
   стоит там, где нужно. */
body.pdd .pdd-listing-card .pdd-listing-card__stats .rating_ball {
	margin: 0;
}

/* margin: 0 — skin.css:.sections .rating добавляет 12px сверху
   и снизу, и строка рейтинга занимала 49.5px против 18.8 у
   соседних (замер 16.08.2026). Ритм строк в эталоне один на все:
   6px сверху, высота по тексту. */
body.pdd .pdd-listing-card .pdd-listing-card__stats .rating {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	flex-wrap: wrap;
	margin: 0;
	font-size: var(--font-size-caption);
	/* мелкая ступень звезды: 13px в карточках против 15px в шапках
	   (шкала эталона, см. --stars-size в tokens.css). На 15px
	   строка рейтинга поднималась до 21.8px против 18.8 у соседних */
	--stars-size: 13px;
}

/* Оценка — закрашенная плашка «4,8 ★», рядом количество отзывов
   (.rating / .rating--high в design2/assets/css/main.css:1144–1169).
   Движок печатает три вещи подряд: число в .rating_ball, пять
   звёзд в .stars, отзывы в .ratingCount. Плашка собирается из
   первой, звезда дорисовывается псевдоэлементом, ряд звёзд
   гасится: в эталоне звёзд в карточке листинга нет вовсе.

   Форма звезды — общий токен --star-shape (tokens.css). Копия
   пути стоит запасным значением: файл карточки должен рисоваться
   и в одиночку, без чужого токена. */
body.pdd .pdd-listing-card .pdd-listing-card__stats .rating_ball {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	margin: 0;
	padding: 3px var(--space-3);
	font-size: var(--font-size-caption);
	font-weight: var(--font-weight-semibold);
	line-height: var(--line-height-tight);
	color: var(--color-text-inverse);
	background-color: var(--color-rating-mid);
	border-radius: var(--radius-sm);
}

/* margin: 0 — у .points движок держит margin-right 10px, и внутри
   плашки они вставали между числом и звездой: плашка выходила
   56.9px против 46.8 у эталона. Расстояние до звезды задаёт gap. */
body.pdd .pdd-listing-card .pdd-listing-card__stats .rating_ball .points {
	margin: 0;
	font-size: inherit;
	font-weight: inherit;
	line-height: inherit;
	color: inherit;
}

body.pdd .pdd-listing-card .pdd-listing-card__stats .rating_ball::after {
	content: "";
	flex: 0 0 auto;
	width: 13px;
	height: 13px;
	background-color: currentColor;
	-webkit-mask: var(--star-shape, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath d='M7 1.2 8.8 5l4.1.5-3 2.8.8 4-3.7-2-3.7 2 .8-4-3-2.8L5.2 5 7 1.2Z'/%3E%3C/svg%3E") no-repeat center center);
	mask: var(--star-shape, url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath d='M7 1.2 8.8 5l4.1.5-3 2.8.8 4-3.7-2-3.7 2 .8-4-3-2.8L5.2 5 7 1.2Z'/%3E%3C/svg%3E") no-repeat center center);
	-webkit-mask-size: contain;
	mask-size: contain;
}

/* Цвет плашки — по значению, три ступени эталона: 4,5 и выше
   зелёная, от 3,0 жёлтая, ниже красная (пороги одни и те же
   в design2/assets/js/listing.js:160, similar.js:54, site.js:155).

   Класса со значением в разметке движка нет — его дописывает
   наш скин там, где и так подставляет рейтинг
   (replace_dynamic_button_placeholders). Умолчание выше —
   жёлтая: если движок однажды напечатает сниппет иначе и класс
   не встанет, карточка всё равно нарисуется. */
body.pdd .pdd-listing-card .pdd-listing-card__stats .rating.pdd-rating--low .rating_ball {
	background-color: var(--color-rating-low);
}

body.pdd .pdd-listing-card .pdd-listing-card__stats .rating.pdd-rating--mid .rating_ball {
	background-color: var(--color-rating-mid);
}

body.pdd .pdd-listing-card .pdd-listing-card__stats .rating.pdd-rating--high .rating_ball {
	background-color: var(--color-rating-high);
}

/* Ряд звёзд снят: в эталоне оценка живёт плашкой, звёзды рядом
   с ней — это разметка движка, а не дизайн. Вместе со звёздами
   уходит и их margin-right 25px, поставленный с !important. */
body.pdd .pdd-listing-card .pdd-listing-card__stats .stars {
	display: none;
}

/* «N отзывов» — .reviews эталона (design2/assets/css/main.css:1343):
   12px обычного начертания, вторичный цвет, иконка 14px в общем
   цвете иконок, зазор 4.

   Класс здесь наш, а не движковый: обёртку переименовывает
   detach_reviews_styling() в скине. Пока на узле стоял ratingCount,
   его держал skin.css плагина — цвет через !important, размер 16px,
   вес 500, а вместо иконки пузырёк фоном псевдоэлемента шириной
   26px. Ни цвет, ни размер иконки оттуда не задавались. Плагин
   обновляемый и в deny, поэтому уведён узел, а не правлен плагин. */
body.pdd .pdd-listing-card .pdd-listing-card__stats .pdd-listing-card__reviews {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	/* order задаём сами. Движок расставляет строку рейтинга через
	   order: .rating_ball 1, .stars 2, а третьим шёл .ratingCount.
	   Вместе с чужим классом ушёл и его order — блок отзывов падал
	   в 0 и вставал ПЕРЕД плашкой. */
	order: 3;
	font-size: var(--font-size-micro);
	font-weight: var(--font-weight-regular);
	color: var(--color-text-secondary);
	white-space: nowrap;
}

body.pdd .pdd-listing-card .pdd-listing-card__stats .pdd-listing-card__reviews a {
	margin: 0;
	font-size: inherit;
	font-weight: inherit;
	color: inherit;
}

body.pdd .pdd-listing-card .pdd-listing-card__stats .pdd-listing-card__reviews a:hover {
	color: var(--color-primary);
}

/* Иконка: движок печатает её svg с fill="#2196F3" в атрибуте
   презентации — CSS перебивает его без !important. Размеры заданы
   атрибутами 17x15, эталон держит 14x14. */
body.pdd .pdd-listing-card .pdd-listing-card__stats .pdd-listing-card__reviews svg {
	flex: 0 0 auto;
	width: 14px;
	height: 14px;
	transform: translateY(1px);
}

body.pdd .pdd-listing-card .pdd-listing-card__stats .pdd-listing-card__reviews svg path {
	fill: var(--color-icon);
}

body.pdd .pdd-listing-card .pdd-listing-card__stats .no-rating {
	font-size: var(--font-size-micro);
	color: var(--color-text-muted);
}

/* ------------------------------------------------------------
   6. СТРОКИ: режим работы, адрес, маршрут, категории

   Внутренности печатает движок (.title-list-item-v3 —
   подпись поля, .text-list-item-v3 — значение). Обёртку
   и иконку — мы.
   ------------------------------------------------------------ */
body.pdd .pdd-listing-card .pdd-listing-card__row {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	min-width: 0;
	margin: var(--space-3) 0 0;
	padding: 0;
	font-size: var(--font-size-caption);
	line-height: var(--line-height-base);
	color: var(--color-text-secondary);
}

body.pdd .pdd-listing-card .pdd-listing-card__row > svg {
	flex: 0 0 auto;
	color: var(--color-icon);
}

body.pdd .pdd-listing-card .pdd-listing-card__row .icon-metro {
	color: var(--color-metro);
}

body.pdd .pdd-listing-card .pdd-listing-card__row .title-list-item-v3 {
	flex: 0 0 auto;
	font-size: inherit;
	font-weight: var(--font-weight-regular);
	color: var(--color-text-muted);
}

body.pdd .pdd-listing-card .pdd-listing-card__row .text-list-item-v3 {
	min-width: 0;
	overflow: hidden;
	font-size: inherit;
	color: inherit;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* адрес — самая длинная строка, обрезается многоточием */
body.pdd .pdd-listing-card .pdd-listing-card__row--address .text-list-item-v3 {
	color: var(--color-text);
}

/* режим работы: движок дорисовывает сюда бейдж состояния
   .working-hours-status — «Откроется в четверг, 18:00». Он же
   стоит на карточке школы, поэтому цвета берём те же токены. */
body.pdd .pdd-listing-card .pdd-listing-card__row--hours {
	flex-wrap: wrap;
}

/* Плашку снимаем: frontend.css:.working-hours-status рисует пилюлю
   (padding .28rem .7rem, radius 999px, подложка под цвет состояния).
   В эталоне режим работы — обычный текст в строке: «Открыто»
   зелёным, «Закрыто» красным, рядом серым до скольких
   (.hours / .hours__till, design2/assets/css/listing.css:169–187).
   Пилюля к тому же поднимала строку до 23.4px против 18.8
   у соседних — ряд строк шёл вразнобой. */
body.pdd .pdd-listing-card .working-hours-status {
	display: inline-flex;
	align-items: center;
	gap: var(--space-2);
	padding: 0;
	font-size: var(--font-size-micro);
	font-weight: var(--font-weight-semibold);
	background: none;
	border-radius: 0;
}

body.pdd .pdd-listing-card .working-hours-status--open {
	color: var(--color-rating-high);
}

body.pdd .pdd-listing-card .working-hours-status--closed {
	color: var(--color-rating-low);
}

body.pdd .pdd-listing-card .working-hours-status__icon {
	display: none;
}

/* маршрут: движок печатает иконку поля картинкой — прячем её,
   свою svg рисуем сами, иначе в строке две иконки подряд */
body.pdd .pdd-listing-card .pdd-listing-card__row--route img {
	display: none;
}

body.pdd .pdd-listing-card .pdd-listing-card__row--route a {
	color: var(--color-primary);
}

/* метро */
body.pdd .pdd-listing-card .pdd-listing-card__row .station {
	min-width: 0;
	overflow: hidden;
	color: var(--color-text);
	text-overflow: ellipsis;
	white-space: nowrap;
}

body.pdd .pdd-listing-card .pdd-listing-card__row .walk {
	flex: 0 0 auto;
	color: var(--color-text-muted);
}

/* категории: движок отдаёт значения списком <span> */
body.pdd .pdd-listing-card .pdd-listing-card__row--cats .text-list-item-v3 span + span::before {
	content: ", ";
}

/* ------------------------------------------------------------
   7. УСЛУГИ С ЦЕНАМИ

   Прайс есть не у каждой школы — блока в разметке просто нет,
   когда pricing пуст (см. get_object_card, шаг 5).

   Движок красит .card-item-ver-3 .price градиентной плашкой
   (skin.css, строка 1376) — снимаем, у прототипа это простой
   список со разделителями.
   ------------------------------------------------------------ */
body.pdd .pdd-listing-card .pdd-listing-card__pricebox {
	display: flex;
	flex-direction: column;

	/* Прайс печатается ребёнком карточки, а не тела (см. get_object_card):
	   боковые поля, которые раньше давало тело, теперь его собственные.

	   Нижнее поле — зазор до ряда кнопок: «Все цены» и «Подробнее»
	   стояли вплотную и читались одной полосой кнопок. На широком
	   экране прайс в рамке, и там зазор даёт padding-top у .buttons-new
	   (раздел 10), поэтому нижнее поле там снимается. */
	margin: var(--space-5) var(--card-inset) var(--space-7);
	padding: 0;
	background: none;
	border-radius: 0;
}

/* Ширина — по полям, а не 100%.

   Движок задаёт .page-template-newlisting .price { width: 100% }
   в мобильной ширине, и при своих полях прайс вылезал за карточку
   ровно на них: 372 вместо 348 (замер на 390). */
body.pdd.page-template-newlisting .pdd-listing-card .pdd-listing-card__pricebox {
	width: auto;
}

body.pdd .pdd-listing-card .pdd-listing-card__services {
	margin: 0;
	padding: 0;
	list-style: none;
}

/* Строка услуги — ряд: галочка, название, цена справа
   (.service в design2/assets/css/listing.css:221).

   Обёртка прайса несёт ещё и движковый класс price, поэтому по
   строке бьют два чужих правила сразу:
       .card-item-ver-3 .price ul li      justify-content center
       .page-template-newlisting .price li span   width 100%
   Первое сгоняло содержимое к середине, второе раздувало оба
   span на всю ширину — название и цена вставали друг под другом
   по центру вместо одной строки (замер 16.08.2026 на карточке
   с прайсом). Ниже обоим дан ответ. */
body.pdd .pdd-listing-card .pdd-listing-service {
	display: flex;
	flex-wrap: nowrap;
	align-items: center;
	justify-content: flex-start;
	gap: var(--space-4);
	margin: 0;
	padding: var(--space-3) 0;
	font-size: var(--font-size-caption);
	color: var(--service-color);
	/* Названия услуг стояли по центру строки: обёртка прайса несёт
	   движковый класс price, а .card-item-ver-3 .price выравнивает
	   текст по середине. justify-content строку уже чинил, но
	   короткое название всё равно вставало посередине своего span —
	   его равняет text-align, а не флекс (замер 19.08.2026 на 390). */
	text-align: left;
	border-top: var(--border-width) solid var(--service-divider);
	list-style: none;

	/* Разделитель у строки ровно один — верхний.

	   До 500px движок рисует второй, свой:
	       .page-template-newlisting .price li
	           border-bottom: 1px dashed rgba(128,133,147,.7)
	           padding-bottom: 15px; margin-bottom: 15px
	   (frontend.css, 17122–17128, внутри @media max-width 500).
	   На узком экране под каждой ценой, кроме последней, шла ещё
	   и пунктирная черта — между двумя ценами их выходило две:
	   наша сплошная сверху и чужая пунктирная снизу. */
	padding-bottom: var(--space-3);
	margin-bottom: 0;
	border-bottom: 0;
}

body.pdd .pdd-listing-card .pdd-listing-service .icon-check {
	flex: 0 0 auto;
	color: var(--service-check);
}

/* Название услуги: 13px полужирным. Движок печатает его в 14px
   обычного начертания — в эталоне ступень мельче, а вес выше
   (замер: 13px/600 против наших 14px/400). */
body.pdd .pdd-listing-card .pdd-listing-service__name {
	flex: 1 1 auto;
	text-align: left;
	width: auto;
	min-width: 0;
	overflow: hidden;
	font-size: var(--font-size-caption);
	font-weight: var(--font-weight-semibold);
	color: inherit;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* Цена крупнее названия услуги.

   В прототипе это не написано в разделе листинга: размер приходит
   общим правилом .service__price (design2/assets/css/main.css, 1833)
   — 19px, жирные, с тем же letter-spacing, что у заголовков.
   Замер эталона: название 19px высотой, цена 28. */
body.pdd .pdd-listing-card .pdd-listing-service__price {
	flex: 0 0 auto;
	text-align: right;
	width: auto;
	margin-left: auto;
	font-size: var(--font-size-price);
	font-weight: var(--font-weight-semibold);
	letter-spacing: var(--letter-spacing-title);
	color: var(--color-text);
	white-space: nowrap;
}

/* Обе цифры — тем же кеглем, что и вся строка цены.

   До 500px движок бьёт по тегу: .page-template-newlisting .price li b
   ставит font-size 16px и margin-top 6px (frontend.css, 17140–17145).
   Размер на самом теге сильнее наследования от span, поэтому цена
   на узком экране мельчала, а отбивка сверху роняла её ниже строки. */
body.pdd .pdd-listing-card .pdd-listing-service__price .old,
body.pdd .pdd-listing-card .pdd-listing-service__price .new {
	margin: 0;
	font-size: inherit;
}

body.pdd .pdd-listing-card .pdd-listing-service__price .old {
	margin-right: var(--space-2);
	font-weight: var(--font-weight-regular);
	color: var(--color-text-muted);
	text-decoration: line-through;
}

body.pdd .pdd-listing-card .pdd-listing-service__price .new {
	color: var(--color-rating-low);
}

/* «Все цены» — залитая мягким синим кнопка под списком, по левому
   краю (.card__prices, design2/assets/css/listing.css:251; замер
   эталона: 95x38, поля 0/10, зазор 4, радиус 8, 13px/600,
   #5e73e2 на #e8ecfd, без рамки).

   width: auto обязателен: движок задаёт .card-item-ver-3
   .show-all-price-ver-3 ширину 100%, и кнопка растягивалась
   во всю карточку — align-self элемент с явной шириной не ужимает. */
body.pdd .pdd-listing-card .pdd-listing-card__prices {
	display: inline-flex;
	/* по центру прайса, а не по левому краю: узкая карточка читается
	   столбцом, и плашка на середине не сливается с рядом кнопок */
	align-self: center;
	justify-content: center;
	align-items: center;
	gap: var(--space-2);
	width: auto;
	height: var(--action-height);
	margin-top: var(--space-4);
	padding: 0 var(--space-5);
	font-size: var(--action-font);
	font-weight: var(--font-weight-semibold);
	color: var(--color-primary);
	background: var(--color-primary-soft);
	border: 0;
	border-radius: var(--radius-md);
}

body.pdd .pdd-listing-card .pdd-listing-card__prices:hover {
	color: var(--color-text-inverse);
	background: var(--color-primary);
}

/* ------------------------------------------------------------
   8. РЯД КНОПОК

   Печатает движок: replace_dynamic_button_placeholders() кладёт
   в .buttons-new кнопку сравнения, кнопки форм, ссылку на сайт
   и «Подробнее». Состав зависит от настроек сегмента, поэтому
   раскладка должна переживать и одну кнопку, и четыре.

   Что перебиваем:
       .page-template-newlisting .buttons-new  padding-left 303px,
                                               margin-top 30px,
                                               min-height 50px   frontend.css
       .card-item-ver-3 .buttons-new           display grid
                                               1fr 1fr            skin.css
   ------------------------------------------------------------ */
body.pdd .pdd-listing-card .buttons-new {
	display: flex;
	gap: var(--space-3);
	min-height: 0;
	margin: 0;
	padding: 0 var(--card-inset) var(--card-inset);
	grid-template-columns: none;
}

/* min-height задаём наравне с height: у .btn_blue родительской темы
   стоит min-height 48px, и без ответа кнопки держали 48 вместо 38
   (замер 14.08.2026). Насыщенность в эталоне 600, не 500.

   margin: 0 — .page-template-newlisting .buttons-new .btn_blue
   в мобильной ширине добавляет снизу 10px, и ряд кнопок стоял
   на 10px выше низа карточки. */
body.pdd .pdd-listing-card .buttons-new > * {
	flex: 1 1 0;
	min-width: 0;
	height: var(--action-height);
	min-height: var(--action-height);
	margin: 0;
	display: inline-flex;
	align-items: center;
	justify-content: center;
	gap: var(--space-2);
	padding: 0 var(--space-3);
	font-size: var(--action-font);
	font-weight: var(--font-weight-semibold);
	border-radius: var(--radius-md);
	white-space: nowrap;
}

/* skin.css красит кнопки листинга селектором (0,3,1) —
   .page-template-newlisting .buttons-new button:not(.favorite).
   Ответный селектор на класс длиннее: body.pdd.page-template-newlisting
   даёт (0,4,1). Тот же приём уже применён в main.css. */
/* Вторичные кнопки ряда — .card__actions > * прототипа: белая плашка,
   волосяная рамка, текст основного цвета (не синий: замер эталона даёт
   #0b0b0b, синим там только залитая CTA). */
body.pdd.page-template-newlisting .pdd-listing-card .buttons-new .btn_blue.invert,
body.pdd.page-template-newlisting .pdd-listing-card .buttons-new > a.btn_blue:not(.invert) {
	background-color: var(--color-surface);
	border-color: var(--color-border);
	border-radius: var(--radius-md);
	color: var(--color-text);
}

body.pdd.page-template-newlisting .pdd-listing-card .buttons-new .btn_blue.invert:hover,
body.pdd.page-template-newlisting .pdd-listing-card .buttons-new > a.btn_blue:not(.invert):hover {
	background-color: var(--color-primary);
	border-color: var(--color-primary);
	color: var(--color-text-inverse);
}

/* «Записаться» — .card__cta прототипа: единственная залитая кнопка
   в ряду. Селектор длиннее нужного из-за skin.css: там
   .page-template-newlisting .buttons-new button:not(.favorite) (0,3,1)
   делает её контурной. */
body.pdd.page-template-newlisting .pdd-listing-card .buttons-new button:not(.favorite) {
	background-color: var(--color-primary);
	border-color: var(--color-primary);
	border-radius: var(--radius-md);
	color: var(--color-text-inverse);
}

body.pdd.page-template-newlisting .pdd-listing-card .buttons-new button:not(.favorite):hover {
	background-color: var(--color-primary-hover);
	border-color: var(--color-primary-hover);
	color: var(--color-text-inverse);
}

/* Шире соседних — главное действие, то есть залитая «Записаться»
   (.card__cta { flex: 1.3 1 0 } в design2/assets/css/listing.css:289).
   Раньше 1.3 стояло на «Подробнее»: вместе с неразведённым order
   получалось, что слева и уже — залитая кнопка, справа и шире —
   белая, то есть ряд читался наоборот. */
body.pdd .pdd-listing-card .buttons-new button:not(.favorite) {
	flex: 1.3 1 0;
}

/* Залитая кнопка — последняя в ряду, как .card__cta прототипа.
   Движок печатает кнопки форм раньше ссылок («Записаться», потом
   «Подробнее»), в эталоне порядок обратный: сначала действия
   попроще, справа — главное.

   Порядок задаём обеим кнопкам, а не одной. frontend.css уже даёт
   order: 1 всему .buttons-new .btn_blue — и залитой, и белой.
   Одинаковый order разводится порядком в разметке, поэтому одного
   нашего order: 1 не хватало: «Записаться» так и стояла первой
   (замер 16.08.2026). */
body.pdd .pdd-listing-card .buttons-new > a.btn_blue:not(.invert) {
	order: 0;
}

body.pdd .pdd-listing-card .buttons-new button:not(.favorite) {
	order: 1;
}

/* «Позвонить» вместо «Записаться» на широком экране (29.08.2026).

   Кнопку печатает наш скин (call_button() в class-messia-listing-tmpl-pdd.php)
   и только там, где в конструкторе объекта есть телефон; ряд с ней помечен
   классом .pdd-buttons--call. Ниже 1024 ряд остаётся прежним: там «Записаться»
   ведёт в попап движка, и мобильную строку заказчик менять не просил.

   Вид у неё — главной кнопки ряда, то есть той же залитой, что была
   «Записаться»: правило вторичных ссылок выше (> a.btn_blue:not(.invert))
   покрасило бы её в белую, поэтому отвечаем ему более длинным селектором. */
body.pdd .pdd-listing-card .buttons-new .pdd-card-call {
	display: none;
}

@media (min-width: 1024px) {

	body.pdd.page-template-newlisting .pdd-listing-card .buttons-new > a.pdd-card-call {
		display: inline-flex;
		flex: 1.3 1 0;
		order: 1;
		background-color: var(--color-primary);
		border-color: var(--color-primary);
		color: var(--color-text-inverse);
	}

	body.pdd.page-template-newlisting .pdd-listing-card .buttons-new > a.pdd-card-call:hover {
		background-color: var(--color-primary-hover);
		border-color: var(--color-primary-hover);
		color: var(--color-text-inverse);
	}

	/* !important — ответ инлайновому style="display:flex" движка
	   (get_post_form_buttons_3 печатает его прямо в атрибуте). */
	body.pdd .pdd-listing-card .buttons-new.pdd-buttons--call button.form_button {
		display: none !important;
	}
}

/* ------------------------------------------------------------
   9. ТЕКСТ ОПИСАНИЯ И ТЕГИ КАТЕГОРИЙ

   the_content печатается, когда сегмент это разрешает, а теги
   дорисовывает плагин category_tags на messia_listing_03_card_before_content.
   Обе вещи чужие — задаём им только размер и отступ.
   ------------------------------------------------------------ */
body.pdd .pdd-listing-card .pdd-listing-card__content {
	margin-top: var(--space-4);
	font-size: var(--font-size-caption);
	color: var(--color-text-secondary);
}

body.pdd .pdd-listing-card .pdd-listing-card__content p {
	margin: 0 0 var(--space-3);
}

body.pdd .pdd-listing-card .category_tags {
	margin-top: var(--space-4);
}

/* ============================================================
   10. ШИРОКИЙ ЭКРАН: КАРТОЧКА

   Источник — design2/assets/css/web.css, строки 846–952.
   Карточка разворачивается вбок: кадр слева фиксированного
   размера, текст справа, под ними во всю ширину прайс, ещё ниже
   ряд кнопок.

   Кадр не тянется по высоте карточки намеренно: у карточки
   с прайсом фото иначе выходит заметно выше, чем у соседней
   без него.

   Раскладка страницы (две колонки и карта справа) — ниже,
   отдельным разделом: она про каркас, а не про карточку.
   ============================================================ */
@media (min-width: 1024px) {

	body.pdd.page-template-newlisting {
		--card-inset: var(--space-7);
		--font-size-card-title: 19px;

		/* Кадр прижат к краям карточки: мышью листают стрелками,
		   краешек следующего кадра больше ничего не подсказывает
		   (web.css, 98–106). Скругление кадру не нужно — его даёт
		   сама карточка, у неё overflow: hidden. */
		--media-inset: 0px;
		--media-radius: 0px;

		/* кадр во всю ширину колонки фото, без зазора и краешка */
		--slide-gap: 0px;
		--peek: 0px;
		--slide-width: 100%;
	}

	body.pdd .pdd-listing-card {
		display: grid;
		grid-template-columns: var(--web-photo-w) minmax(0, 1fr);
		grid-template-rows: auto auto auto;
		align-content: start;
		margin-bottom: var(--grid-gap);
		transition: box-shadow 0.16s ease, border-color 0.16s ease;
	}

	body.pdd .pdd-listing-card .pdd-listing-card__media {
		grid-row: 1;
		grid-column: 1;
		align-self: start;
		width: var(--web-photo-w);
		height: var(--web-photo-h);
		margin: 0;
		aspect-ratio: auto;
		border-radius: 0;
	}

	/* точки — по центру кадра: он тут один, стыка нет
	   (design2/assets/css/web.css, 1016–1020) */
	body.pdd .pdd-listing-card .pdd-listing-card__dots {
		left: 0;
		right: 0;
		justify-content: center;
	}

	/* ----------------------------------------------------------
	   Стрелки ленты (design2/assets/css/web.css, 1113–1143)

	   Пальцем здесь не листают, поэтому кадры переключают стрелки
	   по краям фото. Появляются при наведении на карточку.
	   ---------------------------------------------------------- */
	body.pdd .pdd-listing-card .pdd-listing-card__arrow {
		position: absolute;
		top: 50%;
		z-index: 4;
		display: grid;
		place-items: center;
		width: 32px;
		height: 32px;
		padding: 0;
		transform: translateY(-50%);
		color: var(--color-text);
		background: var(--color-surface);
		border: none;
		border-radius: var(--radius-pill);
		box-shadow: var(--shadow-float);
		opacity: 0;
		transition: opacity 0.15s ease;
	}

	body.pdd .pdd-listing-card .pdd-listing-card__arrow--prev {
		left: var(--space-4);
	}

	body.pdd .pdd-listing-card .pdd-listing-card__arrow--next {
		right: var(--space-4);
	}

	body.pdd .pdd-listing-card:hover .pdd-listing-card__arrow {
		opacity: 1;
	}

	body.pdd .pdd-listing-card .pdd-listing-card__arrow:hover {
		background: var(--color-surface);
		filter: brightness(0.95);
	}

	/* кадр один и во всю ширину — сердечко возвращается в угол */
	body.pdd .pdd-listing-card .pdd-listing-card__track ~ .favorite {
		right: var(--space-4);
	}

	/* просвета между кадрами тут нет — подложка снова у полосы */
	body.pdd .pdd-listing-card .pdd-listing-card__media {
		background: var(--color-photo-stub);
	}

	/* Плашка рейтинга в поток здесь больше не возвращается: она
	   и не уходит из него — раздел 5, решение 19.08.2026. */

	body.pdd .pdd-listing-card .pdd-listing-card__body {
		grid-row: 1;
		grid-column: 2;
		padding: var(--card-inset) var(--card-inset) var(--space-3);
	}

	/* ----------------------------------------------------------
	   Прайс в рамке (design2/assets/css/web.css, 954–998)

	   На широком экране прайс идёт не в колонке текста, а своей
	   строкой под фото и текстом, во всю ширину карточки: блок
	   с деньгами видно, не читая строк. Кнопка «Все цены» стоит
	   внутри рамки по центру у нижнего края.
	   ---------------------------------------------------------- */
	body.pdd .pdd-listing-card .pdd-listing-card__pricebox {
		grid-row: 2;
		grid-column: 1 / -1;
		display: flex;
		flex-direction: column;
		margin: var(--space-5) var(--card-inset) 0;
		padding: var(--space-4) var(--space-5) var(--space-5);
		background: var(--color-surface);
		border: var(--border-width) solid var(--color-border-strong);
		border-radius: var(--radius-lg);
	}

	body.pdd .pdd-listing-card .pdd-listing-card__services {
		margin-top: 0;
		padding: 0;
	}

	/* верхняя черта первой строки дублировала бы рамку */
	body.pdd .pdd-listing-card .pdd-listing-service:first-child {
		border-top: 0;
	}

	/* width: auto здесь обязателен: движок задаёт .show-all-price-ver-3
	   ширину 100%, и кнопка растягивалась во всю рамку прайса вместо
	   того, чтобы встать по центру. */
	body.pdd .pdd-listing-card .pdd-listing-card__prices {
		align-self: center;
		justify-content: center;
		width: auto;
		height: 32px;
		margin-top: var(--space-5);
	}

	/* ряд кнопок не липнет ни к рамке прайса, ни к фото: у школ
	   без прайса он шёл вплотную под кадром */
	body.pdd .pdd-listing-card .buttons-new {
		grid-row: 3;
		grid-column: 1 / -1;
		justify-content: stretch;
		padding: var(--space-6) var(--card-inset) var(--card-inset);
	}

	/* кнопки во всю ширину контента карточки: полоса начинается
	   и кончается там же, где текст (web.css, 892–905) */
	body.pdd .pdd-listing-card .buttons-new > * {
		flex: 1 1 0;
		min-width: 0;
	}

	body.pdd .pdd-listing-card:hover {
		border-color: var(--color-border-strong);
		box-shadow: var(--shadow-hover);
	}
}

/* ============================================================
   11. ЗАГОЛОВОК АРХИВА

   Источник — design2/assets/css/main.css, строки 874–898
   (.page-header, .page-title, .page-subtitle).

   Движок печатает заголовок в блоке .cap > .container, где
   .cap-left — текст, .cap-right — Carbon-блоки («промо» прототипа).
   frontend.css красит .cap белой плашкой во всю ширину и разводит
   половины флексом; здесь остаётся то же деление, но на токенах.
   ============================================================ */
body.pdd .pdd-page-header {
	background: none;
	box-shadow: none;
}

body.pdd .pdd-page-header > .container {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	align-items: flex-start;
	gap: var(--space-6);
	padding-top: var(--space-8);
	padding-bottom: 0;
}

/* flex-basis здесь — про ширину, поэтому направление ряда задаётся
   явно. Движок в мобильной ширине переводит .cap .container
   в колонку, и без flex-direction: row базис 320px превращался
   в ВЫСОТУ: шапка держала 320px при 74px текста. */
body.pdd .pdd-page-header__main {
	flex: 1 1 260px;
	min-width: 0;
}

/* Селектор длиннее нужного намеренно: у элемента остаётся класс .h1
   движка, и .page-template-newlisting .cap .h1 в skin.css — это (0,3,0)
   против (0,2,1) у короткого варианта. Он и выигрывал: цвет уходил
   в #2a2a2a вместо #0b0b0b, а под заголовком появлялись лишние 20px. */
body.pdd.page-template-newlisting .cap .pdd-page-title,
body.pdd .pdd-page-title {
	margin: 0;
	font-size: var(--font-size-title);
	font-weight: var(--font-weight-bold);
	line-height: var(--line-height-tight);
	letter-spacing: var(--letter-spacing-title);
	color: var(--color-text);
}

body.pdd .pdd-page-subtitle {
	margin: var(--space-3) 0 0;
	font-size: var(--font-size-subtitle);
	color: var(--color-text-secondary);
}

body.pdd .pdd-page-subtitle b {
	color: var(--color-text);
	font-weight: var(--font-weight-semibold);
}

body.pdd .pdd-page-header__text {
	margin-top: var(--space-3);
	font-size: var(--font-size-caption);
	color: var(--color-text-secondary);
}

/* Сводка под заголовком — это тот же .v3_top_text, то есть текст
   «Текст результата запроса» из SEO-шаблона сегмента в админке.
   Числа в него подставляет движок ({{count}}, {{average_rating}},
   {{price_min}} и прочие), а плашки рисуются, если админ обернул
   куски текста в .pdd-webhero__stat — разметка плашки описана
   ниже, в разделе широкого экрана.

   Инлайновый рейтинг движка ({{average_rating}}) приходит парой
   .rating_ball + .stars; в строке сводки он должен стоять в ряд
   с текстом, а не занимать строку целиком. */
body.pdd .pdd-webhero__summary .rating_ball,
body.pdd .pdd-webhero__summary .stars-inline {
	display: inline-flex;
	align-items: center;
	vertical-align: middle;
}

body.pdd .pdd-webhero__summary .points {
	font-weight: var(--font-weight-semibold);
	color: var(--color-text);
}

/* Текста под заголовком у сегмента может не быть вовсе.

   Узел при этом остаётся в разметке всегда: после AJAX
   Messia.updateSeo() кладёт новый текст именно в '.v3_top_text'
   (listing.js, 676–690). Пустым он не должен занимать ни поля,
   ни строки — иначе под H1 висит пустая полоса. Плейсхолдер
   в скине напечатан вплотную к тегам, чтобы :empty сработал. */
body.pdd .pdd-page-header__text:empty {
	display: none;
	margin: 0;
}

body.pdd .info-ver-3-outer:not(:has(> .info-ver-3:not(:empty))) {
	display: none;
}

/* «промо» справа от заголовка — Carbon-блоки из настроек.
   Пусто — блок не занимает места. */
body.pdd .pdd-page-header__promo:empty {
	display: none;
}

/* Сводка — устройство широкого экрана: в эталоне .webhero объявлен
   display: none и включается только от 1024px (web.css, 58–73).
   Ниже этой ширины обёртка растворяется — заголовок и «промо»
   остаются прямыми детьми .container, как были до неё, — а плашки
   с цифрами не выводятся вовсе. */
@media (max-width: 1023.98px) {

	body.pdd .pdd-webhero {
		display: contents;
	}

	body.pdd .pdd-webhero__stat {
		display: none;
	}
}

/* Поля шапки — 16px, как у .page-header эталона (замер на 390:
   заголовок 358 в окне 390). Движок держит .container на 90%
   ширины окна, и заголовок стоял уже карточек: 327 против 358. */
@media (max-width: 1023.98px) {

	body.pdd.page-template-newlisting .pdd-listing .cap.pdd-page-header > .container,
	body.pdd.page-template-newlisting .container.pdd-listing__layout {
		width: 100%;
		max-width: var(--app-max-width);
		margin-inline: auto;
	}

	body.pdd.page-template-newlisting .pdd-listing .cap.pdd-page-header > .container {
		padding-inline: var(--page-padding);
	}
}

/* ============================================================
   12. ПАНЕЛЬ НАД СПИСКОМ

   Источник — design2/assets/css/main.css, строки 899–1085:
   .search-row, .search, .filter-button, .results, .map-button,
   .sort--compact.
   ============================================================ */
body.pdd .pdd-listing__toolbar {
	display: block;
	padding: 0;
	background: none;
	box-shadow: none;
}

/* gap: 0 намеренно. Отбивки внутри панели в эталоне заданы на самих
   рядах (margin-top у строки поиска, padding у строки результатов),
   и общий gap складывался бы с ними: между поиском и «На карте»
   выходило 26px вместо 16. */
body.pdd .pdd-listing__toolbar .pdd-toolbar {
	display: flex;
	flex-direction: column;
	gap: 0;
}

/* ---- строка поиска ---- */
body.pdd .pdd-listing__toolbar .pdd-search-row {
	display: flex;
	gap: var(--space-4);
	margin-top: var(--space-7);
}

body.pdd .pdd-listing__toolbar .pdd-search {
	position: relative;
	flex: 1;
	min-width: 0;
	margin: 0;
	padding: 0;
	background: none;
}

body.pdd .pdd-listing__toolbar .pdd-search form,
body.pdd .pdd-listing__toolbar .pdd-search .input_text {
	position: relative;
	width: 100%;
	margin: 0;
	padding: 0;
}

body.pdd .pdd-listing__toolbar .pdd-search .input_text > svg {
	position: absolute;
	left: var(--space-6);
	top: 50%;
	width: 20px;
	height: 20px;
	transform: translateY(-50%);
	color: var(--color-icon);
	pointer-events: none;
}

body.pdd .pdd-listing__toolbar .pdd-search input[type="text"] {
	width: 100%;
	height: var(--control-height-search);
	margin: 0;
	padding: 0 var(--space-6) 0 42px;
	font-family: inherit;
	font-size: var(--font-size-input);
	color: var(--color-text);
	background: var(--color-surface);
	border: var(--border-width) solid var(--color-border-strong);
	border-radius: var(--radius-lg);
}

body.pdd .pdd-listing__toolbar .pdd-search input[type="text"]::placeholder {
	color: var(--color-text-muted);
}

body.pdd .pdd-listing__toolbar .pdd-search input[type="text"]:focus {
	outline: none;
	border-color: var(--color-primary);
}

/* кнопка фильтров справа от поиска */
body.pdd .pdd-listing__toolbar .pdd-filter-button {
	flex: 0 0 auto;
	display: grid;
	place-items: center;
	width: var(--control-height-search);
	height: var(--control-height-search);
	padding: 0;
	color: var(--color-icon-strong);
	background: var(--color-surface);
	border: var(--border-width) solid var(--color-border-strong);
	border-radius: var(--radius-lg);
}

/* обводку у иконки движок задаёт белой — на светлой кнопке её не видно */
body.pdd .pdd-listing__toolbar .pdd-filter-button svg path {
	stroke: currentColor;
}

body.pdd .pdd-listing__toolbar .pdd-filter-button:hover {
	background: var(--color-surface-muted);
}

/* ---- строка «На карте» + сортировка ---- */
/* Отбивка сверху и снизу — из .results прототипа (16 / 12).
   Боковых полей нет: их даёт .container страницы */
body.pdd .pdd-listing__toolbar .pdd-results {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-4);
	margin: 0;
	padding: var(--space-7) 0 var(--space-6);
}

/* Отступ от сортировки до первой карточки — 12px, и ровно один.

   Замер 19.08.2026 на 390: у эталона .results отбит снизу на 12
   (design2), и на этом всё — .grid начинается сразу. У нас те же
   12 давала нижняя добивка .pdd-results, а сверх них движок клал
   ещё 24: margin-bottom у .sorting-full и margin-top 12 у обёртки
   списка. Соседние вертикальные поля схлопываются в большее из
   двух, поэтому набегало 12 + 24 = 36 вместо 12.

   Гасим обе чужие отбивки: расстояние держит одна добивка панели.
   На широком экране ряд карточек начинается иначе — правило
   ниже, в разделе широкой ширины, ничего из этого не трогает. */
body.pdd.page-template-newlisting .sorting-full.sorting_search {
	/* !important — не по лени: обе чужие отбивки объявлены с ним же
	   (.page-template-v3 .sorting_search { margin: 0 0 24px 0
	   !important } в скине messia_redesign), а !important
	   специфичностью не перебивается. Проверено 19.08.2026 через
	   CSS.getMatchedStylesForNode: без него побеждает чужое
	   правило, отступ остаётся 36 вместо 12. */
	margin-bottom: 0 !important;
}

body.pdd.page-template-newlisting .pdd-listing__content > div:has( > .sections ) {
	margin-top: 0 !important;
}

body.pdd .pdd-listing__toolbar .pdd-map-button {
	flex: 0 0 auto;
	display: inline-flex;
	align-items: center;
	gap: var(--space-3);
	height: var(--control-height-map);
	max-width: none;
	margin: 0;
	padding: 0 var(--space-6);
	font-size: var(--font-size-meta);
	/* .seemap движка идёт полужирной; в эталоне .map-button — 400 */
	font-weight: var(--font-weight-regular);
	color: var(--color-text);
	background: var(--color-surface);
	border: var(--border-width) solid var(--color-border);
	border-radius: var(--radius-md);
}

body.pdd .pdd-listing__toolbar .pdd-map-button svg {
	color: var(--color-icon-strong);
}

body.pdd .pdd-listing__toolbar .pdd-map-button:hover {
	background: var(--color-surface-muted);
}

/* Сортировка.

   На select[name=sort] движок вешает Select2 (listing.js, 215),
   поэтому на экране виден не сам select, а .select2-selection.
   Красим её под .sort--compact прототипа: та же высота, та же
   рамка и радиус, что у «На карте», — они читаются парой. */
/* Ширину сортировки задаём мы, а не Select2.

   Select2 меряет исходный select при инициализации и пишет результат
   инлайном на .select2-container. Мерить там нечего: select лежит
   в блоке, которому ширину даёт флекс-строка, и на момент замера
   Select2 получает 2px — с ними контейнер схлопывается в ноль,
   а сама плашка .select2-selection шириной 58px вылезает наружу
   (на 390px это давало вылет страницы).

   Инлайн-стиль обычным селектором не перебить, но min-width и
   max-width сильнее width из любого источника. Поэтому ширину
   держит .pdd-sort, а контейнер растягивается ровно по ней. */
body.pdd .pdd-listing__toolbar .pdd-sort {
	flex: 1 1 auto;
	min-width: 0;
	max-width: 220px;
	margin: 0;
	padding: 0;
	background: none;
}

/* Первый кадр листинга рисует сортировку дважды.

   Select2 поднимается на jQuery ready, то есть после того, как
   страница уже отрисована, и до этого момента на экране виден сам
   <select> — родительская тема даёт ему 48 высотой, 17-й кегль
   и синюю рамку (замер на 390: 227x48, 17px, #2e5fda), а плашка
   Select2 следом встаёт 227x30, 13-м кеглем и серой рамкой.
   Отсюда и «загружается прошлый вариант, а потом новый».

   Прятать select до инициализации нельзя: не приедет listing.js —
   и сортировка пропадёт совсем. Поэтому нативному select даём
   ровно тот же вид, что и плашке Select2; подмена остаётся,
   но перестаёт быть видна.

   Стрелку не рисуем: у Select2 она своя, и подложить под неё
   вторую значило бы ловить их наложение в момент подмены. */
body.pdd .pdd-listing__toolbar .pdd-sort > select {
	box-sizing: border-box;
	width: 100%;
	height: var(--control-height-map);
	min-height: 0;
	margin: 0;
	padding: 0 var(--space-6);
	font-family: inherit;
	font-size: var(--font-size-meta);
	font-weight: var(--font-weight-regular);
	line-height: var(--line-height-base);
	color: var(--color-text);
	background: var(--color-surface);
	border: var(--border-width) solid var(--color-border);
	border-radius: var(--radius-md);
	appearance: none;
	-webkit-appearance: none;
}

body.pdd .pdd-listing__toolbar .pdd-sort .select2-container {
	min-width: 100%;
	max-width: 100%;
}

body.pdd .pdd-listing__toolbar .pdd-sort .select2-container--default .select2-selection--single {
	height: var(--control-height-map);
	display: flex;
	align-items: center;
	padding: 0 var(--space-6);
	background: var(--color-surface);
	border: var(--border-width) solid var(--color-border);
	border-radius: var(--radius-md);
}

body.pdd .pdd-listing__toolbar .pdd-sort .select2-container--default .select2-selection--single .select2-selection__rendered {
	padding: 0;
	font-size: var(--font-size-meta);
	line-height: var(--line-height-base);
	color: var(--color-primary);
	font-weight: var(--font-weight-medium);
}

body.pdd .pdd-listing__toolbar .pdd-sort .select2-container--default .select2-selection--single .select2-selection__placeholder {
	color: var(--color-text);
	font-weight: var(--font-weight-regular);
}

body.pdd .pdd-listing__toolbar .pdd-sort .select2-container--default .select2-selection--single .select2-selection__arrow {
	height: 100%;
}

/* «Применить фильтры» — плавающая кнопка движка, показывается
   только когда панель фильтров открыта */
body.pdd .apply_filter {
	border-radius: var(--radius-lg);
}

/* Плавающая полоса снизу: те же «Фильтры» и «На карте», что уже
   стоят в панели. В разметке оставлена (её ищет код движка),
   на экране не нужна. */
body.pdd .mobile-buttons-filter-compare {
	display: none;
}

/* ============================================================
   13. СПИСОК И «ЗАГРУЗИТЬ ЕЩЁ»

   Источник — design2/assets/css/main.css, строки 1087–1114.
   ============================================================ */
body.pdd .pdd-listing__content #objects {
	margin-top: var(--space-6);
}

/* Лента карточек в эталоне шире остальной страницы: поле сетки 8px
   (--grid-padding) против 16px у заголовка и панели. .container даёт
   16 — выносим на разницу в минус ИМЕННО список и кнопку под ним,
   а не всю колонку: панель фильтров и строка поиска остаются на 16,
   как в прототипе. Замер: карточка 374 при экране 390. */
@media (max-width: 1023px) {
	body.pdd .pdd-listing__content #objects,
	body.pdd .pdd-listing__content > .pdd-load-more {
		margin-inline: calc(var(--grid-padding) - var(--page-padding));
	}
}

body.pdd .pdd-load-more {
	display: block;
	margin-top: var(--space-7);
	text-decoration: none;
}

body.pdd .pdd-load-more__button {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	max-width: none;
	height: var(--control-height-button);
	margin: 0;
	padding: 0;
	font-size: var(--font-size-button);
	font-weight: var(--font-weight-semibold);
	color: var(--color-text);
	background: var(--color-surface);
	border: var(--border-width) solid var(--color-border);
	border-radius: var(--radius-lg);
	box-shadow: var(--shadow-card);
}

body.pdd .pdd-load-more__button:hover {
	background: var(--color-surface-muted);
	border-color: var(--color-border-strong);
	color: var(--color-text);
}

/* ============================================================
   14. ПАНЕЛЬ ФИЛЬТРОВ

   Источник — design2/assets/css/main.css, строки 492–874
   (.sheet, .sheet__section, .sheet__row и прочее). Токены
   --sheet-* уже лежат в tokens.css, поэтому здесь только правила
   и только по классам движка: разметку панели мы не переписываем,
   на её data-атрибутах держится сборка запроса в listing.js.
   ============================================================ */
body.pdd .pdd-sheet {
	/* Токены панели рассчитаны на шторку во всю ширину экрана:
	   боковые поля там даёт --page-padding на головах секций,
	   а у самих секций горизонтального поля нет. У нас панель
	   стоит карточкой с рамкой, поэтому поле нужно и секциям. */
	--sheet-section-pad: var(--space-5) var(--space-6);

	/* 16/16/12 — поля головы панели в эталоне (.sheet__head, замер
	   на 1280: 16 сверху, 12 снизу, 16 по бокам). */
	--sheet-head-pad: var(--space-7) var(--space-7) var(--space-6);
	--sheet-foot-pad: var(--space-5) var(--space-6);
	--sheet-row-pad: 0;

	background: var(--color-surface);
	border: var(--border-width) solid var(--color-border);
	border-radius: var(--radius-xl);
	box-shadow: var(--shadow-card);
}

/* line-height задан явно: без него шапку меряет строка темы
   (17/31), и голова панели выходит 62 вместо 54 эталона
   (замер .sheet__head на 1280: 274x54 = 16 + 25 + 12 + рамка). */
body.pdd .pdd-sheet__title {
	display: flex;
	align-items: center;
	gap: var(--space-5);
	padding: var(--sheet-head-pad);
	font-size: var(--sheet-title-size);
	font-weight: var(--sheet-title-weight);
	line-height: var(--line-height-base);
	color: var(--color-text);
	border-bottom: var(--border-width) solid var(--color-border);
}

body.pdd .pdd-sheet__title-text {
	flex: 1 1 auto;
}

/* «Сбросить» в голове панели — действие, а не подпись, поэтому
   идёт цветом марки (эталон .sheet__reset, main.css:575–582). */
body.pdd .pdd-sheet__reset {
	display: flex;
	align-items: center;
	flex: 0 0 auto;
	padding: 0;
	font-family: inherit;
	font-size: var(--font-size-control);
	font-weight: var(--font-weight-medium);
	line-height: var(--line-height-base);
	color: var(--color-primary);
	background: none;
	border: none;
	cursor: pointer;
}

body.pdd .pdd-sheet__reset:hover {
	color: var(--color-primary-strong, var(--color-primary));
	opacity: 0.85;
}

/* Прежняя ссылка сброса внизу панели. Убрать её из разметки
   нельзя: по ней движок выстраивает порядок секций
   (listing.js:182–198), см. комментарий в скине. */
body.pdd .pdd-sheet .reset-all-filters.pdd-sheet__reset-anchor {
	display: none;
}

/* ---- секция фильтра ---- */
body.pdd .pdd-sheet .category-filter {
	margin: 0;
	padding: var(--sheet-section-pad);
	background: var(--sheet-section-bg);
	border: none;
	border-bottom: var(--border-width) solid var(--color-border);
	border-radius: 0;
}

body.pdd .pdd-sheet .category-filter:last-of-type {
	border-bottom: none;
}

body.pdd .pdd-sheet .title-newfilter {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--space-4);
	min-height: var(--sheet-section-head-height);
	margin: 0;
	padding: 0;
}

body.pdd .pdd-sheet .title-newfilter b {
	font-size: var(--sheet-section-title-size);
	font-weight: var(--sheet-section-title-weight);
	color: var(--sheet-section-title-fg);
	text-transform: var(--sheet-section-title-transform);
}

body.pdd .pdd-sheet .title-newfilter .arrow-down {
	flex: 0 0 auto;
	color: var(--color-icon-strong);
	background-color: transparent;
	border: none;
}

/* ---- поиск внутри секции ----

   Строка поиска — то же поле, что и везде на сайте (.search__input
   эталона, main.css:923-942): 40 высоты, белый фон, рамка #dfe3ee,
   радиус 8, лупа слева. До этой правки поле брало токены
   --sheet-field-*, а они заведены под вилку цены — поле-подчёркивание
   без фона, без полей и без скругления (tokens.css:475-480). На
   экране выходил голый прямоугольник, ни на что на сайте не похожий.

   Лупа — фоновой картинкой, а не отдельным узлом: разметку строки
   печатает движок, своего места под иконку в ней нет. */
body.pdd .pdd-sheet .possticky {
	display: flex;
	align-items: center;
	gap: var(--space-3);
	margin: var(--space-4) 0 0;
	padding: 0 0 var(--space-3);

	/* Подложка обязательна. Движок держит строку липкой
	   (position: sticky, z-index 99), и список секции, уезжая
	   под неё, просвечивал сквозь прозрачный фон: строки
	   наезжали на поиск и читались обе сразу. */
	background: var(--color-surface);
}

body.pdd .pdd-sheet .search-in-filter {
	flex: 1;
	min-width: 0;
	height: var(--control-height-search);

	/* margin: 0 — не косметика. Движок задаёт полю нижнюю отбивку,
	   и строка-флекс вырастала на неё (56 вместо 40): поле вставало
	   по верхнему краю, а кнопка «Все» — по центру строки, то есть
	   на 8px ниже поля. Это и есть «кнопка поехала». */
	margin: 0;
	padding: 0 var(--space-6) 0 36px;
	font-family: inherit;
	font-size: var(--font-size-input);
	color: var(--color-text);
	background: var(--color-surface) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%239aa0b0' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7'/%3E%3Cpath d='m20 20-3.5-3.5'/%3E%3C/svg%3E") no-repeat var(--space-6) center;
	border: var(--border-width) solid var(--color-border-strong);
	border-radius: var(--radius-lg);
}

body.pdd .pdd-sheet .search-in-filter::placeholder {
	color: var(--color-text-muted);
	opacity: 1;
}

body.pdd .pdd-sheet .search-in-filter:focus {
	outline: none;
	border-color: var(--color-primary);
}

body.pdd .pdd-sheet .select-all-localfilter {
	flex: 0 0 auto;
	height: var(--control-height-search);
	margin: 0;
	padding: 0 var(--space-6);
	font-size: var(--font-size-control);
	line-height: var(--control-height-search);
	color: var(--color-primary);
	background: var(--color-primary-soft);
	border: none;
	border-radius: var(--radius-lg);
}

/* ---- строки-опции ----

   Эталон (.sheet__rows / .sheet__row / .sheet__box, main.css:706–745;
   замер 19.08.2026 на 1440): список — сетка с шагом 2, строка 242x42
   без внутренних полей, коробка 22x22 с волосяной рамкой, от неё до
   подписи 10, подпись 14/1.45 своей шириной (210, а не вся строка).

   Движок печатает строку иначе: <li><label><input><span>. Поле между
   строками даёт `#sidebar ul li { margin-bottom: 10px }`, а коробку
   рисует skin.css фоном-картинкой 25x25 со штрихом 2px #D9D9D9.

   #sidebar в селекторах обязателен: правила движка бьют по id,
   цепочкой классов их не перебить. */
body.pdd #sidebar.pdd-sheet .category-new {
	display: grid;
	gap: var(--space-1);
	margin: 0;
	padding: 0;
	list-style: none;
}

body.pdd #sidebar.pdd-sheet .category-new li {
	margin: 0;
	padding: 0;
	list-style: none;
}

body.pdd #sidebar.pdd-sheet .checkbox-new,
body.pdd #sidebar.pdd-sheet .radio-new {
	position: relative;
	display: flex;
	align-items: center;
	gap: var(--sheet-row-gap);
	min-height: var(--sheet-row-height);
	margin: 0;
	padding: var(--sheet-row-pad);
	font-size: var(--sheet-row-size);
	color: var(--color-text);
	cursor: pointer;
}

/* Коробка отметки.

   Рисуется псевдоэлементом самой строки, а не подписи: строка —
   flex, поэтому ::before встаёт отдельной колонкой, до подписи
   получается ровно --sheet-row-gap, а подпись остаётся своей
   шириной, как .sheet__row-label в эталоне.

   Картинку движка гасим целиком: skin.css рисует коробку фоном
   .checkbox_text:after, и отмеченное состояние там ещё и
   с !important (skin.css:1447–1456) — перебить его можно было бы
   только своим !important, поэтому :after просто снят с показа. */
body.pdd #sidebar.pdd-sheet .checkbox_text::after,
body.pdd #sidebar.pdd-sheet .radio_text::after,
body.pdd #sidebar.pdd-sheet .radio_text::before {
	display: none;
}

body.pdd #sidebar.pdd-sheet .checkbox-new::before,
body.pdd #sidebar.pdd-sheet .radio-new::before {
	content: "";
	flex: 0 0 auto;
	width: var(--sheet-box-size);
	height: var(--sheet-box-size);
	background: var(--sheet-box-bg);
	border: var(--sheet-box-border);
	border-radius: var(--sheet-box-radius);
}

body.pdd #sidebar.pdd-sheet .radio-new::before {
	border-radius: var(--radius-pill);
}

/* Отмеченная строка. :has() читает живое состояние input: движок
   правит галочки без перезагрузки, переключая само свойство. */
body.pdd #sidebar.pdd-sheet .checkbox-new:has(input:checked)::before,
body.pdd #sidebar.pdd-sheet .radio-new:has(input:checked)::before {
	background: var(--sheet-box-active-bg) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='m3 8.4 3.2 3.2L13 4.8' stroke='%23ffffff' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center center no-repeat;
	border-color: var(--sheet-box-active-border);
}

body.pdd #sidebar.pdd-sheet .checkbox_text,
body.pdd #sidebar.pdd-sheet .radio_text {
	flex: 1 1 auto;
	display: block;
	min-width: 0;
	padding: 0;
	overflow: hidden;
	font-size: var(--sheet-row-size);
	line-height: var(--line-height-base);
	color: inherit;
	text-overflow: ellipsis;
	white-space: nowrap;
}

/* вложенные ветки — отступом, как в прототипе */
body.pdd .pdd-sheet .category-new ul {
	margin: 0 0 0 var(--space-6);
	padding: 0;
	list-style: none;
}

/* ---- низ панели ---- */
body.pdd .pdd-sheet .reset-all-filters {
	display: block;
	padding: var(--sheet-foot-pad);
	font-size: var(--font-size-control);
	color: var(--color-text-secondary);
	text-align: center;
}

body.pdd .pdd-sheet .reset-all-filters:hover {
	color: var(--color-primary);
}

body.pdd .pdd-sheet .apply-all-filters-wrapper {
	padding: var(--sheet-foot-pad);
	background: var(--sheet-foot-bg);
	border-top: var(--border-width) solid var(--color-border);
}

body.pdd .pdd-sheet .apply-all-filters {
	display: flex;
	align-items: center;
	justify-content: center;
	width: 100%;
	height: var(--sheet-apply-height);
	font-size: var(--sheet-apply-size);
	font-weight: var(--font-weight-semibold);
	color: var(--sheet-apply-fg);
	background: var(--sheet-apply-bg);
	border-radius: var(--sheet-apply-radius);
}

body.pdd .pdd-sheet .apply-all-filters:hover {
	color: var(--sheet-apply-fg);
	opacity: 0.92;
}

/* ============================================================
   15. ШИРОКИЙ ЭКРАН: КАРКАС СТРАНИЦЫ

   Источник — design2/assets/css/web.css, строки 170–226
   (каркас «фильтры · карточки · карта») и 1477–1530 (третья
   колонка с картой от 1280px).

   Каркас движка — .container > .filter_result_wrapper + .content,
   поэтому колонки раздаются им, а не блокам прототипа.
   ============================================================ */
@media (min-width: 1024px) {

	/* Подмены токенов широкого экрана — ровно те же, что прототип
	   держит на .listing (design2/assets/css/web.css, 80–124):
	   мышь вместо пальца, места больше. */
	body.pdd.page-template-newlisting {
		--grid-gap: 14px;
		--grid-padding: 0px;
		--font-size-title: 28px;
		--font-size-subtitle: 15px;
		--action-height: 40px;
		--action-font: 14px;

		/* Шапка на широком экране уезжает вместе со страницей.

		   В эталоне .topbar здесь — такой же элемент общей сетки
		   .app, как заголовок и лента (web.css:196-202: grid-column
		   1/-1, grid-row 1). Липкость у элемента сетки ограничена
		   его же строкой в один ряд высотой, то есть не работает
		   вовсе, и шапка эталона просто уходит за верхний край.

		   У нас шапка печатается движком выше .container и в сетку
		   листинга не попадает, поэтому sticky из tokens.css здесь
		   срабатывал по-настоящему и полоса висела над списком.
		   Липкость нужна только в узкой ширине: там шапка прячется
		   и возвращается по прокрутке (--topbar-slide), и это
		   поведение эталона для телефона. */
		--topbar-position: static;
	}

	/* Шапка архива и каркас списка стоят на ОДНОЙ сетке.

	   В прототипе это одна сетка .app на всю страницу, и .page-header
	   в ней — такой же её ребёнок, как панель фильтров и лента
	   (web.css, 196–207). У движка шапка печатается отдельным узлом
	   .cap рядом с .container, поэтому сетка задаётся обоим одинаково:
	   тогда заголовок начинается ровно там же, где панель фильтров,
	   и кончается там же, где лента.

	   display с !important. Проверено 14.08.2026: в skin.css стоит

	       .page-template-newlisting main .container:has(.filter_result_wrapper),
	       .page-template-newlisting main .flex-listing-content,
	       .faq_block_inner .container   { display: flex !important }

	   и он бил наш grid. Из-за этого широкий экран не собирался
	   вовсе: фильтры, список и карта вставали друг под другом
	   (замер на 1440: сайдбар 384 сверху, список 1210 под ним,
	   карта 2px сбоку). Специфичность тут не помогает — !important
	   перебивается только !important.

	   Ширина страницы до 1280px — колонка --content-max по центру,
	   как на главной и карточке школы (web.css, 187–192). От 1280px
	   ограничение снимается: там справа встаёт карта до края окна. */
	body.pdd.page-template-newlisting .cap.pdd-page-header,
	body.pdd.page-template-newlisting .container.pdd-listing__layout {
		display: grid !important;
		grid-template-columns: var(--web-sidebar-width) minmax(0, var(--web-content-width));
		align-items: start;
		column-gap: var(--space-6);

		width: auto;
		max-width: calc(var(--content-max) + var(--page-padding) * 2);
		margin-inline: auto;
		padding-inline: var(--page-padding);
	}

	/* Внутренняя обёртка шапки — не колонка сетки, а её строка:
	   .cap-left/.cap-right внутри раскладывает уже сама сводка.

	   Лишний .pdd-listing в цепочке — не украшение: ровно тот же
	   селектор без него стоит в разделе 11a НИЖЕ по файлу и при
	   равном весе выигрывает, оставляя шапке flex. */
	body.pdd.page-template-newlisting .pdd-listing .cap.pdd-page-header > .container {
		grid-column: 1 / -1;
		display: block;
		width: auto;
		max-width: none;
		margin-inline: 0;
		padding: var(--space-8) 0 0;
	}

	/* Липкая здесь не колонка, а сама панель: колонка тянется во всю
	   высоту сетки, панель едет внутри неё (web.css, 1151–1177).
	   Прежний вариант — прокрутка у колонки — обрезал панель по высоте
	   экрана: замер давал 276x880 при 1598 содержимого. */
	body.pdd .pdd-listing__side {
		grid-column: 1;
		width: auto;
		align-self: stretch;
		overflow: visible;

		/* Колонка стоит ровно от низа сводки до низа кнопки
		   «Загрузить ещё» — как в эталоне, где .sheet занимает
		   строки 3–5 сетки и кончается вместе с .load-more (замер
		   на 1440: и колонка, и кнопка кончаются на 4617).

		   Оба отступа — чужие. Сверху движок вешает
		   .filter_result_wrapper margin: 40px, из-за него панель
		   начиналась на 40 ниже сводки; снизу тот же margin
		   опускал низ колонки под кнопку. Замер до правки:
		   колонка 288..4440, кнопка 4418..4464. */
		margin-block: 0;
	}

	/* Нижние 16 — margin ленты, из-за него строка сетки была
	   на 16 длиннее кнопки, и колонка фильтров не сходилась
	   с ней низом. Отбивку до хвоста страницы держат сами
	   блоки хвоста. */
	body.pdd .pdd-listing__content {
		grid-column: 2;
		width: auto;
		margin-bottom: 0;
	}

	/* Внутренняя обёртка панели держит свою ширину от движка
	   (384px) и вылезала из колонки 276.

	   Высота на 100% — не украшение, а единственное, что даёт
	   панели прилипать. Липкий узел ездит внутри своего родителя
	   и дальше его низа не идёт; у движка обе обёртки
	   (.filter_wrapper и .container.flex-listing-content)
	   схлопывались ровно в высоту панели — замер на 1440 давал
	   888 при 888, — и ехать ей было некуда: панель уходила вверх
	   вместе с лентой. Колонка .pdd-listing__side уже растянута
	   на всю сетку (align-self: stretch), эти две обёртки тянем
	   следом. В эталоне так же: .sheet растянут по строкам сетки,
	   липкая — .sheet__panel внутри него (web.css:1151–1166). */
	body.pdd .pdd-listing__side .filter_wrapper,
	body.pdd .pdd-listing__side .container.flex-listing-content {
		width: 100%;
		max-width: none;
		height: 100%;
	}

	/* карта в разметке есть всегда, но переносит её туда JS
	   и только от 1280px — до этой ширины колонки на неё не хватает */
	body.pdd .pdd-webmap {
		display: none;
	}

	/* ----------------------------------------------------------
	   Строка над списком — .webbar прототипа (web.css, 430–508
	   и 744–774).

	   Одна белая плашка на всю ширину ленты: поиск слева,
	   сортировка и разделы «Списком · На карте» справа. В эталоне
	   плашкой служит сама .search-row, у движка поиск и результаты
	   лежат в двух рядах внутри .pdd-toolbar — плашкой становится
	   она, а ряды внутри превращаются в её части.
	   ---------------------------------------------------------- */
	/* Отбивку сверху держит внешний узел, а не плашка: у плашки
	   margin-top ушёл бы схлопыванием наружу, и .pdd-webbar мерился
	   бы на 16px ниже эталона (78 против 62). */
	body.pdd .pdd-listing__toolbar {
		padding-top: var(--space-7);
	}

	body.pdd .pdd-listing__toolbar .pdd-toolbar {
		flex-direction: row;
		flex-wrap: wrap;
		align-items: center;
		gap: var(--space-4);
		padding: var(--space-5);
		background: var(--color-surface);
		border: var(--border-width) solid var(--color-border);
		border-radius: var(--radius-xl);
		box-shadow: var(--shadow-card);
	}

	body.pdd .pdd-listing__toolbar .pdd-search-row {
		flex: 1 1 320px;
		margin-top: 0;
	}

	body.pdd .pdd-listing__toolbar .pdd-results {
		flex: 0 0 auto;
		align-items: center;
		gap: var(--space-4);
		padding: 0;
	}

	/* кнопка фильтров нужна только там, где панель прячется
	   в шторку; на широком экране панель стоит колонкой слева */
	body.pdd .pdd-listing__toolbar .pdd-filter-button {
		display: none;
	}

	/* ---- сортировка: селект движка в виде .sortbox эталона ----

	   Сам селект скрыт плагином select2 (он подменяет его своей
	   разметкой), поэтому размеры и обводка задаются контейнеру
	   select2, а не <select>. Переписывать контрол на свой
	   выпадающий список нельзя: на <select> висит data-url="query",
	   по которому listing.js собирает запрос сортировки. */
	body.pdd .pdd-listing__toolbar .pdd-sort {
		flex: 0 0 auto;
		width: auto;
		max-width: none;
		height: var(--control-height-search);
	}

	body.pdd .pdd-listing__toolbar .pdd-sort .select2-container,
	body.pdd .pdd-listing__toolbar .pdd-sort .select2-selection--single,
	body.pdd .pdd-listing__toolbar .pdd-sort .selection {
		width: 223px;
		height: var(--control-height-search);
	}

	body.pdd .pdd-listing__toolbar .pdd-sort .select2-selection--single {
		display: flex;
		align-items: center;
		padding: 0 var(--space-5);
		background: var(--color-surface);
		border: var(--border-width) solid var(--color-border-strong);
		border-radius: var(--radius-lg);
	}

	body.pdd .pdd-listing__toolbar .pdd-sort .select2-selection__rendered {
		padding: 0;
		font-size: var(--font-size-meta);
		font-weight: var(--font-weight-semibold);
		color: var(--color-text);
		line-height: normal;
	}

	body.pdd .pdd-listing__toolbar .pdd-sort .select2-selection__placeholder {
		color: var(--color-text-secondary);
		font-weight: var(--font-weight-regular);
	}

	/* Порядок в правой половине панели: сначала сортировка, потом
	   разделы — как в эталоне. Разметка движка печатает их в этом же
	   порядке, но frontend.css раздаёт .sort свой order, и разделы
	   вставали левее сортировки. */
	body.pdd .pdd-listing__toolbar .pdd-sort {
		order: 0;
	}

	/* ---- разделы «Списком · На карте» ---- */
	body.pdd .pdd-webtabs {
		order: 1;
		display: inline-flex;
		gap: var(--space-2);
		padding: 3px;
		background: var(--color-surface-muted);
		border-radius: var(--radius-lg);
	}

	body.pdd .pdd-webtabs__item {
		display: inline-flex;
		align-items: center;
		justify-content: center;
		gap: var(--space-3);
		width: auto;
		max-width: none;
		height: calc(var(--control-height-search) - 6px);
		margin: 0;
		padding: 0 var(--space-6);
		font-size: var(--font-size-control);
		font-weight: var(--font-weight-regular);
		color: var(--color-text-secondary);
		background: none;
		border: 0;
		border-radius: var(--radius-md);
		box-shadow: none;
	}

	body.pdd .pdd-webtabs__item:hover {
		color: var(--color-text);
	}

	body.pdd .pdd-webtabs__item.is-active {
		font-weight: var(--font-weight-semibold);
		color: var(--color-text);
		background: var(--color-surface);
		box-shadow: var(--shadow-card);
	}
}

/* Ниже 1024px разделов нет: там мобильная строка движка, в которой
   «На карте» стоит одной кнопкой, как и было. Обёртка растворяется,
   чтобы кнопка осталась ребёнком .pdd-results и её не перекрашивала
   плашка разделов. */
@media (max-width: 1023.98px) {

	body.pdd .pdd-webtabs {
		display: contents;
	}

	body.pdd .pdd-webtabs__item--list {
		display: none;
	}
}

/* ------------------------------------------------------------
   От 1280px страница разбита надвое: слева фильтры со списком,
   справа карта во всю высоту экрана. Карту в свою колонку
   переносит pdd-listing.js — сама она лежит в модальном окне
   движка, и переносить её разметку в PHP нельзя: модалку
   открывает кнопка «На карте», а инициализирует карту чужой
   скрипт по своим событиям.
   ------------------------------------------------------------ */
@media (min-width: 1280px) {

	/* Четыре колонки эталона (web.css, 1481–1512): поле слева, панель
	   фильтров, лента и карта до края окна. Лента держит свои 864
	   при любой ширине окна, а всё лишнее забирает карта — поэтому
	   на 1280 она узкая (замер эталона: 69px), а к 1440 дорастает
	   до 188. Раньше здесь стояла фиксированная колонка карты
	   --web-map-width, и на 1280 недостающие 104px карта отъедала
	   у ленты: 760 вместо 864. */
	body.pdd.pdd-listing--map.page-template-newlisting .cap.pdd-page-header,
	body.pdd.page-template-newlisting .container.pdd-listing__layout--map {
		grid-template-columns:
			minmax(var(--space-6), 0.35fr)
			var(--web-sidebar-width)
			var(--web-content-width)
			minmax(0, 1fr);
		max-width: none;
		margin-inline: 0;

		/* Левое поле = поле страницы плюс сдвиг (раздел 1).
		   До 1600px сдвиг нулевой и правило ничего не меняет. */
		padding-left: calc(var(--page-padding) + var(--web-content-shift));
	}

	body.pdd .pdd-listing__layout--map .pdd-listing__side {
		grid-column: 2;
	}

	/* Цепочка повторяет правило раздела выше: там у шапки
	   grid-column: 1 / -1 весом (0,6,1), и коротким селектором
	   его не перебить — заголовок разъезжался с колонкой фильтров
	   и накрывал ещё и карту. */
	body.pdd.pdd-listing--map.page-template-newlisting .pdd-listing .cap.pdd-page-header > .container {
		grid-column: 2 / 4;
	}

	body.pdd .pdd-listing__layout--map .pdd-listing__content {
		grid-column: 3;
	}

	body.pdd .pdd-listing__layout--map .pdd-webmap {
		display: block;
		grid-column: 4;
		grid-row: 1 / -1;
		align-self: stretch;

		/* карта доходит до самого края окна */
		margin-right: calc(-1 * var(--page-padding));
	}

	/* ---- Карта во всю высоту окна, а не в границах ленты ----

	   Эталон: колонка карты занимает всю сетку страницы целиком
	   (web.css:1505–1512, grid-row: 1 / -1), а внутри неё подложка
	   липкая, top: 0, height: 100vh, без скруглений и без рамок,
	   кроме левой (web.css:1514–1521). Замер эталона на 1440:
	   .webmap 188x5173 от y=0, .webmap__inner 188x1000.

	   У нас колонка живёт в .container.pdd-listing__layout, а он
	   начинается ПОД шапкой листинга и кончается задолго до конца
	   документа — замер давал 188x3900 от y=288 при документе 6109.
	   Липкая подложка ограничена родителем и потому пропадала
	   и сверху, и снизу.

	   Растянуть саму колонку нельзя: её сетка — это .container,
	   а сводка, SEO-блоки и подвал лежат вне его. Поэтому липкую
	   подложку меняем на фиксированную: она не привязана ни к
	   какому родителю и видна на всей прокрутке, ровно как липкая
	   подложка эталона. Левый край берётся у самой колонки —
	   ширину так по-прежнему раздаёт сетка, а не арифметика:
	   переменную пишет pdd-listing.js при загрузке и на ресайзе.

	   В режиме «На карте» карта встаёт на место ленты обычным
	   блоком — там фиксированная подложка не нужна. */
	body.pdd .pdd-listing__layout--map:not(.pdd-listing__layout--mapmode) .pdd-webmap__inner {
		position: fixed;
		top: 0;
		right: 0;
		left: var(--pdd-map-left, auto);

		/* Ширину задают left и right, а не 100%: у чужого #map_outer
		   ширина стоит с !important, и переопределить её нечем —
		   поэтому фиксируется обёртка, а чужие 100% считаются уже
		   от неё (см. комментарий в pdd-listing.js, dock). */
		width: auto;
		height: 100vh;
		padding: 0;
		overflow: hidden;
		border: none;
		border-left: var(--border-width) solid var(--color-border);
		border-radius: 0;
	}

	body.pdd .pdd-listing__layout--mapmode .pdd-webmap__inner {
		position: sticky;
		top: var(--space-5);
		height: calc(100vh - var(--space-8));
		padding: 0;
		overflow: hidden;
		border: var(--border-width) solid var(--color-border);
		border-radius: var(--radius-xl);
	}

	body.pdd .pdd-webmap .modal-body,
	body.pdd .pdd-webmap #map_outer {
		height: 100%;
		padding: 0;
	}

	/* ---- Хвост страницы и подвал — по краям ленты ----

	   Карта стоит колонкой до самого края окна, а всё, что идёт
	   ниже сетки листинга (SEO-блоки, кросслинки, подвал сайта),
	   лежит вне её и центруется по окну: замер на 1440 давал
	   подвал 1152 от x=144, то есть до 1296 — при том что карта
	   начинается с 1252. Отсюда и наезд.

	   В эталоне подвал занимает те же колонки, что заголовок
	   и лента, и кончается ровно там же, где они (замер: .footer
	   1152 от x=88, карта с 1252, между ними те же 12 зазора).

	   Края берутся у самого заголовка — переменные пишет
	   pdd-listing.js, — а не считаются заново по токенам колонок:
	   так они не разъедутся, если ширины поменяют. */
	body.pdd.pdd-listing--map .pdd-listing > *:not(.pdd-page-header):not(.pdd-listing__layout),
	body.pdd.pdd-listing--map .pdd-footer {
		width: var(--pdd-content-width, auto);
		max-width: none;
		margin-right: 0;
		margin-left: var(--pdd-content-left, auto);
	}

	body.pdd .pdd-webmap .ym-container,
	body.pdd .pdd-webmap [id^="map-"] {
		width: 100%;
		height: 100%;
	}

	/* Раздел «На карте»: лента уступает место, карта занимает всю
	   ширину контента — от своей колонки и до края окна
	   (web.css, 776–787).

	   Строка над списком при этом остаётся на экране: разделы
	   переключают именно ею. Поэтому в этом режиме у сетки
	   появляется вторая строка — панель сверху, карта под ней. */
	body.pdd .pdd-listing__layout--mapmode {
		grid-template-rows: auto minmax(0, 1fr);
	}

	body.pdd .pdd-listing__layout--mapmode .pdd-listing__side {
		grid-row: 1 / -1;
	}

	body.pdd .pdd-listing__layout--mapmode .pdd-listing__content {
		grid-row: 1;
	}

	body.pdd .pdd-listing__layout--mapmode #objects,
	body.pdd .pdd-listing__layout--mapmode .pdd-load-more {
		display: none;
	}

	body.pdd .pdd-listing__layout--mapmode .pdd-webmap {
		grid-row: 2;
		grid-column: 3 / -1;
	}
}

/* ------------------------------------------------------------
   12a. РАЗМЕРЫ ДВУХ КОНТРОЛОВ ПАНЕЛИ

   «На карте» и сортировка — единственные два места на странице,
   где движок задаёт ширину селекторами тяжелее наших. Замерено
   на живой странице (перечислены все правила, задающие width
   или max-width этим узлам):

     .sorting_search .sort                          w 100%  mw 235px  frontend.css
     .sorting_search .sort            @991          w 100%  mw 250px  frontend.css
     .page-template-newlisting .sorting_search .sort @991   w 100%  mw 100%  frontend.css
     .sorting-full.sorting_search .sort                     w 100%  mw 175px  skin.css
     .sorting-full.sorting_search .sort              @991           mw none   skin.css
     .seemap                                        w 100%  mw 222px  frontend.css + skin.css
     .page-template-v3 .seemap                              mw 133px  skin.css

   Самое тяжёлое здесь — (0,3,0). Наши (0,3,1) выигрывают не у всех
   сочетаний, потому что чужие правила раскиданы по медиазапросам
   и добивают друг друга по порядку. Поэтому для этих двух узлов
   берём заведомо больший вес — (0,5,1), повторяя чужую цепочку
   целиком, — и задаём и width, и max-width сразу: без явного width
   у флекс-элемента базой остаётся чужие 100%, и кнопка «На карте»
   занимала всю строку, выталкивая сортировку за край экрана.

   Ни одного !important: чужие правила здесь обычные, их берёт
   специфичность.
   ------------------------------------------------------------ */
body.pdd.page-template-newlisting .sorting-full.sorting_search .pdd-map-button {
	width: auto;
	max-width: none;
}

body.pdd.page-template-newlisting .sorting-full.sorting_search .pdd-sort {
	width: 100%;
	max-width: 220px;
}

@media (min-width: 1024px) {

	/* Базис флекса, а не ширина: у флекс-элемента flex-basis сильнее
	   width, и пока здесь стояло 220px, поле оставалось 220 при любых
	   правилах ширины ниже по файлу. Размер задаёт раздел 21. */
	body.pdd.page-template-newlisting .sorting-full.sorting_search .pdd-sort {
		flex: 0 0 auto;
	}
}

/* ------------------------------------------------------------
   11a. ЗАГОЛОВОК: СНЯТИЕ ПЛАШКИ ДВИЖКА

   Тот же случай, что с контролами панели: движок описывает шапку
   листинга цепочками в три класса, и (0,2,1) наших правил им
   проигрывает. Замерено на живой странице:

     .cap .cap-left                      padding 32px 40px   frontend.css
     .page-template-newlisting .cap .cap-left   padding 30px 40px   skin.css
     .page-template-newlisting .cap .cap-left   padding 20px        skin.css @мобильная
     .page-template-newlisting .cap .container  display grid        skin.css

   В прототипе (part-archive-header) заголовок лежит прямо на фоне
   страницы: белой плашки под ним нет, полей у неё нет, и высоту
   ей никто не задаёт — блок ровно по тексту. Поэтому здесь плашка
   снимается целиком, а поля даёт .container страницы.
   ------------------------------------------------------------ */
body.pdd.page-template-newlisting .cap.pdd-page-header > .container {
	display: flex;
	flex-direction: row;
	flex-wrap: wrap;
	align-items: flex-start;
	gap: var(--space-6);
	padding-top: var(--space-8);
	padding-bottom: 0;
}

body.pdd.page-template-newlisting .cap.pdd-page-header .pdd-page-header__main {
	min-height: 0;
	margin: 0;
	padding: 0;
	background: none;
	border-radius: 0;
	box-shadow: none;
}

body.pdd.page-template-newlisting .cap.pdd-page-header .info-ver-3-outer {
	min-height: 0;
	margin: 0;
	padding: 0;
	background: none;
}

/* Высота шапки — по тексту.

   frontend.css задаёт .cap .container { align-items: stretch },
   и левая половина шапки растягивалась на высоту всего блока.
   align-self снимает растяжение у самого элемента и не зависит
   от того, кто последним выиграл align-items у контейнера. */
body.pdd.page-template-newlisting .cap.pdd-page-header .pdd-page-header__main {
	align-self: flex-start;
	height: auto;
}

body.pdd.page-template-newlisting .cap.pdd-page-header > .container {
	min-height: 0;
	height: auto;
}

/* Значение строки — в одну строку с иконкой.

   frontend.css задаёт .text-list-item-v3 ширину в 100%, и в нашем
   флексе значение уезжало на строку ниже иконки: у адреса это
   выглядело как пустая строка с булавкой. Явные flex и width
   возвращают значение в ряд, min-width: 0 разрешает многоточие. */
body.pdd .pdd-listing-card .pdd-listing-card__row {
	flex-wrap: nowrap;
}

body.pdd .pdd-listing-card .pdd-listing-card__row .text-list-item-v3 {
	flex: 1 1 auto;
	width: auto;
	min-width: 0;
}

/* Режим работы — исключение: там к значению добавляется бейдж
   состояния, и на узком экране паре нужен перенос. */
body.pdd .pdd-listing-card .pdd-listing-card__row--hours {
	flex-wrap: wrap;
}

/* И второе исключение той же строки: flex: 1 выше растягивает
   значение поля на всю ширину — для адреса это правильно
   (длинная строка, многоточие), а в режиме работы значений два,
   расписание и состояние. Растянутое расписание отбрасывало
   «Откроется завтра, 08:45» к правому краю карточки, за 700px
   от своей строки (замер 16.08.2026 на 1280). В эталоне «Открыто»
   и «до 21:00» стоят подряд сразу за часами. */
body.pdd .pdd-listing-card .pdd-listing-card__row--hours .text-list-item-v3 {
	flex: 0 1 auto;
}

/* ============================================================
   19. ГДЕ ПРИШЛОСЬ ОТВЕТИТЬ СВОИМ !important

   Правило темы «ни одного !important» держится специфичностью,
   и до сих пор её хватало. Но родительская тема и skin.css часть
   элементов листинга задают именно с !important, а он ничем, кроме
   ответного !important, не перебивается — специфичность здесь
   бессильна, каким бы длинным ни был селектор.

   Проверено 14.08.2026 через CSS.getMatchedStylesForNode
   (scripts/important-scan.js). Список чужих правил дословно:

       .seemap                        padding 14px 16px 14px 48px !important
       .page-template-v3 .seemap      border-radius 12px !important
                                      border 1px solid rgba(78,71,255,.2) !important
       .page-template-v3
         #search .input_text input    height 48px, border-radius 12px,
                                      border, background, padding,
                                      min-width 227px — всё !important
       .page-template-v3 .select2-container--default .select2-selection--single
                                      height 48px, border-radius 12px,
                                      border, background, padding !important
       .card-item-ver-3               box-shadow none !important
       .page-template-v3 .seemap,
         .page-template-v3 .compare_all @1200  color #0B0B0B !important
       .page-template-v3 .sorting_search      margin 0 0 24px 0 !important

   Разметку сменить нельзя: на button.seemap висит обработчик карты
   (yandex.js:23, google.js:118), на select — Select2, а .card-item-ver-3
   печатает движок. Поэтому здесь и только здесь — ответный !important,
   ровно по тем свойствам, что перечислены выше, и ни по одному лишнему.
   ============================================================ */

/* 19.1 «На карте» — эталон: 30px, поля 0/12, радиус 8, рамка --color-border.
        min-height обязателен: у .seemap стоит 48px, и без ответа кнопка
        держала 48 при height: 30. */
body.pdd .pdd-listing__toolbar .pdd-map-button.seemap {
	min-height: var(--control-height-map);
	padding: 0 var(--space-6) !important;
	border: var(--border-width) solid var(--color-border) !important;
	border-radius: var(--radius-md) !important;
}

/* 19.1.1 Она же на широком экране — вкладкой внутри серого трека.

        Там у кнопки другая роль: эталон рисует неактивную вкладку
        .webtabs__item вовсе без фона и рамки, 98x34, подписью 13/400
        цветом #5a5f6e (web.css:746–774). Свои же правила 19.1 и 12a
        описывают ОДИНОЧНУЮ мобильную кнопку и здесь мешают, поэтому
        цепочка длиннее на класс трека.

        !important тут по двум разным поводам: рамку с ним задаём мы
        сами строкой выше, а цвет — чужое правило
        `.page-template-v3 .seemap, .page-template-v3 .compare_all`
        (skin.css, от 1200px, color #0B0B0B !important). */
@media (min-width: 1024px) {

	body.pdd .pdd-listing__toolbar .pdd-webtabs .pdd-map-button.seemap {
		height: calc(var(--control-height-search) - 6px);
		min-height: 0;
		color: var(--color-text-secondary) !important;
		background: none;
		border: none !important;
		border-radius: var(--radius-lg) !important;
	}

	body.pdd .pdd-listing__toolbar .pdd-webtabs .pdd-map-button.seemap svg {
		color: inherit;
	}

	/* 19.1.2 Она же выбранная. Класс .is-active на обе вкладки ставит
	        bindViewTabs() (pdd-listing.js:402) — и ставил всегда, но
	        вид активной вкладки (.pdd-webtabs__item.is-active) до сюда
	        не доезжал: правило 19.1.1 выше красит .seemap цветом
	        с !important, а фон и тень сбрасывает своей веткой без
	        оглядки на состояние. Выходило, что «Списком» выделяется
	        плашкой, а «На карте» — никогда, хотя нажата именно она.

	        !important на color — ответ тому же чужому правилу
	        .page-template-v3 .seemap (skin.css, от 1200px). */
	body.pdd .pdd-listing__toolbar .pdd-webtabs .pdd-map-button.seemap.is-active {
		font-weight: var(--font-weight-semibold);
		color: var(--color-text) !important;
		background: var(--color-surface);
		box-shadow: var(--shadow-card);
	}
}

/* 19.2 Поле поиска — эталон: 40px, радиус 8, рамка --color-border-strong,
        текст 14px обычного начертания, иконка слева и отступ под неё 42px.

        Селектор начинается с #search намеренно: чужое правило —
        .page-template-v3 #search .input_text input, в нём ID, а ID
        сильнее любого числа классов. Без ответного ID наш !important
        проигрывал бы их !important по специфичности. */
body.pdd .pdd-listing__toolbar #search.pdd-search .input_text input {
	height: var(--control-height-search) !important;
	min-height: var(--control-height-search) !important;
	min-width: 0 !important;
	padding: 0 var(--space-6) 0 42px !important;
	font-size: var(--font-size-input) !important;
	font-weight: var(--font-weight-regular) !important;
	color: var(--color-text) !important;
	background: var(--color-surface) !important;
	border: var(--border-width) solid var(--color-border-strong) !important;
	border-radius: var(--radius-lg) !important;
}

/* Иконка лупы — псевдоэлемент .input_text::before, движок ставит её
   справа. В эталоне она слева, под неё и оставлен отступ 42px выше. */
body.pdd .pdd-listing__toolbar #search.pdd-search .input_text::before {
	left: var(--space-6);
	right: auto;
	width: 20px;
	height: 20px;
	background-size: 20px 20px;
}

/* 19.3 Сортировка — та же пара, что «На карте»: 30px, радиус 8 */
body.pdd .pdd-listing__toolbar .pdd-sort .select2-container--default .select2-selection--single {
	height: var(--control-height-map) !important;
	padding: 0 var(--space-6) !important;
	background: var(--color-surface) !important;
	border: var(--border-width) solid var(--color-border) !important;
	border-radius: var(--radius-md) !important;
}

/* 19.4 Тень карточки. skin.css гасит её у .card-item-ver-3 нацело,
        а в эталоне карточка приподнята: 0 1px 3px rgba(16,18,27,.07) */
body.pdd .pdd-listing-card.card-item-ver-3 {
	box-shadow: var(--shadow-card) !important;
}

/* 19.5 Отступ от строки над списком до первой карточки.

        Эталон: .webbar margin-bottom 12 (web.css:439–444). У нас
        стояло 24 — из skin.css правилом
        `.page-template-v3 .sorting_search { margin: 0 0 24px 0 !important }`.
        Отбивку задаёт именно строка над списком, а не промежуток
        сетки: у ленты карточек row-gap своих 14px, и они между
        карточками.

        Только от 1024px: ниже эталон эту строку прячет вовсе
        (web.css:66–73), сверять не с чем, и трогать сложившийся
        мобильный ритм из-за десктопного замера незачем. */
@media (min-width: 1024px) {

	body.pdd.page-template-newlisting .sorting-full.sorting_search.pdd-listing__toolbar {
		margin: 0 0 var(--space-6) !important;
	}
}

/* ============================================================
   20. ШИРОКИЙ ЭКРАН: СВОДКА НАД СПИСКОМ

   Источник — design2/assets/css/web.css, строки 318–428
   (.webhero) и design2/assets/js/web.js, heroTemplate().

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

   Раздел стоит в конце файла не для красоты: раздел 11 задаёт
   тому же .container display: flex тем же весом, и при равной
   специфичности выигрывает тот, кто ниже по файлу.
   ============================================================ */
@media (min-width: 1024px) {

	body.pdd .pdd-page-header .pdd-webhero {
		display: grid;
		grid-template-columns: minmax(0, 1fr) minmax(280px, 400px);
		gap: var(--space-6);
		margin-top: var(--space-6);
		align-items: stretch;
	}

	/* Блок справа — Carbon-поле crb_blocks сегмента. В базе оно
	   пустое у всех терминов (проверено SELECT'ом 14.08.2026),
	   и по общему правилу блок без данных не выводится: сводка
	   в этом случае занимает всю ширину, а не оставляет дыру. */
	body.pdd .pdd-page-header .pdd-webhero:has(> .pdd-webhero__promo:empty) {
		grid-template-columns: minmax(0, 1fr);
	}

	/* Цепочка длиной с чужую намеренно: раздел 11a снимает с
	   .pdd-page-header__main плашку движка весом (0,5,1), и короткий
	   селектор сводке проигрывал — карточка оставалась без полей
	   и без фона. */
	body.pdd.page-template-newlisting .cap.pdd-page-header .pdd-webhero__stats,
	body.pdd.page-template-newlisting .cap.pdd-page-header .pdd-webhero__promo {
		padding: var(--space-7);
		background: var(--color-surface);
		border: var(--border-width) solid var(--color-border);
		border-radius: var(--radius-xl);
		box-shadow: var(--shadow-card);
	}

	/* Плашки тянутся во всю ширину сводки ровно тогда, когда
	   сводка забрала себе всю строку — то есть когда промо-блока
	   нет.

	   В эталоне плашка стоит по содержимому (435) в колонке 740,
	   и справа от неё остаётся 305 — незаметная щель. У нас при
	   пустом промо колонка становится 1152, и та же плашка в 464
	   оставляла 688 пустоты: она уже не «стоит слева», а болтается
	   в пустом блоке. Промо вернут в настройках сегмента — колонка
	   снова станет 740, правило отвалится вместе с :has, и плашки
	   вернутся к ширине по содержимому. */
	body.pdd .pdd-page-header .pdd-webhero:has(> .pdd-webhero__promo:empty) .pdd-webhero__stat {
		width: auto;
	}

	/* Плашка сводки: строка с обводкой по ширине содержимого. */
	body.pdd .pdd-webhero__stat {
		display: flex;
		align-items: center;
		flex-wrap: wrap;
		gap: var(--space-3);
		width: fit-content;
		margin-top: var(--space-5);
		padding: var(--space-4) var(--space-6);
		font-size: var(--font-size-caption);
		color: var(--color-text);
		border: var(--border-width) solid var(--color-border);
		border-radius: var(--radius-pill);
	}

	body.pdd .pdd-webhero__stat-icon {
		display: inline-flex;
		color: var(--color-icon-strong);
	}

	/* Иконка плашки — из CSS, а не из разметки.

	   Текст плашки теперь пишет администратор в поле «Текст
	   результата запроса», и заставлять его вставлять туда SVG
	   незачем: достаточно класса-модификатора на плашке
	   (.pdd-webhero__stat--reviews / --price), иконку рисует
	   маска. Цвет берётся из currentColor через background. */
	body.pdd .pdd-webhero__stat--reviews::before,
	body.pdd .pdd-webhero__stat--price::before {
		content: "";
		flex: none;
		width: 16px;
		height: 16px;
		background-color: var(--color-icon-strong);
		-webkit-mask-repeat: no-repeat;
		mask-repeat: no-repeat;
		-webkit-mask-position: center;
		mask-position: center;
		-webkit-mask-size: contain;
		mask-size: contain;
	}

	body.pdd .pdd-webhero__stat--reviews::before {
		-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none'%3E%3Cpath d='M17 11.5a3 3 0 0 1-3 3H7l-3.5 2.5v-3.2A3 3 0 0 1 2.5 11V6a3 3 0 0 1 3-3h8.5a3 3 0 0 1 3 3v5.5Z' stroke='%23000' stroke-width='1.6' stroke-linejoin='round'/%3E%3C/svg%3E");
		mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none'%3E%3Cpath d='M17 11.5a3 3 0 0 1-3 3H7l-3.5 2.5v-3.2A3 3 0 0 1 2.5 11V6a3 3 0 0 1 3-3h8.5a3 3 0 0 1 3 3v5.5Z' stroke='%23000' stroke-width='1.6' stroke-linejoin='round'/%3E%3C/svg%3E");
	}

	body.pdd .pdd-webhero__stat--price::before {
		-webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none'%3E%3Cpath d='M10.6 2.8 17 9.2a1.6 1.6 0 0 1 0 2.3l-5.5 5.5a1.6 1.6 0 0 1-2.3 0L2.8 10.6V4.4a1.6 1.6 0 0 1 1.6-1.6h6.2Z' stroke='%23000' stroke-width='1.6' stroke-linejoin='round'/%3E%3Ccircle cx='6.6' cy='6.6' r='1.2' fill='%23000'/%3E%3C/svg%3E");
		mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' fill='none'%3E%3Cpath d='M10.6 2.8 17 9.2a1.6 1.6 0 0 1 0 2.3l-5.5 5.5a1.6 1.6 0 0 1-2.3 0L2.8 10.6V4.4a1.6 1.6 0 0 1 1.6-1.6h6.2Z' stroke='%23000' stroke-width='1.6' stroke-linejoin='round'/%3E%3Ccircle cx='6.6' cy='6.6' r='1.2' fill='%23000'/%3E%3C/svg%3E");
	}

	body.pdd .pdd-webhero__stat-label {
		font-weight: var(--font-weight-semibold);
		color: var(--color-text-secondary);
	}

	/* Средняя цена в шапке — зелёная, как «средн.» у автошкол: там она
	   приходит классом .green из skin.css (#6f9126), здесь цвет задаёт
	   дочерняя тема. Оранжевый --color-star остался от звёзд рейтинга. */
	body.pdd .pdd-webhero__price-mid {
		color: var(--color-rating-high);
	}

	/* Звёзды печатаются разметкой движка (.stars > .mark), а её
	   родительский CSS раскладывает под свою строку рейтинга:
	   81px ширины, margin-left: auto и порядок 2. В плашке сводки
	   всё это лишнее — здесь ряд из пяти иконок по 15px. */
	body.pdd .pdd-webhero__summary .stars,
	body.pdd .pdd-webhero__stars .stars {
		display: inline-flex;
		gap: 1px;
		width: auto;
		flex-basis: auto;
		margin: 0;
		order: 0;
		cursor: default;
	}

	/* padding: 0 обязателен: правило `.mark, mark` родительской темы
	   даёт иконке padding 10px, а при border-box поле больше ширины
	   распирает её до 20x20 — ряд выходил 119x20 вместо 79x15
	   эталона, и вся плашка сводки была на 6px выше. */
	body.pdd .pdd-webhero__stars .stars .mark {
		width: 15px;
		height: 15px;
		padding: 0;
		background-size: contain;
	}
}

/* ============================================================
   21. ШИРОКИЙ ЭКРАН: ДОВОДКА КОНТРОЛОВ ПАНЕЛИ

   Раздел стоит последним по той же причине, что и предыдущие:
   размеры сортировки задают разделы 12a и 19.3 — оба ниже
   раздела 15 по файлу и с той же (или большей) специфичностью,
   а 19.3 ещё и с !important. Перебить их можно только правилом,
   которое идёт после них, — и ровно теми же свойствами.

   Эталон (замер .sortbox на 1280): 223x40, поля 0/10, радиус 8,
   рамка #dfe3ee, подпись серая, значение тёмное.
   ============================================================ */
@media (min-width: 1024px) {

	body.pdd.page-template-newlisting .sorting-full.sorting_search .pdd-sort {
		width: 223px;
		max-width: 223px;
		height: var(--control-height-search);
	}

	body.pdd .pdd-listing__toolbar .pdd-sort .select2-container--default .select2-selection--single {
		height: var(--control-height-search) !important;
		padding: 0 var(--space-5) !important;
		border: var(--border-width) solid var(--color-border-strong) !important;
		border-radius: var(--radius-lg) !important;
	}

	/* Тот же вид — нативному select, пока Select2 не поднялся
	   (см. раздел 12a): иначе первый кадр рисует поле 30px
	   с мобильными полями, а следом встаёт плашка в 40. */
	body.pdd .pdd-listing__toolbar .pdd-sort > select {
		height: var(--control-height-search);
		padding: 0 var(--space-5);
		font-weight: var(--font-weight-semibold);
		border-color: var(--color-border-strong);
		border-radius: var(--radius-lg);
	}

	/* Стрелка справа: у select2 она позиционирована под свои 28px,
	   и в поле 40px висела выше середины. */
	body.pdd .pdd-listing__toolbar .pdd-sort .select2-selection__arrow {
		height: var(--control-height-search);
	}

	/* Ширину контейнера select2 пишет в атрибут style при разборе
	   селекта, поэтому здесь ответный !important — иначе поле
	   остаётся 220 вместо 223 эталона. */
	body.pdd .pdd-listing__toolbar .pdd-sort .select2-container {
		width: 223px !important;
	}

	/* Подпись поля серая — как «Сортировка:» в .sortbox эталона;
	   выбранное значение остаётся тёмным (правило раздела 15). */
	body.pdd .pdd-listing__toolbar .pdd-sort .select2-selection--single {
		gap: var(--space-3);
		color: var(--color-text-secondary) !important;
	}
}

/* ============================================================
   22. ШИРОКИЙ ЭКРАН: ПАНЕЛЬ ФИЛЬТРОВ КОЛОНКОЙ

   Источник — design2/assets/css/web.css, строки 1145–1288
   («колонка фильтров: та же панель .sheet, только не всплывающая,
   а вклеенная в колонку» и секции-выпадашки).

   Раздел стоит после 14-го намеренно: там те же узлы описаны
   для шторки, и правила широкого экрана обязаны идти следом.
   ============================================================ */
@media (min-width: 1024px) {

	/* Обёртки движка держат свою ширину: .container внутри колонки
	   получает от чужого CSS 90% ширины окна и поля, из-за чего
	   панель вылезала из колонки 276 наружу на 384. */
	body.pdd .pdd-listing__side .filter_wrapper,
	body.pdd .pdd-listing__side .flex-listing-content {
		width: 100%;
		max-width: none;
		margin: 0;
		padding: 0;
	}

	/* Липкая панель. max-height не задаём: секции раскрываются
	   вниз, и панель просто становится выше — как в эталоне,
	   где у .sheet__panel max-height снят. */
	body.pdd .pdd-listing__side .pdd-sheet {
		position: sticky;
		top: var(--space-6);
		width: 100%;
		max-width: none;
		margin: 0;
	}

	/* ---- секция как поле выбора ----

	   Аккордеон в панели уже есть у самого движка: клик по
	   .title-newfilter вешает .active на секцию и слайдит
	   .filter-hide-block (listing.js:918). Своего скрипта не надо —
	   нужен только начальный вид: первые две секции закрыты, как
	   в эталоне закрыты «Метро», «Район» и «Категория прав».

	   Дальше состоянием распоряжается сам движок: slideToggle
	   пишет display в атрибут style, а он сильнее любого правила
	   отсюда, и наш :not(.active) в разговор больше не вмешивается. */
	/* Поля панели — 16px, как у .sheet__body эталона (замер: секция
	   242 в панели 276). Движок держит их на самом #sidebar (20px),
	   и вместе с полем секции выходило 33 вместо 17. */
	body.pdd .pdd-listing__side #sidebar.pdd-sheet {
		padding: 0;

		/* Скругление и рамку панели движок задаёт по id (#sidebar),
		   а ID сильнее любой цепочки классов — раздел 14 ему
		   проигрывал, и панель держала радиус 24 вместо 16. */
		border: var(--border-width) solid var(--color-border);
		border-radius: var(--radius-xl);
	}

	body.pdd .pdd-sheet__title,
	body.pdd .pdd-sheet .reset-all-filters,
	body.pdd .pdd-sheet .apply-all-filters-wrapper {
		padding-inline: var(--space-7);
	}

	/* Кнопка «Показать» не уезжает за нижний край экрана.

	   Панель липкая верхним краем, и пока она ниже экрана, низ
	   с кнопкой виден сам собой. Но стоит раскрыть секции —
	   панель перерастает окно, и кнопка уходит вниз за край:
	   в эталоне на 1440 при высоте панели 1249 подвал стоит
	   на экране 1193..1260, то есть за краем окна в 900.

	   Липкий подвал внутри панели решает это, не трогая саму
	   панель: max-height ей ставить нельзя — обрежется выпадающий
	   список города на 510 строк (потому и в эталоне max-height:
	   none, web.css:1201–1203). */
	body.pdd .pdd-sheet .apply-all-filters-wrapper {
		position: sticky;
		bottom: 0;
		z-index: 7;
		background: var(--color-surface);
	}

	body.pdd .pdd-sheet .category-filter {
		padding: var(--space-3) var(--space-7);
		border-bottom: none;
	}

	/* Вид самого бокса секции — в разделе 23.7: там он описан
	   один раз на все секции сразу и с #sidebar в селекторе,
	   иначе его перебивает разметочный CSS движка. */

	/* Список строк — своей прокруткой, а не в полэкрана.

	   Правило одно на оба вида секций: и выпадающий
	   бокс «Города» (510 строк), и раскрытая «Категория
	   прав» (15) держат одну высоту, а лишнее уезжает
	   под прокрутку внутри секции. Сколько именно строк
	   в секции — дело настроек сегмента, панель от этого
	   расти не должна.

	   Прокрутка у списка, а не у всего блока: строка поиска
	   и кнопка «Все» стоят выше .filter-container и остаются
	   на месте, когда список едет (в эталоне ездит весь
	   бокс — там поиска нет). */
	body.pdd .pdd-sheet .filter-hide-block .filter-container {
		max-height: var(--sheet-list-height);
		overflow-y: auto;

		/* Цепочка прокрутки НЕ обрывается: overscroll-behavior
		   здесь стоял contain, и колесо, докрутив список секции
		   до конца, дальше не отдавало прокрутку странице —
		   курсор над панелью, а лента объектов стоит на месте.
		   auto — поведение по умолчанию: список докрутился,
		   дальше едет страница. */
		overscroll-behavior: auto;
		scrollbar-width: thin;
	}
}

/* ============================================================
   23. ДОВОДКА ПО ЗАМЕРАМ: ПАНЕЛЬ ФИЛЬТРОВ, СОРТИРОВКА, ШТОРКА

   Раздел собран по числовой сверке с эталоном
   (scripts/compare-listing.js --map scripts/maps/listing-chrome.json)
   и стоит последним: все правила ниже перебивают либо разметочный
   CSS движка по #sidebar, либо собственные разделы 12a/15/19.3,
   а те идут выше по файлу.

   Карточка листинга здесь не трогается — она за соседним потоком.
   ============================================================ */

/* ---- 23.1 Ритм секций панели ----

   Движок раздаёт секциям поля и отбивки по id (#sidebar aside —
   padding-bottom 24, margin-bottom 20; #sidebar .checkbox-filters
   .title-newfilter — margin-bottom 12). ID специфичностью не
   перебивается цепочкой классов, поэтому здесь тот же #sidebar.

   Эталон: закрытая секция .sheet__section 242x72, головы соседних
   секций ровно в 12px друг от друга. У нас голова 48 (у эталона 60:
   там второй строкой печатается выбранное значение, у движка такой
   строки нет), значит секция = 6 + 48 + 6. */
body.pdd #sidebar.pdd-sheet .category-filter {
	margin-bottom: 0;
	padding-bottom: var(--space-3);
}

/* Отбивка головы панели до первой секции — 12, как верхнее поле
   .sheet__body эталона (замер: голова 54, первая секция в 66 от
   верха панели). Движок держит на заголовке margin-bottom 25. */
body.pdd #sidebar.pdd-sheet .pdd-sheet__title {
	margin-bottom: var(--space-6);
}

body.pdd #sidebar.pdd-sheet .title-newfilter {
	margin-bottom: 0;
}

/* Раскрытый список отбивается своим margin-top (раздел 22),
   поэтому нулевая отбивка головы ему не мешает. */

/* ---- 23.2 Подвал панели ----

   Эталон .sheet__foot: 274x67 = 10 + кнопка 46 + 10 + рамка.
   Кнопке движка задан margin-top: 21px правилом .apply-all-filters,
   из-за него подвал держал 88. */
body.pdd .pdd-sheet .apply-all-filters {
	margin-top: 0;
	line-height: var(--line-height-base);
}

/* Поля подвала — 12, а не 16: в эталоне кнопка «Показать» 250
   в подвале 274, у нас при 16 выходила 242. Правило раздела 22
   задаёт всем трём краям панели padding-inline: 16 — голове это
   верно, подвалу нет. */
@media (min-width: 1024px) {

	body.pdd .pdd-sheet .apply-all-filters-wrapper {
		padding-inline: var(--space-6);
	}
}

/* ---- 23.2а Пустая обёртка панели фильтров ----

   На телефоне панель фильтров — шторка: .filter_result_wrapper
   остаётся в потоке нулевой высоты, но со своим полем от движка
   (skin.css: .page-template-newlisting .filter_result_wrapper
   { margin: 30px 0 }). Сверху и снизу это 60px пустоты между
   плашками сводки и строкой поиска — в эталоне там 16
   (.search-row, margin-top).

   Гасим только у пустой обёртки: когда движок печатает в неё
   выбранные фильтры, поле ей нужно. */
@media (max-width: 1023.98px) {

	body.pdd .filter_result_wrapper:empty,
	body.pdd .filter_result_wrapper.pdd-listing__side {
		margin: 0;
	}
}

/* ---- 23.3 Сортировка на узкой ширине ----

   Эталон .sort--compact: 227x30, ряд .results — space-between,
   и справа от кнопки «На карте» остаётся воздух. Select2 пишет
   ширину контейнера в атрибут style при разборе селекта, но
   родительский CSS сам гасит её `width: 100% !important`,
   поэтому достаточно задать ширину внешнему узлу. */
@media (max-width: 1023.98px) {

	body.pdd.page-template-newlisting .sorting-full.sorting_search .pdd-sort {
		flex: 0 0 auto;
		width: 227px;
		max-width: 227px;
	}

	/* Порядок в ряду: слева «На карте», справа сортировка — как
	   в эталоне (listing.js, archive-toolbar: .map-button печатается
	   первой, замер на 390: карта x=16, сортировка x=147). Движок
	   печатает пару наоборот, поэтому порядок задаём флексом. */
	body.pdd .pdd-listing__toolbar .pdd-results .pdd-map-button {
		order: 0;
	}

	body.pdd .pdd-listing__toolbar .pdd-results .pdd-sort {
		order: 1;
	}

	/* Эталон .sort--compact печатает четыре вещи в ряд с зазором 6:
	   иконку 18x18, «Сортировка:» 13/400 тёмным, значение 13/500
	   синим и шеврон (замер на 390: подпись x=184, значение x=265).
	   Значение у нас уже такое; не хватало иконки и слова —
	   они стояли только в десктопном разделе 23.4.1. */
	body.pdd .pdd-listing__toolbar .pdd-sort .select2-selection--single {
		gap: var(--space-3);
	}

	body.pdd .pdd-listing__toolbar .pdd-sort .select2-selection--single::before {
		content: "";
		flex: 0 0 auto;
		width: 18px;
		height: 18px;
		color: var(--color-icon-strong);
		background: currentColor;
		-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18' fill='none'%3E%3Cpath d='M5.5 3v12M5.5 15 3 12.3M5.5 3 8 5.7M12.5 15V3M12.5 3 15 5.7M12.5 15 10 12.3' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center center;
		mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18' fill='none'%3E%3Cpath d='M5.5 3v12M5.5 15 3 12.3M5.5 3 8 5.7M12.5 15V3M12.5 3 15 5.7M12.5 15 10 12.3' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center center;
		-webkit-mask-size: contain;
		mask-size: contain;
	}

	/* Слово печатает скин в --pdd-sort-label: подпись остаётся
	   переводимой строкой в PHP (см. раздел 23.4.1). */
	body.pdd .pdd-listing__toolbar .pdd-sort .select2-selection--single .select2-selection__rendered::before {
		content: var(--pdd-sort-label, "") " ";
		font-weight: var(--font-weight-regular);
		color: var(--color-text);
	}
}

/* ---- 23.4 Значение сортировки на широкой ширине ----

   Эталон .sortbox__value: 13/19, вес 600, цвет #0b0b0b. У нас поле
   красило правило раздела 12a (мобильное, цепочка на класс больше),
   и значение выходило синим и полужирным-500. Цепочка повторена
   один в один — берёт порядком, а не весом. */
@media (min-width: 1024px) {

	body.pdd .pdd-listing__toolbar .pdd-sort .select2-container--default .select2-selection--single .select2-selection__rendered {
		font-weight: var(--font-weight-semibold);
		color: var(--color-text);

		/* Воздух до шеврона. У эталона шеврон — соседний флекс-элемент
		   с gap 6, у select2 он приколот к правому краю поля, поэтому
		   зазор приходится держать полем самой строки: иначе длинное
		   значение упирается в стрелку вплотную. */
		padding-right: var(--space-3);
	}

	/* ---- 23.4.1 Поле сортировки целиком ----

	   Эталон .sortbox (web.css:468–503, замер на 1440): 223x40,
	   слева иконка 18x18 цветом #4b5162, дальше «Сортировка:»
	   13/400 серым, следом значение 13/600 тёмным, справа шеврон.

	   Разметку печатает select2, поэтому иконка и слово
	   «Сортировка:» — псевдоэлементы: своих узлов в его выводе
	   нет, а подменять шаблон select2 значило бы держать второе
	   состояние рядом с настоящим. Само значение приходит из
	   подписи выбранного пункта (см. комментарий в скине). */
	body.pdd .pdd-listing__toolbar .pdd-sort .select2-selection--single::before {
		content: "";
		flex: 0 0 auto;
		width: 18px;
		height: 18px;
		color: var(--color-icon-strong);
		background: currentColor;
		-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18' fill='none'%3E%3Cpath d='M5.5 3v12M5.5 15 3 12.3M5.5 3 8 5.7M12.5 15V3M12.5 3 15 5.7M12.5 15 10 12.3' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center center;
		mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18' fill='none'%3E%3Cpath d='M5.5 3v12M5.5 15 3 12.3M5.5 3 8 5.7M12.5 15V3M12.5 3 15 5.7M12.5 15 10 12.3' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center center;
		-webkit-mask-size: contain;
		mask-size: contain;
	}

	/* Слово берётся из --pdd-sort-label, а его печатает скин
	   (get_sorting_search). Так подпись остаётся переводимой
	   строкой в PHP и не оседает литералом в CSS, куда локали
	   не заглядывают. Свойство наследуемое, поэтому доходит
	   до узла select2 через все его обёртки. */
	body.pdd .pdd-listing__toolbar .pdd-sort .select2-selection--single .select2-selection__rendered::before {
		content: var(--pdd-sort-label, "") " ";
		font-weight: var(--font-weight-regular);
		color: var(--color-text-secondary);
	}

	/* Крестик очистки. Он появился вместе с настоящим значением
	   в поле: select2 рисует его, когда выбран не placeholder,
	   а движок зовёт его с allowClear (listing.js:222). Сбрасывать
	   сортировку крестиком некуда — «по названию» и есть умолчание,
	   и оно стоит первым пунктом списка. */
	body.pdd .pdd-listing__toolbar .pdd-sort .select2-selection__clear {
		display: none;
	}
}

/* ---- 23.4.2 Плейсхолдер поля поиска ----

   Эталон (.search__input::placeholder, main.css:923–937): 14/400
   цветом #9aa0b0. Наше правило раздела 12a красило его верно,
   но проигрывало: `.page-template-v3 #search .input_text
   input::placeholder` из skin.css бьёт по ID, а ID цепочкой
   классов не перебивается — оттуда и приходили 16/500 чёрным.
   Здесь тот же #search в цепочке, поэтому вес больше. */
body.pdd .pdd-listing__toolbar #search.pdd-search .input_text input::placeholder {
	font-size: var(--font-size-input);
	font-weight: var(--font-weight-regular);
	line-height: var(--line-height-base);
	color: var(--color-text-muted);
	opacity: 1;
}

/* Вкладка «На карте» в сером треке и отступ от строки над списком
   до карточек описаны в разделе 19: обоим понадобился ответный
   !important, а он в теме живёт только там. */

/* ---- 23.5 Шторка фильтров на узкой ширине ----

   Эталон (design2/assets/css/tokens.css, --sheet-width / --sheet-from):
   панель выезжает справа, ширина min(88vw, 360px) — на 390 это 343,
   левые углы скруглены, тень уходит влево. Движок держит #sidebar
   на всю ширину экрана (left: 0; width: 100%), поэтому здесь снова
   нужна специфичность с id.

   Позиционирование остаётся fixed — так его задаёт движок, и слайд
   открытия/закрытия делает он же (display у #sidebar). */
@media (max-width: 1023.98px) {

	body.pdd #sidebar.pdd-sheet {
		left: auto;
		right: 0;
		width: min(88vw, 360px);
		max-width: 360px;

		/* Поля держат голова, секции и подвал — как в эталоне, где
		   у .sheet__panel собственного поля нет. Пока панель несла
		   свои 20px, голова выходила 303 вместо 343. */
		padding: 0;
		border: none;

		/* 12px литералом: --radius-xl на этой странице переопределён
		   в 16 (раздел 1), а у шторки эталона радиус ровно 12. */
		border-radius: 12px 0 0 12px;
		box-shadow: -12px 0 34px rgba(16, 18, 27, 0.24);
	}

	/* Подвал эталона на узкой ширине: 343x71, поля 12/16.

	   Движок держит подвал fixed по низу ЭКРАНА (left: 0; right: 0),
	   и при шторке в 343 полоса торчала из-под неё во всю ширину.
	   Прижимаем к тем же краям, что и панель.

	   z-index: 7 — тот же номер, что у подвала колонки (раздел 22),
	   и по той же причине: он ниже 30 у раскрытой секции, поэтому
	   выпавший список накрывает кнопку «Показать», пока открыт.
	   Движок ставит подвалу 99, и на телефоне выходило наоборот —
	   список уезжал ПОД кнопку (замер на 390, «Район» в Москве:
	   скрыто 62.5px, полторы строки, добраться нельзя никак).
	   Прокручиваемое содержимое подвал кроет и с 7: закрытые
	   секции лежат на 1. */
	body.pdd #sidebar.pdd-sheet .apply-all-filters-wrapper {
		z-index: 7;
		left: auto;
		right: 0;
		width: min(88vw, 360px);
		padding: var(--space-6) var(--space-7);
	}

	body.pdd #sidebar.pdd-sheet .apply-all-filters {
		margin-top: 0;
	}

	/* Поля секции — 16, как у .sheet__body эталона: секция там
	   311 в панели 343. */
	body.pdd #sidebar.pdd-sheet .category-filter {
		padding-inline: var(--space-7);
	}

	/* Голову на узкой ширине печатает сам движок — .title_filter_mob
	   («← Фильтры … Очистить»), и это ровно .sheet__head эталона:
	   название плюс сброс. Своя .pdd-sheet__title тут лишняя — от
	   двух заголовков подряд панель начиналась с дубля. */
	body.pdd #sidebar.pdd-sheet .pdd-sheet__title {
		display: none;
	}

	body.pdd #sidebar.pdd-sheet .title_filter_mob {
		display: flex;
		align-items: center;
		justify-content: space-between;
		gap: var(--space-5);
		margin: 0;
		padding: var(--space-7) var(--space-7) var(--space-6);
		font-size: var(--sheet-title-size);
		font-weight: var(--sheet-title-weight);
		line-height: var(--line-height-base);
		color: var(--color-text);
		border-bottom: var(--border-width) solid var(--color-border);
	}

	/* Плавающая кнопка «Показать» движка прибита к низу экрана
	   на всю его ширину (fixed; left: 0; width: 100%). Пока панель
	   стала шторкой в 343, полоса торчала под ней во весь экран —
	   прижимаем её к тем же краям, и она читается подвалом шторки,
	   как .sheet__foot эталона. */
	body.pdd.page-template-newlisting .btn_blue.apply_filter {
		left: auto;
		right: 0;
		width: min(88vw, 360px);
	}
}

/* ------------------------------------------------------------
   Поле снизу шторке — в высоту подвала.

   Отдельным медиазапросом и на 991, а не на 1023.98: подвал
   становится fixed по низу экрана правилом ДВИЖКА, а у него
   граница 991 (frontend.css:16641). В полосе 992–1023.98 подвал
   стоит в потоке, и поле под него оказалось бы дырой в 76px
   внизу панели (замер на 1000: шторка static, подвал static).

   Высота считается из тех же величин, что складывают сам подвал:
   кнопка --sheet-apply-height, поля --space-6 сверху и снизу,
   рамка --border-width и 5px отбивки, которые движок вешает
   кнопке через !important (frontend.css:16638) — наш margin-top: 0
   без !important его не перебивает. Итого 76 — ровно замеренная
   высота подвала. Без этих 6px поле выходило 70, и низ
   содержимого заходил под подвал на 1.1px.
   ------------------------------------------------------------ */
@media (max-width: 991px) {

	body.pdd #sidebar.pdd-sheet {
		padding-bottom: calc(
			var(--sheet-apply-height) + var(--space-6) * 2 + var(--border-width) + 5px
		);
	}
}

/* ---- 23.6 Шапка идёт по той же сетке, что и страница ----

   От 1280px страница раскладывается в четыре колонки (поле ·
   фильтры · лента · карта), и контент уезжает влево, освобождая
   место под карту: замер на 1440 — контейнер страницы в x=88.
   Шапка в эту сетку не входила и центровалась по всей ширине
   окна — x=144, то есть на 56px правее всего остального.
   В эталоне шапка стоит там же, где контент (замер: x=88).

   Поэтому шапке отдаётся та же сетка и та же пара колонок,
   что и шапке страницы: тогда сдвиг считается один раз и
   держится на любой ширине окна. */
@media (min-width: 1280px) {

	body.pdd.pdd-listing--map.page-template-newlisting header.pdd-topbar {
		display: grid;

		/* column-gap тот же, что у сетки страницы: без него шапка
		   выходила 1140 вместо 1152 — колонки 2–4 складываются
		   без промежутка между фильтрами и лентой. */
		column-gap: var(--space-6);

		/* Те же боковые поля, что у шапки страницы: доля первой
		   колонки (0.35fr) считается от остатка, и без этих 16px
		   остаток был на 32 больше — шапка вставала в x=80
		   вместо 88. */
		padding-inline: var(--page-padding);

		/* Тот же сдвиг, что у сетки страницы, — иначе от 1600px
		   шапка осталась бы на месте, а тело уехало вправо. */
		padding-left: calc(var(--page-padding) + var(--web-content-shift));
		grid-template-columns:
			minmax(var(--space-6), 0.35fr)
			var(--web-sidebar-width)
			var(--web-content-width)
			minmax(0, 1fr);
	}

	body.pdd.pdd-listing--map.page-template-newlisting header.pdd-topbar > .container {
		grid-column: 2 / 4;
		width: auto;
		max-width: none;
		margin-inline: 0;
		/* Шапка теперь сетка с justify-items: center (header.css —
		   так у .container обнуляются боковые поля, как в эталоне).
		   Здесь ширину задают колонки 2–4, а не содержимое: без
		   растяжения коробка садилась по контенту, 1041 вместо 1152. */
		justify-self: stretch;
	}
}

/* ---- 23.6.1 Сдвиг левой части вправо от 1600px ----

   Перенос эталонного правила один в один (web.css:1528–1532).
   Взводится один токен, а расходится он по двум сеткам сразу —
   шапке и странице, — потому что обе считают левое поле от него.

   Только для раскладки с картой: без карты страница остаётся
   двухколоночной и центрируется по max-width, сдвигать её
   некуда и не во что. */
@media (min-width: 1600px) {
	body.pdd.pdd-listing--map.page-template-newlisting {
		--web-content-shift: var(--web-content-shift-wide);
	}
}

/* ---- 23.7 Секция фильтра — боксом выбора ----

   Эталон: .sheet__section--drop, web.css:1209–1288. Бокс 242x60,
   белый фон, рамка #dfe3ee, радиус 8, поля 8/10. Внутри двумя
   этажами: сверху название 13/500 серым (#5a5f6e), под ним
   выбранное значение 13/600 тёмным, справа шеврон 14x14 серым
   (#9aa0b0). Раскрытая секция плашку НЕ теряет — у неё только
   рамка становится цветом марки, а список выпадает поверх
   страницы, а не раздвигает панель.

   Плашку получают НЕ все секции: в эталоне боксом нарисованы
   только выпадающие («Метро», «Район», «Категория прав» —
   web.css:1209–1236, селектор .sheet__section--drop), а короткие
   секции стоят раскрытыми обычным списком. Класс вешает скин
   по признаку $long — тому самому, по которому движок печатает
   секции строку поиска. На 1910 боксами выходят «Город»
   и «Категория прав», раскрытыми — «Время занятий»
   и «Дополнительные фильтры».

   Считать по порядку (nth-of-type) здесь нельзя: секции движок
   переставляет сам, по data-filter-order (listing.js:175–199),
   и порядковый номер в разметке ничего не значит.

   #sidebar в селекторах не для красоты: разметочный CSS движка
   бьёт по id, а ID цепочкой классов не перебивается.

   Раздел работает на всех ширинах. У эталона плашка выбора стоит
   только в колонке, а на телефоне секции раскрыты списком; здесь
   телефон повторяет веб-версию (просьба заказчика 27.08.2026):
   длинные секции («Город», «Категория прав») складываются в бокс
   с выпадающим списком поверх шторки. Короткие («Время занятий»,
   «Дополнительные фильтры») остаются раскрытыми — класс --drop
   скин им не вешает.

   Правило ниже прячет строку значения глобально: показывается она
   только внутри #sidebar.pdd-sheet, где её включает сам раздел.
   В эталоне так же (web.css:70–73, 1243–1244). */
body.pdd .pdd-sheet__picked {
	display: none;
}

/* Название секции — блоком: в эталоне это сам flex-элемент шапки
   (.sheet__section-title, main.css:631–638), а движок печатает его
   вложенным span внутри <b>. Строчный span меряется по глифам
   (36x17 против 198x19) и не отдаёт шапке всю строку. */
body.pdd #sidebar.pdd-sheet .pdd-sheet__section-title {
	display: block;
}

/* Каждая секция — свой стековый контекст.

   Выпадающий список города лежит в потоке над соседней секцией,
   а движок держит её строку поиска липкой с z-index: 99 — то есть
   чужая строка «Поиск… / Все» рисовалась ПОВЕРХ раскрытого списка,
   и в нём читались сразу два блока (снимок заказчика 19.08.2026).

   Правится не гонкой номеров, а границей: z-index на самой секции
   делает её стековым контекстом, и 99 у строки поиска считается
   уже внутри своей секции, а не от корня. Раскрытой секции номер
   больше — её список кроет соседей целиком.

   Номер подвала панели (7) намеренно не трогаем: он ниже 30,
   поэтому длинный список накрывает кнопку «Показать», пока
   открыт, — как и любое выпадение поверх страницы. */
body.pdd #sidebar.pdd-sheet .category-filter {
	position: relative;
	z-index: 1;
}

body.pdd #sidebar.pdd-sheet .category-filter.active {
	z-index: 30;
}

body.pdd #sidebar.pdd-sheet .title-newfilter {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--space-2) var(--space-4);
	min-height: 0;
	cursor: pointer;
}

/* плашка — только у выпадающих секций (web.css:1217–1226) */
body.pdd #sidebar.pdd-sheet .category-filter:not(.pdd-sheet__section--open) .title-newfilter {
	padding: var(--space-4) var(--space-5);
	background: var(--color-surface);
	border: var(--border-width) solid var(--color-border-strong);
	border-radius: var(--radius-lg);
}

body.pdd #sidebar.pdd-sheet .category-filter:not(.pdd-sheet__section--open).active .title-newfilter {
	border-color: var(--color-primary);
}

/* Название секции.

   Цвет назначен вложенному span, а не самому <b>, и это
   единственный способ обойтись без !important: правило
   `.page-template-v3 .checkbox-filters .title-newfilter b`
   задаёт color: #2a2a2a с !important, а его специфичностью
   не перебить. Селектор бьёт по тегу b — вложенный span
   под него не подходит, и цвет наследуется уже наш. */
body.pdd #sidebar.pdd-sheet .title-newfilter b {
	flex: 1 1 auto;
	margin: 0;
	padding: 0;
	font-size: var(--font-size-control);
	font-weight: var(--font-weight-medium);
	line-height: var(--line-height-base);
}

body.pdd #sidebar.pdd-sheet .category-filter:not(.pdd-sheet__section--open) .title-newfilter .pdd-sheet__section-title {
	color: var(--color-text-secondary);
}

/* Раскрытая секция: название — как у базовой .sheet__section-title
   эталона (main.css:631–638), 15/600 тёмным, а не 13/500 серым
   надписью над полем выбора. */
body.pdd #sidebar.pdd-sheet .pdd-sheet__section--open .title-newfilter {
	min-height: var(--sheet-section-head-height);
	margin-bottom: var(--space-5);
	gap: var(--space-5);
}

body.pdd #sidebar.pdd-sheet .pdd-sheet__section--open .title-newfilter b {
	font-size: var(--sheet-section-title-size);
	font-weight: var(--sheet-section-title-weight);
}

body.pdd #sidebar.pdd-sheet .pdd-sheet__section--open .title-newfilter .pdd-sheet__section-title {
	color: var(--sheet-section-title-fg);
}

/* Строка «что выбрано» нужна только полю выбора: в раскрытой
   секции отметки и так видны списком (web.css:1238–1241 — там же
   по этой причине спрятано «Все»). */
body.pdd #sidebar.pdd-sheet .pdd-sheet__section--open .pdd-sheet__picked {
	display: none;
}

/* Строка значения занимает всю ширину бокса и потому переносится
   на второй этаж — order держит её под названием независимо от
   того, где она стоит в разметке. */
body.pdd #sidebar.pdd-sheet .pdd-sheet__picked {
	display: block;
	flex: 1 0 100%;
	order: 3;
	overflow: hidden;
	font-size: var(--font-size-control);
	font-weight: var(--font-weight-semibold);
	line-height: var(--line-height-base);
	color: var(--color-text);
	text-overflow: ellipsis;
	white-space: nowrap;
}

body.pdd #sidebar.pdd-sheet .pdd-sheet__picked--empty {
	font-weight: var(--font-weight-regular);
	color: var(--color-text-muted);
}

/* Шеврон. Движок печатает кнопку с фоновой картинкой
   chevron-up.svg 24x24 и доворачивает её на 180° при раскрытии
   (frontend.css:15518–15535) — то есть ровно наоборот эталону,
   где закрытая секция смотрит стрелкой вниз. Картинка заменена
   маской: сквозь неё видно currentColor, и цвет берётся из
   токена, а не из файла. */
body.pdd #sidebar.pdd-sheet .title-newfilter .arrow-down {
	flex: 0 0 auto;
	width: 14px;
	height: 14px;
	margin: 0;
	color: var(--color-text-muted);
	background: currentColor;
	transform: none;
	-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='m4 6.5 4 4 4-4' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center center;
	mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none'%3E%3Cpath d='m4 6.5 4 4 4-4' stroke='%23000' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat center center;
	-webkit-mask-size: contain;
	mask-size: contain;
}

body.pdd #sidebar.pdd-sheet .title-newfilter .arrow-down.active {
	transform: rotate(180deg);
}

/* ---- Раскрытый список — поверх страницы, а не в потоке ----

   Панель липкая и стоит в узкой колонке: раздвигай она соседей,
   выпадающий список города на 510 строк утащил бы вниз всё, что
   под ним. В эталоне ровно так же (web.css:1261–1274). */

/* Закрыты все секции сразу, и закрыты БЕЗУСЛОВНО — не через
   :not(.active).

   Условие по .active выглядит правильнее, но не работает:
   движок вешает класс и запускает slideToggle одной цепочкой
   (listing.js:918), то есть к моменту замера видимости класс
   уже стоит, правило со скрытием отвалилось, и jQuery видит
   раскрытую секцию — вместо разворота получается сворачивание,
   список не открывается ни разу.

   Безусловное display:none даёт то же начальное состояние,
   а дальше распоряжается сам движок: slideToggle пишет display
   в атрибут style, и инлайн сильнее правила отсюда.

   left/right по 16 — поля секции: контейнер отсчёта у absolute
   это padding-box самой секции, а плашка внутри неё как раз
   отбита на 16.

   width: auto обязателен. В шторке движок задаёт .filter-hide-block
   собственную ширину, а заданная ширина отменяет right: список
   выезжал за правый край экрана на 16px (замер на 390: правый край
   406 при окне 390). В колонке этого правила у движка нет, и там
   ширина и без того считалась из left/right. */
body.pdd #sidebar.pdd-sheet .category-filter:not(.pdd-sheet__section--open) .filter-hide-block {
	display: none;
	position: absolute;
	z-index: 8;
	top: calc(100% + var(--space-2));
	right: var(--space-7);
	left: var(--space-7);
	width: auto;
	margin-top: 0;
	padding: var(--space-4) var(--space-5);
	background: var(--color-surface);
	border: var(--border-width) solid var(--color-border);
	border-radius: var(--radius-lg);
	box-shadow: var(--shadow-drop);
}

/* ---- Раскрытая секция — списком в потоке панели ----

   Эталон держит раскрытыми все секции, кроме трёх выпадающих
   (web.js:150, DROP_SECTIONS): список стоит прямо под названием
   и раздвигает панель. Оттого панель эталона 276x1249, а у нас
   до этой правки была 276x424 — открытых секций не было ни одной.

   Здесь, в отличие от выпадающих, безусловное display:none
   не нужно и вредно: секция обязана быть открытой сразу. Движок
   этому не мешает — slideToggle он запускает только по клику
   (listing.js:918), а до клика инлайнового display на узле нет. */
body.pdd #sidebar.pdd-sheet .pdd-sheet__section--open .filter-hide-block {
	display: block;
	position: static;
	margin-top: 0;
	padding: 0;
	background: none;
	border: none;
	box-shadow: none;
}

/* ------------------------------------------------------------
   24. ВИЛКА ЦЕНЫ

   Секция «Цена обучения» — .sheet__section--range эталона:
   два поля-подчёркивания в ряд (main.css:791–829) и ползунок
   под ними (web.css:1291–1335). Границы вилки печатает скин
   по настоящим MIN/MAX выборки, разметка — get_price_filter_section().

   Правила вне медиазапроса: в шторке на телефоне секция
   выглядит так же, как в колонке.
   ------------------------------------------------------------ */
body.pdd #sidebar.pdd-sheet .pdd-sheet__range {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--space-4);
}

/* Поле — не коробка, а одна черта под строкой (принятый
   в эталоне вариант v2, main.css:797–810). */
body.pdd #sidebar.pdd-sheet .pdd-sheet__field {
	display: flex;
	align-items: center;
	gap: var(--space-4);
	height: var(--sheet-field-height);
	margin: 0;
	padding: var(--sheet-field-pad);
	color: var(--color-text-muted);
	background: var(--sheet-field-bg);
	border: var(--sheet-field-border);
	border-bottom: var(--sheet-field-underline);
	border-radius: var(--sheet-field-radius);
}

body.pdd #sidebar.pdd-sheet .pdd-sheet__input {
	width: 100%;
	height: auto;
	min-height: 0;
	margin: 0;
	padding: 0;
	font-family: inherit;
	font-size: var(--font-size-input);
	line-height: var(--line-height-base);
	color: var(--color-text);
	background: none;
	border: none;
	border-radius: 0;
	outline: none;
	box-shadow: none;
}

body.pdd #sidebar.pdd-sheet .pdd-sheet__input::placeholder {
	color: var(--color-text-muted);
	opacity: 1;
}

body.pdd #sidebar.pdd-sheet .pdd-slider {
	position: relative;
	display: block;
	height: 28px;
	margin-top: var(--space-4);
	touch-action: none;
}

body.pdd #sidebar.pdd-sheet .pdd-slider__track {
	position: absolute;
	top: 50%;
	right: 0;
	left: 0;
	height: 4px;
	background: var(--color-surface-muted);
	border-radius: var(--radius-pill);
	transform: translateY(-50%);
}

body.pdd #sidebar.pdd-sheet .pdd-slider__fill {
	position: absolute;
	top: 0;
	bottom: 0;
	background: var(--color-primary);
	border-radius: var(--radius-pill);
}

/* Кнопка ручки — движок красит все .arrow-down и прочие кнопки
   панели своим фоном, поэтому фон и рамка задаются явно. */
body.pdd #sidebar.pdd-sheet .pdd-slider__knob {
	position: absolute;
	top: 50%;
	width: 20px;
	height: 20px;
	margin-left: -10px;
	padding: 0;
	background: var(--color-surface);
	border: 2px solid var(--color-primary);
	border-radius: var(--radius-pill);
	box-shadow: var(--shadow-float);
	transform: translateY(-50%);
	cursor: grab;
	touch-action: none;
}

body.pdd #sidebar.pdd-sheet .pdd-slider__knob:active {
	cursor: grabbing;
}

/* Ручка не тянется за курсором с задержкой.

   Родительская тема вешает переход на всё подряд:
   frontend.css:18121 — a, button, *:after, *:before { transition: all .3s }.
   Ручка — button, полоса заливки ловит то же через *:after, и
   left/right, которые пишет скрипт на каждый pointermove, ехали
   анимацией в 300мс. Отсюда и «ползунок не успевает за мышкой»:
   курсор уже на месте, ручка ещё догоняет треть секунды.

   Позицию не анимируем вовсе; переход остаётся на подсветке — там
   он и нужен. */
body.pdd #sidebar.pdd-sheet .pdd-slider__knob,
body.pdd #sidebar.pdd-sheet .pdd-slider__fill {
	transition: background-color 0.15s ease, border-color 0.15s ease, box-shadow 0.15s ease;
}

/* Размер подписи строки задан в базовом разделе панели
   (--sheet-row-size, 14): --font-size-subtitle здесь становится
   15 и уводил строку от эталона. */

/* Районы, округа и метро: сужение по городу — страховка.

   Сервер печатает в этих секциях только строки выбранного города
   (скин, pdd_row_visible_for_city), а секцию без единой такой строки
   не печатает вовсе. Правила ниже остаются на случай, если город
   когда-нибудь сменится без перезагрузки: чужие строки не покажутся,
   пока pdd-listing.js не проставит им data-pdd-visible. Прячет CSS,
   а не скрипт: скрипт успевает отработать только после отрисовки. */
body.pdd #sidebar aside.category-filter[data-pdd-city-scoped]:not([data-pdd-city-any]) {
	display: none;
}

body.pdd #sidebar li[data-cities]:not([data-pdd-visible]) {
	display: none;
}

/* ============================================================
   24. ПОДВАЛ СТРАНИЦЫ: ОТЗЫВЫ → «ГОРОД / КАТЕГОРИЯ ПРАВ» → ФУТЕР

   Разметку хвоста печатает движок, полей в дочерней теме не было —
   отступы приезжали из frontend.css и были вдвое больше нужного:

     .listing_reviews_block ─ 70px ─ .search-chekup ─ 88px ─ .footer

   70 — это целиком поля пустого .seo-description (30 сверху,
   40 снизу): текста в нём на /schools/ нет, а поля схлопнуться
   не могут, между ними лежит блок нулевой высоты.
   88 — margin-bottom: 64 у .search-chekup плюс 24 у футера
   (--footer-margin-top, общий для всех страниц, его не трогаем).

   Стало 32 и 40, но и этого оказалось много: замер 23.08.2026 на
   1440 показал 145px пустоты между карточками отзывов и чипами
   «Город / Район» и 101px от «Смотреть все» до баннера подвала —
   при шаге карточек листинга 14px. Пустоту набирали вчетвером:
   42px хвоста слайдера отзывов (12 своих у слайда плюс два
   одинаковых поля по 15 у .slick-track и .slick-list), 32px
   распорки, 40px поля белой карточки и ещё 32px отступа
   .tab-content над чипами внутри неё.

   Стало 44 и 60: хвост слайдера — только собственные 12 слайда,
   симметрично полю сверху; распорка 16; поле карточки 16.
   Оставшиеся 44 внизу — общие для всех страниц поля подвала
   (--footer-margin-top 24 и его padding-top 20), их не трогаем.
   ============================================================ */

/* Два одинаковых поля по 15px, положенных друг на друга, — хвост
   слайдера, а не место под тень: тень карточки укладывается
   в margin слайда (12px сверху и снизу). */
body.pdd.page-template-newlisting .reviews-slider .slick-list,
body.pdd.page-template-newlisting .reviews-slider .slick-track {
	padding-bottom: 0;
}
body.pdd.page-template-newlisting .seo-description {
	margin-top: 16px;
	margin-bottom: 0;
}

/* Текст в блоке есть — поле снизу возвращается, иначе описание
   слипнется с плиткой ссылок. :empty ловит и вариант с одними
   пробелами внутри — движок печатает узел без содержимого. */
body.pdd.page-template-newlisting .seo-description:not(:empty) {
	margin-bottom: 24px;
}

/* Поле до подвала снимаем целиком: своих 24px (--footer-margin-top)
   подвалу хватает, они же стоят между блоками на всех страницах. */
body.pdd.page-template-newlisting .home-filters.search-chekup {
	margin-bottom: 0;
}

/* Белая карточка плиток: 40px по вертикали читались как ещё один
   отступ между блоками. По горизонтали 40 остаются — от них
   зависит ширина плиток.

   Поле сверху снято совсем, и не для плотности: ряд чипов внутри
   несёт свои 32px от `.tab-content { margin: 32px 0 0 0 !important }`
   движка. Специфичностью это не перебивается (проверено
   CSS.getMatchedStylesForNode 23.08.2026), а второй !important
   в теме заводить незачем — те же 32px и работают полем карточки
   сверху, раз убрать их всё равно нельзя. */
body.pdd.page-template-newlisting .home-filters.search-chekup > .bg-white {
	/* flow-root, иначе те самые 32px протекают наружу схлопыванием
	   полей и утаскивают вниз всю карточку вместе с фоном: чипы
	   оказываются впритык к её краю, а просвет над ней вырастает */
	display: flow-root;
	padding-top: 0;
	padding-bottom: 16px;
}

/* ------------------------------------------------------------
   26. Поля ввода на сенсорных — 16px, иначе iOS сам масштабирует

   Safari на iPhone увеличивает страницу при фокусе в поле, у которого
   computed font-size меньше 16px, и обратно масштаб НЕ отматывает.
   Отсюда весь симптом целиком: тапнул в поиск — страница осталась
   зумнутой, layout viewport по-прежнему 390, а visual стал ~342,
   и появилась протяжка влево-вправо, а fixed-блоки поехали.

   16 — порог, зашитый в движок Safari, а не подобранное число:
   ниже него зум срабатывает всегда. Обратно на --font-size-input
   не возвращать, каким бы «выбивающимся из токенов» оно ни казалось.

   Условие pointer: coarse, а не ширина окна: автозум бывает у пальца,
   а не у узкого окна. Поэтому на десктопе поля остаются 14px при любом
   размере, а золотой слепок не сдвигается — spec.js и func-sweep
   поднимают браузер без hasTouch, указатель у них fine.

   Блок последний в файле намеренно: он обязан перебить и правило 19.2
   с !important (стр. 2788), и .pdd-sheet__input (стр. 3866).
   ------------------------------------------------------------ */
@media (pointer: coarse) {

	/* ID и !important — ответ на движковое
	   .page-template-v3 #search .input_text input и на наше же 19.2 */
	body.pdd .pdd-listing__toolbar #search.pdd-search .input_text input {
		font-size: 16px !important;
	}

	body.pdd .pdd-sheet .search-in-filter,
	body.pdd #sidebar.pdd-sheet .pdd-sheet__input {
		font-size: 16px;
	}
}

/* ---- 26.1 Высота шторки считается по текущему экрану, а не по
        максимальному ----

   frontend.css (@media max-width: 991px) держит шторку на
   .page-template-newlisting #sidebar:not(.object_side) с
   max-height: calc(100vh - 80px). На iOS 100vh — высота при СПРЯТАННОЙ
   адресной строке, поэтому при видимой строке шторка длиннее экрана,
   а её fixed-подвал с кнопкой «Показать» уходит под нижнюю границу.

   dvh считается по текущей высоте. 80px и брейкпоинт 991 — те же, что
   у движка: правило перекрывается один в один, меняется только единица.
   Где dvh не поддержан (Safari < 15.4, Chrome < 108) правило целиком
   отбрасывается и остаётся движковое 100vh, то есть как сейчас. */
@media (max-width: 991px) {

	body.pdd.page-template-newlisting #sidebar.pdd-sheet:not(.object_side) {
		max-height: calc(100dvh - 80px);
	}
}
