/* Оформление публичного сайта «Тёплого двора».
   Один файл, системные шрифты, никаких внешних сетей. Телефон — в первую очередь.
   Палитра взята из приложения (app/src/main/java/com/petcare/app/ui/theme/Theme.kt)
   и повторена здесь теми же именами, что в приложении. */

:root {
  /* Светлая тема приложения */
  --bg: #F6F7F9;
  --on-bg: #141A21;
  --surface: #FFFFFF;
  --surface-variant: #EDF0F5;
  --on-surface-variant: #5A6675;
  --primary: #0F7A5A;
  --on-primary: #FFFFFF;
  --primary-container: #D6F1E4;
  --on-primary-container: #05301F;
  --secondary: #54627A;
  --secondary-container: #E7EBF2;
  --tertiary: #A5641A;
  --tertiary-container: #FBE7CE;
  --on-tertiary-container: #341D00;
  --error: #BA3A2E;
  --error-container: #FBE2DF;
  --on-error-container: #3F0E09;
  --outline: #C2C9D4;
  --outline-variant: #E4E8EF;
  --container-low: #F3F5F8;
  --container: #EDF0F5;
  --container-high: #E6EAF1;
  --container-highest: #DFE4EC;
  --scrim: #0B0E12;

  /* Совместимость с именами, которые уже были в вёрстке */
  --ink: var(--on-bg);
  --muted: var(--on-surface-variant);
  --line: var(--outline-variant);
  --accent: var(--primary);
  --accent-dark: #0B5B43;
  --accent-soft: var(--primary-container);
  --ok: #0F7A5A;
  --ok-soft: var(--primary-container);
  --radius: 20px;
  --radius-lg: 26px;
  /* Тень короткая: смещение 2 px, размытие 8 px. При размытии 30 px тень
     ложилась на промежуток между карточками (16 px) и темнила фон на 3.3 % —
     заказчик видел это как «блок темнее основного фона» (13.10). Теперь
     тень затухает внутри промежутка. */
  --shadow: 0 1px 2px rgba(20, 26, 33, .05),
            0 2px 8px rgba(20, 26, 33, .07);
  /* Ширина общего блока — ОДНА на весь сайт. 31.10 заказчик: «сделай ширину как
     у Авито и добавь место под ещё один столбец объявлений». У Авито основной
     блок 1380 px, поэтому берём 1400: этого хватает на четыре карточки в ряд
     (см. --content-w) и выглядит так же широко. */
  --wrap: 1400px;
  --spot-light: .16;
  /* Стекло: ОДНА формула для шапки и нижней панели (заказчик, 31.10).
     Прозрачность заметно выше прежней (.86 → .62), поэтому размытие и насыщенность
     усилены: текст на стекле не «плавает» над просвечивающим содержимым. */
  --glass-tint: rgba(255, 255, 255, .62);
  --glass-line: rgba(20, 26, 33, .07);
  --glass-shadow: 0 1px 2px rgba(20, 26, 33, .04), 0 12px 32px rgba(20, 26, 33, .08);
  --glass-blur: 18px;
  --glass-saturate: 165%;
  /* Блик по верхней кромке: без него стекло читается как обычная полупрозрачная заливка. */
  --glass-highlight: inset 0 1px 0 rgba(255, 255, 255, .7);
  /* Синонимы для шапки: старые имена оставлены, на них ссылаются проверки. */
  --header-bg: var(--glass-tint);
  --header-border: var(--glass-line);
  --header-shadow: var(--glass-shadow);
  --header-blur: var(--glass-blur);
  --control-h: 40px;          /* высота пилюли поиска и кнопки в шапке (по макету) */
  /* Стандарт элементов: высота под палец и шаг отступов. */
  --tap-h: 44px;              /* кнопки и чипы: меньше пальцем не попасть */
  --field-h: 48px;            /* поля ввода: одна высота на всех формах */
  --gap-xs: 8px;
  --gap-s: 12px;
  --gap-m: 16px;
  --gap-l: 24px;
  /* Зазор между меню и контентом — отдельная колонка сетки.
     24 px — тот же порядок, что промежуток между блоками меню (16 px):
     зазор заметен, но не разрывает страницу. Сначала поставил 60 px —
     заказчик 13.10: «это очень большое расстояние, оно должно быть как
     между вертикальными блоками меню». Жёсткая колонка, а не `1fr` и не
     поле: её нельзя сжать, поэтому зазор есть при любой ширине экрана. */
  --gap-wide: 24px;
  /* Пропорции кадра объявления. Ширину задаёт колонка, высоту — пропорция
     (как на Авито). 16:10 на компьютере, 4:3 на телефоне.

     Было `--shot-h`, и кадр считался «от высоты»: 360 × 4/3 = 480 px при колонке
     760 px. Из-за этого кадр был уже блока контактов (заказчик, 13.10). */
  --shot-ratio: 16 / 10;
  --shot-ratio-mobile: 4 / 3;
  /* Отступ между шапкой и содержимым — ОДИН на все страницы. Менять здесь:
     дальше его никто не переопределяет (заказчик, 12.10). */
  --top-gap: 20px;
  /* Ширина колонки с меню и карточкой хозяина. Одна на всех страницах:
     заказчик просил «стандартизировать меню везде одинаково». */
  --side-w: 280px;
  /* Ширина блока контента. Именно этот блок центрируется по экрану,
     а меню просто встаёт слева от него (заказчик, 12.10).
     760 px — та же мера строки, что была у абзацев: 68 знаков. */
  /* Ширина колонки контента. Возвращена к 760 px: запас теперь даёт обёртка
     (1360 px), и сужать текст с фотографиями больше незачем. */
  /* Основная колонка. Было 760 — три карточки в ряд; стало 1060 — четыре
     (4×225 + 3×16 = 948 ≤ 1060). Меньше делать нельзя: заказчик просил
     именно ещё один столбец. */
  --content-w: 1060px;
  /* Светлая тема — и ТОЛЬКО она. Тёмную удалили 13.10 по просьбе заказчика:
     раньше ниже стоял `@media (prefers-color-scheme: dark)`, и на тёмной системе
     сайт темнел. `color-scheme: light` нужен ещё и затем, чтобы браузер рисовал
     светлыми системные части — полосы прокрутки, поля ввода, выпадающие списки:
     без этого они остались бы тёмными и выпадали из страницы. */
  color-scheme: light;
}


* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-padding-top: 88px; }

body {
  margin: 0;
  color: var(--on-bg);
  /* Фон страницы — ровный, без градиента.
     Раньше здесь был градиент `bg → container → bg`. На длинном документе полоса
     более тёмного `--container` попадала в середину экрана и читалась как серая
     подложка поперёк всей страницы — у колонки меню она выглядела как подложка
     под колонной с ровным нижним краем (заказчик, 13.10). Ровный цвет убирает
     полосу совсем. */
  background: var(--bg);
  font: 16px/1.55 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}

img { max-width: 100%; height: auto; display: block; }

a { color: var(--accent-dark); text-decoration: none; }
a:hover { text-decoration: underline; }

h1, h2, h3 { line-height: 1.25; margin: 0 0 .6em; }
h1 { font-size: clamp(1.5rem, 1.2rem + 1.4vw, 2.1rem); }
h2 { font-size: clamp(1.2rem, 1.05rem + .7vw, 1.5rem); margin-top: 1.4em; }
h3 { font-size: 1.05rem; }

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin: 0 auto;
  padding: 0 16px;
  /* Защита от переполнения. `overflow-x: clip` выбран нарочно вместо `hidden`:
     `hidden` создал бы новую область прокрутки и **сломал** `position: sticky` у
     колонки меню, а `clip` только обрезает. Если оформление когда-нибудь снова
     начнёт вылезать за экран, страница останется по ширине, а не поедет вбок
     (заказчик, 15.10: «лента шире, хотя меню по ширине»). */
  max-width: 100%;
  overflow-x: clip;
}
/* Тег main бывает с классом wrap (обычные страницы) или wide (каталог).
   У .wrap отступ только по бокам: вертикальный задаёт правило `main`,
   иначе класс перебивал бы его (селектор класса весит больше тега) —
   так отступ под шапкой и разъезжался (заказчик, 12.10). */
/* Тег main бывает с классом wrap (обычные страницы) или wide (каталог).
   У `.wrap` отступ `padding: 0 16px`, и он весит больше селектора тега
   `main` — поэтому вертикальный отступ приходится повторять здесь.
   Без этой строки отступ под шапкой пропадал совсем (заказчик, 12.10). */
main.wrap { padding-block: var(--top-gap) 48px; padding-inline: 16px; }

/* --- шапка --- */
.site-header {
  position: sticky;
  top: 0;
  z-index: 20;
  background: var(--header-bg);
  border-bottom: 1px solid var(--header-border);
  box-shadow: var(--header-shadow), var(--glass-highlight);
  -webkit-backdrop-filter: blur(var(--header-blur)) saturate(var(--glass-saturate));
  backdrop-filter: blur(var(--header-blur)) saturate(var(--glass-saturate));
}
/* Старые браузеры и слабые телефоны: сплошная поверхность вместо стекла. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  /* Без размытия полупрозрачная плашка выглядит грязным пятном — делаем сплошной. */
  .site-header { background: var(--surface); }
  .bottom-nav { background: var(--surface); }
}
.header-inner {
  display: flex;
  flex-wrap: wrap;
  /* Контейнер занимает всю ширину страницы: без этого шапка сжимается
     по содержимому и меню уезжает за правый край. */
  width: 100%;
  gap: 10px 16px;
  align-items: center;
  justify-content: space-between;
  min-height: 72px;
  padding: 10px 16px;
  position: relative;
}
.brand {
  display: flex; flex-direction: row; align-items: center; gap: 10px;
  text-decoration: none;
  /* Бренд уступает место поиску и меню, а не выдавливает их за край:
     на узком телефоне название сокращается многоточием. */
  flex: 0 1 auto; min-width: 0;
}
.brand:hover { text-decoration: none; }
.brand-logo { width: 41px; height: auto; flex: 0 0 auto; }
.brand-text { display: flex; flex-direction: column; min-width: 0; }
.brand-name {
  font-weight: 700; font-size: 1.15rem; color: var(--ink);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.brand-tagline { font-size: .78rem; color: var(--muted); }

@media (max-width: 420px) {
  /* Узкий телефон: сжимаем всё, чтобы шапка осталась в одну строку. */
  .header-inner { gap: 8px; padding: 10px 12px; }
  .brand-name { font-size: 1rem; }
  .brand-logo { width: 30px; }
  .header-search-toggle { padding: 0 8px; }
}
@media (max-width: 760px) {
  .header-inner { min-height: 60px; gap: 8px 10px; }
  /* На телефоне длинная подпись не помещается рядом с кнопкой «Меню» и выдавливает
     её на вторую строку — убираем подпись, оставляя название. */
  .brand-tagline { display: none; }
  .brand-name { font-size: 1.05rem; }
  .brand-logo { width: 34px; }
  /* Меню и его раскрытие на телефоне описаны в блоке «Главное меню навигации». */
}

/* QR-код приложения в пустых состояниях: открыть клуб на телефоне. */
.empty-actions { display: flex; flex-wrap: wrap; gap: 10px; margin: 12px 0 0; }
.app-qr { margin: 16px 0 0; display: flex; flex-direction: column; align-items: flex-start; gap: 6px; }
.app-qr img { border: 1px solid var(--line); border-radius: 12px; background: #fff; padding: 8px; }
.app-qr figcaption { font-size: .85rem; color: var(--muted); max-width: 260px; }

/* Отступ между шапкой и содержимым — ОДИН на все страницы (заказчик, 12.10).
   Задаётся только здесь и ТОЛЬКО по вертикали: боковые отступы обычным
   страницам даёт класс `wrap` на этом же теге (`padding: 0 16px`).
   Писать здесь полную запись `padding: …` нельзя: селектор класса весит
   больше селектора тега, и класс занулял вертикальный отступ — из-за этого
   отступ под шапкой и разъезжался. Первые блоки сверху ничего не добавляют:
   см. `.site-main > :first-child`. */
main { padding-block: var(--top-gap) 48px; }

/* --- подвал --- */
.site-footer {
  background: var(--surface);
  border-top: 1px solid var(--line);
  padding: 20px 0 28px;
  margin-top: 32px;
}
.footer-links { display: flex; flex-wrap: wrap; gap: 6px 16px; margin-bottom: 10px; }
.footer-links a { font-size: .92rem; }
.footer-note { color: var(--muted); font-size: .85rem; margin: 0; }

/* --- герой и счётчики --- */
.hero { padding: 0 0 4px; }
.lead { font-size: 1.05rem; color: #4a413b; max-width: 62ch; }
.hero-actions { display: flex; flex-wrap: wrap; gap: 10px; margin: 18px 0 4px; }

.counters {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 22px 0 4px;
  padding: 0;
}
.counters > div {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 12px 18px;
  min-width: 150px;
  box-shadow: var(--shadow);
}
.counters dt { color: var(--muted); font-size: .87rem; }
.counters dd { margin: 2px 0 0; font-size: 1.5rem; font-weight: 700; }
.counters-small dd { font-size: 1.2rem; }

/* --- облако ссылок --- */
.cloud-title { margin: 14px 0 6px; color: var(--muted); font-size: .85rem; text-transform: uppercase; letter-spacing: .04em; }
.cloud { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  display: inline-flex;
  gap: 6px;
  align-items: center;
  min-height: var(--tap-h);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 999px;
  padding: 6px 12px;
  font-size: .92rem;
  color: var(--ink);
}
.chip:hover { background: var(--accent-soft); text-decoration: none; }
.chip-count { color: var(--muted); font-size: .87rem; }

/* --- карточки объявлений --- */
.cards {
  display: grid;
  /* 225, а не 230: на экране 1280 контент 964 px, и четвёртая карточка
     влезает только при 225 (4×225 + 3×16 = 948). */
  grid-template-columns: repeat(auto-fill, minmax(215px, 1fr));
  gap: var(--gap-m);
  margin: var(--gap-m) 0;
  /* Та же ширина, что у шапки и фильтров: содержимое не выглядит уже шапки. */
  width: 100%;
  max-width: var(--wrap);
}
.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow);
  display: flex;
  flex-direction: column;
  /* Карточка — точка отсчёта для растянутой ссылки: она накрывает её целиком
     (заказчик, 12.10: «чтобы была кликабельна вся карточка»). */
  position: relative;
}
.card-photo { display: block; background: var(--accent-soft); }
.card .photo { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; }
.card-body { padding: 10px 12px 14px; display: flex; flex-direction: column; gap: 4px; }
.card-title {
  /* 03.11: название — обычным начертанием, жирным только цена (как на Авито):
     заголовок-«h3» по умолчанию жирный, и карточки выглядели тяжёлыми. */
  font-weight: 400;
  font-size: 1rem;
  margin: 0;
  /* Название — не длиннее двух строк: иначе карточки в ряду разной высоты. */
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}
.card-title a { color: var(--ink); }
/* Растянутая ссылка: накрывает карточку целиком, поэтому нажать можно в любое
   место — по фотографии, цене, пустому углу (заказчик, 12.10). Приём без
   JavaScript: сама ссылка остаётся в названии, а псевдоэлемент растягивается на
   ближайшего родителя с `position: relative` — это карточка. */
.card-title a::after { content: ""; position: absolute; inset: 0; }
/* Карточка под курсором-рукой: видно, что нажимается вся, а не только название. */
.card:hover { box-shadow: 0 6px 20px rgba(0, 0, 0, .12); }
/* Клавиатура: обводка вокруг всей карточки, а не вокруг строки названия —
   иначе непонятно, что именно откроется. */
.card:focus-within { outline: 2px solid var(--primary); outline-offset: 2px; }
.card:focus-within .card-title a:focus-visible { outline: none; }
/* Всё нажимаемое внутри карточки (значок «♡», жалоба) обязано быть ВЫШЕ
   растянутой ссылки, иначе нажатие уйдёт в объявление. */
.card a:not(.card-title a),
.card button,
.card input,
.card select,
.card summary { position: relative; z-index: 1; }
.card-price { margin: 0; font-weight: 700; font-size: 1.05rem; }
.card-meta { margin: 0; color: var(--muted); font-size: .87rem; }

/* --- Карточка животного в кабинете (этап A ночной смены) ---
   На скриншотах заказчика кличка стояла посреди строки, а «вид · порода» разъезжались
   на две-три строки, из-за чего карточки в ряду были разной высоты. Причина не
   в ширине (замер: 244 px карточка, 220 px тексту — хватает), а в правилах:
   блоку не задано, сколько строк он занимает, а фото без снимка схлопывалось.
   Считаем строки фиксированно: кличка — до двух, вид и порода — до двух. */
.pet-card .card-photo { aspect-ratio: 4 / 3; }
.pet-card .card-photo .photo,
.pet-card .card-photo .photo-empty { aspect-ratio: 4 / 3; width: 100%; }
.pet-card .card-body { justify-content: flex-start; }
.pet-card .card-title {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  /* Кличка прижата к верху: по центру она «плавала» между строками вида. */
  align-self: flex-start;
  overflow-wrap: anywhere;
}
.pet-card .card-meta {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
  overflow-wrap: anywhere;
  /* Две строки под вид и породу: «Британская короткошёрстная» в одну не влезает,
     а обрезать такую породу жалко (решение заказчика). */
  min-height: calc(2 * 1.35em);
}

/* Телефон: две колонки по 160–170 px — как в мобильном плане.
   Одна колонка во всю ширину растягивала список на несколько экранов. */
@media (max-width: 600px) {
  .cards {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--gap-s);
    margin: 12px 0;
  }
  .card-body { padding: 8px 10px 12px; }
  .card-title { font-size: .95rem; }
  .card-price { font-size: 1rem; }
}
@media (max-width: 420px) {
  .cards { gap: var(--gap-xs); }
  .card-body { padding: 8px 8px 10px; }
  .card-title { font-size: .92rem; }
}

.photo-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--accent-soft);
  color: var(--muted);
  font-size: .85rem;
  aspect-ratio: 4 / 3;
}

/* --- фильтры --- */
.filters {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px;
  margin: 14px 0;
  box-shadow: var(--shadow);
}
.field { display: flex; flex-direction: column; gap: 4px; font-size: .88rem; }
.field > span { color: var(--muted); }
input, select, textarea {
  font: inherit;
  color: var(--ink);
  background: #fff;
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 9px 10px;
  /* Одна высота у всех полей: палец попадает, формы выглядят ровно. */
  min-height: var(--field-h);
  width: 100%;
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--accent-soft); border-color: var(--accent); }
/* Оформление кнопок фильтра живёт вместе с сеткой фильтров (ниже): там заданы и
   выравнивание, и растягивание на телефоне. Отдельное правило перебивало его. */

.button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--tap-h);
  background: var(--accent);
  color: #fff;
  border: 1px solid var(--accent);
  border-radius: 10px;
  padding: 10px 16px;
  font: inherit;
  font-weight: 600;
  cursor: pointer;
}
.button:hover { background: var(--accent-dark); border-color: var(--accent-dark); text-decoration: none; }
.button-plain { background: #fff; color: var(--accent-dark); border-color: var(--line); }
.button-plain:hover { background: var(--accent-soft); color: var(--accent-dark); }
.button-disabled { color: var(--muted); background: #f4efe8; cursor: default; }

.found { color: var(--muted); margin: 4px 0 0; }

/* --- листание, крошки, сообщения --- */
.pagination { display: flex; gap: 10px; align-items: center; margin: 22px 0; flex-wrap: wrap; }
.pagination-page { color: var(--muted); font-size: .9rem; }
.breadcrumbs { color: var(--muted); font-size: .88rem; margin: 0 0 10px; }
.breadcrumbs .crumb { color: var(--accent-dark); }

.flash { border-radius: var(--radius); padding: 10px 14px; margin: 12px 0; border: 1px solid; }
.flash-error { background: var(--error-soft); border-color: #eccfcf; color: var(--error); }
.flash-ok { background: var(--ok-soft); border-color: #cfe4d2; color: var(--ok); }

.empty-state {
  background: var(--surface);
  border: 1px dashed var(--line);
  border-radius: var(--radius);
  padding: 22px;
  margin: 18px 0;
}
.empty-state h2 { margin-top: 0; }

/* --- страница объявления --- */
/* Объявление: галерея и описание. Своей второй колонки у страницы больше нет —
   правая часть теперь общая, с меню сайта. Поэтому объявление в одну колонку:
   если оставить две, описание сжимается до 315 px, а по нему и звонят. */
.listing-layout { display: block; }
.listing-layout .listing-info { margin-top: var(--gap-m); }
.gallery-main .photo { width: 100%; border-radius: var(--radius); background: var(--accent-soft); }
/* Полоса миниатюр под кадром — как на Авито. Миниатюра это `<label>`, связанный
   с переключателем: выбор работает без JavaScript. Полоса не переносится, а
   прокручивается по горизонтали, если кадров много. */
.gallery-thumbs {
  display: flex;
  gap: 8px;
  margin: 10px 0 0;
  padding: 2px 0 4px;
  overflow-x: auto;
  scrollbar-width: thin;
}
.gallery-thumb {
  flex: 0 0 auto;
  display: block;
  padding: 2px;
  border: 2px solid transparent;
  border-radius: 12px;
  cursor: pointer;
  transition: border-color .15s ease;
}
.gallery-thumb:hover { border-color: var(--accent-soft); }
.gallery-thumb .photo {
  width: 76px;
  height: 57px;
  object-fit: cover;
  object-position: center;
  border-radius: 9px;
}

.listing-price { font-size: 1.7rem; font-weight: 700; margin: 0 0 10px; }
.specs { width: 100%; border-collapse: collapse; margin: 0 0 16px; background: var(--surface); border-radius: var(--radius); overflow: hidden; }
.specs th, .specs td { text-align: left; padding: 9px 12px; border-bottom: 1px solid var(--line); vertical-align: top; font-size: .95rem; }
.specs th { color: var(--muted); font-weight: 500; width: 42%; }
.specs tr:last-child th, .specs tr:last-child td { border-bottom: 0; }

.seller, .contact, .description {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 16px;
  margin: 0 0 16px;
  box-shadow: var(--shadow);
}
.seller h2, .contact h2, .description h2 { margin-top: 0; font-size: 1.15rem; }
.badge { display: inline-block; background: var(--ok-soft); color: var(--ok); border-radius: 999px; padding: 3px 10px; font-size: .82rem; }
.phone { font-size: 1.15rem; font-weight: 700; }
.muted { color: var(--muted); }
.small { font-size: .87rem; }
.pre { white-space: pre-wrap; }

/* --- животное, хозяйство --- */
.pet-layout, .farm-head { display: grid; grid-template-columns: minmax(0, 320px) minmax(0, 1fr); gap: 20px; align-items: start; }
@media (max-width: 760px) { .pet-layout, .farm-head { grid-template-columns: 1fr; } }
.pet-photo .photo, .farm-avatar .photo { width: 100%; border-radius: var(--radius); object-fit: cover; }
/* Аватар хозяйства — тоже круг (этап D): та же болезнь, что у фото профиля. */
.farm-avatar .photo:not(.photo-empty) { width: 160px; height: 160px; aspect-ratio: 1 / 1; border-radius: 50%; }
.farm-avatar .photo { max-width: 160px; }
.rating { font-weight: 600; }

.pet-list { list-style: none; padding: 0; display: grid; gap: 10px; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
/* Строка списка животных (этап B ночной смены): фото и текст начинаются на одном
   уровне, а кличка и вид идут друг под другом в одном блоке. Раньше это были два
   отдельных флекс-элемента, и при переносе вида кличка вставала между его строками. */
.pet-list li { display: flex; gap: 10px; align-items: flex-start; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 8px 12px; }
.pet-list .photo { width: 56px; height: 56px; object-fit: cover; border-radius: 10px; }
.pet-list .photo-empty { width: 56px; height: 56px; aspect-ratio: 1 / 1; border-radius: 10px; font-size: .7rem; }
.pet-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.pet-name { font-weight: 600; overflow-wrap: anywhere; }
.pet-kind { overflow-wrap: anywhere; }

.plain-list { padding-left: 18px; }
.plain-list li { margin-bottom: 6px; }

.note, .login-form, .logout-form {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 16px;
  margin: 16px 0;
  box-shadow: var(--shadow);
}
.login-form { max-width: 420px; display: flex; flex-direction: column; gap: 12px; }
.logout-form { display: inline-block; padding: 10px; }
.note p { margin: 0 0 8px; }
.note p:last-child { margin-bottom: 0; }

/* --- экран входа и регистрации (волна 3, блок 0) ---
   Desktop: слева панель 58 %, справа формы. Телефон: панель сверху, формы под ней. */
main.auth-main { padding: 0; max-width: none; }
.auth-layout {
  display: grid;
  grid-template-columns: 58% 42%;
  min-height: 100vh;
  width: 100%;
}
.auth-panel {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  padding: 48px 6vw;
  color: #FFFFFF;
  /* Фон панели: фотография (если её положили в static/login-photo.jpg) и мягкое
     затемнение поверх, чтобы белые буквы читались на светлом снимке. Фото — первым
     слоем: раньше слои стояли наоборот, и плотный градиент закрывал снимок целиком. */
  background-color: var(--primary-container);
  background-image:
    linear-gradient(180deg, rgba(4, 26, 18, .80) 0%, rgba(4, 26, 18, .30) 45%, rgba(4, 26, 18, .82) 100%),
    url("/static/login-photo.jpg"),
    linear-gradient(140deg, #0F7A5A, #05301F);
  background-size: cover, cover, cover;
  background-position: center, center, center;
  background-repeat: no-repeat, no-repeat, no-repeat;
}
.auth-panel::before,
.auth-panel::after {
  /* «Жидкие» пятна, как в фоне приложения. */
  content: "";
  position: absolute;
  border-radius: 50%;
  filter: blur(80px);
  pointer-events: none;
}
.auth-panel::before {
  /* Размер ограничен экраном: пятно декоративное, но и оно не должно быть
     шире телефона (заказчик, 15.10). */
  width: min(340px, 92vw); height: min(340px, 92vw);
  top: -60px; left: -40px;
  background: rgba(69, 214, 160, var(--spot-light));
}
.auth-panel::after {
  width: min(380px, 96vw); height: min(380px, 96vw);
  bottom: -80px; right: -60px;
  background: rgba(240, 194, 123, calc(var(--spot-light) * .8));
}
.auth-panel-inner { position: relative; z-index: 1; max-width: 34ch; }
.auth-brand { font-size: 2.1rem; font-weight: 700; margin: 0 0 4px; letter-spacing: .01em; }
.auth-slogan { font-size: 1.15rem; margin: 0 0 22px; color: rgba(255, 255, 255, .9); }
.auth-points { margin: 0; padding-left: 18px; color: rgba(255, 255, 255, .92); }
.auth-points li { margin-bottom: 8px; }

.auth-forms {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 32px 20px 48px;
}
.auth-box { width: 100%; max-width: 440px; }

/* Переключатель «Вход / Регистрация»: две скрытые радиокнопки и две подписи.
   Работает без JavaScript, состояние переживает перезагрузку страницы. */
.auth-switch-input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.auth-switch {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px;
  padding: 4px;
  margin-bottom: 14px;
  background: color-mix(in srgb, var(--surface) 70%, transparent);
  border: 1px solid var(--outline-variant);
  border-radius: 999px;
}
.auth-switch-tab {
  text-align: center;
  padding: 10px 12px;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  font-weight: 600;
  color: var(--on-surface-variant);
  cursor: pointer;
  user-select: none;
}
.auth-switch-tab:hover { color: var(--on-bg); }
#mode-login:checked ~ .auth-switch label[for="mode-login"],
#mode-register:checked ~ .auth-switch label[for="mode-register"] {
  background: var(--primary);
  color: var(--on-primary);
}
#mode-login:focus-visible ~ .auth-switch label[for="mode-login"],
#mode-register:focus-visible ~ .auth-switch label[for="mode-register"] {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
/* Показываем только выбранное окно. */
.auth-pane { display: none; }
#mode-login:checked ~ .auth-card .auth-pane-login { display: block; }
#mode-register:checked ~ .auth-card .auth-pane-register { display: block; }

.auth-card {
  width: 100%;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  backdrop-filter: blur(14px);
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 24px 24px 20px;
}
.auth-card h1 { margin-top: 0; font-size: 1.4rem; }
.auth-card h2 { font-size: 1.15rem; margin: 22px 0 6px; }
.auth-card .login-form { max-width: none; box-shadow: none; border: 0; padding: 0; margin: 0; background: transparent; }

/* Всё нужное — под окном входа (шапки и подвала сайта на этом экране нет). */
.auth-foot {
  margin-top: 14px;
  padding: 16px 18px;
  background: color-mix(in srgb, var(--surface) 72%, transparent);
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius);
  text-align: left;
}
.auth-foot p { margin: 0 0 8px; font-size: .9rem; color: var(--on-surface-variant); }
.auth-foot p:last-child { margin-bottom: 0; }
.auth-foot-links { display: flex; flex-wrap: wrap; gap: 6px 14px; margin: 10px 0; }
.auth-foot-links a { font-size: .9rem; }
.auth-foot-note { font-size: .82rem; }

.checkbox { display: flex; gap: 10px; align-items: flex-start; font-size: .88rem; }
.checkbox input { width: auto; margin-top: 3px; }

@media (max-width: 1024px) {
  .auth-layout { grid-template-columns: 1fr; min-height: 0; }
  .auth-panel {
    min-height: 260px;
    max-height: 40vh;
    padding: 26px 20px;
    /* На телефоне панель низкая и широкая — берём вертикальный снимок, он в кадре
       смотрится собраннее. Если файла нет, остаётся основное фото из правила выше. */
    background-image:
      linear-gradient(180deg, rgba(4, 26, 18, .78) 0%, rgba(4, 26, 18, .30) 45%, rgba(4, 26, 18, .82) 100%),
      url("/static/login-photo-tall.jpg"),
      url("/static/login-photo.jpg"),
      linear-gradient(140deg, #0F7A5A, #05301F);
    background-size: cover, cover, cover, cover;
  }
  .auth-brand { font-size: 1.6rem; }
  .auth-slogan { margin-bottom: 10px; }
  .auth-points { font-size: .95rem; }
  .auth-forms { padding: 22px 14px 40px; }
  .auth-box { max-width: 100%; }
  .auth-card { max-width: 100%; border-radius: 22px; padding: 18px 16px 16px; }
  .auth-foot { padding: 14px 14px; }
}

/* Кнопки не меньше 44 px по высоте — удобно нажимать пальцем.
   Высота задана токеном --tap-h в правиле .button выше. */

/* Ссылка «пропустить к содержимому» для клавиатуры и читалок. */
.skip-link {
  position: absolute;
  left: -9999px;
  top: 0;
  background: var(--surface);
  color: var(--on-bg);
  padding: 10px 14px;
  border-radius: 0 0 12px 0;
  z-index: 50;
}
.skip-link:focus { left: 0; }

/* Широкие страницы (каталог, заявки) идут во всю ширину, но отступ под шапкой
   у них тот же, что у остальных: vertical padding берём из общего правила.
   Горизонтальные отступы дают внутренние `.wrap`, поэтому их здесь нет. */
main.wide { max-width: none; width: 100%; padding-block: var(--top-gap) 48px; }

/* Экран входа (body.bare): без шапки и подвала сайта, панель во всю высоту —
   здесь отступ под шапкой не нужен вовсе. */
body.bare main.wide { display: block; padding: 0; margin: 0; }

/* Экран входа (body.bare): без шапки и подвала сайта, панель во всю высоту. */
body.bare main.wide { display: block; }
body.bare .site-footer, body.bare .site-header { display: none; }
/* --- Кабинет: две колонки, панель разделов справа ---
   В разметке содержимое идёт первым, панель второй — вправо её ставит сетка.
   Так экранный диктор и обход Tab читают содержимое раньше меню. */
/* Отступ сверху кабинету не нужен: он уже есть у main, иначе выходило 32 px
   вместо 20 — и кабинет отличался от остальных страниц. */
/* --- Раскладка страницы: содержимое и колонка меню -------------------------
   Заказчик 12.10: «перемести все меня с правой части на левую» и «стандартизируй
   меню везде одинаково». Поэтому обычные страницы и кабинет идут **одной**
   раскладкой, а не двумя похожими.

   По умолчанию — одна колонка, меню **сверху**: так страница выглядит на телефоне.
   Две колонки включаются медиазапросом ниже, и там направление разворачивается:
   `row-reverse` ставит меню **слева**, при этом содержимое остаётся **первым**
   в разметке — так его читает экранный диктор и так идёт обход Tab. */
/* Контент по центру экрана, меню — слева от него.

   Раскладка из трёх частей: пустая колонка, меню, контент, пустая колонка.
   Пустые колонки одинаковые (`1fr`), поэтому **центр контента совпадает с
   центром экрана** — и не важно, есть меню или нет.

   Порядок в разметке: содержимое **первым**, меню вторым. Так его читает
   экранный диктор и так идёт обход Tab. На экран меню ставит сетка (первая
   колонка), а не порядок разметки. */
.site-layout,
.cab-layout {
  display: grid;
  /* Зазор — ОТДЕЛЬНАЯ колонка жёсткой ширины. Раньше он складывался из пустой
     колонки `1fr` и поля меню; как только обёртка становилась уже суммы колонок,
     `1fr` сжимался до нуля и зазор исчезал — «ничего не поменялось»
     (заказчик, 13.10). Жёсткую колонку сжать нельзя, поэтому меню и контент
     расходятся всегда.
     Контент — `minmax(0, 760)`: пока места хватает, он ровно 760 px, а когда
     тесно — сжимается до 620 px, не выдавливая зазор. */
  grid-template-columns:
    minmax(0, 1fr)
    var(--side-w)
    var(--gap-wide)
    minmax(0, var(--content-w))
    minmax(0, 1fr);
  grid-template-areas: "left side gap main right";
  gap: 0;
  align-items: start;
}

/* Ширина колонки с меню — одна и та же на всех страницах. */
.site-side,
.cab-side {
  grid-area: side;
  width: var(--side-w);
  /* Поля справа НЕТ: зазор между меню и контентом задаёт отдельная колонка сетки
     (`--gap-wide`). Одно место вместо двух — раньше поле и пустая колонка
     складывались, и при тесном экране зазор исчезал (заказчик, 13.10). */
}

.site-main,
.cab-main {
  grid-area: main;
  min-width: 0;
}

/* Две колонки: меню слева, содержимое справа. До этой ширины страница идёт в одну
   колонку с меню сверху — так на телефоне меню не занимает первый экран. */
@media (min-width: 1160px) {
  /* Панель прилипает только при двух колонках: в одноколоночной раскладке липкая
     панель тянулась бы вдоль всего содержимого. Полосу прокрутки скрываем
     (просьба заказчика от 11.10: «сделай как во ВКонтакте»): сама прокрутка
     остаётся — колесом, пальцем и клавиатурой, а полосы не видно. */
  .site-side,
  .cab-side {
    position: sticky;
    top: 88px;                       /* высота шапки 72 px + зазор 16 px */
    align-self: flex-start;
    max-height: calc(100vh - 104px);
    overflow-y: auto;
  }
}
/* Узкий экран: меню первым. `column-reverse` разворачивает порядок, поэтому
   содержимое, стоящее первым в разметке, оказывается снизу, а меню — сверху. */
@media (max-width: 1159px) {
  /* Одна колонка: контент на всю ширину, меню **над** ним. Порядок задаём явно
     (`dense`), потому что в разметке содержимое стоит первым: без этого меню
     оказалось бы под содержимым, то есть в самом низу страницы. */
  .site-layout,
  .cab-layout {
    display: flex;
    flex-direction: column-reverse;
    gap: var(--gap-m);
    align-items: stretch;
  }
  .site-side,
  .cab-side {
    flex: 1 1 auto;
    width: 100%;
    /* `width: auto` важен: базовое правило задаёт `width: var(--side-w)` (260 px).
       При `column-reverse` и `align-items: stretch` ширина всё равно берётся из
       `width`, и на узком экране это давало лишнюю ширину и полосу прокрутки
       (заказчик, 13.10, снимок при 638 px). */
    max-width: 100%;
    min-width: 0;
    /* Зазор между меню и содержимым задаёт САМО меню. `column-reverse` ставит
       меню сверху, поэтому его нижнее поле и есть нужный промежуток. Раньше поле
       снималось (`margin-right: 0` из двухколоночного вида действовало и здесь),
       и меню стояло вплотную к содержимому — «нет расстояния между меню и
       контентом» (заказчик, 13.10). */
    margin: 0 0 var(--gap-l);
  }
}
.cab-main {
  min-width: 0;
  /* Длинные почта и ссылки переносятся, а не растягивают колонку:
     иначе на телефоне появляется горизонтальная прокрутка страницы. */
  overflow-wrap: break-word;
}
/* Панель кабинета прилипает так же, как колонка сайта: правило ниже, вместе с
   ней. Здесь оставляем только скрытие полосы прокрутки. */
.cab-side {
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.cab-side::-webkit-scrollbar { display: none; }
.cab-side-title {
  margin: 0 0 8px;
  padding: 0 12px;
  font-size: .85rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--muted);
}

/* --- меню кабинета, формы, журналы, графики, значки --- */
.cab-nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px;
  margin: 0;
  background: color-mix(in srgb, var(--surface) 80%, transparent);
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius);
}
/* Пункт меню кабинета: название, счётчик (если есть), стрелка перехода справа.
   Стрелка — та же, что в главном меню (``MENU_ARROW``), поэтому колонка сайта и
   кабинет выглядят одинаково (заказчик, 12.10). */
.cab-link {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: var(--tap-h);
  padding: 0 12px;
  border-radius: 12px;
  font-size: .95rem;
  color: var(--on-surface-variant);
}
.cab-link-text {
  flex: 1 1 auto;          /* название занимает свободное место, стрелка — справа */
  min-width: 0;
}
/* Стрелка тише названия: она подсказка о переходе, а не часть подписи. */
.cab-link > .site-side-arrow {
  flex: 0 0 auto;
  color: var(--outline);
  transition: color .15s ease, transform .15s ease;
}
.cab-link:hover > .site-side-arrow { color: var(--primary); transform: translateX(2px); }
/* Активный пункт залит цветом: стрелку делаем цвета текста, иначе она на нём
   потеряется. */
.cab-link[aria-current="page"] > .site-side-arrow { color: var(--on-primary); }
.cab-link:hover { background: var(--primary-container); text-decoration: none; }
.cab-link[aria-current="page"] {
  background: var(--primary);
  color: var(--on-primary);
  font-weight: 600;
  /* Полоска слева: активный пункт видно даже боковым зрением. */
  box-shadow: inset 3px 0 0 var(--on-primary);
}
.cab-badge {
  display: inline-block;
  flex: 0 0 auto;
  min-width: 1.4em;
  padding: 0 6px;
  /* `margin-left: auto` здесь не нужен: место справа уже занято названием
     (`.cab-link-text` с `flex: 1`), а стрелка должна остаться последней. */
  border-radius: 999px;
  background: var(--tertiary-container);
  color: var(--on-bg);
  font-size: .87rem;
  text-align: center;
}
.cab-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 14px 0; }

.cab-form {
  background: var(--surface);
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 18px;
  margin: 16px 0;
}
.field-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 14px; }
.field-row { display: flex; flex-direction: column; gap: 4px; }
.field-row-wide { grid-column: 1 / -1; }
.field-row label { font-size: .88rem; color: var(--on-surface-variant); }
.field-hint { font-size: .87rem; color: var(--on-surface-variant); }
.field-error { font-size: .87rem; color: var(--error); font-weight: 600; }

.table-wrap { overflow-x: auto; margin: 12px 0; }
.specs.journal th, .specs.journal td { font-size: .9rem; }
.specs.journal form { margin: 0; }
.link-danger {
  background: none;
  border: 0;
  padding: 0;
  color: var(--error);
  font: inherit;
  cursor: pointer;
  text-decoration: underline;
}
.button-danger { background: var(--error); border-color: var(--error); color: #fff; }
.button-danger:hover { background: #8f2a20; border-color: #8f2a20; }

.badge { display: inline-block; border-radius: 999px; padding: 3px 10px; font-size: .82rem; font-weight: 600; }
.badge-ok { background: var(--primary-container); color: var(--on-primary-container); }
.badge-soon { background: var(--tertiary-container); color: var(--on-tertiary-container); }
.badge-overdue { background: var(--error-container); color: var(--on-error-container); }
.badge-none { background: var(--container-high); color: var(--on-surface-variant); }

.status-list { list-style: none; padding: 0; display: grid; gap: 8px; }
.status-list li { background: var(--surface); border: 1px solid var(--outline-variant); border-radius: var(--radius); padding: 8px 12px; }

.pet-card .card-photo .photo { aspect-ratio: 4 / 3; }
.chart { margin: 16px 0; background: var(--surface); border: 1px solid var(--outline-variant); border-radius: var(--radius); padding: 10px; }
.chart figcaption { font-size: .9rem; color: var(--on-surface-variant); margin-bottom: 4px; }

.danger-box {
  background: var(--error-container);
  border: 1px solid color-mix(in srgb, var(--error) 40%, transparent);
  border-radius: var(--radius);
  padding: 14px 16px;
  margin: 14px 0;
  color: var(--on-bg);
}
/* Адаптив кабинета — в конце файла, чтобы порядок правил был очевиден. */
/* --- Карточка объявления (этап 3 волны 5): порядок, связь, липкая панель --- */
.listing-title { margin: 0 0 6px; font-size: 1.7rem; line-height: 1.2; }
.listing-sub { margin: 0 0 6px; font-size: 1.02rem; color: var(--ink); }
.listing-meta { margin: 0 0 16px; font-size: .92rem; color: var(--muted); }
.contact {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 16px;
  margin: 0 0 18px;
}
.contact-actions { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 10px; }
.contact-phone { margin: 0 0 6px; font-size: 1.05rem; font-weight: 600; }
.call-form { display: grid; gap: 10px; max-width: 360px; margin: 10px 0 0; }
.call-form .field-row { display: flex; flex-direction: column; gap: 4px; }
.call-form input[type="tel"] { height: 44px; padding: 0 12px; border: 1px solid var(--line);
  border-radius: 12px; font-size: 1rem; }
/* Согласие на связь (этап F ночной смены): подпись — одним блоком, который
   переносится целиком. Раньше подпись была флекс-элементом и в узкой колонке
   (около 300 px) рассыпалась по словам, а ссылка уезжала вправо.

   Урок 12.10: подпись «рассыпалась по буквам» дважды. Причина всякий раз одна —
   подпись оказывалась **флекс-элементом внутри колонки** (правило чеклиста
   `.check-text` подходило и сюда, а `min-width: 0` разрешал сжать её до одной
   буквы). Поэтому теперь подпись защищена по существу, а не по месту:

   1. `display: block` и `flex: none` — подпись **не флекс-элемент**, её нельзя
      сжать по ширине содержимого;
   2. `flex-basis: auto`, `width: 100%` — ей достаётся вся строка под флажком;
   3. `word-break: normal` и `overflow-wrap: break-word` — перенос по словам,
      а по буквам только если слово само длиннее строки. */
.check-row { display: flex; gap: 8px; align-items: flex-start; font-size: .88rem; color: var(--muted); }
.check-row > .check-text,
.check-row .check-text {
  display: block;
  flex: none;
  flex-basis: auto;
  width: 100%;
  min-width: 0;
  word-break: normal;
  overflow-wrap: break-word;
}
.check-row input { flex: 0 0 auto; margin-top: 3px; }
@media (max-width: 420px) {
  .check-row { flex-direction: column; gap: 6px; }
  .check-row input { margin-top: 0; }
}
.safety-note {
  margin: 12px 0 0;
  padding: 10px 12px;
  background: color-mix(in srgb, var(--tertiary-container, #f3e6c8) 60%, transparent);
  border-left: 3px solid var(--accent-dark, #8a6d3b);
  border-radius: 10px;
  font-size: .9rem;
}
.link-back { display: inline-block; margin-top: 6px; }
.mobile-bar { display: none; }
@media (max-width: 1024px) {
  .mobile-bar {
    display: flex;
    gap: 10px;
    position: sticky;
    bottom: 0;
    /* Полная ширина страницы. Родитель (main.wrap) держит поля 16 px, и без
       отрицательных полей фон полосы не доходил до краёв — выглядело обрезанным
       по бокам (заказчик, 31.10). Внутренние отступы возвращают воздух кнопкам. */
    margin: 0 -16px;
    padding: 10px 16px max(10px, env(safe-area-inset-bottom));
    background: var(--surface);
    border-top: 1px solid var(--line);
    z-index: 15;
  }
  .mobile-bar .button { flex: 1; text-align: center; }
  .listing-title { font-size: 1.4rem; }
  .listing-price { font-size: 1.45rem; }
}
/* --- Восстановление пароля под окном входа (этап 1) --- */
/* Ссылка «Забыли пароль?» под полем пароля на экране входа (заказчик, 15.10).
   Стоит отдельной строкой: её ищут глазами, когда не могут войти. */
.auth-forgot {
  margin: 10px 0 0;
  font-size: .92rem;
}

.auth-recover {
  margin: 10px 0 0;
  padding: 12px 14px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
}
.auth-recover p { margin: 0 0 6px; }
.auth-recover ol { margin: 6px 0 6px 18px; padding: 0; }
.auth-recover li { margin: 4px 0; }

/* --- Страница «Связаться с клубом» ------------------------------------------
   Отдельного ограничения ширины здесь больше нет: раньше форма была 720 px при
   колонке 760 px, и на этой странице блоки выглядели уже, чем на соседних
   («размер блоков скачет» — заказчик, 13.10). Форма занимает колонку целиком,
   как все остальные блоки. */
/* --- Доверие в объявлении (этап 2): цена, бейджи продавца, действия --- */
.price-note {
  margin: 0 0 14px;
  padding: 10px 12px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-left: 3px solid var(--accent-dark, #8a6d3b);
  border-radius: 10px;
  font-size: .92rem;
}
.listing-actions { display: flex; flex-wrap: wrap; gap: 10px; margin: 14px 0 6px; }
.badge-soon { background: var(--tertiary-container); color: var(--on-bg); }
.badge-overdue { background: var(--error-container); color: var(--error); }
.seller .badge { margin: 4px 0 0; }

/* --- Галерея без JavaScript: один крупный кадр и стрелка «›» --- */
/* Один крупный кадр во всю ширину текста и стрелка «›» вправо. Миниатюр нет.

   Пять правил, которые нельзя ломать:

   1. **Высота контейнера зафиксирована** (`aspect-ratio` у `.shots`) и **не
      зависит от фотографии**: при листании высота не меняется вообще. Просьба
      заказчика от 12.10. Раньше высоту давал первый кадр, а лишние кадры стояли
      `position: absolute`; если это правило перебивалось, контейнер схлопывался
      в ноль и нижние публикации накладывались друг на друга.
   2. **Виден ровно один кадр.** Кадры лежат в одной ячейке сетки
      (`grid-area: 1 / 1`), лишние скрыты через `display: none`, а показывает
      нужный переключатель (`#foto-N:checked ~ .shots #foto-N`).
   3. **Снимок показывается целиком** (`object-fit: contain`): обрезка срезала
      голову собаке на вертикальном снимке и край с подписью на фото с печатью.
      Поля остаются цветом карточки — подложку заказчик просил убрать.
   4. **Кадр во всю ширину** — никаких `max-width`: ширина фотографии равна
      ширине текста публикации.
   5. **Одиночный кадр** (`.shot.shot-first`) виден без переключателей. */
/* Пропорция кадра — на ОБЩЕМ контейнере `.gallery`: он есть всегда, и при одной
   фотографии, и при нескольких. Раньше пропорция стояла у `.shots`, а его при
   одном фото нет вовсе — высоту задавала сама картинка, и вертикальный снимок
   растягивался на всю высоту (заказчик, 13.10: «ничего не поменялось»). */
/* `aspect-ratio` у `.shots` не даёт схлопнуться: высота следует из ширины. Раньше
   здесь стоял `min-height` как страховка — теперь он не нужен, но и не мешает;
   оставляем `overflow: visible`, чтобы стрелки не обрезались. */
/* Кадр занимает **всю ширину колонки контента** — и в объявлении, и в ленте
   (заказчик, 13.10: «Сдлелай фотографии по ширине блока контента»). Ширину задаём
   явно, чтобы её не определял размер снимка. */
.gallery { display: block; width: 100%; margin: 0; }
/* Переключатели — служебные: их видно только средствам чтения с экрана. */
.shot-pick {
  position: absolute; width: 1px; height: 1px; opacity: 0;
  pointer-events: none; margin: 0;
}
/* Кадр — ВО ВСЮ ШИРИНУ колонки, высота из пропорции (как на Авито).
   Раньше ширина считалась «от высоты», и при колонке 760 px кадр выходил
   480 × 360 — уже блока «Связаться с продавцом» (заказчик, 13.10). */
.shots {
  position: relative;
  /* Ширина — во всю колонку контента, как у блока «Связаться с продавцом»
     (заказчик, 13.10). Высоту задаёт пропорция: так кадр не «плавает» уже
     колонки и не растягивается на весь экран.

     16:10, а не 4:3: во всю ширину 4:3 дал бы 760 × 570 — кадр стал бы ВЫШЕ
     прежнего, а просили «занимать немного места». Широкая и низкая полоса
     выглядит легче. На телефоне пропорция возвращается к 4:3. */
  /* Размер задаёт КАДР, а не снимок: процентная высота разрешается только от
     определённой высоты родителя, а из пропорции она неопределённая — и тогда
     высоту кадра начинал определять снимок (квадрат 960 × 960 давал кадр уже
     колонки). Ровно это было видно в ленте (заказчик, 13.10). */
  display: block;
  width: 100%;
  aspect-ratio: var(--shot-ratio, 16 / 10);
  border-radius: var(--radius);
  overflow: hidden;
}
/* Одна фотография: обёртка не нужна, но разметка одинакова — рамка та же. */
.gallery > .shots:only-child { margin: 0 auto; }
/* Кадры лежат в одной ячейке; показывает только выбранный переключатель. */
/* Кадры в одной ячейке: виден ровно один, наложения нет. */
.shot { margin: 0; position: absolute; inset: 0; display: none; } /* Одиночный кадр виден без переключателей. Правило стоит ПОСЛЕ `.shot`, потому что
   у них одинаковый вес в каскаде, а выигрывает последнее: раньше `.shot.shot-first`
   перебивал `.shot`, и кадр терял `grid-area` (заказчик, 13.10). */
/* Одиночный кадр стоит В ПОТОКЕ: так он виден даже без `position: relative` у
   родителя. Много кадров лежат друг на друге абсолютно. */
/* Одиночный кадр лежит ТАК ЖЕ, как остальные — абсолютно внутри кадра.
   Раньше он стоял в потоке (`position: static`), и тогда высоту кадра определял
   СНИМОК, а не пропорция: квадратное фото давало квадратный кадр уже колонки
   (заказчик, 13.10). Теперь размер задаёт кадр, снимок его заполняет. */
.shot.shot-first { display: block; position: absolute; }

.shot .photo {
  display: block; width: 100%; height: 100%;
  /* Высоту берём от кадра `.gallery`. Без этого при одной фотографии высота
     считалась от пропорций снимка. */
  /* Снимок ЗАПОЛНЯЕТ кадр, лишнее обрезается по центру.
     `object-fit: contain` вписывал снимок целиком, и высота кадра зависела от
     пропорций фотографии: вертикальная занимала 760 × 1013 px, горизонтальная —
     совсем другую высоту. Одинаково они выглядеть не могут (заказчик, 13.10:
     «чтобы независимо от того, каким размером, они выглядели одинаково»).
     `cover` даёт один и тот же кадр для любого исходного размера — как на Авито.
     Снимок обрезается по центру, поэтому голова на вертикальном фото остаётся. */
  object-fit: cover;
  object-position: center;
  border-radius: var(--radius);
}
.shot .photo-empty {
  display: flex; align-items: center; justify-content: center;
  text-align: center; padding: 12px;
  width: 100%; height: 100%; border-radius: var(--radius);
  background: var(--accent-soft);
}
#foto-1:checked ~ .shots #foto-1,
#foto-2:checked ~ .shots #foto-2,
#foto-3:checked ~ .shots #foto-3,
#foto-4:checked ~ .shots #foto-4,
#foto-5:checked ~ .shots #foto-5,
#foto-6:checked ~ .shots #foto-6,
#foto-7:checked ~ .shots #foto-7,
#foto-8:checked ~ .shots #foto-8 { display: block; }
/* Переход по ссылке #foto-N (миниатюр нет, но адрес может прийти извне). */
/* Если в адресе есть #foto-N, первый кадр уступает ему место: без этого
   правила были бы видны сразу два кадра (нашёл расчёт каскада). */
.shot-count {
  position: absolute; right: 10px; top: 10px; z-index: 2;
  background: rgba(0, 0, 0, .6); color: #fff;
  padding: 3px 10px; border-radius: 999px; font-size: .85rem; font-weight: 600;
}
/* Стрелки листания по краям кадра: слева «назад», справа «вперёд».
   Это <label> к скрытому переключателю: нажатие переключает фото без JavaScript.
   Полоса (`inset: 0`) нажатий не перехватывает — у неё `pointer-events: none`, а у
   самих стрелок `auto`. Иначе полоса закрывала бы кадр целиком. */
/* Миниатюры под кадром — ниже, в разделе галереи. Листать можно стрелками,
   миниатюрами и клавиатурой (переключатели доступны с Tab). */
.shot-nav {
  position: absolute;
  inset: 0;
  z-index: 3;               /* стрелки поверх кадра */
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 8px;
  pointer-events: none;
}
.shot-prev,
.shot-next {
  pointer-events: auto;
  display: inline-flex;
  align-items: center;      /* значок ровно по центру кружка */
  justify-content: center;
  /* 44 px — область нажатия для пальца: в круг 40 px попадать хуже. */
  width: 44px;
  height: 44px;
  padding: 0;
  border-radius: 50%;
  background: rgba(0, 0, 0, .45);
  color: #fff;
  cursor: pointer;
  transition: background .15s ease;
}
.shot-prev:hover,
.shot-next:hover { background: rgba(0, 0, 0, .62); }
.shot-prev:focus-visible,
.shot-next:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.shot-prev .shot-arrow-icon,
.shot-next .shot-arrow-icon { display: block; }
/* Значок один и тот же: «назад» — тот же шеврон, повёрнутый влево. */
.shot-prev .shot-arrow-icon { transform: rotate(180deg); }

/* На телефоне стрелки меньше, но значок так же по центру кружка: круг 40 px
   (кадр уже, и 44 px закрывали бы снимок). */
@media (max-width: 600px) {
  .shot-prev, .shot-next { width: 40px; height: 40px; }
  .shot-arrow-icon { width: 18px; height: 18px; }
}

/* --- Действия и «поделиться» в объявлении (этап 3) --- */
.fav-form { display: inline; margin: 0; }
.share { margin: 0; }
.share > summary { list-style: none; cursor: pointer; }
.share > summary::-webkit-details-marker { display: none; }
.share-body {
  display: grid; gap: 8px; margin-top: 10px; padding: 12px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
}
.share-link { display: flex; flex-direction: column; gap: 4px; font-size: .85rem; color: var(--muted); }
.share-link input { min-height: var(--field-h); padding: 0 10px; border: 1px solid var(--line); border-radius: 10px; font-size: .9rem; }
.listing-actions { align-items: flex-start; }

/* --- Каталог: ряд видов больше не чипами ---------------------------------
   Раньше здесь был ряд чипов `.chips-row` с мобильной прокруткой.
   30.10 заказчик попросил плитки с картинками, как на Авито, — ряд
   заменён на `.species-cards` (стили ниже, в блоке плиток). Мёртвые
   правила удалены: иначе следующая правка идёт «по нерабочему».
   Класс `.chip` остался — он нужен «Все виды» и фильтрам. */

/* Главные фильтры рынка (этап E ночной смены).
   Было `repeat(auto-fit, minmax(150px, 1fr))`: число колонок зависело от содержимого,
   и на части ширин поля не помещались в свою ячейку — кнопка «Ещё фильтры» налезала
   на край списка. Теперь колонки заданы явно: поиск и два поля, дальше перенос. */
/* --- Отзывы: звёзды, карточки, форма ------------------------------------------
   Заказчик 13.10: «чтобы там были и объявления, и отзывы, и животные, и
   возможность оставить отзыв». */
.stars { color: var(--warning, #D98A16); letter-spacing: 1px; white-space: nowrap; }
.stars-on { color: var(--warning, #D98A16); }
.reviews, .seller-reviews { margin: 22px 0 0; }
.reviews-count {
  display: inline-block;
  min-width: 24px;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--container);
  color: var(--muted);
  font-size: .8rem;
  font-weight: 600;
  text-align: center;
}
.reviews-average, .seller-rating {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 8px 0 14px;
  font-size: .95rem;
}
.review-list { list-style: none; margin: 0; padding: 0; }
.review { padding: 12px 0; border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent); }
.review:last-child { border-bottom: 0; }
.review-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.review-author { font-weight: 600; }
.review-when { margin-left: auto; color: var(--muted); font-size: .82rem; }
.review-text { margin: 6px 0 0; }
/* Форма отзыва — как остальные формы кабинета. */
.review-form {
  margin: 16px 0 0;
  padding: 16px;
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow);
}
.review-form h3 { margin: 0 0 12px; font-size: 1.05rem; }
.review-form .field { margin-bottom: 12px; }
.review-form textarea { width: 100%; }
/* Поиск хозяев на рынке: карточки людей над объявлениями. */
.people { display: grid; gap: 10px; grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.person {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 12px;
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow);
  text-decoration: none;
  color: inherit;
}
.person:hover { border-color: var(--accent); }
.person-text { min-width: 0; }
.person-name { display: block; font-weight: 600; }
.person-note { display: block; color: var(--muted); font-size: .84rem; }

/* --- Раскрытые списки: своя стрелка и читаемые варианты -----------------------
   Заказчик 12.10: «можно чтобы раскрытые списки как-то покрасивее выглядели?».
   Сам раскрытый список рисует система — браузеры нарочно не дают оформить его
   целиком. Что доступно: убрать системную стрелку и нарисовать свою, задать
   цвет вариантов и подсветить выбранный. Это и делаем. */
select {
  appearance: none;
  -webkit-appearance: none;
  padding-right: 38px;          /* место под свою стрелку */
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%235A6675' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 12px center;
  background-size: 16px 16px;
  cursor: pointer;
}
/* Варианты списка: свои отступы, размер и цвета. Выбранный — в цвет сайта,
   вместо системного синего. */
select option {
  padding: 10px 12px;
  background: var(--surface);
  color: var(--ink);
  font-size: .95rem;
}
select option:checked {
  background: var(--primary);
  color: var(--on-primary);
  font-weight: 600;
}
/* На узком экране стрелка чуть меньше — поле уже. */
@media (max-width: 640px) {
  select { padding-right: 32px; background-position: right 10px center; }
}

/* --- Порода зависит от вида ---------------------------------------------------
   Заказчик 12.10: «добавь выбор породы в зависимости от вида животного».

   Сделано без JavaScript: виды — радиокнопки, а показ нужного поля породы —
   соседний селектор `:checked ~`. Радиокнопки и список полей лежат в одном
   контейнере, поэтому «сосед» находится. */
.breed-picker { grid-column: 1 / -1; }
.species-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 0 12px;
}
/* Сами радиокнопки прячем: их роль играет подпись-пилюля. */
.species-radio {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.species-chip {
  display: inline-flex;
  align-items: center;
  min-height: 36px;
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  font-size: .9rem;
  cursor: pointer;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.species-chip:hover { background: var(--accent-soft); border-color: var(--accent-soft); }
/* Выбранный вид: залит цветом сайта. */
.species-radio:checked + .species-chip {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--on-primary);
  font-weight: 600;
}
.species-radio:focus-visible + .species-chip {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
/* По умолчанию все поля породы скрыты... */
.breed-list .field-breed { display: none; }
/* ...а показывается то, чей вид выбран. Правило на каждый вид: иначе браузер
   не сопоставит радиокнопку с полем. */
.breed-list {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 12px;
}
.breed-list .field-breed { grid-column: span 3; }
.species-radio[value="COW"]:checked ~ .breed-list .breed-for-COW { display: block; }
.species-radio[value="GOAT"]:checked ~ .breed-list .breed-for-GOAT { display: block; }
.species-radio[value="SHEEP"]:checked ~ .breed-list .breed-for-SHEEP { display: block; }
.species-radio[value="HORSE"]:checked ~ .breed-list .breed-for-HORSE { display: block; }
.species-radio[value="PIG"]:checked ~ .breed-list .breed-for-PIG { display: block; }
.species-radio[value="CHICKEN"]:checked ~ .breed-list .breed-for-CHICKEN { display: block; }
.species-radio[value="RABBIT"]:checked ~ .breed-list .breed-for-RABBIT { display: block; }
.species-radio[value="CAT"]:checked ~ .breed-list .breed-for-CAT { display: block; }
.species-radio[value="DOG"]:checked ~ .breed-list .breed-for-DOG { display: block; }

/* --- Фильтры рынка: ровная сетка ---------------------------------------------
   Заказчик 12.10: «смотри как поплыл фильтр, поправь его, сделай современным и
   красивым». Причина была в трёхколоночной сетке: полей стало больше, и они
   вставали как придётся.

   Теперь сетка на **шесть колонок**, и у каждого поля свой размер. Строка при
   этом всегда ровная: поиск широкий, вид и город — по колонке, цена и возраст —
   по две (в них по два поля). */
.filters-main {
  display: grid;
  gap: 14px 12px;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  align-items: start;
}
.field-search { grid-column: span 2; }
.field-species { grid-column: span 2; }
.field-city { grid-column: span 2; }
/* 31.10: цена и оба возраста — по две колонки, одной строкой.
   Было по три: «Возраст до» уезжал на новую строку и половина
   строки оставалась пустой (дырка справа от полей). */
.field-price { grid-column: span 2; }
.field-age { grid-column: span 2; }
/* «Ещё фильтры» и кнопки — всегда во всю ширину строки, а не в узкой ячейке. */
.filters-extra { grid-column: 1 / -1; }
.filters-actions { grid-column: 1 / -1; }

/* Подпись поля: одна высота у всех, поэтому поля в строке выровнены. */
.filters .field-label {
  display: block;
  margin: 0 0 6px;
  color: var(--muted);
  font-size: .84rem;
  font-weight: 500;
  line-height: 1.2;
}
/* Само поле: одна высота и одна рамка у всех полей фильтра. */
.filters .field > input,
.filters .field > select {
  width: 100%;
  height: var(--field-h);
  padding: 0 12px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: .95rem;
}
.filters .field > input:focus-visible,
.filters .field > select:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}

/* --- Пара полей в одной рамке: «от — до», «число + лет/мес.» -----------------
   Рамку рисует контейнер, а ячейки внутри — без своих рамок. Так пара выглядит
   одним полем, как в современных фильтрах. */
.filters .input-pair {
  display: flex;
  align-items: center;
  height: var(--field-h);
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface);
  overflow: hidden;
}
.filters .input-pair:focus-within { outline: 2px solid var(--primary); outline-offset: 1px; }
.filters .pair-main {
  flex: 1 1 0;
  min-width: 0;
  height: 100%;
  padding: 0 12px;
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: .95rem;
}
.filters .pair-main:focus { outline: none; }
/* Разделитель между «от» и «до». */
.filters .pair-sep {
  flex: 0 0 auto;
  padding: 0 2px;
  color: var(--outline);
}

/* --- Переключатель единиц: «лет / мес.» пилюлей ------------------------------
   Выбранное залито цветом, невыбранное тихое. Видно, что это выбор, а не
   подпись. Работает на <input type=radio>, без JavaScript. */
.filters .segmented {
  display: flex;
  gap: 2px;
  flex: 0 0 auto;
  padding: 3px;
  margin-right: 4px;
  border-radius: 9px;
  background: var(--container);
}
.filters .segmented label { display: block; }
/* Сами переключатели прячем: их роль играет подпись. */
.filters .segmented input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}
.filters .segmented span {
  display: block;
  padding: 4px 10px;
  border-radius: 7px;
  color: var(--muted);
  font-size: .82rem;
  line-height: 1.3;
  cursor: pointer;
  transition: background .15s ease, color .15s ease;
}
.filters .segmented label:hover span { color: var(--ink); }
/* Выбранный: залит цветом. Селектор по состоянию — значит без скриптов. */
.filters .segmented input:checked + span {
  background: var(--primary);
  color: var(--on-primary);
  font-weight: 600;
}
.filters .segmented input:focus-visible + span { outline: 2px solid var(--primary); outline-offset: 1px; }

/* --- Кнопки фильтра: справа -------------------------------------------------- */
.filters-actions {
  display: flex;
  gap: 8px;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
}
.filters-actions .button { min-width: 120px; }

/* Планшет: три колонки. Поиск, вид и город — по одной, пары — во всю строку. */
@media (max-width: 1024px) {
  .filters-main { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .field-search, .field-species, .field-city { grid-column: span 1; }
  .field-search { grid-column: 1 / -1; }
  .field-price, .field-age { grid-column: span 3; }
}
/* Телефон: одна колонка, всё друг под другом. */
@media (max-width: 640px) {
  .filters-main { grid-template-columns: 1fr; }
  .field-search, .field-species, .field-city,
  .field-price, .field-age { grid-column: 1 / -1; }
  .filters-actions { justify-content: stretch; }
  .filters-actions .button { flex: 1 1 auto; }
}
/* Прежние правила `.range` и `.age-field`/`.age-units` убраны: поля теперь собраны
   в пару `.input-pair`, а переключатель единиц — в `.segmented`. Оставленные,
   они задавали бы старый вид и спорили с новым. */
.filters-extra { margin-top: 10px; }
.filters-extra > summary { list-style: none; cursor: pointer; display: inline-block; }
.filters-extra > summary::-webkit-details-marker { display: none; }
.filters-extra-body {
  display: grid; gap: 12px; margin-top: 10px; padding: 14px;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
}
.active-filters { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 0 0 14px; }
.chip-active { background: var(--primary-container); color: var(--on-primary-container); }
.reset-all { margin-left: auto; font-size: .9rem; }
.found { margin: 0 0 14px; color: var(--on-surface-variant); }

/* --- Кабинет и «Мои животные» (этап 5) --- */
.page-head {
  display: flex; flex-wrap: wrap; gap: 12px 20px; align-items: flex-start;
  justify-content: space-between; margin: 0 0 16px;
}
.page-head h1 { margin: 0 0 4px; }
.page-head .muted { margin: 0; max-width: 60ch; }

.toolbar {
  display: flex; flex-wrap: wrap; gap: 10px; align-items: end;
  margin: 0 0 10px;
}
.toolbar .field { margin: 0; }
.toolbar .field-search { flex: 1 1 240px; }
.toolbar select { height: 44px; }
.toolbar .button { height: 44px; }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.counters-links { gap: 12px; }
.counters-links > div { padding: 0; }
.counters-links a {
  display: flex; flex-direction: column; gap: 2px; height: 100%;
  padding: 14px 16px; text-decoration: none;
}
.counters-links a:hover { text-decoration: none; background: var(--container-high); }
.counters-links dt { font-size: .87rem; color: var(--muted); }
.counters-links dd { margin: 0; font-size: 1.6rem; font-weight: 700; }
.counter-hint { font-size: .87rem; color: var(--accent-dark); }

.cab-chips { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 0 0 16px; }
.cab-chips .chip { text-decoration: none; }

.checklist {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--shadow); padding: 16px 18px; margin: 0 0 22px;
}
.checklist h2 { margin: 0 0 10px; font-size: 1.15rem; }
.checklist ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.checklist li {
  display: grid; grid-template-columns: 24px 1fr auto; gap: 10px; align-items: center;
  border-top: 1px solid var(--line); padding-top: 10px;
}
.checklist li:first-child { border-top: 0; padding-top: 0; }
.check-box { color: var(--accent-dark); font-size: 1.1rem; }
/* Только внутри чеклиста: там под каждой строкой идут заголовок и пояснение.
   Без родителя это правило задевало подпись согласия в форме «Жду звонка» —
   она становилась колонкой из одной буквы (заказчик, 12.10).

   Ступень селектора (`>`) обязательна: подпись может оказаться внутри строки
   чеклиста, и тогда прежнее правило снова сделало бы её колонкой. */
.checklist > ul > li > .check-text,
.checklist > .check-text { display: flex; flex-direction: column; gap: 2px; }
@media (max-width: 760px) {
  .checklist li { grid-template-columns: 24px 1fr; }
  .checklist li .button { grid-column: 2; justify-self: start; }
}

.legend { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 16px 0 0; font-size: .9rem; }
.legend .muted { flex: 1 1 260px; }
.pet-card { min-width: 240px; }

/* --- Профиль и карточки животных (этап 5) --- */
.avatar-preview { margin: 0 0 12px; }
/* Круглая иконка профиля (этап D ночной смены): раньше были заданы только
   border-radius и object-fit, а ширины с высотой не было — картинка растягивалась
   по ширине родителя и вместо круга получался овал. Задаём квадрат явно. */
.avatar-preview .photo {
  width: 160px;
  height: 160px;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  object-fit: cover;
}
/* Узкий телефон: 160 px не помещается рядом с формой загрузки. */
@media (max-width: 420px) {
  .avatar-preview .photo,
  .farm-avatar .photo:not(.photo-empty) { width: 128px; height: 128px; }
}
input[type="file"]::file-selector-button {
  margin-right: 10px; padding: 9px 14px; border: 1px solid var(--line);
  border-radius: 12px; background: var(--surface); color: var(--ink);
  font: inherit; cursor: pointer;
}
input[type="file"] { height: auto; padding: 6px 4px; border: 1px solid var(--line); border-radius: 12px; width: 100%; }

/* --- Пошаговые правила («Как продать», «Безопасная сделка») ---
   Раньше у этих классов не было оформления вовсе, и номер слипался с заголовком:
   на странице читалось «1Заполните профиль». Теперь номер — отдельная колонка. */
.rules { display: grid; gap: var(--gap-m); margin: var(--gap-m) 0; padding: 0; list-style: none; }
.rule {
  display: grid;
  grid-template-columns: 32px minmax(0, 1fr);
  gap: var(--gap-s);
  align-items: start;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 14px 16px;
  box-shadow: var(--shadow);
}
.rule-num {
  display: flex; align-items: center; justify-content: center;
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--accent-soft); color: var(--accent-dark);
  font-weight: 700; font-size: .95rem;
}
/* Сетка шага: слева номер, справа заголовок и текст. Номер — на две строки,
   чтобы заголовок и описание начинались на одной вертикали. */
.rule > .rule-num { grid-row: 1 / span 2; }
.rule > h2, .rule > h3 { margin: 0 0 4px; font-size: 1.05rem; }
.rule p { margin: 0; color: var(--muted); }
@media (max-width: 420px) {
  .rule { grid-template-columns: 28px minmax(0, 1fr); padding: 12px; }
  .rule-num { width: 28px; height: 28px; font-size: .9rem; }
}
@media (max-width: 760px) {
  .pet-card { min-width: 0; }
}

/* --- Шапка: поиск -----------------------------------------------------------
   Оформление задано ДЛЯ ВСЕХ ширин. Раньше часть правил жила только в
   `@media (min-width: 1120px)`, часть — только в `(max-width: 760px)`, и в полосе
   761–1119 px у поиска не было вида: показывалась пустая пилюля, а значок рисовался
   размером по умолчанию (300×150) и рвал шапку.

   Устройство: база — «свёрнуто» (лупа-кнопка), с 1120 px — «развёрнуто» (поле). */
.header-search { position: relative; }

.header-search-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--control-h);
  height: var(--control-h);
  padding: 0;
  list-style: none;
  cursor: pointer;
  border: 1px solid var(--outline-variant);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
}
.header-search-toggle::-webkit-details-marker { display: none; }
.header-search-toggle:hover { background: var(--accent-soft); }
.header-search-toggle:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
/* Размер значка ЯВНО. Без него SVG рисуется 300×150 и рвёт шапку. */
.header-search-toggle svg { width: 20px; height: 20px; display: block; }

.header-search-form { display: flex; align-items: center; width: 100%; position: relative; }
/* Свёрнуто: поле прячем, пока не нажали лупу. */
.header-search:not([open]) > .header-search-form { display: none; }
/* Раскрыто на узком экране — панель поверх содержимого, не сдвигая шапку. */
.header-search[open] > .header-search-form {
  position: absolute;
  right: 0;
  top: calc(100% + 8px);
  z-index: 30;
  width: min(360px, calc(100vw - 24px));
  padding: 10px;
  border: 1px solid var(--outline-variant);
  border-radius: 18px;
  background: var(--surface);
  box-shadow: var(--shadow);
}

.header-search-form input {
  width: 100%;
  height: var(--control-h);
  min-width: 0;
  padding: 0 100px 0 16px;
  border: 1px solid var(--line);
  border-radius: 999px;
  /* Светло-серое поле на белой шапке: с белым фоном и светлой рамкой поиск было
     почти не видно на снимках (31.10). Так поле читается сразу, как у Авито. */
  background: var(--bg);
  color: var(--ink);
  font-size: .95rem;
}
.header-search-form input:hover { border-color: var(--outline); }
.header-search-form input::placeholder { color: var(--muted); }
.header-search-form input:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

.header-search-go {
  /* Кнопка «Найти» справа в поле: ТЗ заказчика 30.10 — строка поиска объединяет
     ввод и кнопку. */
  position: absolute;
  right: 4px;
  top: 50%;
  transform: translateY(-50%);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: calc(var(--control-h) - 8px);
  padding: 0 14px;
  border: 0;
  border-radius: 999px;
  background: var(--primary);
  color: var(--on-primary);
  font: inherit;
  font-size: .92rem;
  font-weight: 600;
  cursor: pointer;
}
.header-search-go:hover { background: var(--accent-dark); }
.header-search-go:focus-visible { outline: 2px solid var(--accent-dark); outline-offset: 2px; }
.header-search-go svg { width: 16px; height: 16px; display: block; }

@media (max-width: 1119px) {
  /* Свёрнуто: шапка в одну строку, поле — по нажатию лупы. */
  .header-search { flex: 0 0 auto; }
}
@media (min-width: 1120px) {
  /* Развёрнуто: лупа не нужна, поле видно всегда и занимает остаток места. */
  .header-search { flex: 1 1 320px; max-width: 720px; min-width: 200px; }
  .header-search > summary { display: none; }
  .header-search:not([open]) > .header-search-form,
  .header-search[open] > .header-search-form {
    display: flex;
    position: relative;
    top: auto;
    right: auto;
    width: 100%;
    padding: 0;
    border: 0;
    background: none;
    box-shadow: none;
  }
  .header-inner { flex-wrap: nowrap; }
}
/* Узкий ноутбук и планшет в альбомной ориентации: подпись убираем, чтобы шапка
   осталась в одну строку — она повторяет название и на маленьком экране лишняя. */
.footer-grid {
  display: grid; gap: 18px 24px;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  padding-top: 22px; padding-bottom: 8px;
}
.footer-grid h2 { margin: 0 0 8px; font-size: .95rem; color: var(--ink); }
.footer-grid ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.footer-grid a { color: var(--muted); font-size: .92rem; }
.footer-grid a:hover { color: var(--ink); }
.footer-note { margin: 0 0 18px; }

/* --- Логотип клуба (знак «тёплый дом») --- */
.auth-logo { width: 72px; height: auto; margin: 0 0 10px; }

/* --- Кабинет: адаптив панели управления ---
   Компьютер (от 1025 px): две колонки, панель справа, прилипает.
   Планшет и телефон (до 1024 px): одна колонка, панель сверху.
   Телефон (до 760 px): пункты — прокручиваемая строка, как в мобильном плане. */
@media (max-width: 1024px) {
  .cab-side {
    position: static;
    order: -1;              /* меню — над содержимым, как было до переноса */
    max-height: none;
    overflow: visible;
  }
}
@media (max-width: 760px) {
  .cab-nav {
    flex-direction: row;
    flex-wrap: nowrap;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    border-radius: 999px;
    scrollbar-width: none;
  }
  .cab-nav::-webkit-scrollbar { display: none; }
  .cab-link { flex: 0 0 auto; scroll-snap-align: start; }
}
@media (max-width: 420px) {
  .cab-link { padding: 0 10px; font-size: .9rem; }
  .cab-form { padding: 14px; }
  .field-grid { grid-template-columns: 1fr; }
}

/* Печать: меню кабинета в бумаге не нужно. */
@media print {
  .cab-side, .site-header, .mobile-bar { display: none; }
  .cab-layout { display: block; }
}

/* --- Колонка-спутник страницы -------------------------------------------------
   Заказчик 12.10: «перемести все меня с правой части на левую» и
   «стандартизируй меню везде одинаково». Поэтому здесь одна раскладка на весь
   сайт (её описание — выше, у `.site-layout`): содержимое первым в разметке,
   колонка с меню слева, ширина колонки одна и та же — `var(--side-w)`.
   Панель — только ссылки и подсказки; формы и кнопки действий остаются
   в содержимом. */
.site-main { min-width: 0; overflow-wrap: break-word; }

/* Мера строки: при узкой колонке абзацы становятся длиннее 75 знаков и читаются
   хуже. Ограничиваем только текстовые блоки — карточки, сетки и формы не трогаем. */
@media (min-width: 1160px) {
  .site-main > p, .site-main > ul, .site-main > ol, .site-main > h1, .site-main > h2 { max-width: 68ch; }
  .site-main > .lead { max-width: 62ch; }
}

/* Первый блок содержимого не добавляет отступ сверху: за отступ под шапкой
   отвечает только main. Без этого крошки, заголовок, `.page-head` и `.hero`
   давали разную высоту — заказчик это и заметил. */
.site-main > :first-child, .cab-main > :first-child { margin-top: 0; }
.site-main > :first-child > :first-child,
.cab-main > :first-child > :first-child { margin-top: 0; }

.site-side { min-width: 0; }

/* Прилипает только при двух колонках: в одноколоночной раскладке липкая панель
   занимала бы экран под содержимым. Полосу прокрутки скрываем (просьба заказчика
   от 11.10: «сделай как во ВКонтакте»): сама прокрутка остаётся — колесом,
   пальцем и клавиатурой, а уродливой полосы не видно. Так же сделано у ряда
   видов и меню кабинета. */
@media (min-width: 1160px) {
  .site-side {
    position: sticky;
    top: 88px;                       /* высота шапки 72 px + зазор 16 px */
    align-self: flex-start;
    max-height: calc(100vh - 104px);
    overflow-y: auto;
    scrollbar-width: none;           /* Firefox */
    -ms-overflow-style: none;        /* старый Edge */
  }
  .site-side::-webkit-scrollbar { display: none; }   /* Chrome, Safari */
}

/* Сама панель: карточки-блоки, как в кабинете. */
.site-side-block {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 14px 16px;
  margin: 0 0 var(--gap-m);
}
.site-side-block > h2 {
  margin: 0 0 8px;
  font-size: .85rem;
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--muted);
}
.site-side-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }

/* --- Пункт меню: значок слева, стрелка перехода справа -----------------------
   Образец заказчика (12.10): у каждой подписи слева иконка, у правого края —
   стрелка «›». Значок и стрелка нарисованы контуром и берут цвет из
   `currentColor`, поэтому подсвечиваются вместе с пунктом. */
.site-side-list a > .site-side-icon {
  flex: 0 0 auto;
  color: var(--muted);
  transition: color .15s ease;
}
.site-side-text {
  flex: 1 1 auto;
  min-width: 0;                 /* длинная подпись переносится, а не растягивает меню */
  margin-left: 10px;
}
.site-side-arrow {
  flex: 0 0 auto;
  color: var(--outline);        /* стрелка тише подписи: она подсказка, не текст */
  transition: color .15s ease, transform .15s ease;
}
/* Пункт под курсором или в фокусе: значок и стрелка становятся заметнее,
   стрелка чуть сдвигается вправо — видно, что это переход. */
.site-side-list a:hover > .site-side-icon,
.site-side-list a:focus-visible > .site-side-icon,
.site-side-list a.is-current > .site-side-icon { color: var(--primary); }
.site-side-list a:hover > .site-side-arrow,
.site-side-list a:focus-visible > .site-side-arrow { color: var(--primary); transform: translateX(2px); }
.site-side-list a.is-current > .site-side-arrow { color: var(--primary); }

/* Число объявлений в «Видах животных» стоит перед стрелкой. */
.site-side-list .site-side-count { margin-left: auto; }
.site-side-list a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: var(--tap-h);
  padding: 0 8px;
  border-radius: 10px;
  color: var(--ink);
  font-size: .95rem;
}
.site-side-list a:hover { background: var(--accent-soft); text-decoration: none; }
.site-side-list a:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
/* Текущая страница в меню: видно, где находишься. Полоса слева — тот же приём,
   что у пунктов меню кабинета, чтобы вид был один на весь сайт. */
.site-side-list a.is-current {
  background: var(--accent-soft);
  color: var(--primary);
  font-weight: 600;
  box-shadow: inset 3px 0 0 var(--primary);
}
.site-side-count { color: var(--muted); font-size: .87rem; }
.site-side-note { margin: 0; color: var(--muted); font-size: .87rem; }
.site-side-actions { display: grid; gap: 8px; }

/* Печать: колонки в бумаге не нужно. */
@media print {
  .site-side { display: none; }
  /* По умолчанию одна колонка: правила каталога и карточек ниже не ломаются. */
.site-layout { display: grid; grid-template-columns: minmax(0, 1fr); gap: var(--gap-m); }
}

/* --- Меню сайта: блок «Главное» в правой колонке ---
   Меню одно на сайт и живёт блоком «Главное» (собирает ``site_aside``).
   Отдельной панели «Меню» больше нет: она дублировала эти же ссылки, а на
   телефоне перекрывала карточку хозяина — пропадала кнопка «Выйти». */
.site-nav { margin: 0 0 var(--gap-m); }

/* Шапка без меню: знак слева, поиск занимает свободное место. */
.site-header .header-inner { flex-wrap: nowrap; }
.site-header .header-search { flex: 1 1 auto; max-width: 520px; margin-left: auto; }

/* Ссылка «Обновить» в подвале: просит страницу заново, мимо кеша браузера.
   Нужна после выкладки, когда в кеше осталась старая разметка. */
.footer-fresh {
  margin-left: 6px;
  color: var(--on-primary);
  text-decoration: underline;
  text-underline-offset: 2px;
  white-space: nowrap;
}
.footer-fresh:hover { text-decoration: none; }
.footer-fresh:focus-visible { outline: 2px solid var(--on-primary); outline-offset: 2px; }

/* --- Карточка хозяина: крупная круглая иконка и имя наверху панели ---
   Просьба заказчика от 11.10: имя профиля — в самый верх, иконка крупная и круглая.
   Фотографии нет — показываем буквы имени: серая заглушка выглядит как ошибка. */
/* --- Флажки согласия и чекбоксы: маленькие и аккуратные ----------------------
   Заказчик 12.10: «галочка должна быть компактной, и текст не большой» и
   «сделай галочки маленькими и аккуратными».

   Без явных размеров браузер рисует флажок по размеру шрифта: в широкой ячейке
   он выглядел огромным квадратом. Задаём размер и `accent-color` — тогда флажок
   аккуратный и в цвет сайта. */
.check-row input[type="checkbox"],
.checkbox input[type="checkbox"],
.filters input[type="checkbox"] {
  flex: 0 0 auto;
  width: 16px;
  height: 16px;
  margin: 2px 0 0;
  accent-color: var(--primary);
  cursor: pointer;
}
/* Подпись согласия: помельче и в две строки, а не в четыре. */
.check-row {
  gap: 8px;
  font-size: .84rem;
  line-height: 1.4;
  align-items: flex-start;
}
/* `flex` здесь НЕ задаём: правило защиты подписи (`.check-row > .check-text`)
   ставит `flex: none`, иначе подпись снова можно сжать в колонку из букв. */
/* Текст согласия — обычным начертанием и без раздутого междустрочия. */
.check-row .check-text,
.check-row .check-text a { font-size: .84rem; }

/* Флажки в «Ещё фильтры» стоят в строку с подписью и не растягиваются. */
.filters .check-row { margin: 0; }

/* --- Действия в карточке профиля: одна высота у кнопки и двери ----------------
   Заказчик 12.10: «кнопки по высоте должны быть одни». */
.user-actions { align-items: stretch; }
.user-actions .user-cabinet,
.user-actions .user-logout,
.user-actions .user-exit {
  min-height: var(--tap-h);
  height: var(--tap-h);
}
.user-actions .user-logout { display: flex; }
.user-actions .user-exit { width: var(--tap-h); }

/* --- Карточка хозяина: аватар слева, ФИО и действия справа -------------------
   Макет заказчика от 12.10: круглая аватарка слева, рядом столбиком имя и
   подпись места, ниже кнопка «Редактировать профиль» и иконка двери (выход).
   Карточка одна на весь сайт и на все вкладки кабинета. */
.user-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  box-shadow: var(--shadow);
  padding: 16px;
  margin: 0 0 var(--gap-m);
}
.user-card-top {
  display: flex;
  align-items: center;
  gap: 14px;
  /* Отступ до того, что идёт ниже: имя + подпись места. Без него полоса отзывов
     прилипала к аватарке (заказчик, 13.10). Величина та же, что у отступа полосы
     до кнопки, — промежутки карточки одинаковые. */
  margin: 0 0 12px;
}
.user-avatar {
  flex: 0 0 auto;
  width: var(--user-avatar, 80px);
  height: var(--user-avatar, 80px);
  border-radius: 50%;
  overflow: hidden;
  display: grid;
  place-items: center;
  background: var(--accent-soft);
  color: var(--accent-dark);
  font-weight: 700;
  font-size: calc(var(--user-avatar, 80px) / 3);
  text-decoration: none;
}
.user-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.user-initials { line-height: 1; }
.user-text {
  min-width: 0;                 /* длинное имя переносится, а не растягивает карточку */
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.user-name {
  font-weight: 700;
  font-size: 1.05rem;
  color: var(--ink);
  text-decoration: none;
  overflow-wrap: break-word;
}
.user-name:hover { text-decoration: underline; text-underline-offset: 2px; }
.user-place { color: var(--muted); font-size: .9rem; overflow-wrap: break-word; }

/* Кнопка профиля и выход в одной строке: кнопка тянется, дверь стоит рядом. */
.user-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 14px 0 0;
}
.user-actions .user-cabinet { flex: 1 1 auto; margin: 0; min-height: var(--tap-h); }
.user-logout { display: flex; margin: 0; flex: 0 0 auto; }
/* Дверь — выход. Цвет берётся из currentColor, поэтому меняется при наведении
   без картинок и без скриптов. */
.user-exit {
  display: grid;
  place-items: center;
  width: var(--tap-h);
  height: var(--tap-h);
  padding: 0;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface);
  color: var(--muted);
  cursor: pointer;
  transition: color .15s ease, background .15s ease, border-color .15s ease;
}
.user-exit .icon-door { display: block; }
.user-exit:hover {
  color: var(--accent-dark);
  background: var(--accent-soft);
  border-color: var(--accent-soft);
}
.user-exit:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* --- Завалинка: лента клуба (чтение) ---
   Карточка публикации: шапка с автором, текст, галерея, счётчики.
   Свои правила, а не «card»: у публикации нет цены и заголовка-ссылки,
   зато есть текст в несколько абзацев и фотографии до пяти штук. */
.feed { display: grid; gap: var(--gap-m); max-width: var(--wrap); }

/* --- Бесконечная лента «Завалинки» (заказчик, 12.10) -------------------------
   Публикации лежат в разметке сразу пачкой, а браузер рисует только те, что
   рядом с экраном: `content-visibility: auto`. Человек листает — следующие
   публикации уже готовы, без запроса и ожидания. Скриптов не нужно.

   `contain-intrinsic-size` — предполагаемая высота неотрисованной карточки.
   Без неё полоса прокрутки дёргалась бы: браузер не знает, сколько места
   займёт публикация. Берём среднюю высоту карточки с фотографией и текстом. */
.feed > .post,
.feed > .post-card {
  content-visibility: auto;
  contain-intrinsic-size: auto 520px;
}

/* Подпись под лентой: сколько публикаций уже готово. Видно, что лента не
   кончилась и следующие записи появятся при прокрутке (заказчик, 12.10). */
.feed-note { margin: 12px 0 0; color: var(--muted); font-size: .87rem; }

/* Публикация, ставшая видимой, не должна «прыгать»: анимация появления мягкая
   и отключается для тех, кто просил меньше движения. */
@media (prefers-reduced-motion: no-preference) {
  .feed > .post { animation: feed-appear .28s ease-out both; }
  @keyframes feed-appear {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: none; }
  }
}
@media (prefers-reduced-motion: reduce) {
  .feed > .post { animation: none; }
}
.post {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  padding: 14px 16px 12px;
  /* `anywhere`, а не `break-word`: `break-word` переносит длинное слово, только если
     оно уже не помещается, и длинная ссылка или строка без пробелов всё равно распирала
     карточку шире экрана (заказчик, 15.10: «лента шире, хотя меню по ширине»).
     `anywhere` разрешает разрыв в любом месте И учитывает его при расчёте ширины.
     `break-word` оставлен рядом как запасной вариант для старых браузеров. */
  overflow-wrap: break-word;
  overflow-wrap: anywhere;
}
.post-head { display: flex; align-items: center; gap: 10px; }
.post-avatar {
  flex: 0 0 auto;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  overflow: hidden;
  display: grid;
  place-items: center;
  background: var(--accent-soft);
  color: var(--primary);
  font-weight: 700;
  text-decoration: none;
}
.post-avatar-img { width: 100%; height: 100%; object-fit: cover; display: block; }
.post-initials { font-size: 1.05rem; }
.post-who { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.post-author { font-weight: 600; color: var(--ink); text-decoration: none; }
.post-author:hover { text-decoration: underline; text-underline-offset: 2px; }
.post-when { color: var(--muted); font-size: .87rem; }
.post-text {
  margin: 10px 0 0;
  /* Текст публикации — самое вероятное место длинной неразрывной строки. */
  overflow-wrap: break-word;
  overflow-wrap: anywhere;
}
/* Текст пишут абзацами: переносы строк — часть смысла, поэтому .pre как у объявлений. */
.post-pet { margin: 10px 0 0; color: var(--muted); font-size: .9rem; }
.post-stats {
  margin: 10px 0 0;
  padding-top: 8px;
  border-top: 1px solid var(--line);
  display: flex;
  gap: 14px;
  color: var(--muted);
  font-size: .9rem;
  /* Действия слева, просмотры справа. */
  justify-content: space-between;
}
.post .gallery { margin: 12px 0 0; }
/* Фотографии публикации: как в галерее объявления, но без «миниатюр-полосы»
   на широком экране — в ленте важнее сам снимок. */
.post .shot-count { font-size: .8rem; }
@media (max-width: 600px) {
  .post { padding: 12px 12px 10px; }
  .post-head { gap: 8px; }
  .post-avatar { width: 40px; height: 40px; }
  /* Промежутки счётчиков здесь НЕ переопределяем: раньше тут стояло `gap: 10px`,
     и на телефоне пары сливались — «♥ 3◯ 1◉ 3» (заказчик, 13.10). Места
     достаточно: три пары «значок + цифра» занимают около 250 px. */
}

/* --- Счётчики публикации: значок и число --------------------------------------
   Значки — из набора приложения (контур, цвет из `currentColor`), а не эмодзи:
   эмодзи рисует системный шрифт, и на Windows, Android и macOS они выглядят
   по-разному (заказчик, 12.10). */
.post-stat {
  display: inline-flex;
  align-items: center;
  /* Промежуток значок↔число. 3 px: цифра должна «принадлежать» своему значку,
     а не висеть между парами (заказчик, 13.10: «уменьшить расстояние между
     значком и цифрой»). При 7 px на узком экране цифра читалась как отдельный
     элемент. Промежуток одинаковый у всех трёх счётчиков. */
  gap: 3px;
  min-height: 24px;
}
.post-stat .stat-icon { flex: 0 0 auto; }
.post-stat-num { font-variant-numeric: tabular-nums;
  /* Числа одной ширины: «3» и «12» не должны сдвигать ряд. */
  min-width: 9px;
  text-align: center;
}
/* Числа одной ширины: «3» и «12» не должны сдвигать значки по-разному.
   `tabular-nums` выравнивает цифры между собой, `min-width` — сами числа. */
/* Лайк: сердце заливается, когда лайк поставлен. */
.post-stat-liked { color: var(--error); }
.post-stat-liked .stat-icon { fill: currentColor; }
/* Кнопка лайка: та же строка, что счётчики, но нажимается.
   Поля по бокам НЕТ нарочно. С `padding: 0 6px` видимый зазор после лайка был
   6 + 18 = 24 px, а после комментариев — 18 px: ряд выглядел неровным, и значок
   глаза казался сдвинутым не туда (заказчик, 13.10). Теперь все зазоры считает
   только `gap`: 7 px внутри пары и 18 px между счётчиками. */
.post-stat-button {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  min-height: 32px;
  padding: 0 6px;
  margin: 0;
  border: 0;
  border-radius: 10px;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.post-stat-button:hover { background: var(--accent-soft); }
.post-stat-button:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* --- Комментарии под публикацией: компактно, как в макете заказчика ----------
   Заказчик 12.10: «окно комментариев получилось массивным». Поэтому:
   • никаких цветных полос слева и заголовка «Комментарии: N»;
   • один бабл: иконка автора 32 px слева, справа бабл с именем, временем и текстом;
   • строка ввода: иконка смотрящего и поле со стрелкой отправки внутри;
   • поле при фокусе светлеет и получает мягкую обводку. */
/* Блок комментариев: без фона и рамки — только строки и тонкие разделители. */
.post-comments { margin: 12px 0 0; padding: 0; border: 0; }
.comment-list { list-style: none; margin: 0; padding: 0; }
.comment {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 0;
  padding: 10px 0;
  /* Разделитель — очень тонкая, еле заметная линия. Отступы строк дают воздух,
     поэтому линия читается как разделитель, а не как рамка. */
  border-bottom: 1px solid color-mix(in srgb, var(--line) 55%, transparent);
}
.comment:first-child { padding-top: 0; }
.comment:last-child { border-bottom: 0; padding-bottom: 0; }
.comment-avatar {
  flex: 0 0 auto;
  width: var(--avatar, 32px);
  height: var(--avatar, 32px);
  border-radius: 50%;
  overflow: hidden;
  display: grid;
  place-items: center;
  background: var(--surface-variant);
  color: var(--on-surface-variant);
  font-size: 12px;
  font-weight: 600;
}
.comment-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Подложки нет: комментарий прозрачный, его отделяет только линия выше.
   Раньше здесь был фон и рамка — заказчик просил убрать (12.10). */
.comment-bubble {
  flex: 1 1 auto;
  min-width: 0;
  background: none;
  border: 0;
  padding: 0;
  /* Ответ человека тоже может быть одной длинной строкой без пробелов. */
  overflow-wrap: break-word;
  overflow-wrap: anywhere;
}
.comment-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  margin: 0 0 2px;
}
.comment-who { font-weight: 600; font-size: .82rem; color: var(--ink); }
.comment-when { font-size: .7rem; color: var(--muted); white-space: nowrap; }
.comment-text { display: block; font-size: .85rem; color: var(--ink); }

/* Строка ввода: иконка смотрящего и поле со стрелкой внутри. */
.post-comment-form { margin: 12px 0 0; }
.comment-form { display: flex; align-items: center; gap: 10px; }
.comment-input-wrap { position: relative; flex: 1 1 auto; min-width: 0; display: flex; }
/* Гостю вместо поля — приглашение войти: комментарий подписывается
   именем хозяина, подписывать гостя нечем. */
.comment-login { margin: 0; color: var(--muted); font-size: .88rem; }
.comment-login a { color: var(--accent-dark); }
.comment-input {
  width: 100%;
  height: var(--tap-h);
  padding: 0 44px 0 14px;
  border: 1px solid transparent;
  border-radius: 20px;
  background: var(--container);
  color: var(--ink);
  font: inherit;
  font-size: .88rem;
  transition: background .2s ease, border-color .2s ease, box-shadow .2s ease;
}
.comment-input::placeholder { color: var(--muted); }
.comment-input:focus {
  background: var(--surface);
  border-color: var(--outline);
  box-shadow: 0 0 0 3px var(--container-high);
  outline: none;
}
.comment-send {
  position: absolute;
  right: 6px;
  top: 50%;
  transform: translateY(-50%);
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: var(--primary);
  cursor: pointer;
  display: grid;
  place-items: center;
  transition: background .15s ease, transform .15s ease;
}
.comment-send:hover { background: var(--primary-container); }
.comment-send:active { transform: translateY(-50%) scale(.94); }
.comment-send:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* Кнопка «Показать ещё» — тихой строкой, а не крупной пилюлей: блок должен
   оставаться компактным. */
.comments-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 6px 12px;
  /* Высота под палец: кнопка должна быть не меньше 44 px. */
  min-height: var(--tap-h);
  border: 0;
  border-radius: 10px;
  background: none;
  color: var(--accent-dark);
  font: inherit;
  font-size: .84rem;
  cursor: pointer;
  /* Служебный треугольник у <summary> убираем: он ломает вид кнопки. */
  list-style: none;
}
.comments-toggle::-webkit-details-marker { display: none; }
.comments-toggle::marker { content: ""; }
.comments-toggle:hover { background: var(--accent-soft); }
.comments-toggle:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
/* Кнопка «еще ↓» / «свернуть ↑» — справа. Родитель раскладывает её к правому
   краю; при раскрытии она становится последним элементом <details>, то есть
   опускается в самый низ блока (заказчик, 12.10). */
/* Кнопка «еще …» / «свернуть» — в самом низу блока, у правого края.
   Раньше здесь был `align-items: flex-end` на общем контейнере, и он прижимал
   вправо **все** дочерние элементы — из-за этого второй комментарий уезжал
   вправо (заказчик, 12.10). Теперь вправо прижата только кнопка. */
.comments-more { margin: 6px 0 0; }
.comments-more > .comment-list { margin: 0; width: 100%; }
.comments-more > .comments-toggle {
  display: flex;
  justify-content: flex-end;
  width: 100%;
  margin: 4px 0 0;
}
/* Стрелка внутри надписи — та же, что в меню (шеврон, смотрит вправо).
   Задаём ОБА состояния явно, иначе в свёрнутом виде остаётся исходный шеврон:
     свёрнуто  → вправо (90°)   — «развернётся ниже»
     раскрыто  → вверх  (-90°)  — «свернётся наверх»
   Заказчик 13.10: «сделай стрелочки на права, а вверх и вниз», затем: «у кнопки
   свернуть стрелочка должна быть вверх». */
.comments-toggle .site-side-arrow {
  margin-left: 4px;
  transition: transform .2s ease;
  transform: rotate(90deg);
  /* Значок и текст — на одном уровне. Без этого квадрат 16 px выравнивался по
     базовой линии текста и поднимался над строчными буквами (заказчик, 13.10).
     `transform-origin` в середине: иначе поворот уводит значок в сторону. */
  vertical-align: middle;
  transform-origin: center;
}
/* Подпись кнопки: значок и текст по центру строки. `display` у подписей НЕ
   трогаем: у скрытой надписи он должен остаться `none`, иначе «свернуть» будет
   видно в свёрнутом виде. Достаточно выравнивания в самом `summary` — он уже
   `inline-flex`. */
.comments-toggle { line-height: 1.2; }
.comments-toggle .comments-open,
.comments-toggle .comments-close { align-items: center; }
/* Раскрыто — стрелка ВВЕРХ, у ОБЕИХ надписей.
   В кнопке две надписи, и стрелка есть в каждой: при раскрытии `.comments-open`
   скрывается, показывается `.comments-close`. Раньше правило стояло только у
   `.comments-open`, то есть у СКРЫТОЙ надписи, — и видимая стрелка оставалась
   вправо (заказчик, 13.10: «когда надпись "свернуть", стрелочка должна быть
   вверх»). Задаём поворот обеим: тогда всё равно, какую из них покажет разметка. */
.comments-more[open] .comments-open .site-side-arrow,
.comments-more[open] .comments-close .site-side-arrow { transform: rotate(-90deg); }
/* Надпись на кнопке меняется при раскрытии: свёрнуто — «Показать ещё N»,
   раскрыто — «Свернуть комментарии». Работает без JavaScript: обе надписи лежат
   в разметке, а какую видно — решает состояние <details>. */
.comments-close { display: none; }
.comments-more[open] .comments-open { display: none; }
.comments-more[open] .comments-close { display: inline; }

/* Форма лайка стоит в строке счётчиков и не добавляет отступов. */
.post-like { display: inline-flex; margin: 0; }
/* Пока запрос идёт, кнопка чуть приглушена: видно, что нажатие принято. */
.post-like-busy .post-stat-button { opacity: .6; }

/* --- Избранное: сердце-кнопка ------------------------------------------------
   Заказчик 12.10: «просто сердечко должно становиться заполненным и все».
   Кнопка-значок вместо широкой надписи; при сохранении сердце залито. */
.fav-button {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: var(--tap-h);
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: .95rem;
  cursor: pointer;
  transition: color .15s ease, background .15s ease, border-color .15s ease;
}
.fav-button:hover { background: var(--accent-soft); border-color: var(--accent-soft); }
.fav-button:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
/* Сохранено: сердце залито, подпись меняется. */
.fav-button.fav-on { color: var(--error); border-color: var(--error-container); background: var(--error-container); }
.fav-button.fav-on svg { fill: currentColor; }
.fav-form { display: inline-flex; margin: 0; }
.fav-form.action-busy .fav-button { opacity: .6; }

/* --- Полоса отзывов в карточке профиля ----------------------------------------
   Заказчик 13.10: «между аватаркой и "редактировать" блок отзывов, как на
   андроид». Компактная строка: звёзды и «4.7 · 3 отзыва». Ведёт в раздел отзывов. */
.user-reviews {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 32px;
  padding: 4px 10px;
  margin: 0 0 12px;
  border-radius: 10px;
  background: var(--container);
  color: var(--ink);
  text-decoration: none;
  font-size: .85rem;
}
.user-reviews:hover { background: var(--accent-soft); }
.user-reviews:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.user-reviews-stars { font-size: .9rem; }
.user-reviews-text { color: var(--muted); }

/* --- Лента хозяйства на его странице ------------------------------------------
   Заказчик 13.10: «чтобы ниже отзывов в профиле начиналась лента этого хозяина,
   шла ниже». Карточки — тот же `.feed`, что в «Завалинке», поэтому вид совпадает;
   здесь только отступ раздела. */
.farm-feed { margin: 24px 0 0; }
.farm-feed > .feed { margin: 0; }
.farm-feed > p { margin: 12px 0 0; }

/* --- Жёсткая форма фотографий -------------------------------------------------
   Заказчик 13.10: «придать жёсткую форму для картинок, чтобы независимо от того,
   каким размером, они выглядели одинаково» (пример — Авито).

   Правило одно: **кадр задаёт пропорцию, снимок её заполняет** (`object-fit:
   cover`) и обрезается по центру. Тогда вертикальный, горизонтальный и квадратный
   снимок дают ровно один кадр.

   Пропорция 4:3 — общая для всех мест: объявление, карточка каталога, карточка
   животного, лента. Разные пропорции в разных местах означали бы, что один и тот
   же снимок выглядит по-разному.

   Где снимок виден целиком: миниатюры объявления и полный размер по клику. */
.shot .photo,
.card .photo,
.pet-card .photo,
.gallery-thumbs .photo,
.pet-list .photo,
.avatar-preview .photo,
.farm-avatar .photo {
  object-position: center;
}

/* --- Фотографии объявления в кабинете ------------------------------------------
   Заказчик 13.10: «нужно ещё добавить возможность добавлять в объявление
   несколько фотографий». Сетка кадров: одна пропорция у всех (4:3, как в
   галерее и карточках), у каждого — кнопка «убрать», ниже — выбор файлов. */
.photo-grid {
  display: grid;
  gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  list-style: none;
  margin: 16px 0;
  padding: 0;
}
.photo-grid > li { display: grid; gap: 8px; }
/* Кадр — точка отсчёта для крестика: он лежит ПОВЕРХ снимка в правом верхнем углу. */
.photo-cell { margin: 0; position: relative; }
/* Кадр задаёт пропорцию, снимок её заполняет — как в галерее объявления. */
.photo-cell .photo {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  object-position: center;
  border-radius: 12px;
}
.photo-note {
  margin: 6px 0 0;
  color: var(--muted);
  font-size: .85rem;
}
/* Пометка «главная»: первое фото показывается в списке и в поиске. */
.photo-badge {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--primary);
  font-size: .78rem;
  font-weight: 600;
}
/* Крестик убирает кадр (заказчик, 25.10: «вместо кнопок "Убрать" сделай крестики на
   самом фото»). Лежит поверх снимка в правом верхнем углу. Это обычная кнопка
   отправки формы — работает без JavaScript и доступна с клавиатуры. */
.photo-remove { position: absolute; top: 8px; right: 8px; margin: 0; z-index: 2; }
.photo-remove-x {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  /* Тёмный круг с белёсым крестом: видно на любом снимке — и на светлом, и на тёмном. */
  background: rgba(12, 18, 24, .55);
  color: #fff;
  cursor: pointer;
  transition: background .15s ease, transform .15s ease;
}
.photo-remove-x:hover { background: rgba(12, 18, 24, .8); transform: scale(1.05); }
.photo-remove-x:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
.cross-icon { display: block; }
/* Плитка «+» для добавления: пустой блок той же пропорции, что и кадры. Это <label>
   для поля выбора файлов, поэтому нажатие сразу открывает выбор — без JavaScript. */
.photo-tile-add { display: grid; }
.photo-add-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 100%;
  aspect-ratio: 4 / 3;
  border: 2px dashed var(--outline);
  border-radius: 12px;
  background: var(--surface);
  color: var(--muted);
  cursor: pointer;
  text-align: center;
  transition: border-color .15s ease, color .15s ease, background .15s ease;
}
.photo-add-tile:hover {
  border-color: var(--primary);
  color: var(--primary);
  background: var(--accent-soft);
}
.photo-add-plus { font-size: 42px; line-height: 1; font-weight: 300; }
.photo-add-caption { font-size: .9rem; }
.photo-add-hint { margin: 0; color: var(--muted); font-size: .9rem; }
@media (max-width: 640px) {
  .photo-remove-x { width: 28px; height: 28px; }
  .photo-add-plus { font-size: 34px; }
}
/* Загрузка: поле выбора файлов и кнопка. */
.photo-add {
  display: grid;
  gap: 12px;
  margin: 18px 0;
  padding: 16px;
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow);
}
.photo-add input[type="file"] { font: inherit; }
.photo-add .button { justify-self: start; }
/* Ссылка на фотографии в списке объявлений. */
.listing-photos-link { white-space: nowrap; }

/* --- Мои объявления: карточки, фильтр, действия --------------------------------
   Заказчик 13.10: «создать и обработать хорошо эту страницу». Карточка вместо
   строки: фотография, сведения и действия рядом — по строке нельзя было понять,
   что с объявлением. */
.my-listings { display: grid; gap: 14px; margin: 16px 0; }
.my-listing {
  display: grid;
  gap: 16px;
  grid-template-columns: 220px minmax(0, 1fr);
  padding: 14px;
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius);
  background: var(--surface);
  box-shadow: var(--shadow);
}
/* Кадр той же пропорции 4:3, что в галерее и карточках. */
.my-listing-photo { position: relative; }
.my-listing-photo .photo {
  width: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  object-position: center;
  border-radius: 12px;
}
.my-listing-count {
  position: absolute;
  right: 8px;
  bottom: 8px;
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(0, 0, 0, .62);
  color: #fff;
  font-size: .78rem;
}
.my-listing-body { min-width: 0; }
/* Своё объявление: название обычным, цена — жирным (как в карточках рынка). */
.my-listing-title { margin: 0 0 6px; font-size: 1.05rem; font-weight: 400; }
.my-listing-meta { margin: 0 0 4px; }
.my-listing-note { margin: 0 0 10px; font-size: .84rem; }
/* Предупреждение про объявление без фото: это частая причина, что не открывают. */
.my-listing-warn {
  margin: 0 0 10px;
  padding: 8px 10px;
  border-radius: 10px;
  background: var(--error-container, #fdecea);
  color: var(--error, #a12a20);
  font-size: .85rem;
}
.my-listing-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.my-listing-actions form { margin: 0; }
/* Статус — цветной меткой: видно сразу, без чтения слова. */
.status { font-weight: 600; }
.status-active { color: var(--primary); }
.status-sold { color: var(--muted); }
.status-archived { color: var(--error, #a12a20); }
/* Полоса фильтра по статусу. */
.chips-status { display: flex; flex-wrap: wrap; gap: 8px; margin: 15px 0 4px; }
.chips-status .chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 36px;
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  text-decoration: none;
  font-size: .9rem;
}
.chips-status .chip:hover { background: var(--accent-soft); }
.chips-status .chip.is-current {
  background: var(--primary);
  border-color: var(--primary);
  color: var(--on-primary);
  font-weight: 600;
}
.chips-status .chip-count { opacity: .75; font-variant-numeric: tabular-nums; }
/* Телефон: карточка в одну колонку, фотография во всю ширину. */
@media (max-width: 640px) {
  .my-listing { grid-template-columns: 1fr; }
}

/* --- Карандаш правки в карточке объявления ------------------------------------
   Заказчик 13.10: «карандашик (Редактировать) справа сверху». Поэтому шапка
   карточки — флекс: название слева, карандаш справа и прижат к ВЕРХУ строки. */
.my-listing-head {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin: 0 0 6px;
}
.my-listing-head .my-listing-title { flex: 1 1 auto; margin: 0; min-width: 0; }
.my-listing-edit {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
  color: var(--muted);
  transition: color .15s ease, background .15s ease, border-color .15s ease;
}
.my-listing-edit:hover {
  color: var(--primary);
  border-color: var(--accent-soft);
  background: var(--accent-soft);
}
.my-listing-edit:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* --- Правка объявления: поля в две колонки и фотографии ниже ------------------ */
.listing-edit .field-grid {
  display: grid;
  gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}
.listing-edit .field { margin: 0; }
.listing-edit .check-row { margin: 12px 0; }
.listing-edit textarea { width: 100%; }
.listing-edit-photos { margin: 24px 0 0; }
/* На телефоне поля в одну колонку. */
@media (max-width: 640px) {
  .listing-edit .field-grid { grid-template-columns: 1fr; }
}
.shot-pick:nth-of-type(1):checked ~ .gallery-thumbs .gallery-thumb:nth-child(1),
.shot-pick:nth-of-type(2):checked ~ .gallery-thumbs .gallery-thumb:nth-child(2),
.shot-pick:nth-of-type(3):checked ~ .gallery-thumbs .gallery-thumb:nth-child(3),
.shot-pick:nth-of-type(4):checked ~ .gallery-thumbs .gallery-thumb:nth-child(4),
.shot-pick:nth-of-type(5):checked ~ .gallery-thumbs .gallery-thumb:nth-child(5),
.shot-pick:nth-of-type(6):checked ~ .gallery-thumbs .gallery-thumb:nth-child(6),
.shot-pick:nth-of-type(7):checked ~ .gallery-thumbs .gallery-thumb:nth-child(7),
.shot-pick:nth-of-type(8):checked ~ .gallery-thumbs .gallery-thumb:nth-child(8) {
  border-color: var(--primary);
}

/* Телефон: кадр ниже, миниатюры мельче — иначе кадр съедает весь экран. */
@media (max-width: 640px) {
  /* На телефоне колонка узкая: 16:10 сделал бы снимок слишком низким. */
  .shots { aspect-ratio: var(--shot-ratio-mobile, 4 / 3); }
  .gallery-thumb .photo { width: 64px; height: 48px; }
}

/* --- Шапка списка объявлений: счётчик слева, «Добавить» справа -----------------
   Кнопка стоит над списком нарочно: когда объявлений много, до пустого состояния
   человек не долистает, а добавить захочет отсюда (заказчик, 13.10). */
.my-listings-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 16px 0 0;
}
.my-listings-head .muted { margin: 0; }
.my-listings-head .button { flex: 0 0 auto; }
/* Телефон: кнопка во всю ширину — так в неё проще попасть. */
@media (max-width: 640px) {
  .my-listings-head { flex-direction: column; align-items: stretch; }
  .my-listings-head .button { width: 100%; text-align: center; }
}

/* Пустая полоса отзывов: «Отзывов пока нет — они появятся здесь».
   Спокойнее, чем полоса со звёздами: это не оценка, а подсказка (заказчик, 13.10:
   «Во вкладке обзор нет оценки пользователя»). */
.user-reviews-empty {
  justify-content: center;
  background: none;
  color: var(--muted);
}
.user-reviews-empty .user-reviews-text { font-weight: 500; }
.user-reviews-empty:hover { background: var(--accent-soft); color: var(--primary); }

/* Просмотры — правый блок строки счётчиков. Ничего прижимать не нужно: их ставит
   к правому краю `justify-content: space-between` у `.post-stats`
   (заказчик, 13.10: «перенеси количество просмотров (глазок) в правый край поста»). */

/* Левая группа строки счётчиков: лайк и комментарии. Правый блок (просмотры)
   расталкивает `space-between` у `.post-stats` — прижимать отступом не нужно. */
/* Строка счётчиков — это <div>, потому что внутри лежит <form> лайка:
   <form> нельзя помещать внутрь <p> и <span> — браузер закрывает
   родителя раньше времени, и раскладка разваливается (13.10). */
.post-stats-left {
  display: inline-flex;
  align-items: center;
  gap: 28px;
  min-width: 0;
}

/* Подпись лайка «Нравится». Лежит ВНУТРИ кнопки, поэтому нажимается вместе с
   сердечком (заказчик, 13.10). У гостя подписи нет: кнопки ему тоже нет — лайк
   подписывается именем, и надпись на неработающем счётчике вводила бы в заблуждение. */
.post-like-text {
  white-space: nowrap;
  font-weight: 500;
}
/* На узком экране подпись убираем: строка счётчиков там и без неё тесная. */
@media (max-width: 480px) {
  .post-like-text { display: none; }
}

/* --- Узкий экран: порядок колонки больше не переставляется -------------------
   Заказчик 13.10 присылал снимки телефона: карточка хозяина и два блока меню
   занимали весь экран, а страница начиналась только после прокрутки. Тогда решили
   поднять карточку над содержимым, а меню опустить — через `order` и
   `.site-layout:has(…) > .site-side`.

   **31.10 это отменено:** заказчик попросил показывать сразу содержимое, и колонка
   на телефоне и планшете скрыта целиком (`.site-side`). Переставлять внутри неё
   нечего, поэтому правила `order` и `:has(…) > .site-side` удалены.

   Удаление было не косметикой: у `:has(…) > .site-side` специфичность (0,4,0), и
   оно перебивало скрытие колонки (0,2,0) — блок возвращался на экран, хотя правило
   скрытия стояло ниже в файле. */


/* Лента и её карточки должны сжиматься. Во flex-раскладке (узкий экран) у элемента
   по умолчанию `min-width: auto`, и содержимое может распирать карточку шире
   контейнера — это и была причина «лента шире, хотя меню по ширине» (15.10). */
.feed,
.feed > .post,
.feed > .post-card,
.post-head,
.post-text,
.post-comments {
  min-width: 0;
  max-width: 100%;
}

/* Аватар хозяйства: круг для фотографии и для букв имени. Буквы — когда фотографии
   нет; это не заглушка-ошибка, а узнаваемый профиль (заказчик, 25.10). */
.farm-avatar {
  width: 160px;
  height: 160px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--accent-soft);
  color: var(--primary);
  box-shadow: var(--shadow);
}
.farm-avatar .farm-initials {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  font-size: 2.6rem;
  font-weight: 600;
  line-height: 1;
  letter-spacing: .02em;
}
@media (max-width: 760px) {
  .farm-avatar { width: 112px; height: 112px; }
  .farm-avatar .farm-initials { font-size: 1.9rem; }
}

/* --- Плитки разделов рынка с картинками (заказчик, 30.10: «как на Авито») -----
   Слева подпись и число объявлений, справа фотография животного. Левый край кадра
   растворяется в фоне маской — стык не видно.

   Взято из CSS, который прислал заказчик, с двумя правками: фон из токена `--bg`
   (чтобы плитки шли за палитрой сайта), и `max-width` у картинки, иначе широкий кадр
   заезжал под подпись и текст читался по фотографии. */

/* Плитки видов — flex с фиксированной шириной, а не сетка с 1fr: сетка тянула
   плитки по высоте самой высокой и растягивала «Все» в пустую зелёную коробку.
   Фиксированные плитки одинаковы, переносятся и не тянутся. */
/* 31.10: плитки — сеткой, а не «сколько влезет»: при ширине 1060
   четыре плитки по 240 дают ровные 4 + 4 вместо 5 + 3. */
.species-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 12px;
  margin: 0 0 18px;
}
.species-cards .species-card { width: auto; flex: none; }

.species-card {
  position: relative;
  display: block;
  /* Ширина фиксированная: так все плитки одинаковы, а перенос гарантирован. */
  flex: 0 0 200px;
  width: 200px;
  height: 110px;
  padding: 14px 16px;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--bg);
  color: var(--on-bg);
  text-decoration: none;
  transition: background .15s ease, box-shadow .15s ease, border-color .15s ease;
}
.species-card:hover { background: var(--accent-soft); border-color: var(--primary); text-decoration: none; }
.species-card:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* Выбранный раздел: светлая подложка и рамка. Сплошная заливка, как у прежнего чипа,
   съела бы фотографию. */
.species-card.is-current {
  background: var(--accent-soft);
  box-shadow: inset 0 0 0 2px var(--primary);
}

.species-card-title {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-width: 58%;
  font-weight: 600;
  font-size: .98rem;
  line-height: 1.25;
}
.species-card-count {
  font-weight: 500;
  font-size: .85rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}
.species-card.is-current .species-card-count { color: var(--primary); }

/* Плитка «Все» — без картинки: это весь рынок, а не животное. */
.species-card-all { display: flex; align-items: flex-start; }

.species-card-img {
  position: absolute;
  right: 0;
  bottom: 0;
  height: 100%;
  width: auto;
  max-width: 62%;
  object-fit: cover;
  object-position: top center;
  /* Плавный уход левого края снимка в фон плитки. Без `-webkit-` Safari покажет
     резкий обрыв кадра. */
  /* 10%, а не 22%: объект теперь стоит вплотную к левому краю кадра, и
     широкая маска срезала бы голову. */
  -webkit-mask-image: linear-gradient(to right, transparent 0%, #000 10%);
  mask-image: linear-gradient(to right, transparent 0%, #000 10%);
}

/* Виды без объявлений — под раскрывающимся списком, а не плитками с нулями. */
.species-more { position: relative; display: inline-block; margin: 0 0 18px; }
.species-more-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: var(--tap-h);
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  cursor: pointer;
  font-size: .9rem;
  list-style: none;
}
.species-more-toggle::-webkit-details-marker { display: none; }
.species-more-toggle:hover { background: var(--accent-soft); }
.species-more-body {
  position: absolute;
  z-index: 15;
  margin-top: 6px;
  padding: 10px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  max-width: min(520px, 92vw);
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  box-shadow: var(--shadow);
}

@media (max-width: 640px) {
  .species-cards { gap: 10px;
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); }
  .species-card { flex: 1 1 140px; width: auto; min-width: 140px; height: 96px;
    padding: 12px; border-radius: 14px; }
  .species-card-title { font-size: .92rem; max-width: 64%; }
}

/* --- Шапка в стиле Авито (ТЗ заказчика, 30.10) --------------------------------
   Одна панель: знак, «Все категории», поиск, город, избранное, профиль,
   «Разместить объявление». Всё без JavaScript: раскрытие на <details>. */

/* Поиск шире: он главный элемент шапки.
   margin-left: 0 — иначе старое правило прижимало поиск к правому краю, и поле
   отъезжало от «Все категории». */
.site-header .header-search {
  flex: 1 1 320px;
  max-width: 720px;
  min-width: 200px;
  margin-left: 0;
}
/* До 1024 поиск складывается в лупу (прежнее поведение). Правило поиска выше
   специфичнее узких, поэтому рост надо отменить явно — иначе на телефоне лупа
   растянулась бы на полшапки. */
@media (max-width: 1024px) {
  .site-header .header-search { flex: 0 0 auto; max-width: none; min-width: 0; }
}
.header-search-form input { padding: 0 100px 0 16px; }
.header-search-text { white-space: nowrap; }

/* Бренд не сжимается: иначе на 1100–1278 px имя обрезалось до «Тёплый ...».
   Ширину шапки держим скрытием подписей по порогам, а не сжатием названия. */
.site-header .brand { flex: 0 0 auto; }

/* Общий вид кнопок шапки. */
.hdr-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: var(--control-h);
  padding: 0 14px;
  border: 1px solid var(--outline-variant);
  border-radius: 999px;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: .92rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  list-style: none;
}
.hdr-btn::-webkit-details-marker { display: none; }
.hdr-btn:hover { background: var(--accent-soft); }
.hdr-btn:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.hdr-svg { display: block; }

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

/* Город. */
.hdr-city { position: relative; flex: 0 0 auto; }
.hdr-city-toggle { max-width: 190px; }
.hdr-pin { display: inline-flex; color: var(--primary); }
.hdr-city-name { overflow: hidden; text-overflow: ellipsis; }

/* Выпадающая панель: одна на все три случая (категории, город, профиль). */
.hdr-panel {
  position: absolute;
  z-index: 40;
  top: calc(100% + 8px);
  left: 0;
  min-width: 240px;
  max-width: min(320px, calc(100vw - 24px));
  padding: 12px;
  border: 1px solid var(--outline-variant);
  border-radius: 14px;
  background: var(--surface);
  box-shadow: 0 12px 32px rgba(15, 23, 32, .16);
}
.hdr-panel-title {
  margin: 0 0 8px;
  color: var(--muted);
  font-size: .78rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
}
.hdr-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.hdr-list a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 10px;
  border-radius: 10px;
  color: var(--ink);
  text-decoration: none;
}
.hdr-list a:hover { background: var(--accent-soft); text-decoration: none; }
.hdr-list a.is-current { background: var(--accent-soft); color: var(--primary); font-weight: 600; }
.hdr-empty { display: block; padding: 8px 10px; color: var(--muted); font-size: .9rem; }
.hdr-panel-foot {
  display: block;
  margin: 10px -4px -2px;
  padding: 8px 10px;
  border-top: 1px solid var(--outline-variant);
  color: var(--primary);
  font-weight: 600;
  font-size: .9rem;
  text-decoration: none;
}
.hdr-panel-foot:hover { text-decoration: underline; }

/* Правый блок действий. */
.hdr-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: auto;
  flex: 0 0 auto;
}
.hdr-icon {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--control-h);
  height: var(--control-h);
  border-radius: 50%;
  color: var(--ink);
  text-decoration: none;
}
.hdr-icon:hover { background: var(--accent-soft); text-decoration: none; }
.hdr-icon:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.hdr-badge {
  position: absolute;
  top: 2px;
  right: 0;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: #c62828;
  color: #fff;
  font-size: .72rem;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}

/* Профиль: мини-аватар и имя. */
.hdr-profile { position: relative; flex: 0 0 auto; }
.hdr-profile-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: var(--control-h);
  padding: 0 10px 0 4px;
  border: 1px solid var(--outline-variant);
  border-radius: 999px;
  background: var(--surface);
  cursor: pointer;
  list-style: none;
}
.hdr-profile-toggle::-webkit-details-marker { display: none; }
.hdr-profile-toggle:hover { background: var(--accent-soft); }
.hdr-profile-toggle:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.hdr-avatar {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--accent-soft);
  color: var(--primary);
  font-size: .82rem;
  font-weight: 700;
}
.hdr-avatar-img { width: 32px; height: 32px; object-fit: cover; display: block; }
.hdr-profile-name { font-size: .92rem; font-weight: 600; max-width: 130px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hdr-profile-panel { min-width: 230px; right: 0; left: auto; }
.hdr-profile-me {
  margin: 0 0 8px;
  padding: 0 10px 8px;
  border-bottom: 1px solid var(--outline-variant);
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.hdr-profile-link {
  display: block;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: 10px;
  background: none;
  color: var(--ink);
  font: inherit;
  font-size: .92rem;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}
.hdr-profile-link:hover { background: var(--accent-soft); text-decoration: none; }
.hdr-logout { margin: 4px 0 0; padding-top: 4px; border-top: 1px solid var(--outline-variant); }
.hdr-logout-btn { color: var(--danger, #b3261e); }
.hdr-login { height: var(--control-h); }
.hdr-post {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: var(--control-h);
  padding: 0 16px;
  border-radius: 999px;
  white-space: nowrap;
}
.hdr-post .hdr-svg { display: block; }

/* Узкие экраны: подписи скрываются по важности, чтобы шапка гарантированно
   помещалась. Пороги посчитаны по ширине элементов: сначала уходит подпись под
   названием клуба (самая длинная), потом текст на «Разместить», потом имя в профиле,
   подпись «Все категории», название города и, на самом узком, само название клуба. */
@media (max-width: 1320px) {
  .site-header .brand-tagline { display: none; }
}
@media (max-width: 1160px) {
  .hdr-post { padding: 0 12px; }
  .hdr-post-text { display: none; }
}
@media (max-width: 1100px) {
  .hdr-profile-name { display: none; }
}
@media (max-width: 900px) {
  .hdr-city-name { display: none; }
  .hdr-city-toggle { padding: 0 12px; }
}
@media (max-width: 560px) {
  .header-search-text { display: none; }
  .header-search-go { padding: 0 12px; }
  .header-search-form input { padding: 0 52px 0 14px; }
  /* Профиль — справа в той же строке, как на компьютере (заказчик, 31.10).
     Раньше действия уходили на свою строку и обрезались: справа сверху было
     пусто, а войти с телефона можно было только через нижнюю панель.
     «Разместить объявление» на телефоне прячем: кнопка размещения есть
     в кабинете и в нижней панели, а место в строке нужнее профилю. */
  .hdr-actions {
    flex: 0 0 auto;
    justify-content: flex-end;
    margin-left: auto;
  }
  .hdr-post { display: none; }
  .hdr-profile-toggle { padding: 0 6px; }
  .hdr-login { padding: 0 12px; }
}
@media (max-width: 420px) {
  .site-header .brand-text { display: none; }
}

/* --- Панель разделов: внизу на телефоне, сбоку на планшете (заказчик, 31.10) ----
   Одна разметка `<nav class="bottom-nav">`, три раскладки оформлением. На ПК панель
   скрыта: там остаётся меню в колонке, как и было. */

/* По умолчанию (ПК) — не показываем и место не занимаем. */
.bottom-nav { display: none; }
.nav-svg { display: block; }

@media (max-width: 1159px) {
  /* Колонка-спутник на телефоне и планшете больше не нужна: разделы — в панели,
     кабинет и выход — в профиле шапки, помощь и связь — в подвале. Иначе меню
     дублировалось бы и отнимало два экрана до содержимого.

     Правило продублировано с потомком (.site-layout > .site-side): так его не
     перебьёт ни одно будущее правило для .site-side с такой же специфичностью,
     и блок не вернётся на телефоне случайно. */
  .site-side,
  .site-layout > .site-side { display: none; }
}

/* --- Телефон: полоса внизу --- */
@media (max-width: 700px) {
  .bottom-nav {
    display: flex;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 60;
    padding: 6px 4px calc(6px + env(safe-area-inset-bottom));
    /* Жидкое стекло: та же формула, что у шапки. */
    background: var(--glass-tint);
    border-top: 1px solid var(--glass-line);
    box-shadow: var(--glass-shadow), var(--glass-highlight);
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
    backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
  }
  .bottom-nav-item {
    flex: 1 1 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 3px;
    min-width: 0;
    padding: 4px 2px;
    border-radius: 12px;
    /* На стекле серый текст «плавает» над просвечивающим содержимым — берём основной. */
    color: var(--ink);
    text-decoration: none;
    font-size: .72rem;
    line-height: 1.1;
    text-align: center;
  }
  .bottom-nav-item:hover { text-decoration: none; background: var(--accent-soft); }
  .bottom-nav-item:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
  .bottom-nav-text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
  }
  .bottom-nav-item.is-current { color: var(--primary); }
  .bottom-nav-item.is-current .nav-svg { stroke-width: 2.2; }

  /* Место под панель: содержимое и подвал не уезжают под неё. */
  body.has-bottom-nav { padding-bottom: calc(66px + env(safe-area-inset-bottom)); }
  /* Панель звонка в объявлении встаёт НАД панелью разделов, а не поверх неё. */
  .mobile-bar { bottom: calc(60px + env(safe-area-inset-bottom)); }
}

/* --- Планшет: та же панель сбоку --- */
@media (min-width: 701px) and (max-width: 1159px) {
  .bottom-nav {
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    gap: 6px;
    position: fixed;
    left: 0;
    top: 0;
    bottom: 0;
    width: 88px;
    z-index: 60;
    padding: 14px 6px;
    /* Жидкое стекло: та же формула, что у шапки. */
    background: var(--glass-tint);
    border-right: 1px solid var(--glass-line);
    box-shadow: var(--glass-shadow), var(--glass-highlight);
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
    backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
    overflow-y: auto;
  }
  .bottom-nav-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    padding: 10px 4px;
    border-radius: 12px;
    color: var(--ink);
    text-decoration: none;
    font-size: .72rem;
    line-height: 1.15;
    text-align: center;
  }
  .bottom-nav-item:hover { text-decoration: none; background: var(--accent-soft); }
  .bottom-nav-item:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
  .bottom-nav-item.is-current { color: var(--primary); background: var(--accent-soft); }
  .bottom-nav-text { white-space: normal; }

  /* Контент сдвигается вправо на ширину панели. */
  body.has-bottom-nav { padding-left: 88px; }
  .mobile-bar { bottom: 0; }
}

@media print {
  .bottom-nav { display: none; }
  body.has-bottom-nav { padding: 0; }
}

/* --- Кабинет на телефоне и планшете: без блока меню (заказчик, 31.10) ----------
   «Показывай сразу контент, как в приложении». От блока остаётся ОДНА строка
   разделов кабинета: карточка хозяина и «Главное» убраны (профиль в шапке, разделы
   в нижней панели), заголовок «Кабинет» тоже не нужен.

   Список не убираю совсем: в нижней панели четыре пункта, и «Мои животные», «Отзывы»,
   «Безопасность» стали бы с телефона недоступны. */
@media (max-width: 1159px) {
  .cab-side > .user-card,
  .cab-side > .site-nav,
  .cab-side > .cab-side-title { display: none; }

  .cab-side {
    position: static;
    width: auto;
    max-width: 100%;
    min-width: 0;
    max-height: none;
    overflow: visible;
    margin: 0 0 var(--gap-m);
  }

  /* Разделы кабинета — одна строка чипов с прокруткой пальцем. */
  .cab-nav {
    display: flex;
    flex-wrap: nowrap;
    gap: 8px;
    overflow-x: auto;
    padding-bottom: 4px;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
  }
  .cab-nav::-webkit-scrollbar { display: none; }
  .cab-link {
    flex: 0 0 auto;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: var(--tap-h);
    padding: 0 14px;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--surface);
    color: var(--ink);
    font-size: .9rem;
    text-decoration: none;
    white-space: nowrap;
  }
  .cab-link:hover { background: var(--accent-soft); text-decoration: none; }
  .cab-link:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
  .cab-link[aria-current="page"] {
    background: var(--primary);
    border-color: var(--primary);
    color: var(--on-primary);
  }
  /* Стрелка перехода в чипе лишняя: она нужна в колонке на ПК. */
  .cab-link .icon-arrow, .cab-link svg { display: none; }
}

/* --- Режим приложения: ярлык на рабочем столе (заказчик, 31.10) ----------------
   Когда сайт открыт по ярлыку, браузер (по манифесту и мета-тегам Apple) рисует его
   без адресной строки. Строка состояния при этом лежит ПОВЕРХ страницы, поэтому
   верх надо освободить, иначе логотип уедет под часы.

   `env(safe-area-inset-*)` работает только с `viewport-fit=cover` — он включён в
   `<meta name="viewport">`. */
@media (display-mode: standalone) {
  .site-header { padding-top: env(safe-area-inset-top, 0px); }
  /* Якоря: иначе переход по ссылке прячет заголовок под шапкой. */
  html { scroll-padding-top: calc(88px + env(safe-area-inset-top, 0px)); }
  /* Подсказки «установите приложение» внутри приложения не нужны. */
  .install-hint, .app-install-hint { display: none; }
}

/* iOS: тот же режим определяется иначе — по классу, который ставит Safari
   (`navigator.standalone`). Класс добавляет скрипт, но правило безвредно и без него. */
@media (display-mode: fullscreen) {
  .site-header { padding-top: env(safe-area-inset-top, 0px); }
}


/* --- Экраны клуба: «Сегодня», календарь и разбор (31.10.2026) -------------------
   Приложение и сайт должны выглядеть одной системой: те же радиусы, та же строка
   статуса слева, те же «чипы» для времени. Скриптов здесь нет — только оформление. */

.today-hero { margin: 0 0 18px; }
.today-date { margin: -4px 0 10px; color: var(--muted); font-size: .95rem; }
.today-block { margin: 26px 0; }
.today-block h2 { font-size: 1.1rem; margin: 0 0 10px; }

/* Лекарства на сегодня: время слева, что и кому — справа. */
.dose-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.dose {
  display: flex; gap: 12px; align-items: baseline; flex-wrap: wrap;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--surface);
}
.dose-times { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.chip-time {
  background: var(--accent-soft); color: var(--primary);
  font-variant-numeric: tabular-nums; font-weight: 600;
}
.dose-what { flex: 1 1 220px; }

/* Процедуры: цветная полоса слева показывает срочность, как в карточке приложения. */
.task-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.task {
  display: flex; gap: 8px; align-items: baseline; flex-wrap: wrap;
  padding: 10px 12px; border-radius: 12px; background: var(--surface);
  border-left: 3px solid var(--line);
}
.task-overdue { border-left-color: #C7452A; }
.task-soon { border-left-color: #B98A16; }
.task-when { color: var(--muted); font-variant-numeric: tabular-nums; }
.task-what { font-weight: 600; }
.task-note { color: var(--muted); font-size: .9rem; }

.tips { padding-left: 20px; }
.tips li { margin: 0 0 6px; }

/* Оценка ухода: крупное число, цвет зависит от состояния. */
.score {
  margin: 0 0 18px; padding: 16px 18px; border-radius: 14px;
  background: var(--surface); border: 1px solid var(--line);
  border-left: 4px solid var(--primary);
}
.score-good { border-left-color: #1F7A5A; }
.score-mid { border-left-color: #B98A16; }
.score-bad { border-left-color: #C7452A; }
.score-value { margin: 0; font-size: 2.2rem; font-weight: 700; line-height: 1; }
.score-of { font-size: 1rem; font-weight: 500; color: var(--muted); }
.score-caption { margin: 4px 0 6px; color: var(--muted); }

/* Находки разбора: заголовок, «почему», совет. */
.finding-group { margin: 24px 0; }
.finding-group h2 { font-size: 1.05rem; margin: 0 0 10px; }
.finding {
  border: 1px solid var(--line); border-radius: 12px; padding: 12px 14px;
  margin: 0 0 10px; background: var(--surface);
}
.finding h3 { margin: 0 0 6px; font-size: 1rem; }
.finding-why { margin: 0 0 6px; color: var(--ink); }
.finding-advice { margin: 0 0 6px; }
.finding-urgent { border-left: 4px solid #C7452A; }
.finding-attention { border-left: 4px solid #B98A16; }
.finding-good { border-left: 4px solid #1F7A5A; }

.disclaimer {
  margin: 22px 0; padding: 12px 14px; border-radius: 10px;
  background: var(--accent-soft); border-left: 3px solid var(--primary);
  font-weight: 600;
}

/* Календарь хозяйства: таблица-месяц, понедельник первым. */
.cal { width: 100%; border-collapse: collapse; margin: 14px 0 8px; table-layout: fixed; }
.cal th, .cal td {
  border: 1px solid var(--line); padding: 6px; vertical-align: top;
  font-size: .85rem; height: 74px;
}
.cal th { height: auto; background: var(--accent-soft); font-weight: 600; }
.cal-number { font-weight: 600; display: block; margin-bottom: 2px; }
.cal-today { outline: 2px solid var(--primary); outline-offset: -2px; }
.cal-item {
  display: block; font-size: .72rem; line-height: 1.25; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis;
}
.cal-due { color: #9A3B22; }
.cal-more { display: block; font-size: .72rem; color: var(--muted); }
.cal-legend { display: flex; gap: 14px; color: var(--muted); font-size: .85rem; }

/* Блоки картотеки: «Все / Домашние / Скотина». */
.block-chips { display: flex; gap: 8px; flex-wrap: wrap; margin: 0 0 14px; }
.chip-count { opacity: .65; margin-left: 2px; }
.chip-active { background: var(--primary); color: #fff; border-color: var(--primary); }

@media (max-width: 700px) {
  /* На телефоне подписи в клетках календаря не читаются — оставляем точку и число. */
  .cal th, .cal td { height: 52px; padding: 4px; font-size: .8rem; }
  .cal-item { display: none; }
  .cal-has-items .cal-number::after {
    content: "•"; color: var(--primary); margin-left: 3px;
  }
  .dose, .task { padding: 8px 10px; }
}

/* --- Сообщения, уведомления, тариф (31.10.2026) --- */
.dialog-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.dialog a {
  display: grid; grid-template-columns: 1fr auto; gap: 2px 10px; align-items: baseline;
  padding: 12px 14px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--surface); text-decoration: none; color: var(--ink);
}
.dialog a:hover { background: var(--accent-soft); }
.dialog-peer { font-weight: 600; }
.dialog-listing { grid-column: 1 / -1; color: var(--muted); font-size: .85rem; }
.dialog-preview { grid-column: 1 / 2; color: var(--muted); font-size: .9rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dialog-time { grid-column: 2 / 3; color: var(--muted); font-size: .8rem; text-align: right; }

.chat { display: grid; gap: 8px; margin: 14px 0; }
.chat-message { max-width: min(78%, 620px); padding: 10px 12px; border-radius: 12px;
  background: var(--surface); border: 1px solid var(--line); }
.chat-mine { margin-left: auto; background: var(--accent-soft); }
.chat-body { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.chat-time { margin: 4px 0 0; color: var(--muted); font-size: .75rem; }
.chat-form { margin-top: 16px; }

.notice-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; }
.notice { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap;
  padding: 12px 14px; border-radius: 12px; background: var(--surface);
  border: 1px solid var(--line); }
.notice-unread { border-left: 3px solid var(--primary); }
.notice-icon { width: 1.4em; text-align: center; }
.notice-body { flex: 1 1 240px; color: var(--muted); }
.notice-time { color: var(--muted); font-size: .8rem; margin-left: auto; }

.quota { margin: 18px 0; }
.quota-line { margin: 0 0 6px; }
.quota-bar { height: 10px; border-radius: 999px; background: var(--line); overflow: hidden; }
.quota-bar span { display: block; height: 100%; background: var(--primary); }
.plan-card { margin: 24px 0; }

/* --- Текстовая страница: сетка широкая, строка нормальная ---------------------
   31.10 ширина сайта выросла до 1400, и сплошной текст на справочных страницах
   стал бы 1060 px — это ~120 знаков в строке, читать тяжело. Ограничиваем только
   текстовые блоки: список объявлений и сетки остаются широкими. */
.page-text { max-width: 760px; }

/* --- Шапка по ширине блока контента (заказчик, 31.10) -------------------------
   Раньше шапка была полосой во всё окно, а содержимое лежало в .wrap (1400):
   логотип и кнопки не совпадали по краям с меню и карточками. Теперь на
   компьютере шапка ровно той же ширины, что блок контента: меню + зазор +
   колонка. Ширина берётся ИЗ ПЕРЕМЕННЫХ сетки, чтобы не расходиться с ней. */
@media (min-width: 1160px) {
  /* Страницы с колонкой-меню: шапка = меню + зазор + колонка контента. */
  body.has-aside .site-header {
    /* Ширина блока контента, но не шире полосы страницы без полей .wrap:
       на 1235 px шапка выходила на 32 px шире блока (заказчик, 31.10),
       потому что max-width 1364 больше, чем 1235 − 2×16. */
    max-width: min(
      calc(var(--side-w) + var(--gap-wide) + var(--content-w)),
      calc(100% - 32px)
    );
    margin-inline: auto;
    border-radius: var(--radius);
    /* Обрезку (overflow: clip) убрал 31.10: она резала раскрывающиеся панели
       шапки — «Все категории», поиск, город и профиль обрывались по нижнему
       краю шапки. Скругление работает и без неё: фон и размытие браузер сам
       обрезает по border-radius. */
  }
  body.has-aside .site-header .header-inner {
    /* Внутри шапки нужен воздух: без полей логотип и кнопка прилипали к
       скруглённым краям (заказчик, 31.10: «нет места справа и слева»).
       Ширина самой шапки при этом остаётся равной блоку контента. */
    padding-inline: 18px;
    max-width: none;
  }
}

/* --- Боковое меню на стекле и воздух над шапкой (заказчик, 31.10) -------------
   Шапка «плавает»: 12 px воздуха сверху и столько же при прилипании. Боковая
   колонка — ОДНА стеклянная панель с той же формулой, что у шапки (--glass-*),
   а не три белые карточки: так меню и шапка выглядят одной системой.
   Одно размытие вместо трёх — и легче для слабых видеокарт. */
@media (min-width: 1160px) {
  .site-header {
    top: 12px;
    margin-top: 12px;
  }

  .site-side,
  .cab-side {
    background: var(--glass-tint);
    -webkit-backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
    backdrop-filter: blur(var(--glass-blur)) saturate(var(--glass-saturate));
    border: 1px solid var(--glass-line);
    border-radius: var(--radius);
    box-shadow: var(--glass-shadow), var(--glass-highlight);
    padding: 10px 12px 12px;
    /* Шапка теперь ниже на 12 px — меню прилипает под ней, а не под кромкой. */
    top: 100px;
    max-height: calc(100vh - 112px);
  }

  /* Внутри панели карточки не нужны: фон, рамка и тень — у самой панели. */
  .site-side > .user-card,
  .cab-side > .user-card,
  .site-side .site-side-block,
  .cab-side .site-side-block {
    background: transparent;
    border: 0;
    box-shadow: none;
    /* Отступ даёт сама панель. Раньше складывались поля панели и карточки —
       слева выходило 28 px, и пункты меню выглядели узкими (заказчик, 31.10). */
    padding: 12px 8px;
  }

  /* Разделитель между блоками — тонкая линия вместо отступа карточек. */
  .site-side .site-side-block + .site-side-block,
  .site-side .user-card + .site-nav,
  .cab-side .site-side-block + .site-side-block {
    border-top: 1px solid var(--glass-line);
    padding-top: 12px;
  }
}

/* Без размытия (старые браузеры) стекло выглядит грязным пятном — делаем сплошным. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  @media (min-width: 1160px) {
    .site-side,
    .cab-side { background: var(--surface); }
  }
}

/* --- Строка «Поделиться…» (ночь 02→03.11, S3.2) -------------------------------
   Как свёрнутый композер приложения: карточка во всю ширину, плюс в кружке,
   текст и серым — что можно приложить. Заменяет кнопку «+ Написать»: она была
   кнопкой, а не строкой, и не намекала, что можно фото и видео. */
.composer-line { margin: 0 0 var(--gap-m); }

.composer-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  min-height: 48px;
  padding: 10px 14px;
  background: var(--surface);
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  color: var(--on-bg);
  text-decoration: none;
}

.composer-row:hover { background: var(--container-low); text-decoration: none; }

.composer-row:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

.composer-plus {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--primary);
  color: var(--on-primary);
  font-weight: 700;
  line-height: 1;
}

.composer-text { font-weight: 600; }

.composer-hint { margin-left: auto; color: var(--muted); font-size: .9rem; }

/* --- Поиск города в шапке (03.11) ----------------------------------------------
   Заказчик: «в поле выбора добавить поле поиска, и там показывать сразу результат,
   без кнопки Искать». Поле — обычная форма GET на рынок (работает и без скриптов),
   скрипт подгружает /static/cities.json и фильтрует список на месте. */
.hdr-city-form { margin: 0 0 8px; }

.hdr-city-input {
  width: 100%;
  height: var(--field-h);
  padding: 0 12px;
  border: 1px solid var(--outline-variant);
  border-radius: 12px;
  background: var(--surface);
  color: var(--on-bg);
  font: inherit;
}

.hdr-city-input:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}

.hdr-city-hint { margin: 0 0 8px; }

.hdr-city-results {
  list-style: none;
  margin: 0 0 8px;
  padding: 0;
  max-height: 300px;
  overflow-y: auto;
}

.hdr-city-results a {
  display: block;
  padding: 8px 10px;
  border-radius: 10px;
  color: var(--on-bg);
  text-decoration: none;
}

.hdr-city-results a:hover { background: var(--accent-soft); text-decoration: none; }

.hdr-city-results a.is-current {
  background: var(--primary-container);
  color: var(--on-primary-container);
  font-weight: 600;
}

.hdr-city-results .hdr-city-empty { padding: 8px 10px; }

.hdr-city-popular-title { margin-top: 4px; }

/* Строка поиска над длинным списком в форме (города). */
.field-filter {
  width: 100%;
  max-width: 420px;
  height: var(--field-h);
  margin: 0 0 6px;
  padding: 0 12px;
  border: 1px solid var(--outline-variant);
  border-radius: 12px;
  background: var(--surface);
  color: var(--on-bg);
  font: inherit;
}

.field-filter:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }

/* Атрибут hidden должен побеждать раскладку списка. `.hdr-list` задаёт
   display: grid, а [hidden] из стилей браузера проигрывает классу — из-за этого
   под результатами поиска города оставались популярные (заказчик, 03.11). */
.hdr-list[hidden],
.hdr-city-results[hidden],
.hdr-city-popular-title[hidden],
.hdr-city-popular[hidden] { display: none; }

/* --- Вкладки профиля (03.11) ---------------------------------------------------
   Заказчик: «сверху как вкладки будут пункты профиля». Одиннадцать разделов
   лентой над содержимым, без скриптов; на узком экране лента прокручивается. */
.profile-tabs {
  display: flex;
  gap: 6px;
  margin: 10px 0 14px;
  padding: 3px;
  overflow-x: auto;
  scrollbar-width: thin;
  background: var(--surface);
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
}

.profile-tab {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 34px;
  padding: 0 10px;
  border-radius: 10px;
  color: var(--on-surface-variant);
  font-size: .88rem;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
}

.profile-tab:hover { background: var(--accent-soft); color: var(--on-primary-container); text-decoration: none; }

.profile-tab:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }

.profile-tab[aria-current=page] {
  background: var(--primary-container);
  color: var(--on-primary-container);
}

.profile-tab-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 20px;
  height: 20px;
  padding: 0 6px;
  border-radius: 999px;
  background: var(--primary);
  color: var(--on-primary);
  font-size: .78rem;
  font-weight: 700;
}

/* Очень узкие экраны (смарт-часы, свёрнутые окна): шапке разрешаем перенос —
   иначе «Войти» и город не помещаются в строку и появляется прокрутка. */
@media (max-width: 360px) {
  .site-header .header-inner { flex-wrap: wrap; }
}

/* --- Лента: узкая колонка и объявления справа (03.11) --------------------------
   Заказчик: «в приложении фотографии 3*4… если привести к этому стандарту сайт,
   пост будет огромным. Уменьшить ширину ленты, а справа — объявления из города».
   Колонка 620 px: пост с кадром 3:4 занимает разумную высоту, как во ВКонтакте. */
.feed-layout {
  display: grid;
  /* Лента — 620 px у левого края контента, объявления занимают остаток до
     правого края: пустых полей по бокам нет (заказчик, 03.11). */
  grid-template-columns: minmax(0, 620px) minmax(0, 1fr);
  gap: 24px;
  justify-content: stretch;
  align-items: start;
}

.feed-col { min-width: 0; }

/* Кадры публикаций — вертикальные 3:4, как в приложении. */
.feed-layout .shots {
  /* 03.11: кадры публикаций — квадрат 1:1 (было 3:4). */
  --shot-ratio: 1 / 1;
  --shot-ratio-mobile: 1 / 1;
}

.feed-side {
  display: grid;
  gap: 10px;
  padding: 14px;
  background: var(--surface);
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  /* Как у левого меню (.site-side): держимся ниже закреплённой шапки,
     иначе при прокрутке колонка уезжала под неё (заказчик, 03.11). */
  position: sticky;
  top: 88px;
}

.feed-side-title {
  margin: 0;
  font-size: .95rem;
  font-weight: 600;
}

.nearby-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 8px;
}

/* Карточка объявления в колонке ленты: фото · текст · кнопки. */
.nearby-item {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 10px;
  align-items: center;
  padding: 6px;
  border-radius: 12px;
}

.nearby-item:hover { background: var(--accent-soft); }

.nearby-card {
  display: grid;
  grid-template-columns: 64px minmax(0, 1fr);
  gap: 10px;
  align-items: center;
  padding: 0;
  border-radius: 12px;
  color: inherit;
  text-decoration: none;
}

.nearby-actions {
  display: flex;
  flex-direction: row;
  gap: 6px;
  align-items: center;
}

.nearby-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  border: 1px solid var(--outline-variant);
  border-radius: 50%;
  background: var(--surface);
  color: var(--primary);
  text-decoration: none;
}

.nearby-action:hover {
  border-color: var(--primary);
  background: var(--accent-soft);
  text-decoration: none;
}

.nearby-action-write { background: var(--primary); border-color: var(--primary); color: var(--on-primary); }

.nearby-action-write:hover { background: var(--primary-hover, var(--primary)); color: var(--on-primary); }

.nearby-card:hover { background: var(--accent-soft); text-decoration: none; }

.nearby-photo {
  display: block;
  width: 64px;
  height: 64px;
  border-radius: 10px;
  overflow: hidden;
  background: var(--accent-soft);
}

.nearby-photo-img { width: 100%; height: 100%; object-fit: cover; display: block; }

.nearby-body { display: grid; gap: 1px; min-width: 0; }

.nearby-price { font-weight: 700; font-size: .93rem; }

.nearby-title {
  font-size: .84rem;
  color: var(--on-bg);
  overflow: hidden;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
}

.nearby-city { font-size: .78rem; color: var(--muted); }

.feed-side-more { margin-top: 2px; }

/* Уже 1160 px боковая колонка мешала бы ленте: убираем её, лента занимает
   ширину (на телефоне объявления и так есть на рынке). */
@media (max-width: 1159px) {
  .feed-layout { grid-template-columns: minmax(0, 620px); }
  .feed-side { display: none; }
}

/* --- Колокольчик уведомлений и подссылки кабинета (03.11) ----------------------
   Колокольчик стоит справа от «Редактировать» — та же рамка и размер, что у
   кнопки выхода, только с другой стороны и с числом непрочитанных. */
.user-bell {
  position: relative;
  display: grid;
  place-items: center;
  flex: 0 0 auto;
  width: var(--tap-h);
  height: var(--tap-h);
  border: 1px solid var(--line);
  border-radius: 12px;
  color: var(--ink);
  text-decoration: none;
}

.user-bell:hover { border-color: var(--primary); color: var(--primary); text-decoration: none; }

.user-bell:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

.user-badge {
  position: absolute;
  top: -4px;
  right: -4px;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 999px;
  background: var(--primary);
  color: var(--on-primary);
  font-size: .72rem;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}

/* Строка ссылок внутри вкладки «Кабинет»: Обзор · Отзывы · Безопасность. */
.profile-subtabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: -4px 0 14px;
}

.profile-subtab {
  display: inline-flex;
  align-items: center;
  min-height: 30px;
  padding: 0 12px;
  border: 1px solid var(--outline-variant);
  border-radius: 999px;
  color: var(--on-surface-variant);
  font-size: .85rem;
  text-decoration: none;
}

.profile-subtab:hover { border-color: var(--primary); color: var(--primary); text-decoration: none; }

.profile-subtab[aria-current="page"] {
  border-color: var(--primary);
  background: var(--primary-container);
  color: var(--on-primary-container);
}


/* --- Число в выбранной плашке (03.11) ------------------------------------------
   Заказчик: «где что-то выбрано — не видно цифру; в момент выбора она должна быть
   белой, как текст». У счётчика свой цвет --muted, поэтому на залитой
   плашке он пропадал. Теперь в выбранном состоянии число наследует цвет подписи. */
.chip-active .chip-count,
.chip.is-current .chip-count,
.chips-status .chip.is-current .chip-count,
.species-radio:checked + .species-chip .chip-count {
  color: inherit;
  opacity: .85;
}

/* --- Шапка профиля: аватарка со сменой по наведению (03.11) --------------------
   Заказчик: «фотографию профиля в самый верх… смена — по наведению на аватарку
   появляется иконка загрузки». Аватарка — label для файла, поэтому клик по ней
   открывает выбор файла; кнопка «Загрузить фото» отправляет форму (без скриптов). */
.profile-hero {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
  align-items: center;
  /* 03.11: чуть ниже вкладок — шапка была прижата к меню. */
  margin: 22px 0 26px;
}

.profile-hero-avatar { display: grid; gap: 8px; justify-items: center; margin: 0; }

.profile-avatar {
  position: relative;
  display: block;
  width: 160px;
  height: 160px;
  border-radius: 50%;
  overflow: hidden;
  cursor: pointer;
  background: var(--accent-soft);
  box-shadow: var(--shadow);
}

.profile-avatar-img { width: 100%; height: 100%; object-fit: cover; display: block; }

.profile-avatar-initials {
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  color: var(--primary);
  font-size: 44px;
  font-weight: 700;
}

.profile-avatar-edit {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: 6px;
  background: rgba(12, 18, 24, .5);
  color: #fff;
  font-size: .8rem;
  font-weight: 600;
  text-align: center;
  opacity: 0;
  transition: opacity .15s ease;
}

.profile-avatar:hover .profile-avatar-edit,
.profile-avatar:focus-within .profile-avatar-edit { opacity: 1; }

.profile-avatar-submit { min-height: 34px; padding: 0 14px; font-size: .88rem; }

.profile-hero-text { min-width: 0; }

.profile-hero-name { margin: 0; font-size: 1.35rem; font-weight: 700; }

.profile-hero-place { margin: 2px 0 0; color: var(--muted); }

.profile-hero-rating {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 8px;
  color: var(--muted);
  font-size: .9rem;
  text-decoration: none;
}

.profile-hero-rating:hover { color: var(--ink); text-decoration: none; }

/* На телефоне наведения нет: полоска «Сменить фото» видна всегда. */
@media (hover: none) {
  .profile-avatar-edit {
    inset: auto 0 0 0;
    padding: 6px 4px;
    font-size: .72rem;
    opacity: 1;
    background: rgba(12, 18, 24, .55);
  }
}

/* Компактный блок «Выйти на всех устройствах» (03.11). */
.logout-all {
  display: grid;
  gap: 10px;
  justify-items: start;
  margin: 6px 0 0;
  padding: 14px;
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius);
  background: var(--surface);
}

.logout-all-text { margin: 0; color: var(--muted); font-size: .9rem; }

.logout-all form { margin: 0; }

/* «Показать ещё» — это <summary>: раскрывается на месте, без перезагрузки. */
.nearby-more { margin: 0; }

.nearby-more > summary { list-style: none; cursor: pointer; }

.nearby-more > summary::-webkit-details-marker { display: none; }

.nearby-more > ul { margin-top: 8px; }

.feed-side-more-text {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 2px 0 0;
  color: var(--primary);
  font-size: .9rem;
  font-weight: 600;
  text-decoration: none;
}

.feed-side-more-text:hover { text-decoration: underline; }

/* 03.11: многострочные поля больше не тянутся мышью — размер задан вёрсткой. */
.field textarea,
.field textarea:focus { resize: none; }

/* 03.11: на телефоне вкладки профиля переносятся, а не уезжают вправо. */
@media (max-width: 760px) {
  .profile-tabs { flex-wrap: wrap; overflow-x: visible; }
  .profile-tab { flex: 0 1 auto; }
}

/* --- Переписка с аватарками, как на Авито (03.11) -------------------------------
   Слева фото собеседника, справа имя, объявление, превью и время. */
.dialog-avatar {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--accent-soft);
}

.dialog-avatar-img { width: 100%; height: 100%; object-fit: cover; display: block; }

.dialog-initials { color: var(--primary); font-weight: 700; font-size: .95rem; }

.dialog-body { display: grid; gap: 2px; min-width: 0; flex: 1 1 auto; }

.chat-head {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 0 0 12px;
}

.chat-peer {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--accent-soft);
}

.chat-peer-img { width: 100%; height: 100%; object-fit: cover; display: block; }

.chat-peer-initials { color: var(--primary); font-weight: 700; }

.chat-title { margin: 0; font-size: 1.25rem; }

/* Строка диалога: аватарка · текст · время. */
.dialog > a {
  display: flex;
  align-items: flex-start;
  gap: 12px;
}

/* Показатели в шапке профиля — справа от фотографии (03.11). */
.profile-hero-stats {
  margin: 12px 0 0;
  gap: 8px;
}

.profile-hero-stats > div {
  padding: 8px 14px;
  border-radius: 14px;
}

.profile-hero-stats dt { font-size: .78rem; }

.profile-hero-stats dd { font-size: 1.1rem; }

/* --- Переписка: назад, компактная форма (03.11) --------------------------------- */
.chat-back-row { margin: 0 0 12px; }

.chat-back { min-height: 36px; padding: 0 14px; }

.chat-compose {
  display: flex;
  gap: 10px;
  align-items: flex-end;
}

.chat-compose .field { flex: 1 1 auto; margin: 0; }

.chat-compose textarea {
  min-height: 44px;
  max-height: 160px;
  resize: none;
}

.chat-send { flex: 0 0 auto; min-height: 44px; }

.chat {
  display: grid;
  gap: 10px;
  margin: 0 0 14px;
  max-width: 720px;
}

.chat-message {
  justify-self: start;
  max-width: 80%;
  padding: 10px 14px;
  border-radius: 14px;
  background: var(--surface);
  border: 1px solid var(--outline-variant);
}

.chat-mine {
  justify-self: end;
  background: var(--primary-container);
  border-color: transparent;
  color: var(--on-primary-container);
}

.chat-body { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }

.chat-time { margin: 4px 0 0; color: var(--muted); font-size: .78rem; }

/* «Показать ещё»: при раскрытии список встаёт НАД кнопкой. */
.nearby-more { display: flex; flex-direction: column; }

.nearby-more > ul { order: 1; }

.nearby-more > summary { order: 2; margin-top: 8px; }

/* Поле города: поиск и список рядом. */
.field-select-wrap {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 8px;
  align-items: center;
}

.field-select-wrap .field-filter { max-width: none; margin: 0; }

@media (max-width: 640px) {
  .field-select-wrap { grid-template-columns: minmax(0, 1fr); }
}

/* --- Карточка продавца с аватаркой (03.11) ------------------------------------- */
.seller-top {
  display: flex;
  gap: 14px;
  align-items: flex-start;
  margin: 0 0 10px;
}

.seller-avatar {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  width: 64px;
  height: 64px;
  border-radius: 50%;
  overflow: hidden;
  background: var(--accent-soft);
}

.seller-avatar-img { width: 100%; height: 100%; object-fit: cover; display: block; }

.seller-avatar-initials { color: var(--primary); font-weight: 700; font-size: 1.1rem; }

.seller-who { min-width: 0; }

.seller-name { margin: 0 0 2px; font-size: 1.05rem; font-weight: 700; }

.seller-rating {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 2px 0 0;
  font-size: .9rem;
}

.seller-rating strong { margin-left: 2px; }

.seller-more { margin: 12px 0 0; }

.seller-more .button { min-height: 34px; }

/* Уведомление: значок · подпись · текст · время (03.11). */
.notice > a,
.notice > span { display: inline; }

.notice-title { margin-right: 6px; }

.notice-body { color: var(--on-surface-variant); }

/* --- Карточка продавца: две колонки (03.11) -----------------------------------
   Слева кто продаёт, справа факты сеткой и кнопка — место справа больше не
   пустует. */
.seller-card {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(260px, 380px);
  gap: 24px;
  align-items: start;
}

.seller-id { display: flex; gap: 14px; align-items: flex-start; }

.seller-id .seller-avatar { width: 72px; height: 72px; }

.seller-side { display: grid; gap: 12px; justify-items: start; }

.seller-facts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 12px 20px;
  margin: 0;
  width: 100%;
}

.seller-facts dt { color: var(--muted); font-size: .8rem; }

.seller-facts dd { margin: 2px 0 0; font-size: .95rem; font-weight: 600; }

.seller-note { margin: 0; }

@media (max-width: 900px) {
  .seller-card { grid-template-columns: minmax(0, 1fr); gap: 16px; }
  .seller-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* --- Выбор города поиском, как в шапке (04.11) --------------------------------- */
.city-picker { position: relative; display: block; }

.city-picker-input {
  width: 100%;
  height: var(--field-h);
  padding: 0 12px;
  border: 1px solid var(--outline-variant);
  border-radius: 12px;
  background: var(--surface);
  color: var(--on-bg);
  font: inherit;
}

.city-picker-input:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; }

.city-picker-list {
  position: absolute;
  z-index: 40;
  left: 0;
  right: 0;
  top: calc(100% + 6px);
  max-height: 280px;
  overflow-y: auto;
  margin: 0;
  padding: 6px;
  list-style: none;
  background: var(--surface);
  border: 1px solid var(--outline-variant);
  border-radius: 12px;
  box-shadow: var(--shadow);
}

.city-picker-list li { margin: 0; }

.city-picker-list button {
  display: block;
  width: 100%;
  padding: 8px 10px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--on-bg);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.city-picker-list button:hover,
.city-picker-list button:focus-visible { background: var(--accent-soft); }

.city-picker-empty { padding: 8px 10px; color: var(--muted); font-size: .88rem; }

/* Отзывы отдельной карточкой (04.11). */
.review-block {
  display: grid;
  gap: 10px;
  padding: 16px;
  background: var(--surface);
  border: 1px solid var(--outline-variant);
  border-radius: var(--radius);
}

.review-block-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  font-size: .95rem;
}
