/* Подбор отеля: полоса раздела, список с вкладками, плашки цен на карте.
 *
 * Каркас берётся общий (`workspace is-split`, `side`, `chip`, `btn`) — раздел
 * выглядит частью Tripbox, а не отдельным приложением. Здесь только то,
 * чего в общем слое нет: своя полоса, вкладки списка, строка отеля
 * и ценовая плашка на карте.
 *
 * Значения — токенами. Число в этом файле означает, что нужного токена нет,
 * и тогда оно объяснено рядом.
 */

/* Величины раздела — здесь, а не числами по месту.
 *
 * Цвет, шрифт, отступ, радиус и тень берутся из `tokens.css` и своих
 * не имеют. Но у раздела есть размеры, которых в общей шкале нет вовсе:
 * ширина списка, высота полосы, квадрат значка, ячейка цены. Число,
 * написанное по месту, потом не находят — правят одно из трёх и получают
 * разъехавшуюся вёрстку.
 *
 * Прокату они не общие: разделы снимаются по отдельности, и общий токен
 * связал бы их там, где связь не нужна (решение владельца 05.09.2026). */
.hs-root {
  /* Ширина списка: от неё считается и колонка, и панель поверх карты.
   * Разойдись они, панель накрыла бы список либо оставила щель. */
  --hs-side: 384px;
  /* Полоса раздела и плашка в ней — те же 48 и 26, что у разведки: два
   * приставных раздела не должны выглядеть сделанными в разные годы. */
  --hs-bar: 48px;
  --hs-chip: 26px;
  /* Квадрат значка вида в строке — как у точки проката. */
  --hs-ic: 30px;
  /* Ячейка цены: числа стоят в столбец, иначе разной ширины читаются
   * как разные величины. */
  --hs-price-cell: 88px;
  /* Плашка цены на карте и точка, в которую она превращается в тесном виде. */
  --hs-plate: 22px;
  --hs-dot: 18px;
  /* Плашка не уже круглого пина: короткая цена вроде «9 $» иначе выглядит
   * обрезанной точкой, а не ценником. */
  --hs-plate-min: 28px;
  /* Меню выбора: поездки и этапы называются длинно («Грузия · Тбилиси
   * и Кахетия»), и на узком списке они переносились по слогам. */
  --hs-menu: 320px;
  /* Знак вердикта — поле спрайта Tripbox, 16×16. */
  --hs-mark: 16px;
  /* Панель отеля: та же ширина, что у панели точки проката. */
  --hs-panel: 980px;
  /* Колонка чтения уже панели: строка суждения на девятьсот пикселей
   * не читается — глаз теряет начало следующей. */
  --hs-read: 760px;
  /* Абзац разбора — по числу знаков, а не по пикселям: он набран текстом,
   * и мерить его надо строкой. */
  --hs-prose: 62ch;
  /* Узкая колонка у цены: отказ словами («вход истёк — обнови куки»). Уже
   * прозы, потому что стоит в шапке справа и не должен спорить с именем отеля
   * за ширину. */
  --hs-aside: 26ch;
  /* Плитка каталога. Пропорция 3:2, а не квадрат: источник отдаёт 960×660
   * (1,455:1), и `cover` на 3:2 срезает около 3 % против 31 % у квадрата —
   * то есть показывает то, что снял отель. Однородность, ради которой прежде
   * брали квадрат, держится фиксированной коробкой, а не равными сторонами.
   * 132 px — пять целых плиток и обрезанная шестая в панели при окне 1280,
   * а обрезанная и сообщает, что лента длиннее экрана. */
  --hs-tile: 132px;
  /* Плитка ленты зала — та же 3:2, но крупно: по ней судят зал, не открывая
   * кадр. 288 px — три целых плитки и обрезанная четвёртая в панели 980,
   * две и большая часть третьей при окне 1280; обрезанная сообщает,
   * что лента длиннее. */
  --hs-gym-tile: 288px;
  /* Окно альбома и просмотр кадра. Своя вуаль, а не общий `--scrim` (45 %):
   * тот рассчитан на панель, за которой должно **остаться видно**,
   * а под фотографией — не должно. */
  --hs-light-ground: rgba(20, 22, 25, 0.88);
  --hs-light-frame: 76vh;
  /* Карточка вкладки в ленте категорий. 168 px — семь целых карточек
   * и обрезанная восьмая в окне 1280, а обрезанная и сообщает, что категорий
   * больше: у отеля 133659329 их девять. */
  --hs-album-tab: 168px;
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0;
  /* Раздел — сам элемент flex-строки (`.work`), и без этого его наименьшая
   * ширина равна содержимому: полоса с неразрывными подписями раздвигала
   * весь раздел шире окна, и «собрано 01.10» уезжало за край на 88 px
   * вместо того, чтобы обрезаться. */
  min-width: 0;
}

.hs-stage {
  position: relative;
  display: flex;
  flex: 1;
  min-height: 0;
}

.hs-stage > .workspace {
  flex: 1;
  min-width: 0;
}

.hs-root .workspace.is-split {
  grid-template-columns: var(--hs-side) minmax(0, 1fr);
  /* Окно отбора кладётся поверх карты и отмеряется от левого края рабочей
     области — значит эта область и обязана быть точкой отсчёта. */
  position: relative;
}

/* --- полоса раздела ------------------------------------------------------ */

/* Полоса раздела — своим тоном, а не бумагой: это лента условий, а не
 * поверхность с содержимым. Значения те же, что у разведки: два приставных
 * раздела не должны выглядеть сделанными в разные годы. */
.hs-bar {
  display: flex;
  align-items: center;
  gap: var(--s5);
  flex: none;
  height: var(--hs-bar);
  padding: 0 var(--s8);
  background: var(--band);
  border-bottom: 1px solid var(--edge);
}

/* Имя раздела — плашкой, как «Разведка» у соседа: она же объясняет, почему
 * выбор поездки не в общей шапке — шапка принадлежит Tripbox'у. */
.hs-here {
  display: flex;
  align-items: center;
  height: var(--hs-chip);
  padding: 0 var(--s4);
  border: 1px solid var(--accent-border);
  border-radius: var(--r2);
  background: var(--accent-soft);
  font-size: var(--t-13);
  font-weight: 600;
  color: var(--accent-hover);
  flex: none;
}

/* Полоса держит одну строку. Ступеней у склеенного этапа четыре, и на 1280
 * они не помещаются: ужимаются ступени, а в них — только имя, многоточием.
 * Даты и числа не режутся: по дате различают два «Шанхая» одной поездки.
 *
 * Ступени сжимаются **раньше** подписей справа — множителем, а не порядком:
 * строгой очереди у flex нет. Отказ источника читать нужнее, чем хвост имени
 * поездки. Множитель — миллион, а не тысяча, и это замер: при тысяче подпись
 * теряла 0,2 px, а многоточию хватает и этого — «собрано 01.10» вставало
 * как «собрано 01.…» при свободной полосе. При миллионе доля подписи меньше
 * шага раскладки (1/64 px) и округляется в ноль; сжимается подпись только
 * когда ступени уже стоят на своём наименьшем. */
.hs-pick {
  position: relative;
  flex: 0 1000000 auto;
}

.hs-pick .btn {
  display: inline-flex;
  align-items: center;
  gap: var(--s3);
  max-width: 100%;
  white-space: nowrap;
}

.hs-pick .btn > * {
  flex: none;
}

/* Имя ступени — одной строкой с многоточием, но **не через `.clip`**.
 * `nowrap` делает наименьшей шириной элемента весь текст, и ступень с таким
 * именем не ужимается вовсе: её `min-width: auto` равен полной ширине, а при
 * `min-width: 0` имя сжалось бы в ничто и даты вылезли бы из кнопки.
 *
 * Поэтому ширину задаёт **мерка** — невидимый псевдоэлемент с тем же текстом,
 * переносимым: его наименьшая ширина — самое длинное слово, наибольшая — весь
 * текст одной строкой. На этом пределе flex ступень и замораживает: «Цзиньюнь»
 * и «Шанхай» не режутся никогда, «Китай · Синьцзян и восток» ужимается
 * до ширины «Синьцзян». Показывает имя вложенный элемент — неразрывно, по знакам
 * и на всю отведённую ширину.
 *
 * Два способа проще не прошли замер 01.10.2026. Предел по знакам (`4ch`) резал
 * короткое имя отрезка до «Цзи…»: оно сжималось наравне с длинными. Перенос
 * по словам с одной видимой строкой (`line-clamp`) оставлял в кнопке пустоту:
 * «Китай ·…» в 140 px, потому что «Синьцзян» целиком не влезал.
 *
 * Высота своя: у кнопки `line-height: 1`, и при обрезке по ней срезались бы
 * хвосты «у» и «р». Селектор из трёх классов — чтобы перебить `flex: none`
 * соседей по кнопке. */
.hs-pick .btn > .hs-step-name {
  position: relative;
  flex: 0 1 auto;
  min-width: min-content;
  height: 1lh;
  overflow: hidden;
  line-height: 1.4;
  white-space: normal;
}

.hs-step-name::before {
  content: attr(title);
  visibility: hidden;
}

.hs-step-name > span {
  position: absolute;
  inset: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Меню выбора этапа. Поверх карты, поэтому со своей тенью и бумагой:
 * прозрачное меню на подложке читается как часть карты. */
.hs-menu {
  position: absolute;
  /* Выше панели отеля (`z-index: 15`): список городов раскрывается поверх
     всего экрана, и нижние строки уходили под её шапку. Пока имена набирались
     13 px, список был короче и до панели не доставал — с укрупнением шрифта
     «Сигнахи» оказалась под ней и перестала нажиматься. */
  z-index: 25;
  top: calc(100% + var(--s2));
  left: 0;
  min-width: var(--hs-menu);
  max-height: 60vh;
  overflow-y: auto;
  padding: var(--s2);
  background: var(--card);
  border: 1px solid var(--edge-card);
  border-radius: var(--r4);
  box-shadow: var(--sh-float);
}

/* Третья колонка — число отелей в подборке этого этапа. `auto` вместо
 * фиксированной ширины: у этапов без подборки её нет вовсе, и пустая колонка
 * оставляла бы у них дыру справа от даты. */
.hs-menu-row {
  display: grid;
  grid-template-columns: 1fr auto auto;
  gap: 0 var(--s3);
  width: 100%;
  padding: var(--s3) var(--s4);
  border: 0;
  border-radius: var(--r2);
  background: transparent;
  text-align: left;
  cursor: pointer;
  font: 400 var(--t-15) / 1.3 var(--sans);
  color: var(--ink);
}

.hs-menu-row:hover {
  background: var(--fill-hover);
}

.hs-menu-row.is-on {
  background: var(--accent-tint);
  color: var(--accent);
}

/* Число отелей — чернилами, а не приглушённое: это единственный признак,
 * ради которого меню и открывают. Дата рядом остаётся тихой — она различает
 * одноимённые этапы («Шанхай» в поездке два), но не отвечает «где смотреть». */
.hs-menu-count {
  padding: 0 var(--s2);
  border-radius: var(--r1);
  background: var(--fill);
  font-size: var(--t-13);
  color: var(--ink-2);
}

.hs-menu-row.is-on .hs-menu-count {
  /* На залитой строке общая `--fill` сливается с фоном выбора. */
  background: var(--card);
}

.hs-menu-of {
  grid-column: 1 / -1;
  font-size: var(--t-13);
  color: var(--ink-4);
}

/* Строка сбора: выбрать и удалить — две кнопки рядом. Одной в другой быть
 * нельзя, а удаление в той же строке избавляет от окна со списком сборов. */
.hs-menu-line {
  display: flex;
  align-items: center;
  gap: var(--s2);
}

.hs-menu-line .hs-menu-row {
  min-width: 0;
}

.hs-menu-drop {
  flex: none;
}

/* Взведённое удаление — тоном тревоги: «точно?» обязано отличаться от «×»
 * не только словом. */
.hs-menu-drop.is-armed,
.hs-menu-drop.is-armed:hover {
  background: var(--alarm-bg);
  color: var(--alarm-deep);
}

.hs-menu-foot {
  margin-top: var(--s2);
  padding-top: var(--s2);
  border-top: 1px solid var(--line);
}

.hs-when {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  font-size: var(--t-13);
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- список -------------------------------------------------------------- */

.hs-title {
  display: flex;
  align-items: baseline;
  gap: var(--s3);
}

.hs-title {
  min-width: 0;
}

.hs-title .mono {
  flex: none;
  font-size: var(--t-15);
  font-weight: 500;
  color: var(--ink-3);
}

.hs-root .side-head {
  gap: var(--s5);
  padding: var(--s7) var(--s7) var(--s5);
}

.hs-root .side-scroll {
  gap: 2px;
  padding: var(--s3);
}

/* Вкладки — чипами, как срез оснащения у разведки. Подчёркивание снизу было
 * третьим способом сказать «выбрано» на одном экране: у чипов это уже есть. */
.hs-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2);
  flex: none;
}

.hs-order {
  display: flex;
  gap: var(--s2);
  padding: var(--s4) var(--s2) var(--s3);
}

.hs-clear {
  display: block;
  width: 100%;
  margin-bottom: var(--s3);
  padding: var(--s2) var(--s4);
  border: 1px dashed var(--edge-dash);
  border-radius: var(--r2);
  background: transparent;
  cursor: pointer;
  font: 400 var(--t-13) / 1.2 var(--sans);
  color: var(--ink-3);
  text-align: left;
}

/* Строка отеля: две линии. Одной не хватает — китайские названия длинные,
 * и в линию от имени остаётся половина. */
.hs-row {
  display: flex;
  align-items: flex-start;
  gap: var(--s4);
  padding: var(--s4) var(--s5);
  border: 1px solid transparent;
  border-radius: var(--r3);
  text-decoration: none;
  color: inherit;
  min-width: 0;
  transition: background var(--dur-fast) var(--ease),
    border-color var(--dur-fast) var(--ease);
}

.hs-row:hover {
  background: var(--fill-hover);
}

.hs-row.is-on {
  background: var(--accent-tint);
}

/* Вердикт — засечкой слева, тем же цветом, что плашка этого отеля на карте:
 * список и карта отвечают на один вопрос и обязаны отвечать одинаково. */
.hs-row.is-mark-pick {
  box-shadow: inset 2px 0 0 var(--ok-ink);
}

.hs-row.is-mark-candidate {
  box-shadow: inset 2px 0 0 var(--accent);
}

.hs-row.is-mark-backup {
  box-shadow: inset 2px 0 0 var(--warn-ink);
}

.hs-row.is-mark-doubt {
  box-shadow: inset 2px 0 0 var(--alarm);
}

/* Отклонённый гаснет **на своём месте** — решение владельца: порядок,
 * прыгающий под рукой сразу после нажатия, неприятнее серой строки. Засечки
 * у него нет: серая полоса на погасшей строке ничего не добавляет. */
.hs-row.is-mark-reject {
  opacity: 0.45;
}

/* Значок вида — тем же квадратом, что у точки проката. Цветом не различается:
 * цвет в проекте означает состояние, а вид несут значок и подпись. */
.hs-ic {
  display: grid;
  place-items: center;
  width: var(--hs-ic);
  height: var(--hs-ic);
  border-radius: var(--r2);
  background: var(--fill);
  color: var(--ink-3);
  flex: none;
}

.hs-side {
  display: flex;
  align-items: center;
  gap: var(--s3);
  flex: none;
}

/* Ячейка цены — фиксированной ширины, чтобы числа стояли в столбец: разной
 * ширины они читаются как разные величины. Оценка под ценой, а не рядом. */
.hs-price-cell {
  align-items: flex-end;
  gap: 2px;
  width: var(--hs-price-cell);
  flex: none;
  text-align: right;
}

.hs-price-cell .when {
  font-size: var(--t-12);
}

/* Заголовок и описание района остаются двухстрочными: у района нет цены,
 * и правой колонки ему не нужно. */
.hs-row-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s3);
}

.hs-name {
  font: 500 var(--t-15) / 1.25 var(--sans);
}

.hs-meta {
  font: 400 var(--t-13) / 1.3 var(--sans);
  color: var(--ink-4);
}

/* --- районы -------------------------------------------------------------- */

.hs-districts {
  display: flex;
  flex-direction: column;
  gap: var(--s2);
}

.hs-district {
  width: 100%;
  padding: var(--s4);
  border: 1px solid var(--edge-card);
  border-radius: var(--r3);
  background: var(--card);
  cursor: pointer;
  text-align: left;
  color: inherit;
}

.hs-district.is-on {
  border-color: var(--accent-border);
  background: var(--accent-tint);
}

.hs-note {
  margin: var(--s2) 0 0;
  font: 400 var(--t-13) / 1.45 var(--sans);
  color: var(--ink-2);
}

/* --- плашка цены на карте ------------------------------------------------ */

/* Продолжение обычного пина, а не новый материал: та же бумага канта, тот же
 * графит, та же моноширинная. Отличие одно — ширина по содержимому, потому что
 * внутри цена, а не номер. */
.pin.is-price {
  width: auto;
  min-width: var(--hs-plate-min);
  height: var(--hs-plate);
  padding: 0 var(--s3);
  /* Без этого «451 $» ломается на две строки: у пина ширина задана содержимым,
   * и перенос по пробелу превращает плашку в столбик из числа и знака валюты. */
  white-space: nowrap;
}

/* Цвет плашки несёт **мой вердикт**, а не вид точки: форма у всех одна, разное
 * в них — решение. Отклонённый серый, потому что он выбыл, а не тревожит;
 * терракота звала бы к нему обратно. Токены общие, своих раздел не заводит. */
.pin.is-tone-pick {
  background: var(--ok-ink);
}

.pin.is-tone-candidate {
  background: var(--accent);
}

.pin.is-tone-backup {
  background: var(--warn-ink);
}

/* Сомнения — терракота: комментарий выше говорит, что серый у отклонённого
 * взят именно потому, что тот «выбыл, а не тревожит». Сомнения тревожат. */
.pin.is-tone-doubt {
  background: var(--alarm);
}

.pin.is-tone-reject {
  background: var(--ink-4);
}

/* Под курсором плашка **не раздувается**. Общий `.pin:hover` увеличивает точку
 * на 12% (`motion.css`), и круглому пину 28 px это помогает: цель отвечает
 * на приближение, попасть легче. У плашки мишень и так 52 px, зато цифра
 * при том же масштабе дёргается и налезает на соседнюю — замер: 52×22
 * превращались в 58×25 со сдвигом на 3 px. Цвет наведения остаётся: он и
 * отвечает «курсор здесь». */
.pin.is-price:hover {
  transform: translate(-50%, -50%);
}

/* В тесном виде цены гаснут, остаются точки: плашки шире круглого пина
 * и налезают друг на друга. Возвращаются приближением — в кадре становится
 * меньше отелей. */
.map.is-dense .pin.is-price,
.pin.is-price.is-tight {
  width: var(--hs-dot);
  min-width: 0;
  padding: 0;
  font-size: 0;
}

/* `is-tight` — плашка, которой не нашлось места при разводе (`map/spread.js`).
 * Тот же вид, что в тесной карте: точка, разворачивающаяся под курсором. Своя
 * причина, поэтому и класс свой: тесно бывает и на просторной карте — в одном
 * её углу, где отели стоят на одной улице. */

/* **Под курсором и у выбранной плашка возвращается целиком.** Общее правило
 * тесной карты (`.map.is-dense .pin:hover`, `components.css`) растит точку
 * до пина 28×28 — круглому пину это возвращает значок, а плашке возвращать
 * нечего: ширину держало правило выше, высоту растило общее, цену гасил
 * `font-size: 0`, и под курсором оставался синий столбик 18×28 без единого
 * знака. Теперь наведение отвечает тем, ради чего плашка и нужна, — ценой,
 * и спрашивать её приближением больше не надо. */
.map.is-dense .pin.is-price:hover,
.map.is-dense .pin.is-price.is-on,
.pin.is-price.is-tight:hover,
.pin.is-price.is-tight.is-on {
  width: auto;
  min-width: var(--hs-plate-min);
  height: var(--hs-plate);
  padding: 0 var(--s3);
  font-size: var(--t-13);
}

/* --- отбор ---------------------------------------------------------------- */

/* Порядок и кнопка отбора — одной строкой, кнопка прижата к правому краю:
 * управляют списком они вместе, а стояли двумя рядами и занимали 60 px
 * над первым отелем. */
.hs-tools {
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: var(--s4) var(--s2) var(--s3);
}

.hs-order {
  display: flex;
  gap: var(--s2);
}

.hs-tools > .chip {
  margin-left: auto;
  flex: none;
}

/* Раскрытая кнопка держит окно: без этого при пустом сите она остаётся белой,
 * и окно поверх карты выглядит открывшимся само по себе. Признак берётся
 * у `aria-expanded` — того же, по которому её открывают с клавиатуры. */
.hs-tools > .chip[aria-expanded="true"]:not([aria-pressed="true"]) {
  border-color: var(--ink-4);
  color: var(--ink);
}

/* «из 415» рядом с отобранным числом — тише самого числа: это условие,
 * при котором оно верно, а не второе число. */
.hs-of {
  font-size: var(--t-13);
}

/* Окно отбора — **поверх карты и слева**, тем же устройством, что окно выбора
 * машины у разведки: отсчёт от левого края рабочей области, тень панели,
 * своя шапка и подвал. Выпадающей полосой в колонке отбор разворачивался
 * на 380 px и отжимал список вниз на три экрана — того, что он делает
 * со списком, из-за него самого не было видно.
 *
 * Ширина под четыре состояния в ряд: «с оговоркой 208» требует 120 px,
 * и вчетвером они как раз укладываются. */
.hs-sieve {
  position: absolute;
  left: calc(var(--hs-side) + var(--s5));
  top: var(--s5);
  width: 560px;
  max-width: calc(100% - var(--hs-side) - var(--s8));
  max-height: calc(100% - var(--s8));
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--edge);
  border-radius: var(--r4);
  background: var(--card);
  box-shadow: var(--sh-panel);
  z-index: 20;
}

.hs-sieve-head {
  display: flex;
  align-items: center;
  gap: var(--s3);
  flex: none;
  padding: var(--s4) var(--s5);
  border-bottom: 1px solid var(--line);
  background: var(--field);
}

/* «Отбор» занимает всю свободную ширину: без этого «снять ×» и крестик
 * прижимаются к слову, и шапка читается тремя кнопками подряд. */
.hs-sieve-head > .caps {
  flex: 1;
}

.hs-sieve-rows {
  display: flex;
  flex-direction: column;
  gap: var(--s5);
  min-height: 0;
  overflow-y: auto;
  padding: var(--s5);
}

/* Цена и год — рядом: оба промежутка, оба узкие, и в столбик они гнали окно
 * вниз без всякой на то причины. */
.hs-sieve-pair {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--s5);
}

/* Подпись **над** полем, а не слева: слева она забирала 68 px, и состояния
 * переносились с рваным краем. Ряды разделены волосяной линией — это разные
 * вопросы, а не один список. */
.hs-sieve-row {
  display: flex;
  flex-direction: column;
  gap: var(--s3);
}

.hs-sieve-rows > .hs-sieve-row,
.hs-sieve-pair + .hs-sieve-row {
  padding-top: var(--s5);
  border-top: 1px solid var(--line);
}

.hs-sieve-cap {
  display: flex;
  align-items: center;
  gap: var(--s2);
}

/* Подсказка единицы — у правого края ряда: «$ за ночь» отвечает на вопрос
 * к полю, а не к подписи, и рядом с подписью читалось её продолжением. */
.hs-sieve-cap .hs-meta {
  margin-left: auto;
  font-size: var(--t-12);
}

.hs-sieve-glyph {
  display: flex;
  color: var(--ink-4);
}

/* Промежуток — **одно поле на два числа**: рамка общая, внутри «от», тире
 * и «до». Двумя отдельными полями это читалось как два независимых вопроса,
 * а тире между ними висело в воздухе. */
.hs-span {
  display: flex;
  align-items: center;
  gap: var(--s2);
  padding: 0 var(--s3);
  border: 1px solid var(--edge);
  border-radius: var(--r2);
  background: var(--field);
  transition: border-color var(--dur-fast) var(--ease), box-shadow var(--dur-fast) var(--ease);
}

.hs-span:hover {
  border-color: var(--faint);
}

/* Фокус показывает **всё поле**, а не одну его половину: у чисел внутри
 * своей рамки нет, и без этого кольца непонятно, куда пойдёт набор. */
.hs-span:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 2px var(--accent-tint);
}

.hs-span-num {
  flex: 1;
  min-width: 0;
  padding: var(--s3) 0;
  border: 0;
  background: none;
  font: 400 var(--t-14) / 1.2 var(--mono);
  color: var(--ink);
  text-align: center;
}

.hs-span-num:focus {
  outline: none;
}

/* Край подборки стоит подсказкой — «16 — 89» серым говорит, из чего выбирать.
 * Тише обычного ввода: это не значение поля, и спутать их нельзя. */
.hs-span-num::placeholder {
  color: var(--ink-5);
}

/* Стрелки браузера убраны: две пары кнопок посреди промежутка выглядят
 * управлением самим промежутком, а не набором числа. */
.hs-span-num::-webkit-outer-spin-button,
.hs-span-num::-webkit-inner-spin-button {
  appearance: none;
  margin: 0;
}

.hs-span-num {
  appearance: textfield;
  -moz-appearance: textfield;
}

.hs-span-dash {
  flex: none;
  color: var(--faint);
}

/* Четыре состояния — **в ряд**, а не переносом: в окне на 560 px они
 * укладываются одной строкой, и итог суждения виден целиком одним взглядом.
 * `minmax(0, …)`, потому что колонка `1fr` не сжимается уже содержимого
 * и «с оговоркой 208» распирало бы ряд наружу. */
.hs-sieve-chips {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--s2);
}

/* Вердиктов пять, и пятым столбцом они дают 62 px на чип — «запасной 12»
 * в такой не влезает. Поэтому ряд разбит на две строки по три: слова длиннее,
 * чем у суждений, и укорачивать их значит терять то самое различие, ради
 * которого вердиктов четыре. */
.hs-sieve-chips.is-marks {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

/* Галочки показа — строкой, а не сеткой чипов: это «показывать ли спрятанное»,
 * а не выбор состояния, и чипом во всю колонку «без года» занимало пол-окна. */
.hs-sieve-checks {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s2) var(--s6);
}

.hs-check {
  display: inline-flex;
  align-items: center;
  gap: var(--s2);
  font: 400 var(--t-13) / 1.2 var(--sans);
  color: var(--ink-2);
  cursor: pointer;
}

.hs-check input {
  width: var(--hs-mark);
  height: var(--hs-mark);
  margin: 0;
  accent-color: var(--ink);
  cursor: pointer;
}

.hs-check input:focus-visible {
  outline: 2px solid var(--accent-border);
  outline-offset: 2px;
}

.hs-check-num {
  font-size: var(--t-12);
  color: var(--ink-4);
}

/* Цвет чипа — тот же, что у засечки строки и плашки на карте. Без `is-state`
 * в селекторе намеренно: те же чипы стоят в футере панели отеля, а `is-state`
 * несёт `width: 100%` под сетку сита и в футере распирал бы ряд, схлопывая
 * поле заметки. Синего среди состояний нет — он собран из акцентной тройки. */
.chip.is-mark-pick[aria-pressed="true"] {
  background: var(--ok-bg);
  border-color: var(--ok-edge);
  color: var(--ok-ink);
}

.chip.is-mark-candidate[aria-pressed="true"] {
  background: var(--accent-tint);
  border-color: var(--accent-border);
  color: var(--accent);
}

.chip.is-mark-backup[aria-pressed="true"] {
  background: var(--warn-bg);
  border-color: var(--warn-edge);
  color: var(--warn-ink);
}

.chip.is-mark-doubt[aria-pressed="true"] {
  background: var(--alarm-bg);
  border-color: var(--alarm-edge);
  color: var(--alarm-deep);
}

.chip.is-mark-reject[aria-pressed="true"] {
  background: var(--fill);
  border-color: var(--edge-dash);
  color: var(--ink-3);
}

/* «Нет вердикта» — не решение, а его отсутствие: тем же серым, что «не
 * смотрели» у суждений. */
.chip.is-mark-none[aria-pressed="true"] {
  background: var(--fill);
  border-color: var(--edge-dash);
  color: var(--ink-2);
}

/* Подвал — тем же голосом, что у выбора машины: слева правило, справа то,
 * когда отбор случится. Кнопки «применить» нет — её и нечего нажимать. */
.hs-sieve-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s4);
  flex: none;
  padding: var(--s3) var(--s5);
  border-top: 1px solid var(--line);
  font-size: var(--t-13);
  white-space: nowrap;
}

/* --- знаки вердиктов ----------------------------------------------------- */

/* Знак вердикта — того же размера и того же языка, что значки Tripbox:
 * контур 16×16, а не заливка 20×20. Цвет несёт итог, фигура — вид. */
.hs-mark {
  flex: none;
  width: var(--hs-mark);
  height: var(--hs-mark);
  color: var(--ink-4);
}

.hs-mark.is-ok {
  color: var(--ok-ink);
}

.hs-mark.is-warn {
  color: var(--warn-ink);
}

.hs-mark.is-no {
  color: var(--alarm);
}

/* Незнакомый вид — словом: скилл счёл нужным сказать про отель именно это. */
.hs-mark.is-word {
  display: inline-flex;
  align-items: center;
  width: auto;
  padding: 0 var(--s2);
  border: 1px solid var(--edge);
  border-radius: var(--r1);
  font: 500 var(--t-12) / 1 var(--mono);
  color: var(--ink-3);
}
