/* ==========================================================================
   Ads pages — Enhanced M3 Design
   ========================================================================== */

/* --- Ad Card (horizontal: image left, content right) --- */
.listing-card {
  display: flex;
  flex-direction: row;
  overflow: visible;
  /* Якорь для плашек «Топ»/«Premium»: они висят в правом верхнем углу ВСЕЙ
     карточки, как во Flutter (`Positioned(top: 10, right: 14)` поверх
     текстовой части), а не на фото. На фото правый верх занят флагом
     страны — раньше плашка ныряла под него на 30 px и читалась криво. */
  position: relative;
  background: var(--md-sys-color-surface-container-low);
  border-radius: var(--md-sys-shape-corner-large);
  /* Прозрачная рамка ТОЙ ЖЕ толщины, что цветная у .is-featured/.is-premium
     (3px). Без неё карточка Топ/Premium была на 6 px выше и шире обычной —
     «почему у Premium другой размер» (2026-08-10). Объявляем в БАЗОВОМ
     правиле: цветные варианты со специфичностью 0,2,0 перекроют цвет, но не
     геометрию. */
  border: 3px solid transparent;
  box-shadow: var(--shadow-card);
  transition:
    box-shadow var(--md-sys-motion-duration-medium) var(--md-sys-motion-easing-standard),
    transform var(--md-sys-motion-duration-spring) var(--md-sys-motion-easing-expressive),
    background var(--md-sys-motion-duration-short);
  /* View Transitions — уникальное имя на карту */
  view-transition-name: var(--vt, none);
}

.listing-card:hover {
  transform: translateY(-4px) scale(1.012);
  box-shadow: var(--shadow-card-hover);
  background: var(--md-sys-color-surface-container);
}

.listing-card__image {
  position: relative;
  width: 45%;
  aspect-ratio: 4 / 3;
  flex-shrink: 0;
  overflow: hidden;
  border-radius: var(--md-sys-shape-corner-large) 0 0 var(--md-sys-shape-corner-large);
  background: var(--md-sys-color-surface-variant);
}

/* :not(.listing-card__flag) обязателен: флаг — тоже <img> внутри
   __image, без исключения generic-правило (специфичность 0,1,1 > 0,1,0
   у .listing-card__flag) растягивало его на всё фото (BUG 2026-08-02;
   раньше маскировалось 404 флага по slug-пути). */
.listing-card__image img:not(.listing-card__flag) {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform var(--md-sys-motion-duration-long) var(--md-sys-motion-easing-standard);
}

.listing-card:hover .listing-card__image img:not(.listing-card__flag) {
  transform: scale(1.05);
}

/* Image gradient overlay for readability */
.listing-card__image::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 50%;
  background: linear-gradient(to top, rgba(0,0,0,0.3), transparent);
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--md-sys-motion-duration-short);
}

.listing-card:hover .listing-card__image::after { opacity: 1; }

.listing-card__no-photo {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* --- Category animal icon placeholder (no-photo) --- */
.listing-card__placeholder,
.gallery__placeholder {
  width: 100%;
  height: 100%;
  min-height: 180px;
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Category color gradients (top → bottom, как в мобилке) */
.listing-card__placeholder--cattle,
.gallery__placeholder--cattle {
  background: linear-gradient(180deg, rgba(165,214,167,0.4) 0%, #A5D6A7 100%);
}
.listing-card__placeholder--sheep,
.gallery__placeholder--sheep {
  background: linear-gradient(180deg, rgba(209,179,232,0.4) 0%, #D1B3E8 100%);
}
.listing-card__placeholder--horse,
.gallery__placeholder--horse {
  background: linear-gradient(180deg, rgba(255,224,178,0.4) 0%, #FFE0B2 100%);
}
.listing-card__placeholder--goat,
.gallery__placeholder--goat {
  background: linear-gradient(180deg, rgba(187,222,251,0.4) 0%, #BBDEFB 100%);
}
.listing-card__placeholder--camel,
.gallery__placeholder--camel {
  background: linear-gradient(180deg, rgba(255,249,196,0.4) 0%, var(--c-notice-bg) 100%);
}
.listing-card__placeholder--pig,
.gallery__placeholder--pig {
  background: linear-gradient(180deg, rgba(255,205,210,0.4) 0%, #FFCDD2 100%);
}
.listing-card__placeholder--bird,
.gallery__placeholder--bird {
  background: linear-gradient(180deg, rgba(178,223,219,0.4) 0%, #B2DFDB 100%);
}

/* Background icon pattern (3x3 grid) */
.listing-card__placeholder-pattern {
  position: absolute;
  inset: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  padding: 8px;
  gap: 4px;
}

.listing-card__placeholder-bg-icon {
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0.12;
  filter: brightness(0);
}

/* Central circle with icon */
.listing-card__placeholder-center {
  position: relative;
  z-index: 1;
  width: 96px;
  height: 96px;
  background: rgba(255, 255, 255, 0.92);
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
}

.listing-card__placeholder-center img {
  width: 56px;
  height: 56px;
  object-fit: contain;
}

/* Larger center for detail page */
.listing-card__placeholder-center--lg {
  width: 96px;
  height: 96px;
}

.listing-card__placeholder-center--lg img {
  width: 56px;
  height: 56px;
}

/* Gallery placeholder fills the main area — 4x4 grid for larger space */
.gallery__placeholder {
  border-radius: var(--md-sys-shape-corner-large);
}

.gallery__placeholder .listing-card__placeholder-pattern {
  grid-template-columns: repeat(4, 1fr);
  grid-template-rows: repeat(4, 1fr);
  padding: 16px;
  gap: 8px;
}

/* Флаг основной страны подачи — правый верхний угол фото (заменил бейдж
   «Новое», 2026-08-02). Компактный 24×18, чтобы не спорить с контентом. */
/* +50 % к прежним 24×18 (решение владельца 2026-08-12): на телефоне флаг
   читался как цветная точка, страну по нему было не узнать. Пропорция 4:3
   сохранена — файлы флагов из набора flags/4x3. */
.listing-card__flag {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 36px;
  height: 27px;
  border-radius: 4px;
  object-fit: cover;
  box-shadow: 0 1px 2px rgba(0,0,0,0.3);
  z-index: 1;
}

/* --- Badge (Buy / Top / Premium) ---
   Живёт в `article.listing-card`, а НЕ внутри `.listing-card__image`:
   правый верхний угол карточки — как во Flutter. Координаты те же
   (top 10 / right 14), чтобы не упираться в скругление 31 px. */
.listing-card__badge {
  position: absolute;
  top: 10px;
  right: 14px;
  padding: 2px 8px;
  border-radius: var(--md-sys-shape-corner-extra-small);
  font: var(--md-sys-typescale-label-small);
  letter-spacing: 0.5px;
  z-index: 2;
}

/* «Куплю» — бейдж спроса (скупка) на карточке.
   ⚠️ Был `--md-sys-color-tertiary` — токена с таким именем в tokens.css НЕТ
   (проверено 24.08.2026), поэтому фон не подставлялся вовсе и бейдж читался
   как белый текст на фотографии, то есть был невидим. Берём оливковый
   secondary дизайн-кода: он отличается и от зелёного бренда, и от оранжевого
   «Топ», за которым закреплены деньги. */
.listing-card__badge--buy {
  background: var(--md-sys-color-secondary);
  color: var(--md-sys-color-on-secondary);
}

/* Чипы намерения ленты: Продам / Куплю */
.mkt-intent-tabs {
  display: flex;
  gap: 8px;
  margin: 12px 0 4px;
}
.mkt-intent-tab {
  padding: 6px 18px;
  border-radius: 9999px;
  border: 1px solid var(--md-sys-color-outline-variant);
  font: var(--md-sys-typescale-label-large);
  text-decoration: none;
  color: var(--md-sys-color-on-surface);
}
.mkt-intent-tab--active {
  background: var(--md-sys-color-primary);
  border-color: var(--md-sys-color-primary);
  color: var(--md-sys-color-on-primary);
}

.listing-card__badge--top {
  background: var(--md-sys-color-warning, var(--c-top));
  color: var(--c-on-brand);
}

/* Карточка перевёрнута в столбец (планшет, сетки деталки, каталог) — фото
   занимает всю ширину, и правый верх карточки совпадает с правым верхом
   фото, где висит флаг. Тогда плашка уходит НАЛЕВО: в горизонтальной
   раскладке она справа, как во Flutter, а в вертикальной иначе столкнулась
   бы с флагом. */
.mkt-detail .card-grid .listing-card > .listing-card__badge,
.listings-list--catalog .listing-card > .listing-card__badge {
  left: 10px;
  right: auto;
}

@media (min-width: 840px) and (max-width: 1199.98px) {
  .listings-list .listing-card > .listing-card__badge {
    left: 10px;
    right: auto;
  }
}

.listing-card__badge--verified {
  background: var(--md-sys-color-success);
  color: var(--c-on-brand);
}

.listing-card__content {
  flex: 1;
  min-width: 0;
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

@media (min-width: 600px) {
  .listing-card__content { padding: 16px 20px; gap: 6px; }
}

a.listing-card__header {
  display: block;
  text-decoration: none;
  color: inherit;
  margin-bottom: 2px;
}

a.listing-card__header:hover .listing-card__category,
a.listing-card__header:hover .listing-card__breed {
  color: var(--md-sys-color-primary);
}

.listing-card__category {
  font: 500 16px/22px 'Roboto', sans-serif;
  color: var(--md-sys-color-on-surface);
}

.listing-card__breed {
  font: 500 15px/20px 'Roboto', sans-serif;
  color: var(--md-sys-color-on-surface);
}

@media (min-width: 600px) {
  .listing-card__category { font-size: 20px; line-height: 26px; }
  .listing-card__breed { font-size: 17px; line-height: 22px; }
}

.listing-card__help {
  font-size: 20px;
  color: var(--md-sys-color-outline);
  cursor: help;
  flex-shrink: 0;
}

.listing-card__meta {
  display: flex;
  align-items: center;
  gap: 10px;
  font: 400 12px/16px 'Roboto', sans-serif;
  color: var(--md-sys-color-on-surface-variant);
}
@media (min-width: 600px) {
  .listing-card__meta { gap: 14px; font-size: 14px; line-height: 20px; }
}

.listing-card__chars {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 12px;
  font: 400 12px/16px 'Roboto', sans-serif;
  color: var(--md-sys-color-on-surface-variant);
  margin: 4px 0;
}

@media (min-width: 600px) {
  .listing-card__chars { gap: 10px 18px; font-size: 14px; line-height: 20px; margin: 6px 0; }
}

.listing-card__char {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  white-space: nowrap;
}
/* Правый нижний угол карточки: звезда СВЕРХУ, крупный ценник под ней
   (решение владельца 2026-08-13, скриншот 337.jpg). `column-reverse` —
   потому что в разметке цена идёт первой (её читает и парсер, и старые
   стили), а показать её нужно последней; `margin-top: auto` прижимает всю
   пару к низу, иначе под ценой зияла дыра высотой с фото. */
.listing-card__footer {
  display: flex;
  flex-direction: column-reverse;
  align-items: flex-end;
  gap: 4px;
  margin-top: auto;
  padding-top: 8px;
}

@media (min-width: 600px) {
  .listing-card__footer { gap: 6px; padding-top: 10px; }
}

/* Ценник — главный элемент карточки: 14 px против прежних 12 (2026-08-13,
   после подгонки владельцем: 18 оказалось крупно, −25 %). Правило одно на
   ценник и «Договорную» — они обязаны выглядеть одинаково, это два вида
   одной и той же цены. */
.listing-card__footer .chip {
  margin-left: auto;
  font-size: 14px;
  line-height: 18px;
  font-weight: 600;
  padding: 6px 14px;
}

/* Desktop: larger image */
@media (min-width: 840px) {
  .listing-card__image { width: 45%; }
  .listing-card__category { font-size: 18px; }
  .listing-card__breed { font-size: 16px; }
  .listing-card__chars { font-size: 13px; }
}

/* --- Card grid: single column for ad cards --- */
.listings-list .card-grid {
  grid-template-columns: 1fr;
}

/* --- Filter toggle button --- */
.filter-toggle-btn { margin-bottom: 0; }

@media (min-width: 840px) {
  .filter-toggle-btn { display: none; }
}

/* --- Компактная шапка списков (единый формат вертикалей, без пустого места) ---
   Маленький заголовок (title-large 22px вместо headline-large 36px) + счётчик
   инлайн-бейджем + компактная кнопка «Фильтры» (на десктопе скрыта → sidebar).
   Заменяет крупный page-title + отдельную строку results-counter. */
.listings-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: var(--md-sys-spacing-sm);
}
.listings-header__head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  min-width: 0;
}
.listings-header__title {
  font: var(--md-sys-typescale-title-large);
  margin: 0;
  color: var(--brand-ink);
}
.listings-header__count {
  font-size: 13px;
  font-weight: 600;
  color: var(--md-sys-color-on-surface-variant);
  flex-shrink: 0;
}
.listings-header .filter-toggle-btn {
  padding: 6px 14px;
  font-size: 13px;
}
.listings-header .filter-toggle-btn svg { width: 18px; height: 18px; }

/* --- Detail page --- */
.listing-detail__gallery { margin-bottom: var(--md-sys-spacing-lg); }

.listing-detail__section-title {
  font: var(--md-sys-typescale-title-large);
  color: var(--md-sys-color-on-surface);
  margin: var(--md-sys-spacing-lg) 0 var(--md-sys-spacing-md);
}

.listing-detail__price-row {
  display: flex;
  align-items: center;
  gap: var(--md-sys-spacing-sm);
  margin-bottom: var(--md-sys-spacing-lg);
}

.listing-detail__chars { margin-bottom: var(--md-sys-spacing-lg); }

.listing-detail__description {
  font: var(--md-sys-typescale-body-large);
  line-height: 1.6;
  text-align: justify;
  margin-bottom: var(--md-sys-spacing-lg);
}

.listing-detail__contact {
  text-align: center;
  margin-top: var(--md-sys-spacing-lg);
}

/* Gallery */
.gallery {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 24px;
}

.gallery__main {
  width: 100%;
  aspect-ratio: 4/3;
  border-radius: var(--md-sys-shape-corner-large);
  overflow: hidden;
  background: var(--md-sys-color-surface-variant);
  position: relative;
}

.gallery__main img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity var(--md-sys-motion-duration-medium) var(--md-sys-motion-easing-standard);
}

.gallery__main img.is-switching { opacity: 0.5; }

.gallery__thumbs {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  scrollbar-width: none;
}

.gallery__thumbs::-webkit-scrollbar { display: none; }

.gallery__thumb {
  width: 80px;
  height: 80px;
  border-radius: var(--md-sys-shape-corner-large);
  overflow: hidden;
  cursor: pointer;
  flex-shrink: 0;
  border: 2px solid transparent;
  transition: border-color var(--md-sys-motion-duration-short),
              transform var(--md-sys-motion-duration-short);
}

.gallery__thumb:hover { transform: scale(1.05); }

.gallery__thumb--active {
  border-color: var(--md-sys-color-primary);
}

.gallery__thumb img { width: 100%; height: 100%; object-fit: cover; }

/* ===========================================================================
   Галерея-плеер деталки (includes/_gallery.html + js/gallery_player.js)
   Раскладка-референс — карточка товара Ozon: миниатюры колонкой слева,
   кадр вписывается целиком на размытой подложке из него же.
   =========================================================================== */
.gallery--player {
  display: grid;
  grid-template-columns: 72px minmax(0, 1fr);
  align-items: start;
  gap: 12px;
  margin-bottom: 24px;
}

/* Без миниатюр (одно фото или ни одного) — только сцена. Класс ставит
   шаблон: `:has()` не знают Firefox < 121 и Safari < 15.4, а без него колонка
   миниатюр съедала бы 72 px пустоты слева. */
.gallery--solo { grid-template-columns: minmax(0, 1fr); }
.gallery--player:not(:has(.gallery__thumbs)) { grid-template-columns: minmax(0, 1fr); }

.gallery--player .gallery__thumbs {
  flex-direction: column;
  max-height: min(70vh, 560px);
  overflow-y: auto;
  overflow-x: hidden;
  padding-right: 2px;
}

.gallery--player .gallery__thumb {
  width: 64px;
  height: 64px;
  padding: 0;
  background: var(--md-sys-color-surface-variant);
  border-radius: 12px;
  position: relative;
}

.gallery__thumb--video .gallery__thumb-play {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--c-on-brand);
  background: rgba(0, 0, 0, 0.35);
  border-radius: 10px;
}

.gallery--player .gallery__main {
  aspect-ratio: 4 / 3;
  display: grid;
  place-items: center;
  background: var(--md-sys-color-surface-variant);
}

/* Кадр целиком: скот больше не режется по рогам/ногам. */
.gallery--player .gallery__img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  opacity: 0;
  transition: opacity 260ms var(--md-sys-motion-easing-standard);
  z-index: 1;
}

.gallery--player .gallery__img--active { opacity: 1; }

.gallery__backdrop {
  position: absolute;
  inset: -8%;
  background-size: cover;
  background-position: center;
  filter: blur(28px) saturate(1.1) brightness(0.85);
  transform: scale(1.06);
  z-index: 0;
}

.gallery__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
  background: #000;
  display: none;
  z-index: 3;
}

.gallery--video .gallery__video { display: block; }

/* Сегментный прогресс — как в сторис. Тёмная вуаль сверху: на светлом кадре
   (а у скота фон обычно небо/снег) белые полоски иначе сливаются. */
.gallery--player .gallery__main::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 44px;
  background: linear-gradient(rgba(0, 0, 0, 0.28), transparent);
  z-index: 3;
  pointer-events: none;
}

.gallery--solo .gallery__main::before,
.gallery--player:not(:has(.gallery__segments)) .gallery__main::before { display: none; }

.gallery__segments {
  position: absolute;
  top: 10px;
  left: 12px;
  right: 12px;
  display: flex;
  gap: 4px;
  z-index: 4;
  pointer-events: none;
}

.gallery__segment {
  flex: 1;
  height: 3px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.35);
  overflow: hidden;
}

.gallery__segment i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--c-surface);
  border-radius: 3px;
}

.gallery__segment.is-done i { width: 100%; }
.gallery__segment.is-active i { width: 100%; transition: width 260ms linear; }

/* Кнопка авто-показа — слева внизу: справа внизу сидит счётчик «i / N». */
.gallery__play {
  position: absolute;
  left: 12px;
  bottom: 12px;
  z-index: 4;
  width: 36px;
  height: 36px;
  display: grid;
  place-items: center;
  border: none;
  border-radius: 50%;
  color: var(--c-on-brand);
  background: rgba(0, 0, 0, 0.55);
  cursor: pointer;
}

.gallery__play:hover { background: rgba(0, 0, 0, 0.72); }
.gallery__play svg { width: 18px; height: 18px; }

/* Пауза ⇄ play: в паузе показываем «плей» через CSS-маску-символ. */
.gallery__play--paused svg { display: none; }
.gallery__play--paused::before {
  content: '';
  width: 0;
  height: 0;
  border-left: 11px solid var(--c-on-brand);
  border-top: 7px solid transparent;
  border-bottom: 7px solid transparent;
  margin-left: 3px;
}

@media (max-width: 900px) {
  /* Мобильный: миниатюры полосой под фото (колонка слева съедает ширину). */
  .gallery--player {
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
  }

  .gallery--player .gallery__thumbs {
    order: 2;
    flex-direction: row;
    max-height: none;
    overflow-x: auto;
    overflow-y: hidden;
  }

  .gallery--player .gallery__stage { order: 1; }
  .gallery--player .gallery__thumb { width: 56px; height: 56px; }
}

@media (prefers-reduced-motion: reduce) {
  .gallery--player .gallery__img { transition: none; }
  .gallery__segment.is-active i { transition: none; }
}

/* Detail header / actions */
.detail-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 16px;
}

.detail-header__title {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Price hero — заметный фокус (M3 Expressive headline) */
.detail-price {
  margin-bottom: 24px;
  view-transition-name: price-hero;
}
.detail-price .price--lg {
  font: var(--md-sys-typescale-display-large);
  font-variation-settings: "opsz" 48, "wght" 900, "GRAD" 50;
  letter-spacing: -2px;
  color: var(--md-sys-color-primary);
  font-size: 44px;
  line-height: 1.0;
}

/* --- Characteristics list · M3 Expressive с tonal surface --- */
.char-list {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 10px 24px;
  margin: 8px 0 24px;
}
.char-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 14px;
  border-radius: var(--md-sys-shape-corner-small);
  background: var(--md-sys-color-surface-container-low);
  transition: background var(--md-sys-motion-duration-short) var(--md-sys-motion-easing-standard);
}
.char-item:hover { background: var(--md-sys-color-surface-container); }
.char-item svg {
  width: 20px; height: 20px;
  color: var(--md-sys-color-primary);
  flex-shrink: 0;
}
.char-item strong { color: var(--brand-ink); font-weight: 600; }
.char-item span { color: var(--md-sys-color-on-surface-variant); font-size: 14px; }

/* --- Glass floating CTA · Call + Favorite (M3 Expressive + Acrylic) --- */
.floating-cta {
  position: sticky;
  bottom: 16px;
  left: 0; right: 0;
  display: flex;
  gap: 10px;
  padding: 12px 16px;
  margin: 24px auto 0;
  max-width: 720px;
  background: var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-border);
  box-shadow: var(--glass-rim);
  border-radius: var(--md-sys-shape-corner-full);
  box-shadow: 0 6px 24px rgba(27, 116, 62, 0.15);
  z-index: 50;
}
.floating-cta__primary {
  flex: 1;
  font: var(--md-sys-typescale-label-large);
  font-size: 16px; font-weight: 700;
  padding: 14px 20px;
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-primary);
  color: var(--md-sys-color-on-primary);
  border: none; cursor: pointer;
  transition: transform var(--md-sys-motion-duration-short) var(--md-sys-motion-easing-expressive);
}
.floating-cta__primary:hover { transform: scale(1.03); }

.detail-actions {
  display: flex;
  gap: 12px;
  margin-top: 24px;
}

.contact-section { margin-top: 32px; }

/* --- Filter panel styling --- */
.filter-panel {
  padding: 4px 0;
  /* Bug 6: на mobile фильтры "елозили" — selects/inputs выходили за
     края bottom-sheet. Жёстко прибиваем к 100% ширине контейнера. */
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
}

.filter-panel *,
.filter-panel *::before,
.filter-panel *::after {
  box-sizing: border-box;
}

.filter-panel .input-group {
  margin-bottom: 12px;
  /* min-width:0 — обязательно для flex-children в input-group__range */
  min-width: 0;
}

.filter-panel .input-group__label {
  font: 500 13px/16px 'Roboto', sans-serif;
  color: var(--md-sys-color-on-surface);
  margin-bottom: 6px;
}

.filter-panel .select {
  font-size: 14px;
  padding: 10px 36px 10px 14px;
  min-height: 42px;
  border-radius: var(--md-sys-shape-corner-small);
}

.filter-panel .input {
  font-size: 14px;
  padding: 10px 14px;
  min-height: 42px;
  border-radius: var(--md-sys-shape-corner-small);
}

.filter-panel__range-inputs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  width: 100%;
}

.filter-panel__range-inputs > div {
  flex: 1 1 0;
  min-width: 0;
}

.filter-panel__range-inputs .input {
  width: 100%;
  min-width: 0;
}

/* "Ещё фильтры" button */
.filter-panel__more-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  width: 100%;
  padding: 10px;
  margin-top: 8px;
  border: none;
  background: none;
  cursor: pointer;
  font: 500 14px/20px 'Roboto', sans-serif;
  color: var(--md-sys-color-primary);
  border-radius: var(--md-sys-shape-corner-full);
  transition: background 0.15s;
}

.filter-panel__more-btn:hover { background: rgba(27,116,62,0.06); }
/* Extra filters (hidden by default) */
.filter-panel__extra {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.filter-panel__extra.is-open {
  /* Запас на 4 input-group (Страна/Валюта/Возраст/Молоко); раньше 400px
     обрезал нижние поля. overflow:hidden нужен только для transition. */
  max-height: 600px;
}

/* --- Десктоп: фильтры показываем ЦЕЛИКОМ, без «Ещё» ---------------------
   Решение владельца 25.08.2026: «в фильтрах убрать «Ещё» и держать
   открытой, чтоб весь выбор видели». На широком экране прятать половину
   фильтров незачем — место есть, а спрятанное поле человек просто не
   находит. На мобильном сворачивание ОСТАЁТСЯ: там высота дорогая.

   Брейкпоинт 840px — тот же, на котором появляется десктопный сайдбар
   (base.css), чтобы «десктоп» означал одно и то же во всём интерфейсе.

   max-height: none обязателен вместе со скрытием кнопки: без него панель
   осталась бы схлопнутой в 0 и открыть её было бы уже нечем. Блок идёт
   ПОСЛЕ правила .is-open — иначе то перебило бы его своей 600px. */
@media (min-width: 840px) {
  .filter-panel__more-btn { display: none; }
  .filter-panel__extra,
  .filter-panel__extra.is-open {
    max-height: none;
    overflow: visible;
  }
}

/* Reset link */
.filter-panel__reset {
  display: block;
  text-align: center;
  margin-top: 12px;
  font: 400 13px/18px 'Roboto', sans-serif;
  color: var(--md-sys-color-on-surface-variant);
}

.filter-panel__reset:hover {
  color: var(--md-sys-color-error);
}

input[type="range"] {
  width: 100%;
  accent-color: var(--md-sys-color-primary);
}

/* --- Featured card highlight (паритет с Flutter: жирнее рамка + заметный glow) --- */
.listing-card.is-featured {
  /* Цветное свечение «Топ» + та же тень объёма, что у обычной карточки:
     иначе платная карточка светилась, но не поднималась над фоном, и
     соседние обычные казались объёмнее её. Оранжевый берём из токена —
     старое rgba(245,127,23) осталось от прежнего оттенка. */
  border: 3px solid var(--c-top);
  box-shadow: 0 4px 20px rgba(224, 123, 30, 0.32), var(--shadow-card);
}

/* Золотая рамка продавца с подпиской Premium — тот же приём, что TOP, но в
   золоте венка (#D9A521, как слово «Premium» в ЛК). featured приоритетнее:
   шаблоны ставят is-premium только когда карточка НЕ featured. */
.listing-card.is-premium {
  border: 3px solid var(--c-premium);
  box-shadow: 0 4px 20px rgba(199, 154, 31, 0.32), var(--shadow-card);
}

/* Плашка «Premium» на фото — как --top, но золото; латинский бренд-маркер. */
.listing-card__badge--premium {
  background: var(--c-premium);
  color: var(--c-on-brand);
}

/* Плашка НА фото (у молока — «Регулярно»): левый низ, подальше от флага в
   правом верхнем углу. Инлайновых `style="position:absolute;top:30px"` в
   шаблонах больше нет — лесенка ломалась при каждом изменении размеров. */
.listing-card__chip-photo {
  position: absolute;
  left: 8px;
  bottom: 8px;
  z-index: 2;
}

/* --- EPD grid --- */
.epd-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
  margin-bottom: var(--md-sys-spacing-md);
  /* bag2: предотвращаем горизонтальный overflow viewport'а на mobile.
     Без max-width 100% и min-width 0 у ячеек длинные числовые value
     растягивают column шире чем 1fr → ломают grid → появляется H-scroll. */
  max-width: 100%;
}

@media (min-width: 600px) {
  .epd-grid { grid-template-columns: repeat(3, 1fr); }
}

@media (min-width: 840px) {
  .epd-grid { grid-template-columns: repeat(4, 1fr); }
}

.epd-item {
  display: flex;
  flex-direction: column;
  padding: 10px 14px;
  background-image: linear-gradient(rgba(164,161,108,0.08), rgba(164,161,108,0.08)),
                     linear-gradient(var(--md-sys-color-surface), var(--md-sys-color-surface));
  border-radius: var(--md-sys-shape-corner-medium);
  border: 1px solid var(--md-sys-color-outline-variant);
  /* bag2: grid item shrink + перенос длинных слов */
  min-width: 0;
  overflow-wrap: anywhere;
  word-break: break-word;
}

.epd-item__label {
  font: 400 11px/14px 'Roboto', sans-serif;
  color: var(--md-sys-color-on-surface-variant);
  margin-bottom: 4px;
  min-width: 0;
  overflow-wrap: anywhere;
}

.epd-item__value {
  font: 600 18px/24px 'Roboto', sans-serif;
  color: var(--md-sys-color-primary);
  min-width: 0;
  overflow-wrap: anywhere;
}

/* --- Skeleton cards --- */
.listing-card-skeleton {
  display: flex;
  flex-direction: row;
  overflow: hidden;
  border-radius: var(--md-sys-shape-corner-medium);
  background: var(--md-sys-color-surface);
  box-shadow: var(--md-sys-elevation-1);
}

.listing-card-skeleton__image {
  width: 120px;
  min-height: 120px;
  flex-shrink: 0;
}

.listing-card-skeleton__content {
  flex: 1;
  padding: 12px 16px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

@media (min-width: 840px) {
  .listing-card-skeleton__image { width: 200px; min-height: 160px; }
}

/* ==========================================================================
   Ad Detail — двухколоночный layout (kopeika.shop-style в CattleSales палитре)
   ========================================================================== */

.mkt-detail {
  max-width: 1280px;
  margin: 0 auto;
  padding: 12px 16px 64px;
  /* Safety net: ни один внутренний grid/flex не должен растянуть viewport. */
  overflow-x: clip;
  min-width: 0;
}

/* Универсальный fix для grid/flex items внутри detail —
   без min-width: 0 контент с длинными словами/URL/неразрывными значениями
   расширяет свою ячейку, ломая весь layout. Применяем рекурсивно ко всем
   grid/flex children, чтобы не выискивать каждый случай отдельно. */
.mkt-detail :is(.mkt-detail__layout, .mkt-detail__main, .mkt-detail__aside,
                .mkt-specs, .mkt-specs__row, .mkt-aside__cta-row,
                .epd-grid, .mkt-detail__stats, .card-grid) > * {
  min-width: 0;
  max-width: 100%;
}

/* Сетки `.card-grid--related` («Похожие объявления» плиткой) больше нет: блок
   рисуется той же горизонтальной каруселью, что и «Другие объявления
   продавца» (`includes/_seller_carousel.html`) — решение владельца. Правила
   вида компактной карточки живут ниже, под `.mkt-seller-carousel`. */

/* --- Breadcrumbs --- стили переехали в components.css (глобальный app.css),
   чтобы крошки работали на ВСЕХ страницах, не только маркетплейсных. --- */

/* --- Title row --- */
.mkt-detail__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 20px;
}
.mkt-detail__title {
  margin: 0;
  font: 700 28px/34px 'Roboto', system-ui, sans-serif;
  color: var(--brand-ink);
  flex: 1;
  min-width: 0;
  word-wrap: break-word;
}
@media (min-width: 768px) {
  .mkt-detail__title { font-size: 32px; line-height: 40px; }
}
/* Share/QR-иконки справа от заголовка (паритет с Flutter-деталкой). */
.mkt-detail__share-row {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}
.mkt-detail__share-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 0;
  background: none;
  border-radius: 50%;
  color: var(--brand-green, var(--c-brand));
  cursor: pointer;
}
.mkt-detail__share-btn:hover,
.mkt-detail__share-btn:focus-visible {
  background: rgba(27, 116, 62, 0.08);
}

/* --- Двухколоночный grid --- */
.mkt-detail__layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 24px;
}

@media (min-width: 960px) {
  .mkt-detail__layout {
    grid-template-columns: minmax(0, 1fr) 360px;
    gap: 32px;
    align-items: start;
  }
}

@media (min-width: 1200px) {
  .mkt-detail__layout {
    grid-template-columns: minmax(0, 1fr) 380px;
  }
}

.mkt-detail__main {
  min-width: 0;
  /* bag2 safety net: блокируем горизонтальный scroll если внутри
     случайно появится over-wide элемент (видео iframe без max-width,
     pre-блок с длинной строкой, и т.п.) */
  overflow-x: hidden;
}

.mkt-detail__aside {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

@media (min-width: 960px) {
  .mkt-detail__aside {
    position: sticky;
    top: 80px;
    align-self: start;
    max-height: calc(100vh - 96px);
    overflow-y: auto;
    scrollbar-width: thin;
    /* Прячем scrollbar — sticky-блок прокручивается при необходимости,
       но визуальный шум минимизируем */
    scrollbar-color: var(--md-sys-color-outline-variant) transparent;
  }
}

/* --- Gallery с overlay-кнопками + ribbons --- */
/* Полоса сегментов «сторис» занимает самый верх кадра (top 10), поэтому
   плашки и флаг начинаются ниже неё — раньше «Топ» стоял в том же левом
   верхнем углу, что и флаг страны, и попросту закрывал его (2026-08-12). */
.gallery__ribbon {
  position: absolute;
  top: 26px;
  z-index: 2;
  padding: 6px 12px;
  font: 600 12px/16px 'Roboto', system-ui, sans-serif;
  letter-spacing: 0.5px;
  text-transform: uppercase;
  border-radius: var(--md-sys-shape-corner-small);
  display: inline-flex;
  align-items: center;
  gap: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}
/* «Топ» — СПРАВА, как плашка на карточке ленты и во Flutter. Слева сверху
   живёт флаг страны. */
.gallery__ribbon--top {
  right: 12px;
  background: linear-gradient(135deg, var(--c-premium) 0%, var(--c-top) 100%);
  color: var(--c-on-brand);
}
.gallery__ribbon--top svg { font-size: 14px; }
.gallery__ribbon--sold {
  right: 12px;
  background: rgba(26, 28, 24, 0.85);
  /* Обе плашки сразу (проданное объявление было в «Топе») — «Продано»
     опускается под «Топ». В разметке featured идёт первым, поэтому хватает
     соседнего комбинатора. */
  color: var(--c-on-brand);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
}

.gallery__ribbon--top ~ .gallery__ribbon--sold { top: 66px; }

/* Prev/Next нав-кнопки на главном фото */
.gallery__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: none;
  background: rgba(255, 255, 255, 0.92);
  color: var(--brand-ink);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.18);
  opacity: 0;
  transition: opacity var(--md-sys-motion-duration-short),
              transform var(--md-sys-motion-duration-short),
              background var(--md-sys-motion-duration-short);
  z-index: 2;
}
.gallery:hover .gallery__nav,
.gallery__main:focus-within .gallery__nav { opacity: 1; }
.gallery__nav:hover {
  background: var(--c-surface);
  transform: translateY(-50%) scale(1.05);
}
.gallery__nav svg { font-size: 24px; }
.gallery__nav--prev { left: 12px; }
.gallery__nav--next { right: 12px; }

@media (hover: none) {
  /* На touch-устройствах кнопки видны всегда (нет :hover) */
  .gallery__nav { opacity: 0.85; }
}

/* Counter «1 / N» справа снизу */
.gallery__counter {
  position: absolute;
  bottom: 12px;
  right: 12px;
  padding: 4px 10px;
  font: 500 12px/16px 'Roboto', system-ui, sans-serif;
  background: rgba(26, 28, 24, 0.72);
  color: var(--c-on-brand);
  border-radius: var(--md-sys-shape-corner-full);
  backdrop-filter: blur(4px);
  -webkit-backdrop-filter: blur(4px);
  z-index: 2;
  pointer-events: none;
}

/* --- Stats row под галереей --- */
.mkt-detail__stats {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  padding: 12px 0;
  margin: 8px 0 24px;
  border-top: 1px solid var(--md-sys-color-outline-variant);
  border-bottom: 1px solid var(--md-sys-color-outline-variant);
  font-size: 13px;
  color: var(--md-sys-color-on-surface-variant);
}
.mkt-detail__stats-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.mkt-detail__stats-item svg {
  color: var(--md-sys-color-outline);
  font-size: 18px;
}
.mkt-detail__stats-item--id {
  margin-left: auto;
  color: var(--md-sys-color-outline);
  font-variant-numeric: tabular-nums;
}

/* Просмотры — крупнее остальных stats (акцент по запросу). */
.mkt-detail__stats-item--views {
  font-size: 15px;
  font-weight: 600;
  color: var(--md-sys-color-on-surface);
}
.mkt-detail__stats-item--views svg { font-size: 20px; }
.mkt-detail__views-count {
  font-size: 17px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* Кнопка «в избранное» в stats-row — заметная, с активным состоянием. */
.mkt-fav {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: none;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: 100px;
  cursor: pointer;
  color: var(--md-sys-color-on-surface-variant);
  font-size: 15px;
  font-weight: 600;
  line-height: 1;
  padding: 7px 14px;
  text-decoration: none;
  transition: color .15s, border-color .15s, background .15s;
}
/* Звезда «в избранное»: жёлтая в активном состоянии, серая в покое
   (2026-08-12; было розовое сердце-лайк). */
.mkt-fav:hover {
  color: var(--cs-favorite);
  border-color: var(--cs-favorite);
  text-decoration: none;
}
.mkt-fav--active {
  color: var(--cs-favorite);
  border-color: var(--cs-favorite);
  background: rgba(245, 179, 1, .10);
}
.mkt-fav svg { font-size: 20px; }
.mkt-fav__count { font-variant-numeric: tabular-nums; }
/* Bounce-анимация при клике (как .favorite-btn). */
.mkt-fav svg {
  transition: transform var(--md-sys-motion-duration-medium, .25s)
              var(--md-sys-motion-easing-emphasized, ease);
}
.mkt-fav.is-animating svg { animation: favorite-bounce 0.4s ease; }

/* --- Sections (Описание / Характеристики / Видео) --- */
.mkt-section {
  margin-bottom: 28px;
}
.mkt-section__title {
  margin: 0 0 14px;
  font: 600 20px/26px 'Roboto', system-ui, sans-serif;
  color: var(--brand-ink);
}

/* Заголовок карусели-вставки («Объявления из других стран») — крупнее и с
   акцентной полосой слева: в ленте он шёл рядовой строкой и терялся между
   карточками, читатель не понимал, откуда вдруг чужие страны (2026-08-12).
   Полоса — тем же primary, что ценник и активные чипы: новых цветов не
   вводим. */
.mkt-section__title--carousel {
  margin: 0 0 10px;
  padding-left: 10px;
  border-left: 4px solid var(--md-sys-color-primary);
  font: 700 22px/28px 'Roboto', system-ui, sans-serif;
}

@media (min-width: 600px) {
  .mkt-section__title--carousel { font-size: 24px; line-height: 30px; }
}

/* Вставка в ленте: сама секция не должна оставлять полосу пустоты под
   карточками — они низкие (фото + название + цена), а секция несла отступ
   как полноразмерный блок деталки. */
.mkt-section--carousel {
  /* Разрыв до следующей карточки ленты — как между обычными карточками
     (grid gap 8 px), не как между блоками деталки. Замер 13.08: было
     44 px суммарно — 12 margin + 8 gap + 24 внутри скроллера. */
  margin-bottom: 2px;
}
.mkt-section__text {
  font: 400 15px/24px 'Roboto', system-ui, sans-serif;
  color: var(--md-sys-color-on-surface);
  white-space: pre-wrap;
  word-wrap: break-word;
}

/* --- Specs table (две колонки key/value) --- */
.mkt-specs {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  margin: 0;
  background: var(--md-sys-color-surface-container-lowest);
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-medium);
  overflow: hidden;
  max-width: 100%;
  min-width: 0;
}
/* 2 колонки key:val — только когда хватает ширины (1200+).
   До этого 1 колонка чтобы values не обрезались (iPad landscape 1024-1200). */
@media (min-width: 1200px) {
  .mkt-specs { grid-template-columns: 1fr 1fr; }
}

.mkt-specs__row {
  display: grid;
  grid-template-columns: minmax(110px, 38%) 1fr;
  gap: 12px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--md-sys-color-outline-variant);
  min-width: 0;
  overflow-wrap: anywhere;
  word-break: break-word;
  align-items: center;
  margin: 0;
}
.mkt-specs__row:last-child,
.mkt-specs__row:nth-last-child(2):nth-child(odd) {
  border-bottom: none;
}
@media (min-width: 600px) {
  /* На 2-колоночной сетке убрать border у предпоследних */
  .mkt-specs__row:nth-last-child(-n+2) { border-bottom: none; }
  .mkt-specs__row:nth-child(odd) { border-right: 1px solid var(--md-sys-color-outline-variant); }
}

.mkt-specs__key {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin: 0;
  min-width: 0;
  font-size: 16px;
  color: var(--md-sys-color-on-surface-variant);
  overflow-wrap: anywhere;
  word-break: break-word;
}
.mkt-specs__key svg {
  color: var(--brand-green);
  flex-shrink: 0;
}
.mkt-specs__val {
  margin: 0;
  min-width: 0;
  font-size: 17px;
  font-weight: 500;
  color: var(--brand-ink);
  word-wrap: break-word;
  overflow-wrap: anywhere;
  word-break: break-word;
}

/* --- Aside cards (правый sticky-блок) --- */
.mkt-aside {
  background: var(--md-sys-color-surface-container-lowest);
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-large);
  padding: 18px;
  box-shadow: 0 1px 3px rgba(26, 28, 24, 0.04);
}
.mkt-aside__title {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 0 0 12px;
  font: 600 15px/20px 'Roboto', system-ui, sans-serif;
  color: var(--brand-ink);
}
.mkt-aside__title svg {
  color: var(--brand-green);
}

.mkt-aside__price {
  font: 800 30px/36px 'Roboto', system-ui, sans-serif;
  letter-spacing: -0.5px;
  color: var(--brand-green);
  margin-bottom: 4px;
  word-break: break-word;
}
@media (min-width: 768px) {
  .mkt-aside__price { font-size: 32px; line-height: 38px; }
}
.mkt-aside__price--negotiable {
  font-size: 22px;
  line-height: 28px;
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

.mkt-aside__price-note {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  color: var(--md-sys-color-on-surface-variant);
  margin-bottom: 12px;
}

.mkt-aside__status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px;
  margin: 8px 0 12px;
  font-size: 13px;
  border-radius: var(--md-sys-shape-corner-small);
}
.mkt-aside__status--sold {
  background: rgba(26, 28, 24, 0.06);
  color: var(--md-sys-color-on-surface-variant);
}

/* CTA-кнопки в правом блоке */
.mkt-aside__cta-row {
  margin: 14px 0 8px;
}
.mkt-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: 100%;
  min-height: 48px;
  padding: 12px 18px;
  font-size: 15px;
  font-weight: 600;
  border-radius: var(--md-sys-shape-corner-medium);
  margin-bottom: 8px;
}
.mkt-cta--primary {
  background: var(--brand-green);
  color: var(--c-on-brand);
}
.mkt-cta--secondary {
  background: transparent;
  color: var(--brand-green);
  border: 1.5px solid var(--brand-green);
}
.mkt-cta--secondary:hover {
  background: rgba(27, 116, 62, 0.06);
}
.mkt-cta--disabled {
  color: var(--md-sys-color-outline);
  border-color: var(--md-sys-color-outline-variant);
  cursor: not-allowed;
}
.mkt-cta--revealed {
  background: rgba(27, 116, 62, 0.08);
  font-variant-numeric: tabular-nums;
}
.mkt-cta--share,
.mkt-cta--voip {
  width: 100%;
  justify-content: center;
  font-size: 14px;
  font-weight: 500;
  min-height: 40px;
  color: var(--md-sys-color-on-surface-variant);
}
.mkt-aside__voip {
  display: flex;
  gap: 8px;
  margin-top: 4px;
}
.mkt-aside__voip .mkt-cta--voip { flex: 1; }

/* --- Seller card --- */
.mkt-seller {
  display: flex;
  gap: 12px;
  align-items: flex-start;
}
.mkt-seller__avatar {
  width: 48px;
  height: 48px;
  border-radius: 50%;
  background: var(--brand-olive);
  color: var(--c-on-brand);
  display: flex;
  align-items: center;
  justify-content: center;
  font: 600 20px/1 'Roboto', system-ui, sans-serif;
  flex-shrink: 0;
  overflow: hidden;
}
.mkt-seller__avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.mkt-seller__avatar-initial {
  text-transform: uppercase;
}
.mkt-seller__body {
  flex: 1;
  min-width: 0;
}
.mkt-seller__name {
  font: 600 15px/20px 'Roboto', system-ui, sans-serif;
  color: var(--brand-ink);
  word-wrap: break-word;
}
.mkt-seller__farm {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 13px;
  color: var(--md-sys-color-on-surface-variant);
  margin-top: 2px;
}
.mkt-seller__joined {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: var(--md-sys-color-outline);
  margin-top: 4px;
}
.mkt-seller__ads-count {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 12px;
  color: var(--md-sys-color-on-surface-variant);
  margin-top: 4px;
}
.mkt-seller__badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 6px;
  padding: 4px 12px;
  font-size: 14px;
  font-weight: 600;
  color: var(--brand-green);
  background: rgba(27, 116, 62, 0.10);
  border: 1px solid rgba(27, 116, 62, 0.35);
  border-radius: 100px;
}
/* Продавец не верифицирован — приглушённый информационный вариант. */
.mkt-seller__badge--muted {
  /* `--c-text-disabled` тут не годится: спецификация отводит его под
     плейсхолдеры и выключенное, а «Не верифицирован» — это ЧИТАЕМОЕ
     сообщение о продавце. На disabled контраст был 2.51, читалось блёкло. */
  color: var(--c-text-muted);
  background: rgba(0, 0, 0, 0.05);
  border: 1px solid rgba(0, 0, 0, 0.25);
}
.mkt-seller__info-link {
  width: 100%;
  margin-top: 12px;
}
.mkt-seller__add-form {
  margin-top: 12px;
}
.mkt-seller__add-btn {
  width: 100%;
  justify-content: center;
  font-size: 13px;
  min-height: 36px;
}

/* --- Location card --- */
.mkt-location {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 14px;
  color: var(--brand-ink);
}
.mkt-location__row {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
.mkt-location__row svg {
  color: var(--md-sys-color-outline);
  flex-shrink: 0;
}
.mkt-location__flag {
  width: 22px;
  height: 16px;
  border-radius: 2px;
  object-fit: cover;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.06);
  flex-shrink: 0;
}

/* Маленький инлайн-флаг в строке характеристик (страна-производитель). */
.mkt-flag-inline {
  width: 18px;
  height: 13px;
  border-radius: 2px;
  object-fit: cover;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.06);
  vertical-align: middle;
  margin-right: 4px;
}

/* --- Safety tips card --- */
.mkt-aside--safety {
  /* Спецификация дизайн-кода: «Безопасная сделка» и предупреждения — своя
     пара токенов. Раньше фон брался у кремовой поверхности, а рамка была
     полупрозрачным оливковым — цвет предупреждения не читался как роль. */
  background: var(--c-notice-bg);
  border-color: var(--c-notice-border);
}
.mkt-safety {
  margin: 0;
  padding: 0 0 0 18px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--md-sys-color-on-surface-variant);
}
.mkt-safety li { margin-bottom: 6px; }
.mkt-safety li:last-child { margin-bottom: 0; }

/* Третичная кнопка (спецификация § «Страница объявления»): мягкая зелёная
   заливка, текст брендовый, граница — `--c-brand-border`. Отличает её от
   вторичной «Позвонить», у которой заливки нет вовсе. */
.mkt-seller__info-link.btn--outlined {
  background: var(--c-brand-tint);
  border-color: var(--c-brand-border);
  color: var(--c-brand);
}

/* --- Share-toast --- стили переехали в components.css (глобальный app.css):
   тост показывают и НЕмаркетплейсные страницы (например «Мои объявления» —
   ошибки покупки продвижения), а market.css туда не грузится. --- */

/* ============================================================================
   Mobile + Tablet-portrait reorder: aside ПОСЛЕ Описания (UX-bag1)
   ============================================================================
   До 960px aside рендерился в самом конце страницы — пользователь сначала
   видел галерею → описание → характеристики → EPD → ... → потом цену+CTA.
   Это плохо: цена и кнопки «Позвонить»/«Написать» должны быть в верхней
   четверти прокрутки.

   Решение — `display: contents` на `.mkt-detail__main` распаковывает его
   children в `.mkt-detail__layout` (flex-контейнер на мобиле). Тогда
   sections + `.mkt-detail__aside` становятся flex-сиблингами и можно
   управлять их `order`.

   Каскад:
   - gallery       (div.gallery)         → order 1
   - stats         (.mkt-detail__stats)  → order 2
   - 1-я section   (Описание, либо если её нет — Характеристики) → order 3
   - aside         (.mkt-detail__aside)  → order 4
   - остальные sections (n+2)            → order 5

   Sticky НЕ работает у элемента с `display: contents` parent'ом, но на mobile
   она и не нужна (одна колонка). На desktop (>=960px) ниже всё откатывается
   обратно на grid + `display: block` — sticky восстанавливается. */
@media (max-width: 959.98px) {
  .mkt-detail__layout {
    display: flex;
    flex-direction: column;
    gap: 24px;
    overflow-x: hidden; /* bag2 safety net на flex-контейнере */
  }
  /* Распаковываем main: его прямые children становятся flex-сиблингами
     `.mkt-detail__aside` в `.mkt-detail__layout`. */
  .mkt-detail__main {
    display: contents;
  }
  /* Default order — DOM-селекторы (display:contents НЕ меняет селекторное
     дерево, только box-tree, поэтому используем фактических DOM-родителей). */
  .mkt-detail__main > * { order: 10; }
  .mkt-detail__layout > .mkt-detail__aside { order: 4; }

  /* Gallery — самой первой. */
  .mkt-detail__main > .gallery { order: 1; }
  /* Stats — сразу после галереи. */
  .mkt-detail__main > .mkt-detail__stats { order: 2; }
  /* Первый .mkt-section (Описание, если есть; иначе Характеристики). */
  .mkt-detail__main > .mkt-section:nth-of-type(1) { order: 3; }
  /* Все остальные sections — после aside. nth-of-type считает среди
     `<section>` сиблингов в DOM-родителе (`.mkt-detail__main`). */
  .mkt-detail__main > .mkt-section:nth-of-type(n+2) { order: 5; }

  /* На mobile/tablet aside не sticky — это просто блок в потоке. */
  .mkt-detail__aside {
    position: static;
    max-height: none;
    overflow: visible;
  }
}

/* --- Tablet portrait (768-959px): центрирование контента, mid-size шрифты
   Между mobile-фолбэком и desktop 2-column layout. iPad portrait
   (768×1024) и аналоги. Контент не должен растягиваться на всю ширину
   планшета — иначе строки слишком длинные (читабельность). */
@media (min-width: 768px) and (max-width: 959.98px) {
  .mkt-detail { padding: 16px 24px 56px; }
  .mkt-detail__layout {
    max-width: 760px;
    margin: 0 auto;
  }
  /* Цена увеличена относительно mobile, но меньше desktop (32). */
  .mkt-aside__price { font-size: 36px; line-height: 42px; }
  /* Галерея main не должна превышать ширину контейнера. */
  .gallery__main { max-width: 720px; margin-left: auto; margin-right: auto; }
}

/* --- Mobile (< 768px): компактные паддинги, мелкие нав-кнопки галереи --- */
@media (max-width: 767.98px) {
  .mkt-detail { padding: 8px 12px 48px; }
  .mkt-detail__header { margin-bottom: 12px; }
  .mkt-aside { padding: 14px; }
  .mkt-aside__price { font-size: 26px; line-height: 32px; }
  .gallery__nav { width: 38px; height: 38px; }
  .gallery__nav svg { font-size: 20px; }
}

/* --- Desktop (>=960px) explicit reset: возвращаем grid + block-main + sticky
   На случай если каскад от mobile-блока выше «протёк» через специфичность,
   явно сбрасываем display и order. */
@media (min-width: 960px) {
  .mkt-detail__main { display: block; }
  .mkt-detail__main > *,
  .mkt-detail__layout > .mkt-detail__aside { order: initial; }
}

/* Edit ad/product/service форма — резиновая, тон M3 (без чужих синих) */
.ad-edit {
  max-width: 720px;
  margin: 0 auto;
  padding: 16px;
  background: var(--md-sys-color-surface-container-low);
  border-radius: var(--md-sys-shape-corner-large);
  border: 1px solid var(--md-sys-color-outline-variant);
}
.ad-edit .page-title {
  font-size: 22px;
  margin-bottom: 16px;
  color: var(--brand-ink);
}
.ad-edit__form { display: grid; gap: 16px; }
.ad-edit__field { display: block; }
.ad-edit__field > span {
  display: block;
  font-size: 13px;
  color: var(--md-sys-color-on-surface-variant);
  margin-bottom: 6px;
  font-weight: 500;
}
.ad-edit__field input[type=text],
.ad-edit__field input[type=number],
.ad-edit__field input[type=url],
.ad-edit__field select,
.ad-edit__field textarea {
  width: 100%;
  min-height: 48px;
  padding: 12px 14px;
  border: 1px solid var(--md-sys-color-outline-variant);
  border-radius: var(--md-sys-shape-corner-small);
  box-sizing: border-box;
  font: var(--md-sys-typescale-body-large);
  color: var(--md-sys-color-on-surface);
  background: var(--md-sys-color-surface);
  outline: none;
  transition: border-color 0.15s;
}
.ad-edit__field input:focus,
.ad-edit__field select:focus,
.ad-edit__field textarea:focus {
  /* CattleSales green вместо нативного синего outline. */
  border-color: var(--md-sys-color-primary);
  border-width: 2px;
  padding: 11px 13px;
}
.ad-edit__field input:disabled {
  background: var(--md-sys-color-surface-container);
  color: var(--md-sys-color-on-surface-variant);
  cursor: not-allowed;
  opacity: 0.7;
}
.ad-edit__field textarea {
  min-height: 110px;
  resize: vertical;
  font-family: inherit;
}
.ad-edit__checkbox {
  display: flex;
  gap: 10px;
  align-items: center;
  cursor: pointer;
  padding: 6px 0;
  font-size: 14px;
  color: var(--md-sys-color-on-surface);
}
.ad-edit__checkbox input[type=checkbox] {
  width: 20px;
  height: 20px;
  accent-color: var(--md-sys-color-primary);
  cursor: pointer;
}
.ad-edit__actions {
  display: flex;
  gap: 12px;
  margin-top: 8px;
  flex-wrap: wrap;
}
.ad-edit__actions .btn { flex: 1 1 auto; min-width: 120px; }
.ad-edit__divider { margin: 24px 0; border: 0; border-top: 1px solid var(--md-sys-color-outline-variant); }
.ad-edit__delete-form button.btn--danger { width: 100%; }

.btn--danger {
  background: var(--md-sys-color-error);
  color: var(--md-sys-color-on-error);
  border: none;
}
.btn--danger:hover { filter: brightness(1.08); }

@media (min-width: 600px) {
  .ad-edit { padding: 24px 28px; }
  .ad-edit .page-title { font-size: 24px; margin-bottom: 20px; }
  .ad-edit__form { gap: 18px; }
}
@media (min-width: 840px) {
  .ad-edit { padding: 32px 36px; }
  .ad-edit .page-title { font-size: 28px; }
  .ad-edit__form {
    /* На планшете двухколоночный layout — компактнее по вертикали. */
    grid-template-columns: 1fr 1fr;
    gap: 18px 24px;
  }
  /* Полноразмерные поля занимают обе колонки. */
  .ad-edit__form > .ad-edit__field:has(textarea),
  .ad-edit__form > .ad-edit__actions,
  .ad-edit__form > .ad-edit__field:nth-last-of-type(-n+2):has(input[type=url]) {
    grid-column: 1 / -1;
  }
}

/* ==========================================================================
   Bug 15/16: tablet/related-cards — горизонтальная карта на узких колонках
   ad-detail (main + aside = ~720px на 840px → карточки получают <240px) ломает
   текст. На планшете и в related-блоках разворачиваем карточку в column —
   image сверху, content снизу. Также fluid между 840-1042 без ступенек.
   ========================================================================== */

/* Сетки деталки (`.mkt-detail .card-grid`) — всегда vertical layout, никаких
   side-image на планшете/десктопе: колонка main+aside узкая (~720px на 840px),
   и горизонтальная карточка ломала текст. */
.mkt-detail .card-grid .listing-card {
  flex-direction: column;
}
.mkt-detail .card-grid .listing-card__image {
  width: 100%;
  border-radius: var(--md-sys-shape-corner-large) var(--md-sys-shape-corner-large) 0 0;
}
.mkt-detail .card-grid .listing-card__content {
  flex: 1 1 auto;
}

/* Планшет 840-1199 — карточки на /market/ тоже vertical (image сверху).
   На 840-1042 без этого правила: image слева 45% + content справа узкий
   → текст вылазит, неадаптивно. */
@media (min-width: 840px) and (max-width: 1199.98px) {
  .listings-list .card-grid {
    /* Минимум 280px на карточку — auto-fit подстраивается. */
    grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  }
  .listings-list .listing-card { flex-direction: column; }
  .listings-list .listing-card__image {
    width: 100%;
    border-radius: var(--md-sys-shape-corner-large) var(--md-sys-shape-corner-large) 0 0;
  }
  /* Detail layout: на planshet aside становится узким (320px) чтобы main
     не сжимался ниже 480px. */
  .mkt-detail__layout {
    grid-template-columns: minmax(0, 1fr) 320px;
    gap: 20px;
  }
}

/* Bug 3: на мобиле кнопка «Фильтры» должна полностью помещаться. Контейнер
   .listings-list имеет padding=16, но flex-row title+btn могут переполнить.
   Добавляем flex-wrap + ограничение размеров кнопки. */
.filter-toggle-btn {
  margin-bottom: 0;
  flex-shrink: 0;
  max-width: 100%;
  white-space: nowrap;
}
.listings-list > div:first-child {
  /* Wrap для строки с title + кнопкой Фильтры на узких экранах. */
  flex-wrap: wrap;
  gap: 8px;
}

/* Bottom-sheet (mobile filters) — гарантируем что не вылазит за viewport. */
.bottom-sheet { max-width: 100vw; box-sizing: border-box; }
.bottom-sheet__body {
  overflow-x: hidden;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

/* --- Каталог товаров / ветеринарии (listings-list--catalog) --------------
   Лента животных — горизонтальные карточки в одну колонку (богатый контент).
   Товары/ветеринария — компактный grid вертикальных карточек на ВСЕХ ширинах.
   Иначе на десктопе ≥1200 `.listings-list .card-grid` падает в `1fr`
   (одна колонка) → карточки растягиваются во всю ширину и выглядят огромными.
   Правила идут после базовых/медиа-правил .listings-list → при равной
   специфичности побеждают по порядку источника на любой ширине. */
.listings-list--catalog .card-grid {
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: var(--md-sys-spacing-md);
}
.listings-list--catalog .listing-card {
  flex-direction: column;
}
.listings-list--catalog .listing-card__image {
  width: 100%;
  aspect-ratio: 4 / 3;
  border-radius: var(--md-sys-shape-corner-large) var(--md-sys-shape-corner-large) 0 0;
}
@media (min-width: 600px) {
  .listings-list--catalog .card-grid {
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  }
}

/* ===========================================================================
   Карточки лент — компактные ГОРИЗОНТАЛЬНЫЕ строки, как в mobile app (Flutter):
   небольшое фото слева + контент справа. Единый вид для животных / товаров /
   мяса / молока / ветеринарии. Одна колонка на мобиле/планшете, 2 колонки на
   широком десктопе (чтобы строки не растягивались). Блок в КОНЦЕ файла →
   перекрывает прежние правила (+ !important на grid и flex-direction).
   =========================================================================== */
.listings-list .card-grid,
.listings-list--catalog .card-grid {
  grid-template-columns: 1fr !important;
  gap: var(--md-sys-spacing-sm);
}
.listings-list .listing-card,
.listings-list--catalog .listing-card {
  flex-direction: row !important;
  align-items: stretch;
}
/* Фото карточки ленты — размеры один в один с мобильным приложением
   (`home_screen.dart`: SizedBox(width: 202) + карточка minHeight 160).
   Было 120×120: на телефоне веб-лента выглядела заметно беднее приложения,
   фото занимало треть карточки против половины (сверка скриншотов
   2026-08-10). Высоту задаёт `min-height` карточки, а не квадрат: фото
   растягивается на всю её высоту, как Positioned.fill во Flutter. */
.listings-list .listing-card,
.listings-list--catalog .listing-card {
  min-height: 160px;
}
/* Ровная шапка — иначе высота карточки скачет от длины заголовка: в одной
   ленте были 160, 166, 188 и 207 px. 56 px = верхняя строка + заголовок в две
   строки (подзаголовок «страна · возраст» убран — карточка приведена к виду
   приложения, см. `_ad_card.html`).
   Селектор через `.card-grid > .listing-card` намеренно: карточки внутри
   каруселей «Другие объявления продавца» / «Из других стран» лежат ГЛУБЖЕ и
   под правило не попадают — им лишняя высота ни к чему (проверено: карусель
   раздувалась с 265 до 302 px). */
.listings-list .card-grid > .listing-card .listing-card__header,
.listings-list--catalog .card-grid > .listing-card .listing-card__header {
  min-height: 56px;
}
.listings-list .listing-card__image,
.listings-list--catalog .listing-card__image {
  width: 202px !important;
  min-width: 202px;
  /* ⚠️ Пропорцию НЕ переопределяем — наследуем `aspect-ratio: 4/3` базового
     `.listing-card__image`. Попытка поставить здесь `auto` стоила прода:
     без заданной пропорции высоту блока начинает диктовать его содержимое, а
     внутри может лежать <video> (авто-ролик или premium) со своим
     intrinsic-размером — карточка с роликом вырастала до 372 px против
     188 px у карточки с фото, и лента ехала (2026-08-10, час после выката).
     Нужную высоту даёт `min-height: 160px` карточки выше: flex-стретч
     растягивает фото до высоты карточки, то есть до 202×160 — ровно как
     `SizedBox(width: 202)` + `minHeight: 160` в приложении. */
  border-radius: var(--md-sys-shape-corner-large) 0 0 var(--md-sys-shape-corner-large) !important;
}
.listings-list .listing-card__content,
.listings-list--catalog .listing-card__content {
  padding: 10px 12px;
  gap: 4px;
}
/* Мета-чипы переносятся, а не сжимаются: в приложении это `Wrap` со
   `spacing: 8 / runSpacing: 2`. У животных чипов до пяти (просмотры, голов,
   возраст, удой, дата) — во flex без переноса они лезли за край карточки. */
.listings-list .listing-card__meta,
.listings-list--catalog .listing-card__meta {
  flex-wrap: wrap;
  row-gap: 2px;
}
/* Типографика карточки ленты — один в один с приложением (эталон дизайна,
   решение владельца 2026-08-10). Во Flutter: верхняя строка 12 px w600
   АКЦЕНТНЫМ цветом (`theme.colorScheme.primary`), заголовок 14 px w600 в две
   строки с многоточием. В вебе верхняя строка была того же цвета, что и
   заголовок, — иерархия читалась хуже, чем в приложении. */
.listings-list .listing-card__category,
.listings-list--catalog .listing-card__category {
  font-size: 12px;
  line-height: 16px;
  font-weight: 600;
  color: var(--md-sys-color-primary);
}
.listings-list .listing-card__breed,
.listings-list--catalog .listing-card__breed {
  font-size: 14px;
  line-height: 19px;
  font-weight: 600;
  /* maxLines: 2 + ellipsis у Flutter-заголовка. Без клампа длинное название
     породы в третьей строке ломало равную высоту карточек. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
/* Ховер подсвечивает заголовок, но верхняя строка и так акцентная — красить
   её в тот же цвет незачем (в приложении она статична). */
a.listing-card__header:hover .listing-card__category { color: var(--md-sys-color-primary); }

/* Заголовок + компактный бейдж справа («Халяль») — Row(Expanded(Text), badge)
   из `MarketListingCard`. Бейдж вынесен ИЗ клампа заголовка: внутри
   `-webkit-box` его срезало бы вместе с текстом. Раньше «Халяль» лежал
   поверх фотографии инлайновым `position:absolute`. */
.listing-card__title-row {
  display: flex;
  align-items: flex-start;
  gap: 4px;
}
.listing-card__title-row .listing-card__breed {
  flex: 1;
  min-width: 0;
}
.listing-card__title-badge {
  flex-shrink: 0;
  padding: 2px 6px;
  border-radius: 8px;
  font: 700 11px/15px 'Roboto', sans-serif;
  color: var(--md-sys-color-primary);
  /* 12 % прозрачности — как `color.withValues(alpha: 0.12)` в приложении. */
  background: color-mix(in srgb, var(--md-sys-color-primary) 12%, transparent);
}

/* Колонки сетки задаёт блок «Маркет v3» в конце файла (2/3/4 от ширины).
   Прежнее правило «2 колонки от 1000px» снято 2026-08-24 — оно осталось бы
   мёртвым дублем в том же медиа-запросе и путало при чтении. */

/* Совсем узкие экраны — фото чуть меньше, но пропорция приложения
   сохраняется (202 px на 412-px экране ≈ половина ширины карточки). */
@media (max-width: 380px) {
  .listings-list .listing-card__image,
  .listings-list--catalog .listing-card__image {
    width: 168px !important;
    min-width: 168px;
  }
}

/* Силуэт животного в плейсхолдере карточки (нет фото) — паритет с Flutter
   AnimalSilhouette. meat: m.category|meat_icon; milk: species_root|category_icon. */
.listing-card__placeholder-silhouette {
  width: 56px;
  height: 56px;
  object-fit: contain;
  opacity: 0.85;
}

/* Чипы под заголовком деталки (Халяль / Регулярная поставка) — meat/milk */
.mkt-detail__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 4px 0 8px;
}
/* Единица цены рядом с ценой в сайдбаре (за кг/л/...) — meat/milk */
.mkt-aside__price-unit {
  font-size: 14px;
  font-weight: 400;
  color: var(--md-sys-color-on-surface-variant, var(--c-text-muted));
}

/* ============================================================
   Верхние табы вертикалей маркетплейса (_vertical_tabs.html)
   Рендерятся в base.html над лентой/деталкой при market_vertical.
   Горизонтальный скролл как .category-row; активный — primary-fill.
   ============================================================ */
.market-tabs {
  margin: 0 0 var(--md-sys-spacing-md);
}

.market-tabs__scroll {
  display: flex;
  gap: var(--md-sys-spacing-sm);
  overflow-x: auto;
  padding-bottom: var(--md-sys-spacing-xs);
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.market-tabs__scroll::-webkit-scrollbar { display: none; }

.market-tabs__tab {
  display: inline-flex;
  align-items: center;
  gap: var(--md-sys-spacing-xs);
  flex: 0 0 auto;
  padding: var(--md-sys-spacing-sm) var(--md-sys-spacing-md);
  border-radius: var(--md-sys-shape-corner-full);
  border: 1px solid var(--md-sys-color-outline-variant);
  background: var(--md-sys-color-surface-container-low);
  color: var(--md-sys-color-on-surface-variant);
  font-size: 14px;
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  text-decoration: none;
  transition: background-color .15s ease, color .15s ease, border-color .15s ease;
}

.market-tabs__tab svg {
  width: 18px;
  height: 18px;
  flex: 0 0 auto;
}

/* Эмодзи-иконка вертикали (единый набор с Mini App / Flutter). */
.market-tabs__emoji {
  font-size: 16px;
  line-height: 1;
  flex: 0 0 auto;
}

.market-tabs__tab:hover {
  background: var(--md-sys-color-secondary-container-solid);
  color: var(--md-sys-color-on-secondary-container);
}

.market-tabs__tab--active,
.market-tabs__tab--active:hover {
  background: var(--md-sys-color-primary);
  border-color: var(--md-sys-color-primary);
  color: var(--md-sys-color-on-primary);
}

/* Узкие экраны — компактнее padding/шрифт, чтобы влезало больше табов */
@media (max-width: 380px) {
  .market-tabs__tab {
    padding: var(--md-sys-spacing-xs) var(--md-sys-spacing-sm);
    font-size: 13px;
  }
  .market-tabs__tab svg { width: 16px; height: 16px; }
  .market-tabs__emoji { font-size: 15px; }
}

/* fix BUG-2017: карусель «Другие объявления продавца» — паритет с Flutter
   (mobile_app SellerAdsCarousel): плоские карточки 150px без рамки/тени,
   фото 150×120 со скруглением 12, название до 2 строк, цена зелёным жирным.
   Категория и счётчик просмотров в компактной карусели скрыты (во Flutter
   их нет). Перекрывает базу из components.css (market.css грузится позже). */
/* 190 вместо 150 (2026-08-12): карточка карусели была заметно мельче
   карточек ленты, а место под ней всё равно пустовало — владелец просил
   «увеличить карусель и убрать воздух». */
/* ⚠️ Единственный контейнер компактной карточки — `.mkt-seller-carousel`
   (горизонтальная лента). Ею рисуются ОБА блока деталки: «Другие объявления
   продавца» и «Похожие объявления» — второй переехал на ту же карусель, и
   параллельного набора правил под сетку `.card-grid--related` больше нет.
   Шаблон карточки один — `_ad_card_compact.html`. */
.mkt-seller-carousel > article,
.mkt-seller-carousel > .listing-card {
  background: transparent;
  border: none;
  border-radius: 0;
  box-shadow: none;
  overflow: visible;
}
.mkt-seller-carousel > article,
.mkt-seller-carousel > .listing-card {
  width: 190px;
}
.mkt-seller-carousel > article:hover,
.mkt-seller-carousel > .listing-card:hover {
  box-shadow: none;
  transform: translateY(-2px);
  background: transparent;
}
.mkt-seller-carousel .listing-card__image {
  aspect-ratio: 4 / 3;      /* пропорция кадра — как у фото в ленте */
  border-radius: 12px;
}
.mkt-seller-carousel .listing-card__image img:not(.listing-card__flag),
.mkt-seller-carousel .listing-card__placeholder {
  border-radius: 12px;
  min-height: 0;
}
.mkt-seller-carousel .listing-card__content {
  padding: 6px 2px 2px;
}
.mkt-seller-carousel .listing-card__category,
.mkt-seller-carousel .stats__item {
  display: none;
}
.mkt-seller-carousel .listing-card__breed {
  min-height: 0;
  font-size: 13px;
  font-weight: 500;
}
.mkt-seller-carousel .listing-card__footer {
  margin-top: 2px;
}
.mkt-seller-carousel .listing-card__footer .chip,
.mkt-seller-carousel .listing-card__footer .chip--primary {
  font-size: 14px;
  font-weight: 700;
}

/* fix BUG-2050: seller_info (профиль продавца) — .card-grid вне .mkt-detail
   не получал min-width:0 на items → длинный контент карточки (chips/цены)
   распирал grid-ячейку и карточки вылезали за край экрана на mobile. */
.seller-info .card-grid {
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
}
.seller-info .card-grid > * {
  min-width: 0;
  max-width: 100%;
  box-sizing: border-box;
}
.seller-info .card-grid .listing-card__content {
  min-width: 0;
  flex: 1 1 auto;
}
/* Карточка в профиле продавца — ВЕРТИКАЛЬНАЯ (фото сверху), как в сетке
   ленты. Правила «вида как в приложении» объявлены под `.listings-list` и
   сюда не доезжают, а базовая `.listing-card` — горизонтальная строка с фото
   в 45 % ширины: в ячейке 280 px тексту оставалось ~150 px, название и цена
   ломались в узкую колонку. Дублируем только геометрию — типографику и цвета
   даёт база, поэтому расхождения с лентой тут не заводится. */
.seller-info .card-grid .listing-card {
  flex-direction: column;
}
.seller-info .card-grid .listing-card__image {
  width: 100%;
  border-radius: var(--md-sys-shape-corner-large) var(--md-sys-shape-corner-large) 0 0;
}

/* fix BUG-2054: деталка мяса — на mobile блок «Характеристики» идёт сразу
   под «Описанием», ДО aside (цена/продавец). Перекрывает mobile-reorder
   `.mkt-section:nth-of-type(n+2) { order: 5 }` выше (специфичнее на класс).
   nth-of-type(-n+2) — первые ДВЕ секции: Описание + Характеристики; если
   Описания нет — Характеристики и так первые (order 3 от базового правила). */
@media (max-width: 959.98px) {
  .mkt-detail--specs-first .mkt-detail__main > .mkt-section:nth-of-type(-n+2) {
    order: 3;
  }
}

/* fix BUG-2058: блок «Сертификаты» на деталках мяса/молока — бейджи
   (Халяль/Ветсправка/HACCP...) + ссылка «посмотреть» на скан документа. */
.mkt-certs {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.mkt-certs__item {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 12px;
  min-width: 0;
}
.mkt-certs__badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border-radius: var(--md-sys-shape-corner-large, 16px);
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-on-secondary-container);
  font: 600 13px/18px 'Roboto', system-ui, sans-serif;
}
.mkt-certs__badge svg { flex-shrink: 0; }
.mkt-certs__meta {
  font-size: 13px;
  color: var(--md-sys-color-on-surface-variant);
}
.mkt-certs__link {
  font-size: 13px;
  font-weight: 500;
  color: var(--md-sys-color-primary, var(--c-brand));
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* --- Fullscreen-лайтбокс фото (includes/_gallery_lightbox.html) --- */
.mkt-lightbox {
  position: fixed;
  inset: 0;
  z-index: 1100;
  background: rgba(0, 0, 0, 0.92);
  display: flex;
  align-items: center;
  justify-content: center;
}
.mkt-lightbox[hidden] { display: none; }
.mkt-lightbox__img {
  max-width: 92vw;
  max-height: 88vh;
  object-fit: contain;
  border-radius: 8px;
}
.mkt-lightbox__close,
.mkt-lightbox__nav {
  position: absolute;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: rgba(255, 255, 255, 0.14);
  color: var(--c-on-brand);
  border-radius: 50%;
  cursor: pointer;
}
.mkt-lightbox__close:hover,
.mkt-lightbox__nav:hover { background: rgba(255, 255, 255, 0.28); }
.mkt-lightbox__close {
  top: 16px;
  right: 16px;
  width: 44px;
  height: 44px;
  font-size: 28px;
  line-height: 1;
}
.mkt-lightbox__nav {
  top: 50%;
  transform: translateY(-50%);
  width: 48px;
  height: 48px;
  font-size: 34px;
  line-height: 1;
  padding-bottom: 4px;
}
.mkt-lightbox__nav--prev { left: 12px; }
.mkt-lightbox__nav--next { right: 12px; }
/* Одно фото — стрелки не нужны, счётчик «1 / 1» остаётся. */
.mkt-lightbox--single .mkt-lightbox__nav { display: none; }
.mkt-lightbox__counter {
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  color: var(--c-on-brand);
  font-size: 14px;
  background: rgba(0, 0, 0, 0.45);
  padding: 4px 12px;
  border-radius: 100px;
}

/* --- Hide-on-scroll нижнего бара + мини-панель вертикалей (mobile web) ---
   Паритет с мобильным приложением (APK 1.72.x): скролл вниз на лентах
   маркета прячет .bottom-nav (js/market_nav.js вешает --hidden) и
   показывает стеклянную пилюлю с эмодзи 5 вертикалей. Только mobile
   (<840px — брейкпоинт bottom-nav); деталки/прочие страницы не затронуты
   (скрипт и панель подключены только в 5 list-шаблонах). */
.bottom-nav {
  transition: transform 0.2s cubic-bezier(0.215, 0.61, 0.355, 1);
}
.bottom-nav--hidden {
  /* 150%, не 110%: FAB «Подать объявление» выступает на ~34px НАД баром
     (margin-top:-34) — при 110% его макушка оставалась видна из-под
     мини-панели (прод-скрин 2026-08-02). */
  transform: translateY(150%);
}

.mkt-mini-verticals {
  position: fixed;
  left: 50%;
  bottom: calc(12px + env(safe-area-inset-bottom, 0px));
  z-index: 100; /* как .bottom-nav — поверх контента и оверлеев галереи */
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 6px 8px;
  border-radius: 36px;
  /* Дизайн 1:1 с верхним glass-баром вертикалей (.market-tabs в base):
     блюр + полупрозрачный кремовый градиент + рамка + мягкая тень. */
  -webkit-backdrop-filter: blur(24px);
  backdrop-filter: blur(24px);
  /* Стекло +25% прозрачнее верхнего бара: 0.62/0.45 → 0.465/0.34. */
  background: linear-gradient(
    to bottom,
    rgba(255, 251, 238, 0.28),
    rgba(255, 251, 238, 0.2)
  );
  /* Чёткий ободок-рамка (0.95, 1.5px) — край панели читается на любом
     фоне (эмулятор-итерация 2026-08-02: 0.45 был невидим). */
  border: 1.5px solid rgba(255, 251, 238, 0.95);
  /* Тень-ободок для лёгкого объёма (2026-08-02). В CSS outer box-shadow
     по спеке НЕ рисуется под собственным border-box — сквозь стеклянную
     заливку не просвечивает (в отличие от Flutter BoxShadow, где
     понадобился BlurStyle.outer + вынос из ClipRRect). */
  box-shadow: 0 5px 16px rgba(0, 0, 0, 0.2);
  /* Скрыта по умолчанию; --shown ставит market_nav.js при скрытии бара. */
  opacity: 0;
  transform: translateX(-50%) translateY(16px) scale(0.7);
  pointer-events: none;
  transition: opacity 0.2s cubic-bezier(0.215, 0.61, 0.355, 1),
    transform 0.2s cubic-bezier(0.215, 0.61, 0.355, 1);
}
.mkt-mini-verticals--shown {
  opacity: 1;
  transform: translateX(-50%) translateY(0) scale(1);
  pointer-events: auto;
}
.mkt-mini-verticals__item {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 48px;
  border-radius: 22px;
  font-size: 26px;
  line-height: 1;
  text-decoration: none;
  border: 1px solid transparent;
}
.mkt-mini-verticals__item--active {
  /* «Пузырёк» активной — как active-таб вертикалей. */
  background: var(--md-sys-color-primary-container);
  border-color: rgba(27, 116, 62, 0.18);
}
@media (min-width: 840px) {
  .mkt-mini-verticals { display: none; } /* desktop: bottom-nav и так скрыт */
}

/* Чипы «Продам/Куплю» + кнопка «Фильтры» — В ОДНОЙ строке (паритет с
   приложением, 316.jpg): чипы слева, кнопка справа. Используется во ВСЕХ пяти
   лентах — товарам и ветеринарии чипы добавили последними, и кнопка «Фильтры»
   переехала туда же из `.listings-header`. */
.mkt-intent-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  margin: 12px 0 4px;
}
.mkt-intent-row .mkt-intent-tabs {
  margin: 0;
}

/* Premium-видео в карточке ленты (автоплей по центру экрана, market_nav-стиль) */
.listing-card__video-badge {
  position: absolute;
  left: 8px;
  top: 8px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  border-radius: 8px;
  background: rgba(0, 0, 0, .45);
  color: var(--c-on-brand);
  font-size: 12px;
  line-height: 1;
  pointer-events: none;
}

/* Карусель-вставка «Из других стран» внутри card-grid ленты — на всю ширину
   ряда (иначе секция сжимается в одну колонку грида). 2026-08-05 */
.card-grid > .mkt-section { grid-column: 1 / -1; min-width: 0; }

/* Карусель-вставка «Из других стран» ВНУТРИ ленты: листовые правила
   (.listings-list .listing-card { flex-direction: row !important } +
   __image 120px !important) ломали компакт-карточки карусели — текст
   налезал на фото. Возвращаем колонки с бОльшей специфичностью и позже
   по каскаду (2026-08-05). */
.listings-list .mkt-seller-carousel > .listing-card,
.listings-list--catalog .mkt-seller-carousel > .listing-card {
  flex-direction: column !important;
  width: 150px;
  align-items: stretch;
}
.listings-list .mkt-seller-carousel .listing-card__image,
.listings-list--catalog .mkt-seller-carousel .listing-card__image {
  width: 100% !important;
  min-width: 0 !important;
  aspect-ratio: 5 / 4 !important;
  border-radius: 12px !important;
}
.listings-list .mkt-seller-carousel .listing-card__content,
.listings-list--catalog .mkt-seller-carousel .listing-card__content {
  padding: 6px 2px 2px;
}

/* Флаг основной страны на главном фото деталки (2026-08-05). Слева сверху —
   правый верх занят счётчиком фото «1 / N». */
.gallery__main { position: relative; }
/* img-селектор ОБЯЗАН быть сильнее `.gallery__main img { width:100% }` —
   иначе флаг растягивался на всю галерею (скрин 101.png, 2026-08-06). */
/* +50 % к прежним 28×21 — тот же шаг, что у флага карточки (2026-08-12).
   top 26 — под полосой сегментов, вровень с плашками. */
.gallery__main img.gallery__flag,
.gallery__flag {
  position: absolute;
  top: 26px;
  left: 12px;
  width: 42px;
  height: 32px;
  border-radius: 4px;
  object-fit: cover;
  z-index: 2;
  box-shadow: 0 1px 4px rgba(0,0,0,.25);
}

/* Карусель крупнее (2026-08-05 → 2026-08-12): было 160×170, стало 200×210.
   Владелец показал на скриншоте 335.jpg полосу пустоты под карусельными
   карточками: секция несла отступ полноразмерного блока, карточки были
   мельче ленточных, и разрыв читался как «тут что-то не дорисовалось».
   Лечим с двух сторон — карточка растёт (эти правила), а лишний отступ
   снят в `.mkt-section--carousel` + `align-items: flex-start`.
   Пропорция кадра близка к прежней (0.94 → 0.95), поэтому кроп по бокам
   не изменился — рога и ноги животного видно ровно так же.
   ⚠️ Это ПОСЛЕДНИЕ по каскаду правила размеров карусели: значения выше
   (190 / aspect-ratio) перекрываются отсюда — правьте здесь. */
.mkt-seller-carousel > article,
.mkt-seller-carousel > .listing-card { width: 200px; }
.mkt-seller-carousel .listing-card__image {
  aspect-ratio: auto;
  height: 210px;
}
.listings-list .mkt-seller-carousel > .listing-card,
.listings-list--catalog .mkt-seller-carousel > .listing-card { width: 200px; }
.listings-list .mkt-seller-carousel .listing-card__image,
.listings-list--catalog .mkt-seller-carousel .listing-card__image {
  aspect-ratio: auto !important;
  height: 210px !important;
}
/* Название и цена в карусели — крупнее под новый размер карточки.
   ⚠️ `min-height` на две строки — ЭТО и есть лекарство от «воздуха» под
   каруселью (скриншот 338.jpg, замер 13.08): контейнер тянется по самой
   высокой карточке, у одной название переносилось на вторую строку (38 px
   против 19), и под всеми остальными зияла полоса. Отступами это не
   лечится — карточки должны быть одной высоты. */
.mkt-seller-carousel .listing-card__breed {
  font-size: 14px;
  line-height: 19px;
  min-height: 38px;
}
.mkt-seller-carousel .listing-card__footer .chip,
.mkt-seller-carousel .listing-card__footer .chip--primary { font-size: 15px; }

/* Ценник компактной карточки остаётся в одну строку слева — там нет звезды, и
   column-reverse из карточки ленты только добавил бы отступ. */
.mkt-seller-carousel .listing-card__footer {
  flex-direction: row;
  align-items: center;
  margin-top: 2px;
  padding-top: 0;
}
.mkt-seller-carousel .listing-card__footer .chip { margin-left: 0; padding: 0; }

/* ===========================================================================
   «Псевдо-видео» карточки ленты (js/feed_video.js, 2026-08-09)
   Два слоя <img> с кросс-фейдом + Ken Burns: неподвижная картинка читается
   как слайд при любой частоте смены, поэтому кадр всё время едет.
   Анимируются только opacity/transform — композитные свойства, main thread
   не трогаем (в ленте одновременно двигается ровно одна карточка).
   =========================================================================== */
.listing-card__image .feed-slide-layer {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Линейно: у кросс-фейда ease-in-out даёт «ступеньку» яркости. */
  transition: opacity 1200ms linear;
  will-change: opacity, transform;
}

/* Базовый слой — исходная обложка карточки, лежит под клоном. */
.listing-card__image .feed-slide-layer--base { z-index: 1; }
.listing-card__image .feed-slide-layer:not(.feed-slide-layer--base) { z-index: 2; }

/* Наезд + увод в одну из четырёх сторон. Зум ВСЕГДА «внутрь»: если
   чередовать наезд с отъездом, на стыке кадров масштаб отскакивает назад и
   глаз это ловит. Разнообразие даёт направление увода, а не знак зума. */
@keyframes feedKbRight { from { transform: scale(1) translate(0, 0); }      to { transform: scale(1.12) translate(14px, 0); } }
@keyframes feedKbLeft  { from { transform: scale(1) translate(0, 0); }      to { transform: scale(1.12) translate(-14px, 0); } }
@keyframes feedKbUp    { from { transform: scale(1) translate(0, 0); }      to { transform: scale(1.12) translate(0, -14px); } }
@keyframes feedKbDown  { from { transform: scale(1) translate(0, 0); }      to { transform: scale(1.12) translate(0, 14px); } }

/* 3.8 c при показе 2.2 c — движение НЕ должно упираться в край раньше, чем
   кадр сменится, иначе картинка на мгновение замирает и читается как слайд.
   Кривая как у камеры: мягкий разгон и торможение, не линейка. */
.feed-slide-kb-0 { animation: feedKbRight 6000ms cubic-bezier(.37,0,.63,1) forwards; }
.feed-slide-kb-1 { animation: feedKbLeft  6000ms cubic-bezier(.37,0,.63,1) forwards; }
.feed-slide-kb-2 { animation: feedKbUp    6000ms cubic-bezier(.37,0,.63,1) forwards; }
.feed-slide-kb-3 { animation: feedKbDown  6000ms cubic-bezier(.37,0,.63,1) forwards; }

/* Полоска прогресса убрана из ленты (2026-08-09): любой индикатор «i из N»
   сообщает «это слайды». Правила оставлены — их использует только код,
   явно включающий индикатор. */
.feed-slide-progress {
  position: absolute;
  left: 8px;
  right: 8px;
  bottom: 8px;
  height: 2px;
  border-radius: 2px;
  background: rgba(255, 255, 255, 0.35);
  z-index: 3;
  pointer-events: none;
}

.feed-slide-progress i {
  display: block;
  width: 0;
  height: 100%;
  border-radius: 2px;
  background: var(--c-surface);
}

@media (prefers-reduced-motion: reduce) {
  .feed-slide-kb-0,
  .feed-slide-kb-1,
  .feed-slide-kb-2,
  .feed-slide-kb-3 { animation: none; }
  .listing-card__image .feed-slide-layer { transition: none; }
}

/* ===========================================================================
   МАРКЕТ v3 — вертикальная карточка и сетка колонок
   (design_handoff_market_v3, решение владельца 2026-08-24)

   ⚠️ Блок ОСОЗНАННО отходит от правила «приложение — эталон дизайна»:
   владелец выбрал вести веб впереди приложения («делаем только для веб
   пока»). Приложение подтянут отдельной задачей. Что именно разошлось —
   в docs/design.md § «Маркет v3».

   Что взято из v3: вертикальная карточка на десктопе, сетка 4/3/2, цена
   текстом вместо зелёной пилюли, звезда напротив цены, бейдж статуса на
   фото слева сверху, ровная рамка вместо цветной у «Топ»/Premium,
   категория под названием приглушённым цветом.

   Что НЕ взято, по решению владельца:
   * фон и тень карточки остаются --c-surface-alt + --shadow-card
     (решение 22.08, коммит 064d1966 — иначе карточка светлее фона);
   * активная звезда остаётся жёлтой --cs-favorite, а не зелёной;
   * фото НЕ ужимается до 150 px: держим пропорцию 4:3 — ровно ту, в
     которой уже нарезаны миниатюры (600×450 и 300×225), чтобы картинки
     ложились без обрезки и карточка выходила крупнее макета.

   Блок идёт ПОСЛЕДНИМ в файле и перекрывает горизонтальную раскладку
   выше (там `!important` на grid-template-columns и flex-direction).
   =========================================================================== */

/* --- Рамка карточки ----------------------------------------------------
   ГЕОМЕТРИЯ одна у всех трёх состояний — 1px. Иначе платные карточки
   физически крупнее обычных, и в ленте видно «почему у Premium другой
   размер» (дефект 2026-08-10). Цвет статуса даём ТОЛЬКО цветом рамки и
   кольцом на box-shadow: spread не занимает места в потоке, поэтому
   толщина кольца ни на что не влияет.

   ⚠️ Задание v3 §1 просило убрать цветную обводку у «Топ» совсем («статус
   несёт только бейдж»). Убрали — владелец вернул 25.08.2026: обводка была и
   должна остаться. Не снимать повторно; за --c-top и --c-premium в
   дизайн-коде закреплена пара «бейдж + рамка» (tokens.css). */
.listings-list .listing-card,
.listings-list--catalog .listing-card,
.listings-list .listing-card.is-featured,
.listings-list--catalog .listing-card.is-featured,
.listings-list .listing-card.is-premium,
.listings-list--catalog .listing-card.is-premium {
  border: 1px solid var(--c-border);
  box-shadow: var(--shadow-card);
}
/* «Топ» — оранжевое кольцо + своё свечение поверх обычной тени. */
.listings-list .listing-card.is-featured,
.listings-list--catalog .listing-card.is-featured {
  border-color: var(--c-top);
  box-shadow: 0 0 0 2px var(--c-top),
              0 4px 20px rgba(224, 123, 30, 0.32),
              var(--shadow-card);
}
/* Premium — то же золотом венка. featured приоритетнее: шаблоны ставят
   is-premium только когда карточка НЕ featured. */
.listings-list .listing-card.is-premium,
.listings-list--catalog .listing-card.is-premium {
  border-color: var(--c-premium);
  box-shadow: 0 0 0 2px var(--c-premium),
              0 4px 20px rgba(199, 154, 31, 0.32),
              var(--shadow-card);
}

/* --- Бейдж статуса — левый верх ФОТО (v3), флаг остаётся справа ------- */
.listings-list .listing-card__badge,
.listings-list--catalog .listing-card__badge {
  top: 9px;
  /* Логические свойства обязательны: в ar/fa/ur карточка зеркалится, и
     физический left увёл бы бейдж под флаг. Физические сбрасываем ПЕРЕД
     логическими: базовое правило ставит `right: 14px`, и без сброса в RTL
     бейдж оказался бы прижат с обеих сторон разом. */
  left: auto;
  right: auto;
  inset-inline-start: 9px;
  inset-inline-end: auto;
  padding: 3px 10px;
  border-radius: 6px;
  font: 500 11px/15px 'Roboto', sans-serif;
  letter-spacing: 0.2px;
  color: var(--c-on-brand);
}
.listings-list .listing-card__flag,
.listings-list--catalog .listing-card__flag {
  left: auto;
  right: auto;
  inset-inline-end: 8px;
  inset-inline-start: auto;
}
/* ▶ premium-видео уезжает вниз: левый верх занял бейдж статуса. */
.listings-list .listing-card__video-badge,
.listings-list--catalog .listing-card__video-badge {
  top: auto;
  bottom: 8px;
  left: auto;
  right: auto;
  inset-inline-start: 8px;
  inset-inline-end: auto;
}

/* --- Порядок в теле карточки ------------------------------------------
   DOM НЕ трогаем — переставляем визуально. Так разметка остаётся
   семантической (заголовок раньше цены) и не ломаются структурные
   проверки паритета, а вид получается как в v3.                        */
.listings-list .listing-card__content,
.listings-list--catalog .listing-card__content {
  display: flex;
  flex-direction: column;
  padding: 12px 14px 14px;
  gap: 4px;
}
.listings-list .listing-card__footer,
.listings-list--catalog .listing-card__footer { order: 0; margin: 0; }
.listings-list .listing-card__header,
.listings-list--catalog .listing-card__header {
  order: 1;
  display: flex;
  flex-direction: column;
  gap: 3px;
}
/* Ровная шапка больше не нужна: высоту держит сетка, а не min-height. */
.listings-list .card-grid > .listing-card .listing-card__header,
.listings-list--catalog .card-grid > .listing-card .listing-card__header {
  min-height: 0;
}
.listings-list .listing-card__header .listing-card__title-row,
.listings-list .listing-card__header .listing-card__breed,
.listings-list--catalog .listing-card__header .listing-card__title-row,
.listings-list--catalog .listing-card__header .listing-card__breed { order: 0; }
.listings-list .listing-card__header .listing-card__category,
.listings-list--catalog .listing-card__header .listing-card__category { order: 1; }
.listings-list .listing-card__meta,
.listings-list--catalog .listing-card__meta { order: 2; margin-top: 6px; }

/* --- Первая строка: цена текстом + звезда напротив --------------------- */
.listings-list .listing-card__footer,
.listings-list--catalog .listing-card__footer {
  display: flex;
  /* ⚠️ Базовое правило ставит `column-reverse` — так делалась «звезда НАД
     ценой» из паритета с приложением (решение 13.08). В v3 они стоят в одной
     строке напротив друг друга, поэтому направление возвращаем в строку явно:
     без этого звезда уезжает на строку выше и слева. */
  flex-direction: row;
  align-items: flex-start;
  justify-content: space-between;
  gap: 8px;
}
/* Плашка-кнопка цены превращается в обычный текст: фон, рамка и padding
   снимаются, остаётся типографика 17/700. */
.listings-list .listing-card__footer .chip--primary,
.listings-list .listing-card__footer .chip--negotiable,
.listings-list--catalog .listing-card__footer .chip--primary,
.listings-list--catalog .listing-card__footer .chip--negotiable {
  background: none;
  border: 0;
  padding: 0;
  border-radius: 0;
  color: var(--c-text);
  font: 700 17px/22px 'Roboto', sans-serif;
  /* Базовое правило (market.css:394) прижимает ценник вправо через
     `margin-left: auto` — в горизонтальной карточке он стоял в правом
     нижнем углу. В v3 цена идёт ПЕРВОЙ слева, поэтому авто-отступ снимаем,
     иначе цена и звезда меняются местами. */
  margin: 0;
}

/* --- Название и категория --------------------------------------------- */
.listings-list .listing-card__breed,
.listings-list--catalog .listing-card__breed {
  font-size: 14px;
  line-height: 18px;
  font-weight: 500;
  color: var(--c-text);
}
/* Категория уходит под название и гаснет — в v3 она перестала быть
   акцентной ссылкой. */
.listings-list .listing-card__category,
.listings-list--catalog .listing-card__category,
a.listing-card__header:hover .listing-card__category {
  font-size: 12px;
  line-height: 16px;
  font-weight: 400;
  color: var(--c-text-muted);
}

/* --- Нижняя строка: параметры слева, просмотры прижаты вправо ---------- */
.listings-list .listing-card__meta,
.listings-list--catalog .listing-card__meta {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 12px;
  color: var(--c-text-muted);
}
/* Просмотры стоят в разметке ПЕРВЫМИ (так их читает и приложение, и
   гард-тест) — визуально уводим в конец строки. */
.listings-list .listing-card__meta > .stats__item:first-child,
.listings-list--catalog .listing-card__meta > .stats__item:first-child {
  order: 9;
  margin-inline-start: auto;
}

/* --- Вертикальная карточка и сетка колонок ---------------------------- */
@media (min-width: 640px) {
  .listings-list .listing-card,
  .listings-list--catalog .listing-card {
    flex-direction: column !important;
    min-height: 0;
  }
  .listings-list .listing-card__image,
  .listings-list--catalog .listing-card__image {
    width: 100% !important;
    min-width: 0;
    /* ⚠️ Пропорцию здесь НЕ задаём — наследуем 4/3 базового правила.
       Своя `height` или `aspect-ratio: auto` вернули бы регрессию
       10.08.2026: высоту начинал диктовать <video> внутри, и карточка
       с роликом вырастала до 372 px против 188 px у карточки с фото. */
    border-radius: 14px 14px 0 0 !important;
  }
  .listings-list .card-grid,
  .listings-list--catalog .card-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    gap: 16px;
  }
}
@media (min-width: 1000px) {
  .listings-list .card-grid,
  .listings-list--catalog .card-grid {
    grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
  }
}
@media (min-width: 1360px) {
  .listings-list .card-grid,
  .listings-list--catalog .card-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
  }
}

/* --- Мобильный: карточка остаётся горизонтальной ----------------------
   Фото НЕ ужимаем до 150 px макета (решение владельца 24.08): держим
   прежнюю ширину, чтобы уже нарезанные миниатюры 4:3 ложились крупно. */
@media (max-width: 639.98px) {
  .listings-list .listing-card,
  .listings-list--catalog .listing-card { min-height: 168px; }
  .listings-list .listing-card__image,
  .listings-list--catalog .listing-card__image {
    border-radius: 14px 0 0 14px !important;
  }
  .listings-list .listing-card__footer .chip--primary,
  .listings-list--catalog .listing-card__footer .chip--primary,
  .listings-list .listing-card__footer .chip--negotiable,
  .listings-list--catalog .listing-card__footer .chip--negotiable {
    font-size: 16px;
    line-height: 21px;
  }
}

/* --- Панель фильтров v3 §3 -------------------------------------------- */
.filter-panel {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: 14px;
  padding: 18px 18px 20px;
}
.filter-panel__title {
  font: 700 15px/20px 'Roboto', sans-serif;
  color: var(--c-text);
  margin-bottom: 14px;
}
/* Строка-подсказка вместо кнопки «Показать»: объясняет, почему кнопки нет,
   и сразу показывает размер выдачи. */
.filter-panel__hint {
  margin: 14px 0 0;
  padding: 8px 12px;
  background: var(--c-brand-tint);
  border: 1px solid var(--c-brand-border);
  border-radius: 10px;
  font: var(--md-sys-typescale-label-medium);
  color: var(--c-brand);
}
/* Мобильная шторка уже сама карточка — вторая рамка внутри неё лишняя. */
.bottom-sheet .filter-panel {
  background: none;
  border: 0;
  border-radius: 0;
  padding: 0;
}
.bottom-sheet .filter-panel__title { display: none; }

/* --- Выбор порядка выдачи (v3 §5) ------------------------------------- */
.listings-header__head { flex-wrap: wrap; }
.listings-sort {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-inline-start: auto;
  font: var(--md-sys-typescale-label-large);
  color: var(--c-text-muted);
}
.listings-sort__select {
  border: 1px solid var(--c-border-strong);
  border-radius: 9px;
  background: var(--c-surface);
  color: var(--c-text);
  height: 36px;
  padding-inline: 10px 28px;
  font: var(--md-sys-typescale-label-large);
  cursor: pointer;
}
@media (max-width: 639.98px) {
  /* На телефоне порядок стоит рядом с кнопкой «Фильтры», а не под заголовком —
     иначе шапка ленты занимает два экрана прокрутки до первой карточки. */
  .listings-sort { margin-inline-start: 0; width: 100%; }
}
