/* ─── Экран лота: воронка, характеристики, блоки, вертикали, просмотрщик ─────
   Грузится ПОСЛЕДНИМ из наших файлов: перекрывает часть правил кнопок
   действий из feed.css (`#detail .acts button` — крупнее, чем в ленте).
   ──────────────────────────────────────────────────────────────────────── */

/* ─── воронка разметки (31.07): стадия · важность · исход ─── */
/* Отдельная ось от 👍/👎: те отвечают «система права, что показала лот»,
   эта — «что Я с ним делаю». Блок намеренно выделен фоном: это не ещё один
   ряд кнопок, а другой по смыслу инструмент. */
.funnel {
  display: flex; flex-direction: column; gap: 8px;
  margin: 10px 0; padding: 10px 12px;
  background: var(--surface); border-radius: var(--r-sm);
}
.funnel-head { display: flex; align-items: center; justify-content: space-between;
  font-size: var(--fs-small); color: var(--ink-soft); }
.funnel-head .more {
  background: none; border: none; color: var(--ink-soft);
  /* 20px — размер самого глифа «…», а не роль в типографике: на шкалу не
     заводим, иначе смена заголовочной ступени поедет и сюда. */
  font-size: 20px; line-height: 1; padding: 0 6px; cursor: pointer;
}
.funnel-head .more.on { color: var(--accent); }
.funnel-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.funnel-row .lab { font-size: var(--fs-meta); color: var(--ink-soft); margin-right: 2px; }
.funnel-row button:not(.i) {
  flex: 0 1 auto; padding: 8px 10px; font-size: var(--fs-body);
  background: var(--bg); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-sm); cursor: pointer;
}
.funnel-row button[aria-pressed="true"] {
  background: var(--accent); color: var(--on-accent); border-color: var(--accent);
}
.funnel-row button:disabled { opacity: .45; }
.stage-mon { background: var(--accent-soft); color: var(--accent); }
/* Подсказка «i» — маленький кружок, тексты приходят с сервера. */
button.i {
  width: 20px; height: 20px; flex: 0 0 auto; padding: 0;
  border-radius: 50%; border: 1px solid var(--line);
  background: var(--bg); color: var(--ink-soft);
  font-size: var(--fs-meta); line-height: 1; cursor: pointer;
}
.funnel-note { display: flex; flex-direction: column; gap: 6px; }
.funnel-note .ask { font-size: var(--fs-small); color: var(--ink-soft); }
.funnel-note textarea {
  width: 100%; min-height: 68px; padding: 8px; font: inherit; font-size: var(--fs-body);
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--bg); color: var(--ink); resize: vertical;
}
.funnel-note .row { display: flex; align-items: center; gap: 8px; }
/* Журнал МОИХ пометок — визуально отделён от общих заметок ниже: они
   разной природы (общая заметка про ЛОТ, эта про МОЁ решение), и путать
   их нельзя. Отсюда подпись «только вы» и другой отступ. */
.journal { display: flex; flex-direction: column; gap: 6px; }
.journal-cap { font-size: var(--fs-meta); color: var(--ink-soft); }
.jrow { border-left: 2px solid var(--line); padding-left: 8px; font-size: var(--fs-small); }
.jrow .when { color: var(--ink-soft); margin-right: 6px; }
.jrow .jtext { margin-top: 2px; }
.outcome {
  align-self: flex-start; padding: 4px 8px; border-radius: var(--r-sm);
  background: var(--accent-soft); color: var(--accent); font-size: var(--fs-small);
}

/* Подпись над общей заметкой — чтобы её не путали с личным журналом выше. */
.notes-cap {
  display: flex; align-items: center; gap: 6px;
  margin-top: 12px; font-size: var(--fs-meta); color: var(--ink-soft);
}

/* Лист выбора исхода: `showPopup` Telegram умеет только 3 кнопки, а
   исходов четыре — поэтому свой. */
.sheet { position: fixed; inset: 0; z-index: 30; background: rgba(0,0,0,.4);
  display: flex; align-items: flex-end; }
.sheet-in {
  width: 100%; background: var(--bg); border-radius: 16px 16px 0 0;
  padding: 14px 14px calc(14px + env(safe-area-inset-bottom));
  display: flex; flex-direction: column; gap: 8px;
}
.sheet-h { display: flex; align-items: center; gap: 8px; font-size: var(--fs-ui); font-weight: 600; }
/* `:not(.i)` обязателен: без него кружок подсказки получал вид полноценного
   пункта меню и вставал в один ряд с исходами. */
.sheet-in button:not(.i) {
  padding: 12px; font-size: var(--fs-ui); text-align: left;
  background: var(--surface); color: var(--ink);
  border: none; border-radius: var(--r-sm); cursor: pointer;
}
.sheet-in button.ghost { text-align: center; color: var(--ink-soft); }

/* Правила широких экранов собраны ОДНОЙ секцией в конце файла (см. «широкие
   экраны: документ слева, действия справа»): так видно, что телефонная вёрстка
   выше не тронута ни одним из них, и это же проверяет сторож в тестах. */

/* ─── экран лота ─── */
/* Экран лота — белое полотно (полноэкранный документ), лента — серое.
   Без нижнего отступа: липкая панель кнопок не может выйти за пределы своего
   контейнера, и отступ здесь оставлял бы щель под ней. */
#screen-detail { background: var(--bg); min-height: 100vh; }
#detail { padding: 0; }
#gallery {
  display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none;
  padding: calc(10px + env(safe-area-inset-top)) 14px 4px;
  scroll-snap-type: x mandatory;
}
#gallery::-webkit-scrollbar { display: none; }
#gallery img {
  height: 190px; border-radius: 12px; scroll-snap-align: start;
  background: var(--surface);
}
#detail .pad { padding: 0 14px; }
/* Шапка «тип предмета» — верхняя строка канальной карточки. */
#detail .kind {
  font-size: var(--fs-caption); font-weight: 600; letter-spacing: .07em;
  color: var(--ink-soft); text-transform: uppercase; margin-top: 12px;
}
#detail h1 { font-size: var(--fs-title); line-height: 1.25; font-weight: 700; letter-spacing: -.015em; margin: 6px 0 3px; }
#detail .meta { font-size: var(--fs-small); color: var(--ink-soft); }
/* Предмет лота словами — то, ЧТО продают. */
#detail .subject { font-size: var(--fs-ui); margin: 8px 0 0; }
#detail .price-big { font-size: var(--fs-display); font-weight: 700; letter-spacing: -.02em; margin: 10px 0 10px; }

/* Таблица характеристик — разделители, не рамки. */
#detail table { width: 100%; border-collapse: collapse; font-size: var(--fs-body); margin-top: 4px; }
#detail td { padding: 9px 0; vertical-align: top; border-bottom: 1px solid var(--line); }
#detail tr:last-child td { border-bottom: 0; }
#detail td:first-child { color: var(--ink-soft); width: 42%; padding-right: 10px; }
#detail .desc { font-size: var(--fs-body); line-height: 1.5; white-space: pre-wrap; margin: 14px 0 6px; }
#detail .more {
  border: 0; background: none; padding: 6px 0; margin-bottom: 6px;
  color: var(--accent-strong); font: inherit; font-size: var(--fs-body); font-weight: 500;
}

/* ⚠️ Расхождение площадей: класс НТО, где ЕГРН-площадь контейнера
   перетирает площадь предмета (#21229). А ещё предупреждение про алко.
   Селектор ОБЯЗАН быть привязан к экрану лота. Без `#detail` слово `warn`
   становится общим на всё приложение, а имя это напрашивающееся: на экране
   «Ещё» подписи вида «7 сбоев» уже получили отсюда рамку с подложкой и
   отступами, которых им никто не задавал (поймано живьём 05.08). Класс
   ставит `renderDetail`, и ровно два места — обе внутри `#detail`. */
#detail .warn {
  margin: 12px 0 0; padding: 10px 12px; border-radius: var(--r-sm);
  border-left: 3px solid var(--warn);
  font-size: var(--fs-small); line-height: 1.45; background: var(--warn-soft); color: var(--warn);
}

/* Блоки парити с каналом: объекты, домохозяйства, self-storage, парковка. */
.block {
  margin: 12px 0 0; padding: 11px 13px; border-radius: var(--r-sm);
  background: var(--surface); display: flex; flex-direction: column; gap: 3px;
}
.block-title { font-size: var(--fs-ui); font-weight: 600; }
.block-line { font-size: var(--fs-body); line-height: 1.45; color: var(--ink-soft); }
.fold { margin: 4px 0 0; }

/* ─── заметки к лоту (Этап 5) ─── */
.notes { margin: 14px 0 0; display: flex; flex-direction: column; gap: 8px; }
.note {
  background: var(--surface); border-radius: var(--r-sm); padding: 10px 12px;
  border-left: 3px solid var(--line);
}
.note.mine { border-left-color: var(--accent); }
.note .who { font-size: var(--fs-meta); color: var(--ink-soft); margin-bottom: 3px; }
.note .body { font-size: var(--fs-body); white-space: pre-wrap; overflow-wrap: anywhere; }
#note-form { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
#note-form textarea {
  width: 100%; min-height: 72px; padding: 10px 12px; resize: vertical;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--bg); color: var(--ink); font: inherit; font-size: var(--fs-body);
}
#note-form .row { display: flex; gap: 6px; align-items: center; }
#note-form button {
  border: 0; border-radius: var(--r-sm); padding: 9px 14px;
  background: var(--accent); color: var(--on-accent);
  font: inherit; font-size: var(--fs-body); font-weight: 600;
}
#note-form button.ghost { background: var(--surface); color: var(--ink); }
#note-form .hint { font-size: var(--fs-meta); margin-left: auto; }

/* Фин-модель: три числа + кнопка. Числа — ответ на «когда вернётся, сколько
   вложить, какая доходность»; файл со всеми листами идёт вторым шагом. */
.finbox { margin: 14px 0 0; }
.finnums {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px;
  margin-bottom: 8px;
}
.finnum {
  background: var(--accent-soft); border-radius: var(--r-sm);
  padding: 8px 10px; min-width: 0;
}
.finnum .lab { font-size: var(--fs-caption); color: var(--ink-soft); }
.finnum .val {
  font-size: var(--fs-ui); font-weight: 600; color: var(--accent-strong);
  margin-top: 2px; overflow-wrap: anywhere;
}
.finnum .sub { font-size: var(--fs-caption); color: var(--ink-soft); margin-top: 1px; }

/* Ручные допущения модели — ставка аренды и целевая заполняемость
   (04.09.2026). Стоят между числами и кнопкой файла: сначала «что получилось»,
   потом «из чего это посчитано», потом «забрать книгу».
   Поля в столбик, кнопка одна на оба: пересборка книги стоит десять секунд
   процессора, и две подряд ради двух чисел — это двадцать секунд. */
.finparams { margin: 10px 0 0; }
.finparam + .finparam { margin-top: 10px; }
.finparams .lab {
  display: block; font-size: var(--fs-caption); color: var(--ink-soft);
}
.finparams input {
  display: block; width: 100%; margin-top: 4px; padding: 11px 12px;
  font: inherit; font-size: var(--fs-ui); color: var(--ink);
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--r-sm); box-sizing: border-box;
}
.finparams input:focus { outline: 2px solid var(--accent); outline-offset: -2px; }
.finparams input:disabled { color: var(--ink-soft); }
.finparams .apply {
  display: block; width: 100%; margin-top: 10px; padding: 11px 14px;
  border: 0; border-radius: var(--r-sm); font: inherit;
  font-size: var(--fs-ui); font-weight: 500;
  background: var(--accent-soft); color: var(--accent-strong);
}
.finparams .apply:disabled { background: var(--surface); color: var(--ink-soft); }
.finparams .sub {
  margin-top: 5px; font-size: var(--fs-caption); color: var(--ink-soft);
  line-height: 1.4; overflow-wrap: anywhere;
}
/* «Вернуть» — текстовая кнопка внутри подписи: это отмена, а не действие того
   же веса, что пересчёт, и плашки она не заслуживает. */
.finparams .linkish {
  padding: 0; border: 0; background: none; font: inherit;
  font-size: var(--fs-caption); color: var(--accent-strong);
  text-decoration: underline;
}
.finparams .status {
  margin-top: 5px; font-size: var(--fs-caption); color: var(--ink-soft);
}
/* «Числа посчитаны по другим допущениям» — состояние аварийное: значение уже
   сохранено, а пересборка книги упала. Тем же цветом, что расхождение
   площадей, — это тот же класс сообщения. */
.finparams .stale {
  margin-top: 8px; padding: 6px 8px; border-radius: var(--r-sm);
  background: var(--warn-soft); color: var(--warn);
  font-size: var(--fs-caption); line-height: 1.4;
}

/* Презентация лота: два формата рядом. Кнопки равного веса — выбор между
   «редактировать» и «переслать», а не главное и второстепенное действие.
   Статус отдельной строкой: первая сборка занимает до минуты, и молчащая
   кнопка в это время выглядит как сломанная. */
.deckbox { margin: 14px 0 0; }
.decktitle { font-size: var(--fs-ui); font-weight: 600; color: var(--ink); }
.deckbox .sub { font-size: var(--fs-caption); color: var(--ink-soft); margin-top: 2px; }
.deckrow { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 8px; }
.deckbtn {
  padding: 13px; border: 0; border-radius: var(--r-sm); font: inherit;
  font-size: var(--fs-ui); font-weight: 500;
  background: var(--accent-soft); color: var(--accent-strong);
}
.deckbtn:disabled { background: var(--surface); color: var(--ink-soft); }
.deckstatus { min-height: 16px; margin-top: 6px; }

/* Карта лота — действие того же веса, что «Скачать модель», а не ссылка. */
.map-open {
  display: block; width: 100%; margin: 8px 0 0; padding: 12px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--bg); color: var(--accent-strong);
  font: inherit; font-size: var(--fs-ui); font-weight: 600;
}
.map-open:active { background: var(--surface); }

/* Выбор профиля для копирования ссылки на карту: у продуктов, аптек, алко,
   кладовок и каждого ПВЗ своя карта — свои дома и свои конкуренты. */
.maplinks-list {
  margin-top: 6px; border: 1px solid var(--line); border-radius: var(--r-sm);
  overflow: hidden;
}
.maplink {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; padding: 11px 12px; border: 0; border-top: 1px solid var(--line);
  /* Цвета — токенами живой палитры. До 05.08 здесь и у приписки ниже стояли
     два имени из ПРЕЖНЕЙ палитры, которых в `:root` нет вовсе. Объявление с
     неизвестной переменной невалидно на этапе вычисления значения, свойство
     откатывается в `inherit` — и цвет держался случайно, унаследованным от
     родителя. У строки он совпадал с `--ink`, а вот приписка «N из M домов»
     из-за этого печаталась основным цветом вместо приглушённого, хотя
     задумана и набрана как вторичная (`--fs-meta`). */
  background: var(--bg); color: var(--ink); font: inherit; font-size: var(--fs-body);
  text-align: left;
}
.maplink:first-child { border-top: 0; }
.maplink:active { background: var(--surface); }
.maplink-note { color: var(--ink-soft); font-size: var(--fs-meta); flex: none; }

/* Аналитика по вертикалям — та же, что в карточке канала. */
.verticals { margin: 14px 0 0; display: flex; flex-direction: column; gap: 8px; }
.vert {
  background: var(--surface); border-radius: var(--r-sm); padding: 11px 13px;
  display: flex; flex-direction: column; gap: 5px;
}
.vert .head { display: flex; align-items: center; gap: 6px; font-size: var(--fs-ui); font-weight: 600; }
.vert .verdict { margin-left: auto; font-size: var(--fs-small); font-weight: 500; color: var(--ok); }
.vert .verdict.no { color: var(--ink-soft); }
.vert .nums { font-size: var(--fs-body); line-height: 1.45; color: var(--ink-soft); }
.vert .nums b { color: var(--ink); font-weight: 600; }
.vert a { color: var(--accent-strong); text-decoration: none; font-size: var(--fs-body); font-weight: 500; }
/* Приписка «мало метров» внутри блока вертикали. Селектор нарочно вложенный:
   имя `warn` в этом файле уже один раз протекло на всё приложение (см. коммент
   у `#detail .warn`), а эта пометка живёт только внутри `.vert`. Подложка та
   же, что у общего предупреждения, но кегль мельче — она спорит с галочкой в
   шапке блока, а не с карточкой лота. Ширину не задаём: блок и так тянется по
   колонке `.vert`, а `overflow-wrap` спасает узкий телефон. */
.vert .area-warn {
  padding: 6px 8px; border-radius: var(--r-sm);
  background: var(--warn-soft); color: var(--warn);
  font-size: var(--fs-small); line-height: 1.4; overflow-wrap: anywhere;
}

/* Кнопки карточки лота прилипают к низу экрана: страница длинная, и без
   этого после таблицы и описания за оценкой надо было листать обратно.
   ГОЧА: липнет ОБЁРТКА, а не сам ряд. `position: sticky` не может выйти за
   свой контейнер, а ряд лежит в коробочке по своей высоте — ездить внутри
   неё некуда, и панель просто не появлялась. */
#detail .actbar {
  position: sticky; bottom: 0; z-index: 4;
  margin: 16px -14px 0; padding: 8px 14px calc(8px + env(safe-area-inset-bottom));
  background: var(--bg); border-top: 1px solid var(--line); box-shadow: var(--shadow-up);
}
#detail .actbar .acts { margin: 0; }
#detail .acts button { height: 48px; font-size: var(--fs-lead); }

#detail .finmodel {
  display: block; width: 100%; margin: 14px 0 0; padding: 13px;
  border: 0; border-radius: var(--r-sm); font: inherit; font-size: var(--fs-ui); font-weight: 500;
  background: var(--accent-soft); color: var(--accent-strong);
}
#detail .finmodel:disabled { background: var(--surface); color: var(--ink-soft); }
/* Внешние ссылки — одним списком с разделителями, а не пятью отдельными
   кнопками: пять плашек подряд занимали пол-экрана и читались как пять
   разных действий одного веса. */
.links {
  display: flex; flex-direction: column; margin: 16px 0 0;
  background: var(--surface); border-radius: var(--r); overflow: hidden;
}
.links a {
  display: flex; align-items: center; padding: 13px 14px;
  color: var(--accent-strong); text-decoration: none; font-size: var(--fs-ui); font-weight: 500;
  border-bottom: 1px solid var(--line);
}
.links a:last-child { border-bottom: 0; }
/* 19px — размер шеврона, подогнанный к строке ссылки; роли в шкале у него нет. */
.links a::after { content: '›'; margin-left: auto; color: var(--ink-soft); font-size: 19px; line-height: 1; }
.links a:active { background: var(--accent-soft); }

/* ─── просмотрщик фото: карусель на весь экран с приближением ─── */
/* Тут единственное тёмное место в приложении, и это намеренно: фото
   рассматривают на чёрном, светлая рамка вокруг снимка мешает. */
#viewer { position: fixed; inset: 0; z-index: 20; background: #000; display: flex; flex-direction: column; }
#viewer-bar {
  display: flex; align-items: center; gap: 10px;
  padding: calc(8px + env(safe-area-inset-top)) 14px 8px;
  color: #fff; font-size: var(--fs-body);
}
#viewer-bar .grow { flex: 1; }
#viewer-bar button {
  border: 0; background: rgba(255, 255, 255, .16); color: #fff;
  width: 34px; height: 34px; border-radius: 17px; font-size: var(--fs-lead); line-height: 1;
}
#viewer-track {
  flex: 1; display: flex; overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory; scrollbar-width: none;
}
#viewer-track::-webkit-scrollbar { display: none; }
.vslide {
  flex: none; width: 100%; height: 100%; scroll-snap-align: center;
  overflow: auto; display: flex; align-items: center; justify-content: center;
}
/* Фото открывается ЦЕЛИКОМ в окно (contain), а не по ширине экрана: при
   `width: 100%` вертикальный снимок вылезал за экран и его приходилось
   прокручивать, чтобы увидеть весь (замечание юзера 30.07). Приближение
   задаёт инлайновую ширину в пикселях и снимает эти ограничения. */
.vslide img {
  max-width: 100%; max-height: 100%;
  width: auto; height: auto; margin: auto; display: block;
}
/* Подпись живёт в ВЕРХНЕЙ панели, а не в кадре: абсолютная подпись внутри
   прокручиваемого кадра позиционировалась относительно всего экрана, и все
   11 подписей налезали друг на друга. */
#viewer-cap { color: rgba(255, 255, 255, .7); }


/* ─── «Назад» вне Telegram (03.09) ────────────────────────────────────────
   В Mini App экран лота разбирает системная кнопка клиента. В браузере её
   нет, нижняя панель на экране лота спрятана (`.at-lot #nav` в layout.css),
   а «Назад» браузера уводил с сайта целиком — из карточки было не выйти.
   Кнопка ПЛАВАЮЩАЯ, а не в потоке: карточка начинается галереей во всю
   ширину, и кнопка в потоке отодвинула бы фото вниз на каждом лоте.
   ─────────────────────────────────────────────────────────────────────── */
#lot-back { display: none; }
.no-tg #screen-detail:not([hidden]) #lot-back {
  display: inline-flex; align-items: center; gap: 2px;
  position: fixed; z-index: 7;
  top: calc(10px + env(safe-area-inset-top)); left: 10px;
  height: 34px; padding: 0 12px 0 7px;
  border: 0; border-radius: var(--r-pill);
  /* Полупрозрачная плашка с размытием: под кнопкой оказывается то фото, то
     белый фон карточки, и сплошная заливка спорила бы с одним из двух. */
  background: color-mix(in srgb, var(--bg) 84%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(12px);
  backdrop-filter: saturate(180%) blur(12px);
  box-shadow: 0 1px 6px rgba(20, 32, 30, .18);
  color: var(--ink); font: inherit; font-size: var(--fs-ui); font-weight: 500;
  transition: transform var(--fast) ease;
}
#lot-back svg {
  width: 20px; height: 20px; fill: none; stroke: currentColor;
  stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
}
#lot-back:active { transform: scale(.96); }
/* На широком экране слева стоит колонка навигации (210 px, layout.css), и
   кнопка в углу окна ложилась ПОВЕРХ имени приложения в ней (живая проверка
   04.09: «Назад» закрывал «LotFind»). Сдвигаем на ширину колонки. */
@media (min-width: 1180px) {
  .no-tg #screen-detail:not([hidden]) #lot-back { left: calc(210px + 14px); }
}
/* Лот без фото начинается текстом — освобождаем под кнопку строку. Метку
   `nogal` ставит `renderDetail`: есть ли галерея, знает только он. */
.no-tg #detail.nogal { padding-top: 52px; }


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

   ЗАЧЕМ. Замер до правки (1280×800, контейнер уже ограничен 720 px):
     подпись в таблице     291 px из 692 — 42 % строки, значение начиналось
                           на трети ширины от подписи;
     страница              2350 px при экране 800 — почти три экрана;
     аналитика вертикалей  начиналась на 1501-й точке, воронка разметки
                           уезжала из экрана после первого же движения.
   То есть ради того, за чем лот открывают, надо было пролистать два экрана.

   РАЗМЕТКУ НЕ ТРОГАЕМ. Почти всё лежит плоскими детьми `.pad`, а сам `.pad`
   через `display: contents` растворяется: его дети становятся прямыми
   элементами грида `#detail` наравне с `#gallery`, и раскладывать их по
   колонкам можно явным назначением. Тот же приём уже держит карточку ленты
   (`.main` в feed.css).

   ГРАНИЦА 980 px — по замеру, а не на глаз, и ПЕРЕПРОВЕРЕНА на новом кегле
   05.08. Правой колонке нужно 300 px (четыре кнопки 👍/👎/⭐/📡 выходят по
   66 px, кнопки стадий воронки встают в два ряда), промежуток — 24 px,
   боковые поля — 28 px. Документ при этом не должен становиться уже ~620 px:
   на 618 px подпись в таблице занимает треть строки (перемерено: 195 px из
   618 — 31,6 %; при кегле 14 px было 191 из 618 — 30,9 %, то есть подъём
   шкалы этот предел не сдвинул), ниже — снова та беда, ради которой всё
   затевалось. Итого нужно 970 px ДОСТУПНОЙ ширины. Доступная — это окно
   МИНУС колонка навигации 210 px, которая появляется на 1180 px и на экране
   лота не прячется: на 1180 остаётся ровно 970 (документ 618), на 1179 — все
   1179. Один порог 980 обслуживает оба режима, провала на стыке нет.

   Порог НЕ поднимаем вслед за кеглем, и это осознанно. Соблазн есть: 620 px
   при кегле 14 — это 620 × 15/14 ≈ 664 при 15, а 664 + 352 = 1016. Но тогда
   две колонки включались бы с 1016, на 1180 (навигация съедает 210, остаётся
   970 → документ 618 < 664) схлопывались бы обратно в одну и снова
   разворачивались лишь к 1226. Провал на стыке хуже, чем документ на 618 px:
   это 72 знака в строке — тесно, но читаемо, и подпись в таблице держится
   под третью.

   Между 760 и 980 колонка одна: две туда не помещаются, а растягиваться
   документу нельзя — отсюда ограничение по `--content-max`.
   ──────────────────────────────────────────────────────────────────────── */

/* ─── wide: окно шире телефона ─── */
@media (min-width: 760px) {
  /* Лот перестаёт растягиваться. Ширину задаёт ЧИТАЕМОСТЬ СТРОКИ, а не размер
     окна и не лента: с 04.08 лента живёт по своему `--feed-max` (1500 px), и
     это законно — карточка объявления тратит ширину на фото и правую зону, а
     документ на длину строки. Равнять их больше нельзя.

     ЧИТАЕМАЯ ШИРИНА — ЗАМЕР, не вкус. 05.08, 60 живых описаний лотов
     (44 тыс. знаков), Inter 15 px, строки резались Range'ом по живой вёрстке;
     считались только строки, оборванные ПЕРЕНОСОМ (хвост абзаца занижает
     среднее). Развёртка по ширине колонки:
       700 → 84 знака · 720 → 87 · 740 → 89 · 750 → 90 · 760 → 91 · 792 → 96.
     Прежние 692 px давали 88–89 знаков ПРИ КЕГЛЕ 14 px (перемерено тем же
     способом — старый замер воспроизвёлся). На широком экране шкала поднялась
     (--fs-body 14 → 15), и ту же строку держит уже другая ширина:
     692 × 15/14 ≈ 741. Шире не растим: длинная строка читается хуже, а не
     лучше.

     `min()` — потому что `--content-max` общий на три экрана («Ещё», пороги,
     лот), и трогать его отсюда нельзя, а 820 px это 792 px текста = 96 знаков.
     Берём меньшее из «сколько разрешает общий токен» и «сколько читается»:
     токен остаётся верхней границей, читаемость — рабочей. Если токен
     когда-нибудь опустят до 778 (= 750 + поля), правило станет тождеством и
     ничего не изменит. */
  #screen-detail #detail {
    /* Поля документа. В одну колонку их держит `.pad` (14 px в телефонном
       правиле выше), в две — сам `#detail`: `.pad` там растворяется. Числа
       обязаны совпадать, иначе документ поедет на переходе между режимами. */
    --doc-pad: 14px;
    --doc-w: 750px;
    max-width: min(var(--content-max), calc(var(--doc-w) + var(--doc-pad) * 2));
    margin: 0 auto;
  }

  /* ГОЧА (поймано живьём 05.08). `more` — имя, занятое дважды: у нас это
     кнопки «Показать полностью» и «…» на карточке лота, а в more.css —
     КОНТЕЙНЕР экрана «Ещё», и он центрует себя `margin-left/right: auto` от
     760 px. more.css грузится ПОСЛЕ нас, специфичность у голого `.more` та
     же, что у `.funnel-head .more`, — и обе кнопки лота уезжали в середину
     колонки (кнопка описания — на 226 px от края при ширине 618).
     Забираем поля обратно на своей специфичности; на телефоне ничего не
     трогаем — там `.more` из чужого файла полей не задаёт вовсе. */
  #detail .more { margin-left: 0; margin-right: 0; max-width: none; }

  /* Подпись в таблице — по своему содержимому, а не 42 % строки. 42 % на
     телефоне это 152 px, и подписи занимают их целиком; на широком экране те
     же 42 % — это 311 px при 195 px букв, и между «Тип» и значением зияет
     треть строки.
     `width: 100%` у второй ячейки сжимает первую до максимума содержимого —
     обычный приём авторазметки таблицы: `display` менять не надо, семантика
     таблицы цела, и пустоты не остаётся вовсе.

     ГРАНИЦА 760, А НЕ 980 (правка 05.08). Правило родилось вместе с
     двухколоночным режимом и лежало в нём же — а беда начинается раньше, с
     любой ширины шире телефонной. Живьём на планшете 768: колонка подписи
     311 px из 740, а самая длинная подпись («Домохозяйств (оптимум)») —
     183 px, то есть 128 px пустоты после неё и куда больше после коротких
     («Тип» — 27 px букв на 311 px колонки). Чем шире документ, тем хуже: те
     же 42 % на читаемых 750 px — это уже 315 px.
     Замер после переноса (20 лотов ленты, все ширины): колонка 195 px = те же
     183 px букв плюс зазор — 26 % на 750, 28 % на 718, 31,6 % на 618 (самая
     узкая из двухколоночных ширин). Шире набор бывает у лотов с расхождением
     площадей, где появляется пара «Площадь помещения (из описания)/(ЕГРН)», —
     но и там ширина занята буквами, а не пустотой. Зазор 12 px, а не 16: на
     618 px эти 4 px решают, останется подпись под третью строки или нет. */
  #detail td:first-child { width: auto; white-space: nowrap; padding-right: var(--sp-3); }
  #detail td + td { width: 100%; }
}

/* ─── две колонки: документ · действия ─── */
@media (min-width: 980px) {
  #screen-detail #detail {
    /* `--doc-w` и `--doc-pad` объявлены выше, в правиле от 760 px: читаемая
       ширина — свойство документа, а не двухколоночного режима. */
    --rail-w: 300px;
    --rail-top: var(--sp-3);
    --rail-gap: var(--sp-3);
    /* Высота полосы кнопок — не «примерно»: от неё отсчитывается воронка,
       стоящая под ней в ТОЙ ЖЕ клетке грида (см. ниже). 48 (кнопка) + 8 + 8
       (поля) + 1 + 1 (рамка). От кегля не зависит: высота кнопки задана
       числом, и подъём шкалы (--fs-lead 17 → 20) её не тронул — 66 px
       перемерено живьём 05.08. */
    --rail-acts-h: 66px;

    /* Ширина контейнера — СУММА слагаемых: поля + документ + промежуток +
       колонка действий. Складывает их calc, а не я в уме: подобранное число
       молча разъезжается с тем, из чего оно сложено (так и вышло, когда
       шкала кегля выросла, а контейнер остался прежним). При рельсе 300 это
       1102 px, при 360 (см. «просторные экраны» ниже) — 1162 px. */
    max-width: calc(var(--doc-pad) * 2 + var(--doc-w) + var(--sp-6) + var(--rail-w));
    padding: 0 var(--doc-pad);

    display: grid;
    /* `minmax(0, 1fr)`, а не `1fr`: у грид-колонки минимум по умолчанию
       `auto`, и длинное слово в описании распирало бы её, выдавливая правую
       колонку за край. */
    grid-template-columns: minmax(0, 1fr) var(--rail-w);
    column-gap: var(--sp-6);
    /* Ряды БЕЗ зазора намеренно, и это не экономия: у блоков документа свои
       отступы полями, а правая колонка растянута на 200 рядов (см. ниже) —
       любой `row-gap` умножился бы на их число и разнёс бы карточку. */
    row-gap: 0;
    align-content: start;
  }
  /* `.pad` — обёртка без собственного вида; растворяем её, чтобы разложить её
     плоских детей по колонкам, не трогая разметку. Боковые поля обёртки при
     этом пропадают вместе с её коробкой — они переехали на `#detail` выше. */
  #screen-detail #detail .pad { display: contents; }

  /* ─── левая колонка: документ ─── */
  #screen-detail #detail .pad > * { grid-column: 1; min-width: 0; order: 9; }
  /* Галерея — часть документа, а не шапка во всю ширину: фото и
     характеристики смотрят вместе. Свои боковые поля ей больше не нужны —
     их держит `#detail`, и без этой отмены фото уезжали бы от текста. */
  #screen-detail #gallery {
    grid-column: 1; order: 1;
    padding-left: 0; padding-right: 0;
  }
  /* Порядок внутри документа переставлен `order`-ом — разметку менять нельзя,
     а листать два экрана до аналитики больше незачем: сначала «что это и
     проходит ли», потом справочник (таблица) и юридический текст описания.
     Переставляем ТОЛЬКО нечитаемые с клавиатуры блоки: обход по Tab идёт по
     разметке, и менять местами кнопки значило бы его порвать. В `.verticals`
     и `.block` интерактивного нет вовсе — там числа и вердикты. */
  #screen-detail #detail .pad > .kind,
  #screen-detail #detail .pad > h1,
  #screen-detail #detail .pad > .meta,
  #screen-detail #detail .pad > .subject,
  #screen-detail #detail .pad > .price-big,
  #screen-detail #detail .pad > .chips { order: 2; }
  #screen-detail #detail .pad > .verticals { order: 3; }
  #screen-detail #detail .pad > .block { order: 4; }
  #screen-detail #detail .pad > .warn { order: 5; }
  #screen-detail #detail .pad > table { order: 6; }
  #screen-detail #detail .pad > .fold { order: 7; }
  #screen-detail #detail .pad > .desc,
  #screen-detail #detail .pad > .more { order: 8; }

  /* Подпись в таблице сжата по содержимому правилом от 760 px (см. выше): на
     широком экране она нужна одинаково в обоих режимах, а не только в двух
     колонках. Подъём кегля её не сломал — 191 → 195 px, доля строки при этом
     не выросла, потому что вместе с подписью выросла и колонка. */

  /* ─── правая колонка: то, ради чего лот открывают ─── */
  /* Оба блока стоят в ОДНОЙ клетке (колонка 2 × все ряды) и разведены по
     вертикали отступом. Так пришлось потому, что независимых по высоте
     колонок из плоского списка грид не делает в принципе: ряд общий для обеих
     колонок, и его высота равна большему из двух блоков — соседние элементы
     документа расползлись бы под высоту блоков колонки действий.
     `span 200` — заведомо больше, чем блоков в карточке (их ~27). Клетка
     ОБЯЗАНА покрывать всю высоту документа: `position: sticky` не может выйти
     за свой контейнер, и в клетке по высоте самого блока ехать некуда —
     панель просто не появится (та же гоча, из-за которой на телефоне липнет
     обёртка, а не сам ряд кнопок). Пустые ряды при `row-gap: 0` не стоят
     ничего, а если документ окажется короче колонки — грид растянет ряды под
     неё, и низ колонки не обрежется. */
  #screen-detail #detail .pad > .actbar,
  #screen-detail #detail .pad > .funnel {
    grid-column: 2;
    grid-row: 1 / span 200;
    align-self: start;
  }
  /* Кнопки больше не приклеены к низу окна, а стоят карточкой справа сверху:
     на широком экране низ окна далеко от того места, куда смотрит глаз.
     Отрицательные поля `0 -14px` (они рассчитаны на телефонные поля `.pad`)
     здесь обязаны исчезнуть — иначе ряд вылезает за колонку. */
  #screen-detail #detail .actbar {
    position: sticky; top: var(--rail-top); bottom: auto;
    margin: 0; padding: var(--sp-2);
    /* Не `height`: ряд показывает ошибку действия строкой под кнопками, и
       жёсткая высота её обрезала бы. Строка вылезет за `min-height` и ляжет
       ПОВЕРХ воронки — `z-index: 4` из телефонного правила ровно для этого и
       остаётся, ошибку видно. */
    min-height: var(--rail-acts-h);
    border: 1px solid var(--line); border-radius: var(--r);
    /* Тень «вверх» была от полосы, приклеенной к низу; здесь карточка. */
    box-shadow: var(--shadow);
  }
  /* Воронка — сразу под кнопками, в той же клетке: отступ сверху ровно на их
     высоту плюс зазор. СВОЯ прокрутка обязательна — журнал пометок растёт, и
     без неё до нижних кнопок стадий было бы не добраться (ровно эта беда уже
     случалась с панелью фильтров, см. layout.css). `dvh` — для вебвью, где
     `vh` не учитывает съезжающую панель браузера; `vh` оставлен фолбэком.
     `overscroll-behavior` не пускает прокрутку дальше в документ. */
  #screen-detail #detail .funnel {
    position: sticky;
    top: calc(var(--rail-top) + var(--rail-acts-h) + var(--rail-gap));
    margin: calc(var(--rail-acts-h) + var(--rail-gap)) 0 0;
    max-height: calc(100vh - var(--rail-acts-h) - var(--rail-gap) * 3);
    max-height: calc(100dvh - var(--rail-acts-h) - var(--rail-gap) * 3);
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  /* Кнопки действий выключаются настройкой (`miniapp_actions_enabled`) — тогда
     ряда нет вовсе, и отступ под него оставлял бы дыру в начале колонки.
     Проверка вывернута наизнанку (`:not(:has(…))`) сознательно: если клиент
     не знает `:has()`, он выбросит ЭТО правило, и в редком случае «действия
     выключены» останется лишний отступ — а не наложение воронки на кнопки,
     как вышло бы при прямой записи. */
  #screen-detail #detail .pad:not(:has(> .actbar)) > .funnel {
    top: var(--rail-top);
    margin-top: 0;
    max-height: calc(100vh - var(--rail-gap) * 2);
    max-height: calc(100dvh - var(--rail-gap) * 2);
  }
}

/* ─── просторные экраны: колонке действий её собственная ширина ────────────
   300 px правой колонке подбирались под кегль 14 px, и на поднятой шкале ей
   стало тесно (замер 05.08, окно 1920, `--rail-w` крутился живьём):
     рельс 300 → кнопка 👍 66 px, ряд «Важность» переносится на две строки,
                 воронка 197 px высотой (227 с чипом «📡 Мониторинг»);
     рельс 360 → кнопка 81 px, ряд «Важность» распрямляется в одну строку,
                 воронка 155 px (185 с чипом);
     рельс 400 → кнопка 91 px — уже шире телефонной (86 px), дальше ширина
                 уходит в воздух, а не в дело.
   Берём 360: на телефоне кнопка 86 px, и 81 — это тот же вес, а не «крупнее
   потому что место есть». Два ряда кнопок стадий при чипе мониторинга
   остаются и на 360 — так и задумано, распрямлять их стоило бы 400+ px.

   ГРАНИЦА 1380 px — чтобы прибавка НЕ ушла за счёт документа, а взялась из
   пустого поля по краям. Контейнер при рельсе 360 просит
   14 + 750 + 24 + 360 + 14 = 1162 px ДОСТУПНОЙ ширины; доступная — это окно
   минус колонка навигации 210 px (layout.css, появляется на 1180 px и на
   экране лота не прячется) → 1162 + 210 = 1372, округляем вверх до 1380.
   Ниже границы документ остался бы своим (750 px), а рельс отобрал бы у него
   ровно те 60 px, что взял себе: на 1280 документ и так не добирает до
   читаемой ширины (718 px из 750). Выше границы не меняется НИЧЕГО, кроме
   одного слагаемого, — ширину контейнера пересчитает `calc` выше.
   ──────────────────────────────────────────────────────────────────────── */
@media (min-width: 1380px) {
  #screen-detail #detail { --rail-w: 360px; }
}

/* ─── мышь ────────────────────────────────────────────────────────────────
   `:hover` включаем только там, где указатель реально есть: на тач-экране
   «наведение» залипает после тапа, и кнопка остаётся подсвеченной до
   следующего касания. До этой правки в приложении был только `:active` —
   пальцу его хватает, мыши нет: она хочет знать, что под курсором нажимается,
   ДО нажатия. Цвета — только из палитры, новых не заводим. */
@media (min-width: 760px) and (hover: hover) {
  #detail .acts button,
  #detail .funnel-row button,
  #detail .more,
  #detail .finmodel,
  #detail .map-open,
  #detail .maplink,
  #detail button.i,
  #note-form button,
  .sheet-in button { cursor: pointer; }

  /* Ненажатое — темнеет заливкой и обводкой. `:not([aria-pressed="true"])`
     обязателен: без него это правило (у него `#detail` в селекторе, и оно
     специфичнее правила нажатого состояния из feed.css) красило бы нажатую
     кнопку серым, а подпись на акцентной заливке — тёмно-зелёным по
     тёмно-зелёному. */
  #detail .acts button:hover:not(:disabled):not([aria-pressed="true"]) {
    background: var(--line);
  }
  #detail .funnel-row button:not(.i):hover:not(:disabled):not([aria-pressed="true"]),
  #detail button.i:hover { border-color: var(--accent); color: var(--accent-strong); }
  /* Нажатое (и вообще всё, что УЖЕ залито акцентом) — светлым кольцом внутрь.
     Заливкой тут не отделаться: `--accent` и `--accent-strong` отличаются на
     один шаг и рядом неразличимы, а третьего тёмного в палитре нет и заводить
     его ради наведения нельзя. */
  #detail .acts button[aria-pressed="true"]:hover:not(:disabled),
  #detail .funnel-row button[aria-pressed="true"]:hover:not(:disabled),
  #note-form button:hover:not(:disabled):not(.ghost) {
    box-shadow: inset 0 0 0 2px var(--accent-soft);
  }
  /* Текстовая кнопка — подчёркиванием: она и так набрана акцентом, и сменить
     его на соседний оттенок значит не показать ничего. */
  #detail .more:hover { text-decoration: underline; }
  #detail .finmodel:hover:not(:disabled) { background: var(--accent); color: var(--on-accent); }
  #detail .finparams .apply:hover:not(:disabled) { background: var(--accent); color: var(--on-accent); }
  #detail .finparams .apply,
  #detail .finparams .linkish { cursor: pointer; }
  #detail .map-open:hover { background: var(--accent-soft); }
  /* Список ссылок лежит на `--surface`; строка под курсором ПОДНИМАЕТСЯ до
     белого, а нажатие остаётся акцентным — два разных состояния, не одно. */
  #detail .links a:hover { background: var(--bg); }
  #detail .maplink:hover { background: var(--surface); }
  #note-form button.ghost:hover:not(:disabled) { background: var(--line); }
  .sheet-in button:not(.i):hover { background: var(--line); }
}
