/* Экран «Магазин»: полки по разделам каталога, подкатегории внутри полки,
   редкость, сравнение с надетым, скупка.
   Общее (.win, .grid, .tabs, .tab, .btn, .price, .muted, .req-bad) живёт
   в public/styles.css, а поверх — public/dtf-theme.css. Здесь только своё,
   и написано оно на общих переменных (--ink, --ink-soft, --link), чтобы экран
   одинаково читался и в базовой теме, и в светлой теме DTF.

   ОДНА СЕТКА НА ЭКРАН (просьба владельца 11.08.2026: «всё какое-то
   перегруженное, всё пляшет»). Строка товара — пять колонок: иконка, название,
   одно главное число, цена, кнопка. Ширины цены и кнопки заданы жёстко, так
   что у всех тридцати вещей полки они стоят на одной вертикали, а числа идут
   столбиком (tabular-nums). Всё, что раньше жило в строке россыпью — свойства,
   требования, шутка-подпись, сравнение с надетым, — уехало в раскрытие.

   СЕРОГО МЕНЬШЕ. Заливок в витрине больше нет ни одной: «Копить на», раскрытая
   карточка вещи и итог корзины — белые, с тонкой линией по краю. Плашка внутри
   плашки запрещена: карточка раскрытия одна, и сравнение с надетым лежит прямо
   в ней, без своей подложки. Цвет остался там, где он что-то говорит: кант
   и слово редкости, красная пометка требований, зелёные и красные ЧИСЛА
   сравнения (у самих чисел, а не под ними).

   КОНТРАСТ. Всё, что тут написано словами, держит 4.5:1, а цветные канты —
   3:1 (WCAG 2.1, посчитано, а не на глаз). Из-за этого экран сознательно НЕ
   берёт --dim, --life и --blood: на светлых панелях темы DTF они дают 3.2–3.5,
   то есть подпись, которую и есть-то незачем. Взамен три своих токена ниже.
   Текст тише делаем кеглем и насыщенностью, а не бледностью.

   ДВИЖЕНИЯ ТУТ НЕТ СОВСЕМ: ни одного transition и ни одной анимации. Витрина
   ничего не сообщает о состоянии боя, мигать ей не с чего (.claude/skills/
   arena-motion — «анимация допустима, только если объясняет изменение»). */

.shop {
  --shop-line: var(--dtf-line, #a89670);
  --shop-sheet: var(--dtf-surface, #fffdf6);

  /* Тихий текст витрины — свойства вещи, требования, пояснения, подписи.
     --dim сюда не годится: в теме DTF это #8a8a8a, и он даёт 3.45:1 на белой
     строке при норме 4.5:1 — главная подпись раскладки просто не читалась.
     --ink-soft играет ту же роль «тише основного», но с запасом: 6.29:1 на
     строке. Иерархию держат кегль, курсив и жирность, а не бледность. */
  --shop-quiet: var(--ink-soft);

  /* Числа «стало лучше» и «стало хуже». Тема даёт для них --life (#2f9e44)
     и --blood (#e5484d), но это 3.18:1 и 3.54:1. Берём те же тона плотнее —
     6.45:1 и 6.32:1 на белом; красный взят ровно тот, каким dtf-theme.css уже
     пишет ошибки, чтобы экраны не спорили. */
  --shop-good: #22662f;
  --shop-bad: #a42d32;
}

.shop b { color: var(--ink); }
.shop .muted { color: var(--shop-quiet); }

/* Тихая строка витрины: приписки под списками, пояснения, «ничего не
   изменится». Тише не бледностью, а кеглем — 12 против 13 у строки товара. */
.shop-note {
  font-size: 12px;
  line-height: 1.45;
}
.shop .shop-note { color: var(--shop-quiet); }

/* ── Кошелёк и цель ────────────────────────────────────────────────────────── */

.shop-purse { margin-bottom: 8px; font-size: 15px; }
.shop-purse b { color: var(--link); }

/* «Копить на» — белая карточка с тонкой линией вместо серой заливки.
   Специфичность в две метки нарочно: dtf-theme.css подключён позже и красит
   .shop-goal своим #f6f6f6. */
.shop .shop-goal {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr);
  gap: 8px;
  align-items: center;
  padding: 8px 10px;
  background: transparent;
  border: 1px solid var(--shop-line);
  border-radius: 10px;
}
.shop-goal-head {
  font-size: 11px;
  letter-spacing: .4px;
  text-transform: uppercase;
  white-space: nowrap;
}
.shop-goal-icon { line-height: 0; }
.shop-goal-text { min-width: 0; line-height: 1.45; }
.shop-goal-text b { color: var(--link); }

/* ── Полка: пять колонок ───────────────────────────────────────────────────── */

/* Содержимое ячеек прижато кверху. Специфичность нарочно выше, чем у общей
   строки styles.css («table.grid th, table.grid td { vertical-align: middle }»):
   с одиночным .shop-goods td правило не работало вовсе и молча проигрывало. */
table.grid.shop-goods td { vertical-align: top; }

/* Шапка таблицы: без серой заливки и без капса — четыре слова тонкой строкой
   над столбцами. Специфичность выше, чем у table.grid th из темы (там #fafafa). */
table.grid.shop-goods thead th {
  padding-bottom: 4px;
  background: transparent;
  border-bottom: 1px solid var(--shop-line);
  color: var(--shop-quiet);
  font-size: 11px;
  font-weight: normal;
  letter-spacing: 0;
  text-transform: none;
  text-shadow: none;
  white-space: nowrap;
}

/* 62 = рамка редкости 38 (см. .shop-art) + поля ячейки 12+12: столбец не должен
   разъезжаться от того, что вещь редкая.

   БЫЛО 48 ПОД ЗНАЧОК 26 — И ЭТО СПЛЮЩИВАЛО ВСЕ 133 КАРТИНКИ ПОЛКИ И СКУПКИ.
   Значок вырос до 34, рамка — до 44, а объявленная ширина столбца осталась
   прежней. Дальше срабатывала связка, которую поодиночке не увидеть:
   adaptive.css держит на всех картинках «img { max-width: 100% }», картинка
   от этого сжимаема, значит наименьшая ширина ячейки для таблицы почти нулевая,
   и таблица честно выдавала ровно заказанные 48. Внутри на рисунок оставалось
   48 − 24 (поля) − 8 (поля рамки) − 2 (кант) = 14 точек ШИРИНЫ при 34 точках
   ВЫСОТЫ: пропорция 1:1 ломалась вдвое с лишним, и вещи на полке выглядели
   раздавленными по горизонтали. Тонкие предметы (стилус, линейка, паяльник,
   резак, штатив) при этом превращались в волосок и переставали узнаваться —
   ровно то, на что жаловался владелец.

   Чтобы это не вернулось: ширина столбца обязана быть не меньше рамки плюс
   поля ячейки, а сама рамка ниже задана жёсткой коробкой (не сжимается). */
.shop-icon { width: 62px; line-height: 0; }
/* Цена и кнопка — жёсткой ширины: только так они стоят на одной вертикали
   у всех строк полки, а числа читаются столбиком. */
.shop-cost { width: 92px; white-space: nowrap; }
.shop-act { width: 104px; white-space: nowrap; }

/* ЧИСЛА ПРИЖАТЫ ВПРАВО — иначе никакого столбика нет. Правило стояло тут же,
   на одиночных .shop-cost и .shop-act, и молча не работало: общая строка
   таблицы из styles.css («table.grid th, table.grid td { text-align: left }»)
   весит по WCAG-у специфичности (0,1,2) против (0,1,0) у класса и перебивала
   его. Цены из-за этого шли от ЛЕВОГО края столбца, и на 1280 px «15»
   кончалось на x=993, а «380» — на x=1002: девять точек разнобоя на каждой
   паре соседей. Теперь в селекторе две метки и тип, (0,2,2) — своё берёт верх.
   Заголовок столбца прижимаем тем же правилом: подпись «Цена, плюсы» обязана
   стоять над своими числами, а не над пустым местом слева от них. */
table.grid.shop-goods th.shop-cost,
table.grid.shop-goods td.shop-cost,
table.grid.shop-goods th.shop-act,
table.grid.shop-goods td.shop-act { text-align: right; }
/* Ширина главного числа задана долей нарочно: полка и Скупка — две разные
   таблицы, и без неё столбец «что даёт» вставал бы у них по-разному. */
.shop-main { width: 34%; line-height: 1.45; }
.shop .shop-main { color: var(--ink); }

.shop-cost .price,
.shop-cost .shop-note { font-variant-numeric: tabular-nums; }
/* Слово «плюсов» на широком экране не нужно: над столбцом написано
   «Цена, плюсы», и повторять его тридцать раз — это и есть шум. */
.shop-unit { display: none; }
.shop .price.is-done { color: var(--shop-quiet); font-weight: normal; }

/* Название — оно же кнопка раскрытия: отдельной ссылки «подробнее» в строке
   нет, по названию рука тянется сама. Выглядит как обычный заголовок строки,
   подчёркивание появляется под мышью — иначе полка выглядела бы списком
   тридцати ссылок. */
.shop-open {
  display: inline;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  text-align: left;
  color: inherit;
  cursor: pointer;
}
/* Пунктир под названием — единственный указатель, что строку можно раскрыть.
   Значок-уголок тут стоял раньше и читался как знак препинания: он вставал
   ровно между именем и плашкой редкости. Пунктир ничего не занимает и говорит
   то же самое; под мышью он становится сплошным. */
.shop-name-text {
  font-weight: bold;
  border-bottom: 1px dashed var(--shop-quiet);
}
.shop .shop-name-text { color: var(--ink); }
.shop-open:hover .shop-name-text { border-bottom-style: solid; }
/* Вещь из старого сохранения раскрывать нечем — каталог о ней ничего не знает,
   и пунктир под названием обещал бы то, чего нет. */
.shop-name-text.is-plain { border-bottom: 0; }

/* Тихая пометка у названия: «из старого сохранения». Не красная — это не
   ошибка игрока, а просто след прежней версии. */
.shop-mark {
  margin-left: 6px;
  font-size: 11px;
  white-space: nowrap;
}
.shop .shop-mark { color: var(--shop-quiet); }
.shop-open:focus-visible { outline: 2px solid var(--link); outline-offset: 2px; }

/* Заголовок подкатегории. Ни заливки, ни рельса — тонкая линия сверху и пара
   слов. Специфичность нарочно выше, чем у полосатости и наведения из
   styles.css (table.grid tr:nth-child(even) td, table.grid tbody tr:hover td). */
table.grid.shop-goods tr.shop-subhead td,
table.grid.shop-goods tbody tr.shop-subhead:hover td {
  padding: 12px 12px 4px;
  background: transparent;
  border-bottom: 1px solid var(--shop-line);
}
.shop-subhead-name {
  font-size: 12px;
  font-weight: bold;
  letter-spacing: .3px;
  text-transform: uppercase;
  color: var(--ink);
}
.shop-subhead-count {
  margin-left: 8px;
  font-size: 11px;
  color: var(--shop-quiet);
  white-space: nowrap;
}

/* Шутка-подпись живёт только в раскрытии. Цвет — отдельным правилом: тема
   подключена позже и красит .shop-lore своим #8a8a8a. */
.shop-lore {
  margin: 6px 0 0;
  font-size: 11.5px;
  line-height: 1.45;
  font-style: italic;
}
.shop .shop-lore,
.shop .shop-goal-head { color: var(--shop-quiet); }

/* Красная пометка у строки: первое невыполненное требование, три слова.
   Подробности — в раскрытии. Кант, а не заливка: строка и так не пустая. */
.shop-lock {
  display: inline-block;
  margin-left: 6px;
  padding: 0 5px;
  font-size: 11px;
  line-height: 15px;
  vertical-align: 1px;
  white-space: nowrap;
  border: 1px solid var(--shop-bad);
  border-radius: 3px;
}
.shop .shop-lock { color: var(--shop-bad); }

/* На широком экране пометка говорит, ЧЕГО не хватает; короткий вариант ждёт
   узкого экрана (см. media в конце файла). Ровно тот же приём, что у слова
   «плюсов» в цене: два комплекта слов, показан всегда один. */
.shop-lock-short { display: none; }

/* ── Редкость ──────────────────────────────────────────────────────────────── */

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

   Ровно эти же пять строк живут в public/ui/profile.css (.hero .rar-*) — одна
   вещь обязана краситься одинаково в магазине и в снаряжении, поэтому значения
   взяты оттуда слово в слово. */
.shop .rar-common { --rar-ink: var(--shop-quiet); --rar-edge: transparent; --rar-back: transparent; }
.shop .rar-uncommon { --rar-ink: #2c6b34; --rar-edge: #3f8a4f; --rar-back: #edf7ef; }
.shop .rar-rare { --rar-ink: #0b4fae; --rar-edge: #2f6fbf; --rar-back: #e9f2ff; }
/* Жёлтой была вся СТРОКА товара — её владелец и убрал (11.08.2026): полка
   от этого желтела целиком. Подложка под значком и плашка со словом
   остаются тёплыми: это мелкие пятна, они метят вещь, а не заливают полку. */
.shop .rar-legend { --rar-ink: #8a5a06; --rar-edge: #9c7210; --rar-back: #fff6e2; }
.shop .rar-unique { --rar-ink: #5f34a0; --rar-edge: #7f57c6; --rar-back: #f4edff; }

/* Рамка вокруг иконки. У обычной вещи она прозрачная, но место занимает —
   иначе соседние строки прыгали бы по высоте.

   КОРОБКА ЖЁСТКАЯ, 38×38, И ЭТО ГЛАВНОЕ. Пока рамка была inline-block по
   содержимому, ширину значка решала таблица — и решала неверно (см. длинную
   записку у .shop-icon выше). Заданный размер снимает вопрос: что бы ни
   творилось со столбцом, рисунок внутри остаётся квадратным.

   Селектор двойной (.shop .shop-art) остался с тех пор, когда dtf-theme.css
   ставил на одиночный .shop-art своё поле. Правило из темы убрано 12.08.2026
   (рамка значка — дело витрины), но двойной селектор не мешает и стережёт от
   повторения: тема подключается позже и перебила бы одиночный.
   При равном весе побеждает тот, кто ниже, поэтому одиночным классом отсюда
   ничего не задать — нужен вес выше. Панели Магазина все несут класс .shop
   (win(..., {cls:'shop'})), так что попадание полное.

   ОТКУДА 38. У всех 28 файлов рисунок занимает 224 точки из 256, то есть
   вокруг него уже есть своё прозрачное поле в 6,25 % с каждой стороны. При
   значке 34 это 2,1 точки, и добавлять к ним ещё 4 точки поля рамки незачем:
   кант отходил от рисунка на 6,1 точки — почти пятую часть самого рисунка,
   и рамка читалась как отдельная плашка, а не как обводка вещи. Своих полей
   у рамки теперь нет вовсе: 34 (рисунок) + 2 (кант) + 2 (запас на крупные
   тонкие значки, см. ниже) = 38, а кант отстоит от рисунка на 3,1 точки. */
.shop .shop-art {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  padding: 0;
  overflow: hidden;
  line-height: 0;
  /* Строчный ящик по СЕРЕДИНЕ, а не по опорной линии. Опорную линию inline-flex
     берёт у своего содержимого, и у тонких значков (они крупнее коробки, лишнее
     срезано overflow) она уезжала НИЖЕ дна коробки: восемнадцать строк полки
     из 133 становились на 2 точки выше соседних. С серединой ящик отвязан от
     того, что внутри, и все строки одной высоты. */
  vertical-align: middle;
  border: 1px solid var(--rar-edge, transparent);
  border-radius: 8px;
  background: var(--rar-back, transparent);
}

/* Рисунок внутри рамки: размер задан здесь, а не разметкой, — так его видно
   рядом с размером коробки, и сжать его нечему. max-width снимаем нарочно:
   общее «img { max-width: 100% }» из adaptive.css нужно всей игре, но здесь
   оно и было тем самым прессом. */
.shop .shop-art > .art-item {
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  max-width: none;
}

/* ТОНКИЕ ПРЕДМЕТЫ — ЧУТЬ КРУПНЕЕ ОСТАЛЬНЫХ.
   Стилус, линейка, паяльник, резак и штатив нарисованы длинным узким штрихом
   наискось: чернил в квадрате всего 10–25 % против 40–55 % у прочих (замерено
   по прозрачности самих файлов), и на общем размере они читаются хуже соседей.
   Перерисовывать нельзя, значит остаётся раскладка.
   Взять больше места неоткуда — длинная сторона рисунка и так упирается в
   224 точки из 256. Зато у КАЖДОГО файла есть собственное прозрачное поле в
   16 точек с каждой стороны, и вот его тонким мы и отдаём: рисунок вырастает
   с 34 до 38, чернила — с 29,8 до 33,3 точки (+11,8 %), а занятое место
   не меняется ни на точку, потому что коробка выше жёсткая, а лишнее (только
   прозрачное) обрезано overflow. Строки от этого не двигаются вовсе.
   Больше отдать нечего: при 38 чернила упираются в 36 точек просвета рамки. */
.shop .shop-art > .art-item--stylus,
.shop .shop-art > .art-item--ruler,
.shop .shop-art > .art-item--soldering,
.shop .shop-art > .art-item--blade,
.shop .shop-art > .art-item--stick {
  width: 38px;
  height: 38px;
}

/* Плашка со словом «редкая», «легендарная» и так далее. */
.shop-rar {
  display: inline-block;
  margin-left: 6px;
  padding: 0 5px;
  font-size: 10px;
  line-height: 15px;
  letter-spacing: .2px;
  vertical-align: 1px;
  white-space: nowrap;
  color: var(--rar-ink, var(--shop-quiet));
  cursor: help;
}
.shop-rar.rar-uncommon,
.shop-rar.rar-rare,
.shop-rar.rar-legend,
.shop-rar.rar-unique {
  font-weight: bold;
  border: 1px solid var(--rar-edge);
  border-radius: 3px;
  background: var(--rar-back);
}
/* Уникальная — единственная, у кого плашка залита целиком: такую вещь не
   покупают, её выдают, и спутать её с легендарной нельзя. */
.shop-rar.rar-unique {
  color: #fff;
  border-color: #5f34a0;
  background: #6c40b0;
}

/* Строку целиком не красит больше ничто: и легендарная, и уникальная метятся
   кантом вокруг значка и плашкой со словом. Раньше подложка строки роняла
   контраст всего, что внутри неё написано, и полка желтела целиком.
   Линии сверху и снизу остаются — по ним вещь видно и без заливки.
   Специфичность выше, чем у полосатости и наведения таблицы из styles.css. */
table.grid.shop-goods tr.rar-legend td,
table.grid.shop-goods tr.rar-unique td {
  border-top-color: var(--rar-edge);
  border-bottom-color: var(--rar-edge);
}

/* ── «Уже изучено» ─────────────────────────────────────────────────────────── */

/* Плашка у названия. Чернила --shop-good (#22662f) на бледно-зелёном
   --dtf-green-soft (#edf9f0) дают 6,45:1 при норме 4,5:1, кант #3f8a4f —
   4,24:1 на белой строке при норме 3:1 для нетекстового указателя. Зелёный
   тут не «успех», а «это у тебя уже есть»: тот же смысл, что у зелёной галки
   в списке покупок. */
.shop-known {
  display: inline-block;
  margin-left: 6px;
  padding: 0 6px;
  font-size: 11px;
  font-weight: bold;
  line-height: 15px;
  letter-spacing: .2px;
  vertical-align: 1px;
  white-space: nowrap;
  border-radius: 3px;
  cursor: help;
}
.shop .shop-known {
  color: var(--shop-good);
  border: 1px solid #3f8a4f;
  background: var(--dtf-green-soft, rgba(78, 122, 46, .18));
}

/* Строка «что у меня с этим уже есть»: изучено, лежит в корзине, и то и другое.
   Живёт в раскрытии, а в Скупке — прямо под главным числом: там это ровно та
   книжка, которую человек купил зря и теперь может сдать обратно. */
.shop-owned {
  margin-top: 4px;
  font-size: 12px;
  line-height: 1.45;
}
.shop .shop-owned { color: var(--shop-quiet); }
.shop .shop-owned.is-known { color: var(--shop-good); }

/* Рельс слева у изученной строки: подложку не трогаем совсем. Подкрасить строку
   значило бы уронить контраст всего, что внутри неё написано, а полосу видно
   и так — #3f8a4f к белому даёт 4,24:1 при норме 3:1. Полоса живёт на первой
   ячейке: box-shadow на всей строке в таблице браузеры рисуют по-разному. */
table.grid.shop-goods tr.is-learned td:first-child {
  box-shadow: inset 3px 0 0 #3f8a4f;
}

/* ── Раскрытая строка: одна карточка и ни одной второй подложки ───────────── */

/* Карточка лежит ОТДЕЛЬНОЙ строкой во всю ширину таблицы (colspan), а не внутри
   столбца с названием: в среднем столбце на телефоне остаётся полоска знаков
   в двадцать пять. Тот же приём, что у описаний характеристик в Профиле.
   Специфичность нарочно выше полосатости и наведения из styles.css. */
table.grid.shop-goods tr.shop-more td,
table.grid.shop-goods tbody tr.shop-more:hover td {
  padding-top: 0;
  background: transparent;
}

.shop-more-box {
  padding: 10px 12px;
  background: transparent;
  border: 1px solid var(--shop-line);
  border-radius: 8px;
}

/* Подпись раздела внутри карточки: «Если надеть — вместо …». Тише не
   бледностью, а кеглем и разрядкой. */
.shop-more-head {
  margin-bottom: 6px;
  font-size: 11px;
  letter-spacing: .4px;
  text-transform: uppercase;
}
.shop .shop-more-head { color: var(--shop-quiet); }

/* Опись вещи: подписи слева, содержимое справа — одна сетка на всю карточку,
   и подписи у всех вещей стоят на одной вертикали. */
.shop-facts {
  display: grid;
  grid-template-columns: 92px minmax(0, 1fr);
  gap: 2px 10px;
  margin: 0;
}
.shop-facts dt {
  font-size: 11.5px;
  font-weight: bold;
  line-height: 1.5;
}
.shop .shop-facts dt { color: var(--shop-quiet); }
.shop-facts dd {
  margin: 0;
  font-size: 12px;
  line-height: 1.5;
}
.shop .shop-facts dd { color: var(--ink); }
/* Между сравнением и описью — воздух, а не вторая рамка. */
.shop-deltas + .shop-facts,
.shop-warn + .shop-facts,
.shop-note + .shop-facts { margin-top: 8px; }

/* ── Сравнение с надетым ───────────────────────────────────────────────────── */

/* Три колонки: за что, «было → стало», прибавка. Плиток с заливкой тут больше
   нет: карточка одна, и вторая подложка внутри неё была бы плашкой в плашке.
   Сама строка сравнения — display: contents, поэтому все три колонки живут
   в ОДНОЙ сетке и подравниваются по самому длинному значению: числа стоят
   столбиком, а не разъезжаются каждое по своей строке. */
.shop-deltas {
  display: grid;
  grid-template-columns: max-content max-content max-content;
  justify-content: start;
  gap: 1px 14px;
  font-size: 12px;
  line-height: 1.6;
  font-variant-numeric: tabular-nums;
}
.shop-delta { display: contents; }
.shop-delta-name { min-width: 0; }
.shop .shop-delta-name { color: var(--shop-quiet); }
.shop-delta-val { font-weight: bold; white-space: nowrap; text-align: right; }
.shop-delta-sum { font-weight: bold; white-space: nowrap; text-align: right; }

.shop-delta.is-up .shop-delta-val,
.shop-delta.is-up .shop-delta-sum { color: var(--shop-good); }
.shop-delta.is-down .shop-delta-val,
.shop-delta.is-down .shop-delta-sum { color: var(--shop-bad); }

.shop-warn {
  margin-top: 4px;
  font-size: 11.5px;
}
/* Отдельным правилом — по той же причине, что и у .shop-lore: dtf-theme.css
   идёт позже и красит .shop-warn своим --blood (#e5484d, 3.91:1 на белом). */
.shop .shop-warn { color: var(--shop-bad); }

/* ── Скупка: одинаковые вещи одной строкой ─────────────────────────────────── */

/* Итог корзины и «Продать всё» — одной полосой над списком. Сумма стоит рядом
   с кнопкой нарочно: решение сдать всё разом принимают по числу, а не по
   названию действия. Полоса выглядит как «Копить на» в кошельке — та же белая
   карточка с тонкой линией: это две подсказки одного рода, и спорить им не
   о чем. Специфичность в две метки: тема подключена позже. */
.shop .shop-sum {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 10px;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 8px;
  padding: 8px 10px;
  background: transparent;
  border: 1px solid var(--shop-line);
  border-radius: 10px;
}
.shop-sum-text {
  flex: 1 1 220px;
  min-width: 0;
  font-size: 12.5px;
  line-height: 1.45;
}
.shop .shop-sum-text { color: var(--shop-quiet); }
.shop .shop-sum-text b { color: var(--link); }
.shop-sum-btn { flex: none; }

/* Цена за штуку под общей суммой. Перенос слов возвращаем нарочно: у столбца
   .shop-cost стоит white-space: nowrap ради самой цены. */
.shop-per {
  margin-top: 2px;
  font-size: 11px;
  line-height: 1.4;
  white-space: normal;
}
.shop .shop-per { color: var(--shop-quiet); }

/* «×5» у названия. Заливки нет: число — это не свойство вещи, спорить цветом
   с редкостью ему незачем, а веса шрифта хватает, чтобы его нашли глазами. */
.shop-count {
  margin-left: 6px;
  font-size: 12px;
  font-weight: bold;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.shop .shop-count { color: var(--ink); }

/* Выбор количества. На широком экране живёт в столбце «что даёт», под главным
   числом: в столбце действия помещается ровно одна кнопка, и четыре нажималки
   в ряд выдавили бы оттуда всё остальное. Переносится целиком по своим кускам —
   ни число, ни кнопка не рвутся пополам. */
.shop-pick {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 6px;
  margin-top: 6px;
}

/* Копия для раскрытия нужна только узкому экрану — тут её нет. Разметка
   собирается дважды (shop.js, pickHtml), но показана всегда ровно одна:
   погашенная display:none не ловит ни палец, ни чтение с экрана.
   Тут же и подсказка про стопки: она нужна только там, где выбор спрятан.
   Оба правила стоят ДО @media — у медиазапроса своей силы нет, и написанное
   после него перебило бы узкий экран. */
.shop-pick--more { display: none; }
.shop-narrow-only { display: none; }
.shop-pick-head {
  font-size: 11px;
  letter-spacing: .4px;
  text-transform: uppercase;
  white-space: nowrap;
}
.shop .shop-pick-head { color: var(--shop-quiet); }

/* Само число — крупнее кнопок и тёмное: это главное, что читают в этой полосе.
   Ширина фиксирована, чтобы «+» не прыгал под пальцем, когда счёт переходит
   с одного знака на два. */
.shop-pick-num {
  min-width: 24px;
  text-align: center;
  font-size: 14px;
  font-weight: bold;
  font-variant-numeric: tabular-nums;
}
.shop .shop-pick-num { color: var(--ink); }

/* «−» и «+» — квадратные: две кнопки в ряд, и разной ширины им быть незачем.
   Специфичность в две метки нарочно: одиночный .btn-mini темы подключён позже
   и перебил бы поля. */
.shop-pick .shop-pick-btn {
  min-width: 30px;
  padding: 0 6px;
  text-align: center;
}
.shop-pick .shop-pick-btn:active { padding: 0 6px; }

/* ── Узкий экран ───────────────────────────────────────────────────────────── */

/* Пять колонок в 375 px не помещаются, но и рассыпаться строке нельзя. Она
   складывается в две линии по той же сетке: слева значок, справа — название
   с ценой и главное число с кнопкой. Правый край у цены и кнопки общий, так что
   столбик чисел остаётся столбиком и на телефоне. */
@media (max-width: 700px) {
  .shop .shop-goal { grid-template-columns: auto minmax(0, 1fr); }
  .shop-goal-head { grid-column: 1 / -1; }

  table.grid.shop-goods,
  table.grid.shop-goods tbody { display: block; }
  table.grid.shop-goods thead { display: none; }

  /* Столбец значка, отступы и поля ужаты на пару точек нарочно: всё, что тут
     отнято, уходит в столбец названия. Было 195 точек под имя и плашки, стало
     207 — и на них помещается самое длинное имя каталога («Разгрузка домашнего
     кабинета», 199), после которого плашки садятся вторым рядом, а не третьим.

     Столбец остаётся 34 — и ради этого значок на телефоне мельче, чем на
     большом экране (см. правило .shop .shop-art ниже). Пробовали наоборот,
     раздать столбцу 38 под полную рамку: названию тогда достаётся 203 вместо
     207, восемь строк полки из 133 переносятся лишний раз, и полка вырастает
     на 160 точек. Четыре точки ширины тут дороже четырёх точек значка. */
  table.grid.shop-goods tr.shop-row {
    display: grid;
    grid-template-columns: 34px minmax(0, 1fr) auto;
    grid-template-areas:
      "icon name  cost"
      "icon main  act";
    gap: 2px 6px;
    padding: 10px 6px;
    border-bottom: 1px solid var(--shop-line);
  }
  table.grid.shop-goods tr.shop-row td {
    padding: 0;
    border: 0;
    background: transparent;
  }
  table.grid.shop-goods tr.shop-row .shop-icon { grid-area: icon; width: auto; }

  /* Значок на телефоне мельче: рамка 34 вместо 38, рисунок 30 вместо 34.
     Столбец под него отмерен в 34 точки (см. выше), и рамка обязана в них
     уложиться — иначе она наезжает на первую букву названия. Соотношение
     сохранено ровно то же, что на большом экране: кант отстоит от чернил
     на 2,9 точки, тонкие пятеро по-прежнему занимают весь просвет рамки.
     Профиль на телефоне ужимает значки точно так же (public/ui/profile.css). */
  .shop .shop-art { width: 34px; height: 34px; }
  .shop .shop-art > .art-item { width: 30px; height: 30px; }
  .shop .shop-art > .art-item--stylus,
  .shop .shop-art > .art-item--ruler,
  .shop .shop-art > .art-item--soldering,
  .shop .shop-art > .art-item--blade,
  .shop .shop-art > .art-item--stick { width: 34px; height: 34px; }
  table.grid.shop-goods tr.shop-row .shop-name { grid-area: name; }
  table.grid.shop-goods tr.shop-row .shop-main { grid-area: main; width: auto; }
  table.grid.shop-goods tr.shop-row .shop-cost { grid-area: cost; width: auto; }
  table.grid.shop-goods tr.shop-row .shop-act { grid-area: act; width: auto; }

  /* Заголовков колонок на телефоне нет — слово «плюсов» возвращается в цену. */
  .shop-unit { display: inline; }

  /* Пометка требований — коротким словом. «нужно: Стойкость 10» вместе со
     словом редкости просит 243 точки, а под название на 375 px отведено 207:
     пометка вставала третьим рядом и делала строку на 20 точек выше соседней.
     «Пока рано» с тем же красным кантом занимает 64, встаёт следом за словом
     редкости и держит строку в двух рядах. Чего именно не хватает, написано
     в раскрытии — на телефоне до него один палец. */
  .shop-lock-full { display: none; }
  .shop-lock-short { display: inline; }

  /* Рельс изученного и линии редкости: на сложенной строке они живут на самой
     строке, а не на первой ячейке — ячеек в привычном смысле тут уже нет. */
  table.grid.shop-goods tr.is-learned td:first-child { box-shadow: none; }
  table.grid.shop-goods tr.shop-row.is-learned { box-shadow: inset 3px 0 0 #3f8a4f; }
  table.grid.shop-goods tr.shop-row.rar-legend,
  table.grid.shop-goods tr.shop-row.rar-unique { border-bottom-color: var(--rar-edge); }

  table.grid.shop-goods tr.shop-subhead,
  table.grid.shop-goods tr.shop-more { display: block; }
  table.grid.shop-goods tr.shop-subhead td,
  table.grid.shop-goods tbody tr.shop-subhead:hover td,
  table.grid.shop-goods tr.shop-more td { display: block; padding: 10px 8px 4px; }
  table.grid.shop-goods tr.shop-more td { padding: 0 8px 10px; }

  .shop-facts { grid-template-columns: 78px minmax(0, 1fr); }
  .shop-deltas { gap: 1px 10px; }
  .shop-more-box { padding: 8px 10px; }

  /* Итог корзины — в столбец: кнопка «Продать всё» встаёт под текстом и не
     ужимает его до двух знаков в строке. Ширины кнопке не добавляем: во всю
     полосу она звала бы нажать себя первой, а это самое тяжёлое действие
     на экране. */
  .shop .shop-sum { flex-direction: column; align-items: flex-start; }
  .shop-sum-text { flex: 0 1 auto; }

  /* Кнопки на телефоне высотой 40 px (adaptive.css), поэтому подпись
     «Сколько продать:» уезжает на свою строку — иначе полоса выбора не
     умещается и число отрывается от «+». */
  .shop-pick-head { flex: 1 0 100%; }
  .shop-pick .shop-pick-btn { min-width: 40px; }

  /* И ровно поэтому на 375 px выбор уезжает из строки в раскрытие: своей
     строкой подпись плюс ряд кнопок в 40 точек — это ярус в 50 точек, и он
     доставался только стопкам. Полки давали две высоты (83 и 103), Скупка —
     четыре (83, 133, 153, 173): одна и та же вещь была то выше, то ниже
     соседней просто потому, что её две штуки, а не одна. Теперь строка
     Скупки собрана из того же, что и строка полки, а «сколько продать»
     лежит там же, где остальные подробности вещи, — под её названием. */
  .shop-pick--row { display: none; }
  .shop-pick--more {
    display: flex;
    margin-top: 0;
    margin-bottom: 8px;
  }

  /* Подсказка про стопки — только там, где выбор спрятан в раскрытие. */
  .shop-narrow-only { display: inline; }
}
