/* ─── Лента: карточка, плашки, группы, скелет, кнопки действий ───────────────
   Грузится ПОСЛЕ layout.css и ДО detail.css — тот перекрывает часть правил
   кнопок действий на экране лота (`#detail .acts button`).
   ──────────────────────────────────────────────────────────────────────── */

/* ─── ряд подразделов, когда их стало четыре (👍 Лайк, 05.08) ───────────────
   Кнопки ряда делят ширину поровну (`#segment button { flex: 1 }`), и на
   четырёх «Отработанные» перестаёт влезать: на экране 390 px это ~89 px на
   кнопку против ~108 px при трёх, а текст в ней `nowrap` + `overflow: hidden` —
   то есть обрезался бы МОЛЧА. Уменьшаем кегль и зазоры, но только когда кнопок
   действительно 4+: «количественный» селектор оставляет ряд Поиска (две
   кнопки — «Новые · Все») ровно таким, каким он был.
   Правило лежит здесь, а не в layout.css (каркас — вне границ этого пакета):
   feed.css грузится ПОСЛЕ него, поэтому каскад на нашей стороне. */
#segment button:first-child:nth-last-child(n+4),
#segment button:first-child:nth-last-child(n+4) ~ button {
  font-size: var(--fs-caption); gap: 3px; padding: 0 2px;
}

/* Важность в ленте: полоса слева + очень слабая заливка. Значком нельзя —
   красный на карточке уже занят плашкой срока «≤3 дней». */
/* Заливка — существующими «мягкими» цветами палитры, а не новыми: они уже
   выверены по контрасту с текстом карточки. */
.card.imp-high { border-left: 4px solid var(--danger); background: var(--danger-soft); }
.card.imp-medium { border-left: 4px solid var(--warn); background: var(--warn-soft); }
.card.done { opacity: .6; }

/* ─── лента ─── */
#feed { padding: 10px 12px 20px; display: flex; flex-direction: column; gap: 8px; }
/* Карточка — три полосы сверху вниз: «фото + текст», плашки, кнопки.
   Плашки и кнопки идут НА ВСЮ ШИРИНУ, а не в текстовой колонке справа от
   фото: в колонке 248 px плашки переносились на две строки, а под фото
   оставался пустой прямоугольник в 90 px — карточка выросла до 203 px и на
   экран влезало 3.3 штуки вместо ожидаемых 4.5. */
.card {
  display: flex; flex-direction: column; gap: 5px; padding: 9px;
  background: var(--bg); border-radius: var(--r); box-shadow: var(--shadow);
  cursor: pointer; transition: background var(--fast) ease;
}
.card .main { display: flex; gap: 10px; min-width: 0; }
.card:active { background: var(--surface); }
/* Фото 88×88 (плотность средняя, решение юзера п.37). */
.card .thumb {
  width: 88px; height: 88px; flex: none; border-radius: var(--r-sm);
  object-fit: cover; background: var(--surface);
}
/* Нет фото — рисованная заглушка, а не эмодзи: у 🏚 нет глифа в части
   системных шрифтов, и вместо домика показывался пустой квадрат. */
.card .thumb.empty {
  background: var(--surface) no-repeat 50% 50%;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30' viewBox='0 0 24 24' fill='none' stroke='%235C6B68' stroke-opacity='.5' stroke-width='1.4' stroke-linejoin='round'%3E%3Crect x='3' y='5' width='18' height='14' rx='2.5'/%3E%3Ccircle cx='8.6' cy='10' r='1.6'/%3E%3Cpath d='M4 17.2 8.6 12.6l3.4 3.4 3-3 5 3.6'/%3E%3C/svg%3E");
}

/* ─── кадры карточки: разметка одна, вид выбирает CSS ───────────────────────
   `shotsNode` (app.js) СТРОИТ ОДНУ И ТУ ЖЕ разметку на оба режима — обёртку
   `.shots` с полосой `.strip`, кадрами `.shot` (первый из них по-прежнему
   `.thumb`), точками, стрелками и подписью карты. Так карточка переживает
   изменение ширины окна без перерисовки ленты: режим выбирает медиазапрос, а
   не ветка в JS, которая сработала бы один раз при отрисовке.

   ЗДЕСЬ, вне медиазапросов, живёт ТЕЛЕФОННЫЙ вид — та же марочка 88×88, что и
   была: полоса не прокручивается (`overflow: hidden`, а не `auto`), кадры
   кроме первого не показываются вовсе, стрелок, точек и подписи нет. Ни один
   лишний кадр на телефоне и не грузится: `wake()` в app.js сверяется с
   `--bp-wide` до того, как проставить `src` (иначе тап «открыть лот» тянул бы
   по четыре миниатюры на каждую карточку). */
.card .shots { position: relative; width: 88px; height: 88px; flex: none; }
.card .strip { display: flex; height: 100%; overflow: hidden; }
.card .shot { flex: none; }
.card .shot ~ .shot { display: none; }
.card .nav, .card .dots, .card .cap { display: none; }
/* Обёртка «плашки, кроме срока»: на широком экране срок уезжает в правую зону
   к кнопкам, а остальные плашки остаются в текстовой колонке. На телефоне
   обёртки как будто нет — `display: contents` поднимает плашки прямыми детьми
   `.chips`, и ряд остаётся ровно тем же, что был. */
.tags { display: contents; }
.card .body { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 2px; }
.card .top { display: flex; align-items: baseline; gap: 8px; }
/* Цена — крупная и первая: по ней принимают решение смотреть дальше. */
.card .price { font-size: var(--fs-lead); font-weight: 700; letter-spacing: -.01em; }
.card .num { margin-left: auto; font-size: var(--fs-meta); color: var(--ink-soft); }
/* Адрес — вторым уровнем. */
.card .addr {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; font-size: var(--fs-body); line-height: 1.35;
}
.card .meta { font-size: var(--fs-small); color: var(--ink-soft); }

/* Значки профиля — отдельные плашки, а не хвост строки со сроком:
   склеенные в одну строку они читались как часть даты. */
.chips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 3px; }
.card .chips { margin-top: 0; }
.chip {
  padding: 2px 8px; border-radius: 8px; font-size: var(--fs-meta); line-height: 1.5;
  background: var(--surface); color: var(--ink);
}
.chip.due { background: var(--danger-soft); color: var(--danger); font-weight: 500; }
.chip.soon { background: var(--warn-soft); color: var(--warn); font-weight: 500; }
.chip.done { background: var(--surface); color: var(--ink-soft); }
/* Аренда — отдельным цветом: продаж 753 из 981, красить их все = шум. */
.chip.rent { background: var(--warn-soft); color: var(--warn); font-weight: 500; }

/* Группы ленты: дневной прогон кладёт десятки лотов сразу, и без границы
   «сегодняшнее / раньше» непонятно, что уже просмотрено. */
.group {
  font-size: var(--fs-meta); font-weight: 600; color: var(--ink-soft);
  padding: 8px 4px 2px; text-transform: uppercase; letter-spacing: .06em;
}
/* Подсветка сегодняшних — акцентная полоса слева и очень бледный фон. */
.card.fresh {
  background: var(--accent-tint);
  box-shadow: inset 3px 0 0 var(--accent), var(--shadow);
}
.card.fresh:active { background: var(--accent-soft); }

/* Скелет вместо «загружаю…»: на телефоне пустой экран читается как сбой.
   Повторяет три полосы карточки, иначе лента дёргается в момент подстановки
   данных. */
.skel {
  display: flex; flex-direction: column; gap: 5px; padding: 9px;
  background: var(--bg); border-radius: var(--r); box-shadow: var(--shadow);
}
.skel .main { display: flex; gap: 10px; }
.skel i { display: block; border-radius: 8px; background: var(--surface); animation: pulse 1.4s ease-in-out infinite; }
.skel .sq { width: 88px; height: 88px; flex: none; }
.skel .ln { height: 12px; margin-bottom: 9px; }
.skel .col { flex: 1; padding-top: 5px; }
.skel .bar { height: 22px; margin: 0; }
.skel .bar.tall { height: 34px; }
@keyframes pulse { 0%, 100% { opacity: 1 } 50% { opacity: .5 } }

/* ─── кнопки действий 👍/👎/⭐/📡 ─── */
.acts { display: flex; gap: 6px; margin-top: 8px; }
.acts button {
  /* Одинаковые кнопки: ширина делится поровну независимо от того, есть ли
     счётчик у 👍/👎 и стоит ли галочка у ⭐/📡. Без `flex-basis: 0` кнопка
     с текстом «📡 ✓» была бы шире соседних. */
  flex: 1 1 0; min-width: 0;
  display: flex; align-items: center; justify-content: center; gap: 4px;
  height: 34px; padding: 0 4px; border: 0; border-radius: 9px;
  background: var(--surface); color: var(--ink);
  font: inherit; font-size: var(--fs-ui); line-height: 1;
  transition: background var(--fast) ease, color var(--fast) ease;
}
.card .acts { margin-top: 1px; }
.acts button[aria-pressed="true"] { background: var(--accent); color: var(--on-accent); }
.acts button:disabled { opacity: .45; }
.acts .count { font-size: var(--fs-small); opacity: .85; }
.card.leaving { opacity: 0; transform: translateX(40px); transition: 180ms ease; }

/* ─── широкие экраны: строка-объявление вместо растянутой телефонной ──────
   ВСЁ, что ниже, лежит внутри медиазапросов: телефон (< 760 px) не меняется
   ни одним правилом. Числа границ продублированы литералами — в `@media`
   переменную подставить нельзя, единственный источник правды — `--bp-wide`
   в tokens.css; правя одно, правь и другое.

   ЗАЧЕМ (жалоба юзера 04.08: «всё так скомкано, можно же увеличить всё и
   информацию основную подсвечивать и фотографии сделать побольше, чтобы можно
   было пролистывать прям в ленте»). Карточка — три зоны:

     ┌──────────────┬────────────────────────────┬──────────────────┐
     │ фото-карусель│ 14 179 050 ₽        #28113 │      ещё 26 дней │
     │  ‹ ●●●●○ ›   │ Новосибирск,               │                  │
     │              │ ул. Курчатова, 7/5         │           👍 👎  │
     │              │ 364,5 м² · 1, 2 этаж       │           ⭐ 📡  │
     │              │ 🛒 продукты · 🍷 алко      │                  │
     └──────────────┴────────────────────────────┴──────────────────┘

   Разметку не трогаем: `.main` — лишняя обёртка «фото + текст», и
   `display: contents` поднимает `.shots` и `.body` в ПРЯМЫЕ элементы грида
   `.card`. Тем же приёмом разбирается `.chips`: срок становится элементом
   грида и уезжает в правую зону, а остальные плашки едут под текст вместе с
   обёрткой `.tags` (на телефоне обёртки как будто нет, см. выше).

   ТРИ КОЛОНКИ, а не четыре (в подпорке 04.08 остаток ширины отдавали ПУСТОЙ
   четвёртой): вердиктов по вертикалям в ленте не будет — решение юзера, — так
   что резервировать под них нечего. Остаток отдан колонке `1fr`, а её
   содержимое прижато к правому краю: получается вертикальная линейка «срок и
   действия» через всю ленту. Колонка 3 — `minmax(min-content, 1fr)`, а не
   `minmax(0, 1fr)`: с нулевым минимумом текстовая колонка на 768 px забирала
   бы всю ширину и выдавливала кнопки за край карточки.

   Ряды заданы явно (`max-content 1fr max-content`), и пустой РАСТЯЖИМЫЙ ряд
   посередине — не украшение. Высоту карточки задаёт фото, а не текст: на 1920
   это 240 px против 82 у цены с адресом и 72 у блока кнопок, то есть 78 px
   запаса (на 1280 — 30). Без пустого ряда грид раздал бы этот запас рядам с
   содержимым, и плашки повисли бы в пустоте посреди карточки. Растяжимый ряд
   собирает запас в себя, а содержимое встаёт по четырём углам: цена и срок
   сверху, плашки и кнопки — вровень с нижним краем фото.

   РАЗМЕР ФОТО. Ориентир юзера — «~320×240 на 1920, ~260×195 на 1280», то есть
   размер должен ЕХАТЬ вместе с окном; отдельного порога под это в токенах нет
   (есть только 760 и 1180), поэтому ширина считается формулой, а не ступенями:
     clamp(240, 20vw, 320)  →  768: 240 · 1280: 256 · 1600+: 320
   Пропорция 4:3 — медианная у самих миниатюр (замер 60 оригиналов: 1.33), так
   что `object-fit: cover` почти ничего не срезает. Источник — 400 px по
   длинной стороне: при показе 320 это запас 1.25×, менять его не нужно.

   ЦЕНА ЭТОГО РЕШЕНИЯ (замер живой ленты, «стало» — с фото и каруселью):
                          было              стало
     1280×800   карточка 1046×132     1046×216   в экране 4 → 2
     1920×1080  карточка 1476×132     1476×264   в экране 6 → 3
   Высоту карточки теперь задаёт фото, а не текст, и это меняет прежний расчёт
   в обе стороны: под текстом появился запас, поэтому вторая строка плашек
   больше НИЧЕГО не стоит (раньше добавляла карточке 26 px), но лотов в экране
   стало вдвое меньше. Так и просили: «фотографии побольше, чтобы можно было
   пролистывать прям в ленте» — плотность разменяна на просмотр фото без
   захода в лот. */
@media (min-width: 760px) {
  /* Размер кадра — одной переменной на карточку И скелет: разойдись они хоть
     на пиксель, лента дёрнется в момент подстановки данных (это уже ловили
     тестом). Живёт на `#feed`, а не в tokens.css: это не токен темы, а размер
     одного компонента, и в ленте он единственный. */
  #feed {
    --shot-w: clamp(240px, 20vw, 320px);
    --shot-h: calc(var(--shot-w) * 3 / 4);
  }
  .card {
    display: grid;
    grid-template-columns: var(--shot-w) minmax(0, 640px) minmax(min-content, 1fr);
    grid-template-rows: max-content 1fr max-content;
    align-items: start;
    column-gap: var(--sp-4);
    row-gap: var(--sp-1);
    padding: var(--sp-3);
  }
  .card .main { display: contents; }

  /* ─── зона 1: фото-карусель ─── */
  .card .shots {
    grid-column: 1; grid-row: 1 / -1;
    width: var(--shot-w); height: var(--shot-h);
  }
  /* Полоса кадров прокручивается ПО ГОРИЗОНТАЛИ и защёлкивается на кадре.
     `touch-action` перечисляет ОБЕ оси намеренно: одинокий `pan-x` отнял бы у
     ленты вертикальную прокрутку — палец, начавший движение на фото, не смог
     бы пролистать ленту дальше. `overscroll-behavior-x: contain` не даёт
     докрутке до края уйти в жест «назад» у браузера. */
  .card .strip {
    overflow-x: auto; overflow-y: hidden;
    scroll-snap-type: x mandatory;
    overscroll-behavior-x: contain;
    touch-action: pan-x pan-y;
    scrollbar-width: none;
    border-radius: var(--r-sm);
  }
  .card .strip::-webkit-scrollbar { width: 0; height: 0; }
  /* Кадр ровно в размер полосы. Правило перекрывает телефонные 88×88 у
     `.thumb` (первый кадр — он же) ПОРЯДКОМ: специфичность одинаковая, а этот
     блок ниже по файлу. */
  .card .shot {
    width: 100%; height: 100%;
    scroll-snap-align: start; scroll-snap-stop: always;
    object-fit: cover;
  }
  .card .shot ~ .shot { display: block; }
  /* Карта — не фотография: `cover` срезал бы у неё края вместе с домами, ради
     которых её и показывают. Вписываем целиком на подложку. */
  .card .shot.map { object-fit: contain; background: var(--surface); }
  /* Заглушка «нет фото» рисуется 30-пиксельным SVG — на кадре 320×240 он
     выглядел бы точкой; масштабируем фоном, картинка векторная. */
  .card .thumb.empty { background-size: 56px 56px; }
  /* Точки-индикатор: белая пилюля, а не голые точки на фото — на светлом
     снимке белая точка исчезает, а на тёмном исчезла бы тёмная. */
  .card .dots {
    display: flex; gap: 4px; align-items: center;
    position: absolute; left: 50%; bottom: 6px; transform: translateX(-50%);
    padding: 3px 5px; border-radius: 8px; background: var(--bg); opacity: .9;
  }
  .card .dots i { width: 5px; height: 5px; border-radius: 50%; background: var(--ink-soft); opacity: .35; }
  .card .dots i.on { background: var(--accent); opacity: 1; }
  /* Подпись показывается только на кадре карты (её ставит app.js): без неё
     последний кадр читается как «фото с птичьего полёта». */
  .card .cap {
    display: block; position: absolute; left: 6px; bottom: 6px;
    padding: 1px 6px; border-radius: 7px;
    background: var(--bg); color: var(--ink-soft);
    font-size: var(--fs-caption); line-height: 1.6; opacity: .9;
  }

  /* ─── зона 2: текст ─── */
  .card .body { grid-column: 2; grid-row: 1; }
  /* Подсветка главного: цена — первое и самое крупное на карточке, дальше
     адрес, дальше площади, дальше плашки (26 · 16 · 14 · 13 на широком
     экране). Размеры — только ролями из шкалы, своих чисел здесь нет. */
  .card .price { font-size: var(--fs-title); }
  .card .addr { font-size: var(--fs-ui); }
  /* Номер лота НАМЕРЕННО оставлен телефонным `margin-left: auto`, хотя
     подпорка 04.08 гасила его в `0`. Тогда `1fr` растягивал текст на 1180 px и
     номер улетал от цены; теперь колонка ограничена 640 px, и номер стоит у её
     правого края одной линейкой во всех карточках — по нему и ищут лот. */
  .card .tags {
    grid-column: 2; grid-row: 3;
    display: flex; flex-wrap: wrap; gap: var(--sp-1);
  }
  /* Всё, кроме аренды, — тише: цвет плашки должен означать «требует решения»
     (срок ≤ 3 дней, аренда), а не «здесь тоже что-то написано». */
  .card .tags .chip:not(.rent) { color: var(--ink-soft); }

  /* ─── зона 3: срок и действия, прижаты к правому краю ─── */
  /* `display: contents` разбирает ряд плашек: срок (прямой потомок) уезжает в
     правую зону, остальные едут под текст вместе с обёрткой `.tags`. */
  .card .chips { display: contents; }
  /* Прямой `.chip` внутри `.chips` — это срок, единственная плашка, которую
     `chipsNode` кладёт МИМО `.tags`. */
  .card .chips > .chip {
    grid-column: 3; grid-row: 1; justify-self: end;
    font-size: var(--fs-small);
  }
  /* `.actbox` — обёртка «кнопки + строка ошибки» из `actionRow` (app.js).
     Раньше её ловили как «ребёнок, который не .main и не .chips»: правило
     поехало бы от любого нового узла карточки. */
  .card > .actbox { grid-column: 3; grid-row: 3; justify-self: end; align-self: start; }
  /* Действия — сеткой 2×2, а не рядом из четырёх: ряд шириной 212 px стал бы
     минимумом третьей колонки и на 1280 отобрал бы у текста 118 px. 50×34 —
     по содержимому самой широкой кнопки («👍 12» ≈ 46 px). */
  .card .acts {
    display: grid; grid-template-columns: repeat(2, 50px);
    gap: var(--sp-1); margin-top: 0;
  }
  /* `flex: 1 1 0` в гриде и так не действует, но оставлять его — врать о
     намерении: в этом режиме кнопка фиксированной ширины. */
  .card .acts button { flex: 0 0 auto; }

  /* Скелет ОБЯЗАН повторять новые размеры: он показывается до подстановки
     данных, и разойдись он с карточкой хоть на пиксель — лента прыгнет в
     момент замены (это уже ловили тестом). Разметка скелета совпадает по
     смыслу: `.sq` — фото, `.col` — текст, `.bar` — плашки, `.bar.tall` —
     кнопки. Селекторы через `#feed` намеренно: ТУ ЖЕ разметку скелета
     показывает экран лота, пока грузится карточка, и там она означает
     совсем другое — раскладывать её по колонкам ленты нельзя. */
  #feed .skel {
    display: grid;
    grid-template-columns: var(--shot-w) minmax(0, 640px) minmax(min-content, 1fr);
    grid-template-rows: max-content 1fr max-content;
    align-items: start;
    column-gap: var(--sp-4);
    row-gap: var(--sp-1);
    padding: var(--sp-3);
  }
  #feed .skel .main { display: contents; }
  #feed .skel .sq { width: var(--shot-w); height: var(--shot-h); grid-column: 1; grid-row: 1 / -1; }
  #feed .skel .col { grid-column: 2; grid-row: 1; }
  #feed .skel .bar { grid-column: 2; grid-row: 3; }
  /* 104×72 — размер блока кнопок: 2×50 + 4 в ширину, 2×34 + 4 в высоту.
     Меняешь кнопку — пересчитай здесь, иначе скелет разойдётся с карточкой. */
  #feed .skel .bar.tall {
    grid-column: 3; grid-row: 3; justify-self: end;
    width: 104px; height: 72px;
  }
}

/* ─── стрелки карусели: только там, где есть мышь ────────────────────────
   Пальцем кадры листают свайпом, и стрелки на планшете только закрывали бы
   фото. `(hover: hover)` — тот же приём, что у подсветки карточки ниже.
   Показываем их по наведению НА КАРУСЕЛЬ, а не на карточку: иначе стрелки
   всплывали бы каждый раз, когда курсор просто идёт через ленту. */
@media (min-width: 760px) and (hover: hover) {
  .card .nav {
    display: flex; align-items: center; justify-content: center;
    position: absolute; top: 50%; margin-top: -14px;
    width: 28px; height: 28px; padding: 0 0 2px;
    border: 0; border-radius: 50%;
    background: var(--bg); color: var(--ink);
    font: inherit; font-size: var(--fs-title); line-height: 1;
    box-shadow: var(--shadow); cursor: pointer;
    opacity: 0; transition: opacity var(--fast) ease;
  }
  .card .nav.prev { left: 6px; }
  .card .nav.next { right: 6px; }
  .card .shots:hover .nav, .card .nav:focus-visible { opacity: 1; }
}

/* ─── наведение мыши ─────────────────────────────────────────────────────
   На телефоне состояния наведения нет вовсе (есть `:active`), а на широком
   экране курсор должен получать ответ. `(hover: hover)` — чтобы правило не
   доставалось планшету, где «наведение» залипает после тапа.

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

   Новых значений не вводим: заливка — существующие `--surface`/`--accent-soft`
   (те же, что у нажатия), глубина — тот же токен `--shadow`, взятый трижды.
   Каждый модификатор перекрыт ЯВНО своим цветом: фон карточки несёт смысл
   (сегодняшний · важность), и наведение не имеет права его стирать. */
@media (min-width: 760px) and (hover: hover) {
  .card { transition: background var(--fast) ease, box-shadow var(--fast) ease; }
  .card:hover { background: var(--surface); box-shadow: var(--shadow), var(--shadow), var(--shadow); }
  /* У «сегодняшних» тень несёт ещё и акцентную полосу слева — не повторишь её
     здесь, и при наведении полоса пропадёт. */
  .card.fresh:hover {
    background: var(--accent-soft);
    box-shadow: inset 3px 0 0 var(--accent), var(--shadow), var(--shadow), var(--shadow);
  }
  /* Важность остаётся своим цветом — под курсором она только «приподнимается». */
  .card.imp-high:hover { background: var(--danger-soft); }
  .card.imp-medium:hover { background: var(--warn-soft); }
}
