/* ============================================================
   «Слово дня» — десктопный игровой экран. Этап 3.

   Геометрия снята с эталона 10583:3021 («03 · Игровой экран ·
   подсказки свёрнуты») через get_metadata, поэтому все числа ниже
   проверяемы, а не подобраны на глаз.

   Ритм окна 10 · 24 · 32. itemSpacing окна 10, увеличенные
   промежутки набираются padding-top у блока снизу: 14 у колонок
   (даёт 24) и 22 у нижнего блока (даёт 32). Чем ближе элементы,
   тем сильнее они связаны — поэтому промежутки не выравниваются.

   Главный инвариант, который надо проверять числами:
     top(поле)    === top(правой колонки)
     bottom(поле) === bottom(правой колонки)
   Он держится на том, что правая колонка натурально равна 378:
     hints-cta 215 + 13 + points-widget 150 = 378 = высота поля.
   Тронете внутренние отступы любого из двух блоков — пересчитайте
   и верните разницу туда же, а не в промежуток.
   ============================================================ */

/* ===================== Окно ===================== */

/* Подложка под окном. Переехала из старого слоя: окно давно новое, а
   она оставалась там единственным его описанием. Затемнение 45 % —
   то же, что у тач-шторки, чтобы окно и шторка гасили ленту одинаково. */
.backdrop {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: grid;
  place-items: center;
  padding: 16px;
  background: rgba(0, 0, 0, .45);
}

.game-window {
  box-sizing: border-box;
  width: 880px;
  /* Высота одна на все экраны — 800. Её задаёт игровой экран: он
     самый плотный, и в 800 укладывается ровно, без воздуха снизу.
     820 из макета в нём наполовину уходило под пустоту.

     Кто длиннее — прокручивается (см. .section-view), кто короче —
     просто не занимает всё окно. Так окно не прыгает при переходах
     между разделами. */
  height: 800px;
  /* На невысоких десктопных окнах оставляем видимыми все четыре границы.
     Вложенные экраны уже умеют прокручиваться внутри окна. */
  max-height: calc(100dvh - 32px);
  /* Пол под этим потолком. Если высота вьюпорта неизвестна или равна
     нулю — фрейм без явной высоты, свёрнутая панель предпросмотра, —
     то 100dvh считается нулём, и окно схлопывается до содержимого
     шапки: 880 × 48, игры на экране нет вовсе. Так и случилось в
     стенде, и покраснели все двадцать четыре экрана сразу.

     320 выбраны так, чтобы правило никогда не срабатывало в жизни:
     это ниже самого низкого настоящего вьюпорта — телефон в альбомной
     ориентации даёт 375, минус поля 343. То есть на реальных экранах
     потолок работает как прежде, а пол ловит только вырожденный ноль.
     min-height в CSS сильнее max-height, и это ровно то, что нужно. */
  min-height: 320px;
  /* Ширина фиксирована. Без flex: none окно ужимается, когда родитель
     уже 880, и вся геометрия внутри едет следом. */
  flex: none;
  /* Поле окна переменной, а не числом: прокручиваемые экраны отводят
     ровно его под полосу прокрутки, и разъехаться эти два значения
     теперь не могут. На таче поле другое — переменная там своя. */
  --window-pad: 24px;
  padding: var(--window-pad);
  border-radius: var(--window-radius);
  background: var(--paper);
  box-shadow: var(--window-shadow);
  display: flex;
  flex-direction: column;
  gap: 10px;
  /* Онбординг лежит слоем поверх окна и позиционируется от него. */
  position: relative;
  /* Единственный фрейм, который режет содержимое. У всех вложенных
     overflow остаётся видимым: иначе срезается первая буква кикеров
     и свес звезды у купленной клетки. */
  overflow: hidden;
}

/* Экран игры — такой же ребёнок окна, как шапка, поэтому ритм 10
   продолжается внутри него: тема → 10 → колонки → 10 → низ, а
   увеличенные промежутки набираются padding-top у нижнего блока.

   Селекторы по id, а не по .game-view: у этих двух экранов своя
   раскладка, у разделов другая (.section-view ниже). Раньше id был
   ещё и обходом — старый .game-view выравнивал детей по центру, и
   колонки сжимались по содержимому вместо 832; то правило удалено. */
#view-game,
#view-result {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 10px;
  padding: 0;
  /* Игровой экран укладывается в 800 ровно, финал короче. Прокрутка
     здесь страховка: если содержимое когда-нибудь перерастёт окно —
     длинная тема, лишняя строка, крупный системный шрифт, — его
     покажут целиком, а не обрежут. */
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  /* Полосе прокрутки отдаём поле окна. Накладная полоса ширины не
     занимает и рисуется поверх содержимого — она наезжала на правый
     край кнопки «Поделиться результатом», как только финал перерос
     окно. Обычная полоса откусывала бы те же 15 прямо от 832.
     Отрицательное поле уводит бокс до края окна, внутреннее возвращает
     содержимому его 832: полоса едет по полю, а не по кнопке. */
  margin-right: calc(var(--window-pad) * -1);
  padding-right: var(--window-pad);
}

/* ===================== Тема дня ===================== */

.theme-block {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  text-align: center;
}
.theme-block__title {
  font-size: 26px;
  font-weight: 700;
  line-height: 33px;
  color: var(--ink);
}
.theme-block__sub {
  font-size: 15px;
  font-weight: 400;
  line-height: 23px;
  color: var(--text-secondary);
}

/* Сообщения игры живут под персонажем, а не под темой дня: персонаж
   и есть голос игры, и говорить ей логично оттуда же, откуда она
   предлагает помощь. Блок темы теперь всегда в две строки — это
   заодно сняло нулевой запас, который был на 09, 11 и 12.

   Просто цветной текст: ни плашки, ни фона, ни обводки — капсула
   утяжеляла шапку и спорила с полем.

   Строка осталась одна и одного вида. Красной ветки больше нет: сбои
   переехали в снэкбар (§5.6), а здесь живёт только то, на что игра
   ответила по правилам, — и держится до следующего ввода, а не тает
   по таймеру.

   ⚠️ Токен --status (оранжевый) после этого не применяется нигде. */
.status-msg { color: var(--ink); }
/* Тач-повтор строки: на широком экране сообщение стоит под персонажем. */
.theme-block__status { display: none; }

/* ===================== Колонки ===================== */

.columns {
  display: flex;
  gap: 24px;
  padding-top: 14px;   /* +10 от окна = 24 между темой и игрой */
}

.left-column { flex: none; width: 380px; }

/* Поле задаёт высоту ряда, правая колонка подстраивается под него.
   По вертикали зазор ровно 12, по горизонтали клетки разъезжаются
   по 380 и получают 12,5 — так поле читается как ровная решётка. */
.grid {
  display: flex;
  flex-direction: column;
  row-gap: 12px;
}
.grid__row {
  display: flex;
  justify-content: space-between;
}

.right-column {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 13px;
  min-width: 0;
}

/* ===================== Виджет очков ===================== */

.points-widget {
  box-sizing: border-box;
  height: 150px;
  flex: none;
  padding: 12px;
  border-radius: 18px;
  background: var(--surface);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* Верхняя строка блока держит собственные боковые 4 — итого 16 от
   края. Карточки ниже держат край сами, а голый текст без них
   прилипал. */
.widget-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  padding: 0 4px;
}

.head-copy { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

.kicker {
  font-size: 13px;
  font-weight: 700;
  line-height: 18px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--text-secondary);
}
.head-copy__note {
  font-size: 14px;
  font-weight: 400;
  line-height: 19px;
  color: var(--text-secondary);
}

.attempt-pill {
  flex: none;
  padding: 5px 12px;
  border-radius: 999px;
  background: var(--paper);
  font-size: 15px;
  font-weight: 700;
  line-height: 20px;
  color: var(--ink);
  white-space: nowrap;
}

.reward-ladder { display: flex; gap: 8px; }

/* Ступени равной ширины: 5 × 74,4 + 4 × 8 = 404. Значение стоит по
   центру, вертикальные 26 сверху и снизу дают высоту 78.

   Заливка будущих ступеней — paper, а не line-2. Правило 8 спеки
   говорит «the rest line-2», но в компоненте 10619:3232 стоит paper,
   и это согласуется с общей моделью слоёв: карточка внутри
   блока-колодца возвращается к цвету окна — как карточки покупки в
   панели подсказок и плашка «Попытка N из 5» в этом же виджете. */
.reward-step {
  box-sizing: border-box;
  flex: 1;
  min-width: 0;
  height: 78px;
  border: 2px solid transparent;
  border-radius: 14px;
  background: var(--paper);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  font-size: 20px;
  font-weight: 700;
  line-height: 26px;
  color: var(--ink);
}

/* В «Правилах» ступень несёт три строки — номер попытки, очки и
   монетки — и потому выше игровой: 88 против 78. В игре подписей нет:
   там номер попытки стоит в плашке рядом с кикером, а монетки в игре
   не показываются вовсе (§6.3). Радиус тоже свой: 12 против 14. */
.reward-step--legend { height: 88px; border-radius: 12px; }
/* Монетки в ступени мельче очков и приглушены — как везде, где они
   стоят рядом с очками. */
.reward-step__coins {
  font-size: 13px;
  font-weight: 400;
  line-height: 16px;
  color: var(--text-secondary);
  white-space: nowrap;
}
.reward-step__label {
  font-size: 13px;
  font-weight: 400;
  line-height: 18px;
  color: var(--text-secondary);
}
.reward-step__value { font-size: 20px; font-weight: 700; line-height: 27px; }

/* Потраченная попытка выключена тем же языком, что и недоступная
   карточка покупки: карточка остаётся на paper, появляется обводка
   line, число уходит в text-muted. Заливка line-2 на серой панели
   давала бы отношение 1.15 — граница пропадала. Толщина остаётся
   базовой, 2: при flex: 1 обводка входит в ширину, и 1.5 делали
   пройденные ступени на пиксель уже соседних. */
.reward-step--used {
  border-color: var(--line);
  color: var(--text-muted);
}

/* Единственная сплошная подсветка во всей правой колонке — ровно одна
   на экран. Если их стало две, значит подсвечены две ступени. */
.reward-step--now {
  background: var(--correct-soft);
  border-color: var(--correct-line);
}

/* ===================== Панель подсказок ===================== */

/* Раскрытое состояние. Ровно та же высота 215, что и у свёрнутого
   блока, — иначе подмена двигает колонки и ломает выравнивание. */
.hints-panel {
  box-sizing: border-box;
  height: 215px;
  flex: none;
  padding: 12px;
  border-radius: 18px;
  background: var(--surface);
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.hints-panel__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  padding: 0 4px;
}
/* Интерлиньяж 19, чтобы «Скрыть» не утолщало шапку панели. */
.hints-panel__toggle {
  font-size: 15px;
  font-weight: 400;
  line-height: 19px;
  color: var(--text-secondary);
  background: none;
  border: none;
  cursor: pointer;
}

/* Две карточки делят остаток панели поровну: 215 − 24 (padding)
   − 19 (шапка) − 8 − 8 = 156, то есть по 78 на каждую. */
.buy-row {
  box-sizing: border-box;
  flex: 1;
  padding: 12px 16px;
  border: 1.5px solid transparent;
  border-radius: 14px;
  background: var(--paper);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.buy-row__text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

/* Строка цены: [название] · [интерпункт] · [число + золотая метка].
   Каждый текст держит собственную ширину по содержимому — иначе
   интерпункт отъезжает от названия и зазор перестаёт быть 8. */
.title-row {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 16px;
  line-height: 22px;
  color: var(--ink);
}
.title-row__name  { font-weight: 600; }
.title-row__price { display: flex; align-items: center; gap: 6px; font-weight: 700; }

.buy-row__note {
  font-size: 14px;
  font-weight: 400;
  line-height: 20px;
  color: var(--text-secondary);
}

/* Кнопка покупки ниже базовой и по содержимому: 107 × 44 против
   200 × 48. На 428 полноширинная кнопка не оставила бы места
   названию строки. */
.btn--buy {
  height: 44px;
  min-width: 0;
  flex: none;
  /* 107 по макету. Базовая кнопка держит прозрачный контур 1.5 ради
     единообразия состояний, и он добавлял 3 px к ширине по
     содержимому — те самые 3 px забирались у колонки с подписью. */
  padding: 0 20.5px;
}

/* Недоступная карточка остаётся карточкой: фон paper с обводкой,
   весь текст приглушён, кнопка контурная. Серая заливка на серой
   панели давала отношение 1.15 — граница исчезала. */
.buy-row--off { border-color: var(--line); }
.buy-row--off .title-row,
.buy-row--off .buy-row__note { color: var(--text-muted); }

/* ===================== Финалы =====================
   Геометрия снята с эталона 10586:3154. Экран строится из трёх
   блоков, а не из пяти строк: result-card → actions → «ПО ТЕМЕ».
   Раньше заголовок, слово, награда, таймер и кнопки шли пятью
   полосами с похожими промежутками, ничего не группировалось и
   экран читался как список.

   above-fold и below-fold — имена раскладки, а не видимый элемент.
   Никакой линии сгиба на экране нет и рисовать её нельзя. Они
   кодируют приоритет: если окно придётся ужать, above-fold — то,
   что обязано выжить. */

.above-fold,
.below-fold {
  display: flex;
  flex-direction: column;
}
.above-fold { padding-top: 14px; gap: 20px; }
.below-fold { padding-top: 22px; gap: 14px; }

/* Финал начинается от верхнего края прокручиваемой области. Центровка
   переполненного flex-экрана уводила начало карточки выше доступного
   скролла и визуально срезала зелёную плашку. */
#view-result { justify-content: flex-start; }

/* Финал центрован целиком — и карточка, и подписи под ней. Правило
   переехало из старого слоя: экран давно новый, а строка оставалась
   там последним, что старый слой отдавал игре. */
.result { text-align: center; }

/* Всё про эту партию — в одном блоке. Цвет на финале один: блок
   результата. Янтарь тут не нужен, он означает стеллы. */
.result-card {
  box-sizing: border-box;
  padding: 40px 32px 32px;
  border-radius: 18px;
  background: var(--correct-soft);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 24px;
  text-align: center;
}
/* Поражение не должно выглядеть как победа. */
.result-card--lost { background: var(--surface); }

/* Эмодзи ушло на свою строку и выросло до 44. Не ради красоты: при
   заголовке 36 он встаёт в две строки, и эмодзи слева приклеивалось к
   первой (§5.8). Прежний довод «отдельная строка съедает 62 px» умер
   вместе с «По теме» — блок убран, и место освободилось. */
.result-headline {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  width: 100%;
}
.result-card__emoji {
  font-size: 44px;
  line-height: 40px;
  flex: none;
}
/* Заголовок несёт попытку: «с первой попытки» стоит здесь, а не
   подписью под клетками — повторять это дважды было шумом.
   Headers/Scream 36/40 по центру. */
.result-card__head {
  font-size: 36px;
  font-weight: 700;
  line-height: 40px;
  letter-spacing: .32px;
  color: var(--ink);
}

/* Сбросы фона, полей и ширины отсюда сняты: старый .answer удалён из
   styles.css вместе с остальными одноимёнными правилами, и протекать
   больше нечему. */
.answer {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}
.answer-row { display: flex; gap: 12px; }

/* Пунктирные клетки читаются как «не отгадано», и сам ответ в них
   терялся. После проигрыша это главное, что игрок хочет унести. */
.answer-caption {
  font-size: 16px;
  line-height: 22px;
  color: var(--text-secondary);
}

/* Редакционный комментарий — под словом, внутри карточки. Места в
   макетах финала для него не нашлось, и место выбрано по смыслу:
   он объясняет слово, а не результат партии, и стоя вплотную к нему
   не требует подписи вроде «Почему это слово дня».

   Ширина 560, как у текста пустых состояний: строка на все 784
   растягивается в полосу, которую глаз читает по одной букве. Кегль
   тот же, что у подписи ответа, — обе строки вторичны по отношению
   к слову, и делать между ними иерархию не за что. */
.answer-note {
  margin: 0;
  max-width: 560px;
  font-size: 16px;
  line-height: 22px;
  color: var(--text-secondary);
}

/* Поражение несёт лишнюю строку — подпись под ответом. Чтобы окно не
   переполнилось, макет ужимает промежутки в карточке результата до 10
   и превью в карточках «По теме» с 63 до 56. Так в 10635:3971.
   ⚠️ Свободного места на этом экране остаётся 5 из допустимых 0…60:
   финалы проверять на нём, а не на 13, где запас 12. */
.final-lost .result-card { gap: 10px; }
.final-lost .related__card { height: 159px; }
.final-lost .related__thumb { height: 56px; }

.card-divider {
  width: 100%;
  height: 1px;
  background: var(--correct-line);
  opacity: .5;
}
.result-card--lost .card-divider { background: var(--line); }

/* Две вторичные величины держат углы блока и не требуют отдельных
   полос: награда слева, время до следующего слова справа. */
.card-footer {
  width: 100%;
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 24px;
  text-align: left;
}
.card-footer__label {
  display: block;
  font-size: 14px;
  line-height: 19px;
  color: var(--text-secondary);
}
.foot-timer { text-align: right; }

.amount { display: flex; align-items: baseline; gap: 6px; }
/* Награда тем же кеглем, что и заголовок: экран перестал быть
   двухэтажным, и результат — то, ради чего на него смотрят. */
.amount__value {
  font-size: 36px;
  font-weight: 700;
  line-height: 40px;
  letter-spacing: .32px;
  color: var(--ink);
}
/* Монетки Дзена — третья строка подвала, приглушённая: это бонус, а не
   то, за что играют (§6.3). Ни чипа, ни золота — золото означает
   стеллы, и путать эти две величины нельзя. */
.amount__coins {
  display: block;
  font-size: 16px;
  line-height: 20px;
  letter-spacing: .04px;
  color: var(--text-secondary);
}

/* Очки рейтинга — обычный текст, никогда не чип и никогда не
   «монеты». Стеллы наоборот: всегда чип, никогда голое число. */
.amount__unit {
  font-size: 17px;
  font-weight: 500;
  line-height: 19px;
  color: var(--text-secondary);
}
.foot-timer__value {
  font-size: 22px;
  font-weight: 700;
  line-height: 28px;
  color: var(--ink);
}

/* Обещание про завтрашнюю стеллу. Строкой под таймером оно тонуло
   среди вторичных подписей; отдельный блок с золотым значком
   читается как награда. Единственное место на финале, где
   появляется янтарь — он всегда означает стеллы.

   ⚠️ Блок зависит от §8.1 брифа: начисления за ежедневный вход в
   коде нет, поэтому сейчас он не показывается никогда. Решение «да»
   включает его данными, решение «нет» — удаляет эти правила и
   разметку. */
.daily-stella {
  box-sizing: border-box;
  padding: 14px 16px;
  border-radius: 18px;
  background: var(--accent-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
}
.daily-stella__icon { width: 24px; height: 24px; flex: none; }

/* Приглашение войти. Геометрия — как у обещания стеллы: на финале они
   стоят друг под другом и держат один ритм. Это кнопка, а не сноска:
   вход открывается на месте, а не ищется в шапке.

   Заливка акцентная — та же, что у главной кнопки. На победе гостя
   это и есть главное действие экрана: очки, которых он не получил,
   в этот момент конкретны, а поделиться результатом можно и потом.
   Акцент на финале один, поэтому «Поделиться» в этой ветке уходит во
   вторичные (см. showResult в app.js).

   Янтарь сюда по-прежнему не годится: в игре он означает стеллы, а
   речь про рейтинг. Строка гостю показывается только после победы,
   так что второго вида у неё нет — вошедший её не видит вовсе. */
.signin-note {
  box-sizing: border-box;
  width: 100%;
  padding: 14px 16px;
  border: none;
  border-radius: 18px;
  background: var(--ink);
  font-family: var(--font-sans);
  font-size: 17px;
  font-weight: 600;
  line-height: 23px;
  color: var(--paper);
  text-align: center;
  cursor: pointer;
  transition: opacity .12s ease;
}
/* Наведение и нажатие — как у кнопки: заливку не меняем, гасим целиком.
   Прежний светлый ховер на тёмной заливке был бы вспышкой. */
.signin-note:hover { opacity: .85; }
.signin-note:active { transform: scale(.99); }
.daily-stella__text {
  font-size: 17px;
  font-weight: 600;
  line-height: 23px;
  color: var(--ink);
}

/* Два действия вместо одного: второе очевидное намерение игрока
   больше не приходится искать. На победах главная — «Поделиться»,
   на поражении порядок обратный: делиться нечем. */
.actions { display: flex; gap: 12px; justify-content: stretch; }
.actions .btn { flex: 1; min-width: 0; height: 52px; }

/* Заголовок секции внутри тела — без янтарной метки: метка значит
   «этот экран про», а не «это заголовок». */
.section-kicker {
  display: flex;
  align-items: center;
  height: 32px;
  text-align: left;
}

.related { display: flex; flex-direction: row; gap: 16px; width: auto; text-align: left; }

/* Все карточки одной высоты: заголовок занимает ровно две строки,
   поэтому подписи «Дзен · …» стоят на одной линии независимо от
   длины названия. Растягивать через flex нельзя — ряд схлопнется
   по самой низкой и двухстрочный заголовок вылезет.

   Ширина считается по трёхколоночной сетке, а не делится между тем,
   что есть: три материала дают ровно 266,67 из макета, а один — такую
   же карточку в своей колонке. Через flex: 1 единственный материал
   растягивался на все 832 и превращался в полосу с серой заглушкой
   во всю ширину — так это и выглядело, пока редакция заполняла одно
   поле из трёх. */
.related__card {
  box-sizing: border-box;
  flex: 0 0 calc((100% - 32px) / 3);
  min-width: 0;
  height: 166px;
  padding: 12px;
  /* Карточка бывает ссылкой — подчёркивание и синий тут не нужны. */
  text-decoration: none;
  color: inherit;
  border: 1.5px solid var(--line);
  border-radius: 14px;
  background: var(--paper);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.related__thumb {
  height: 63px;
  border-radius: 10px;
  background: var(--line-2);
  flex: none;
}
/* Две строки ровно: высота фиксирована, чтобы подписи «Дзен · …»
   стояли на одной линии во всех карточках. Заголовки теперь пишет
   редакция, а не клиент, поэтому длинный обрывается многоточием —
   раньше при overflow: hidden он просто срезался посреди буквы. */
.related__title {
  height: 44px;
  font-size: 16px;
  font-weight: 600;
  line-height: 22px;
  color: var(--ink);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.related__source {
  font-size: 14px;
  line-height: 19px;
  color: var(--text-secondary);
}

/* Настройки оформления возвращены как отдельный экран: тема нужна
   мобильному вебу, где системная тема часто не совпадает с желаемой. */
.settings-block {
  box-sizing: border-box;
  padding: 12px;
  border-radius: 18px;
  background: var(--surface);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.settings-block__head { display: flex; padding: 0 4px; }
.setting-row {
  box-sizing: border-box;
  min-height: 72px;
  padding: 14px 16px;
  border-radius: 14px;
  background: var(--paper);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}
.setting-row__copy { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.setting-row__title { font-size: 16px; font-weight: 600; line-height: 22px; color: var(--ink); }
.setting-row__note { font-size: 14px; line-height: 19px; color: var(--text-secondary); }
.theme-select {
  flex: none;
  width: 176px;
  max-width: 190px;
  min-height: 44px;
  padding: 0 38px 0 14px;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  background: var(--paper);
  color: var(--ink);
  font: 600 15px/20px var(--font-sans);
}
.toggle {
  box-sizing: border-box;
  flex: none;
  width: 52px;
  height: 30px;
  padding: 3px;
  border: none;
  border-radius: 999px;
  background: var(--line-2);
  display: flex;
  justify-content: flex-start;
  transition: background .15s ease;
}
.toggle__knob {
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--paper);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .12);
  transition: transform .15s ease;
}
.setting-row input:checked + .toggle { background: var(--ink); }
.setting-row input:checked + .toggle .toggle__knob { transform: translateX(22px); }
.setting-row input:focus-visible + .toggle { outline: 2px solid var(--ink); outline-offset: 2px; }
.setting-row:has(input) { cursor: pointer; }
.setting-row input:disabled + .toggle { opacity: .45; cursor: not-allowed; }
.settings-note { margin: 0; font-size: 14px; line-height: 19px; color: var(--text-secondary); }
.settings-block .btn { width: 150px; height: 44px; }

/* ===================== Разделы =====================
   Геометрия снята с эталона 10591:3184. Вложенный экран устроен
   иначе игрового: шапка несёт только стрелку и заголовок — ни
   крестика, ни ряда иконок. Это не экономия места: крестик
   принадлежит окну игры, стрелка — экрану, в который провалились.

   Ритм здесь ровный 20 сверху донизу, без развилки 10 · 24 · 32:
   на игровом экране промежутки говорят о связности блоков, а раздел
   это список равноправных секций. */

/* Раздел прокручивается, если не помещается в окно: содержимое
   справочное, и резать его ради габарита неправильно. Окно при этом
   упирается в потолок 820 и дальше не растёт. */
.section-view {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 20px;
  padding: 0;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  /* Полоса едет по полю окна, а не по содержимому — то же, что у
     игрового экрана и финала. Разделы прокручиваются штатно, так что
     здесь она видна чаще всего. */
  margin-right: calc(var(--window-pad) * -1);
  padding-right: var(--window-pad);
}

/* Шапка липкая: при прокрутке стрелка «назад» остаётся на месте.
   Другого выхода из раздела нет — крестик принадлежит окну игры. */
.header-nested {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--paper);
  height: 24px;
  display: flex;
  align-items: center;
  gap: 12px;
  flex: none;
}
/* Значок 24, а нажимается 44: §7 требует тач-цель не меньше 44, а
   макет рисует в шапке раздела иконку 24 в строке высотой 30. Кнопка
   держит 44 и втягивается обратно отрицательными полями — в раскладке
   её габарит остаётся 24 × 24, поэтому заголовок стоит там же, где
   стоял, а шапка не растёт. */
.header-nested__back {
  box-sizing: border-box;
  width: 44px;
  height: 44px;
  margin: -10px;
  flex: none;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: var(--ink);
}
.header-nested__back svg { width: 24px; height: 24px; display: block; }
.header-nested__title {
  font-size: 20px;
  font-weight: 700;
  line-height: 24px;
  color: var(--ink);
}

/* Сегмент-контрол переехал в components.css: это компонент дизайн-
   системы, а не верстка раздела. Рейтинг и календарь остаются
   вкладками «Результатов». */

/* Плитки статистики. Сначала число, под ним подпись. Серые блоки под
   каждую плитку читались как четыре одинаковых прямоугольника, из
   которых ничего не выделялось, поэтому обычные плитки — paper с
   обводкой, а две смысловые красятся. */
.stat-numbers { display: flex; gap: 16px; }
.stat {
  box-sizing: border-box;
  flex: 1;
  min-width: 0;
  height: 98px;
  padding: 16px 12px;
  border: 1.5px solid var(--line);
  border-radius: 14px;
  background: var(--paper);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  text-align: center;
}
.stat__value {
  font-size: 32px;
  font-weight: 700;
  line-height: 44px;
  color: var(--ink);
}
.stat__label {
  font-size: 13px;
  line-height: 20px;
  color: var(--text-secondary);
}
/* Зелёное значит «правильно», янтарь — «валюта и серии». */
.stat--win    { background: var(--correct-soft); border-color: transparent; }
.stat--streak { background: var(--accent-soft);  border-color: transparent; }

/* Диаграмма распределения — карточка 832 × 238: BG/Primary, обводка
   Stroke/Primary 1.5, радиус 18, поля 14 / 12.

   Дорожка surface, полоса --chart-bar, лучшая попытка --status-correct.
   Так было не всегда: после перевода на токены дорожка получила
   BG/Tertiary (светлота 0.874), а полоса — BG/Secondary (0.871).
   Отношение 1.003 — полос просто не было видно. Разводит их теперь не
   оттенок серого, а отдельный токен диаграммы. */
.distribution {
  box-sizing: border-box;
  padding: 14px 12px;
  border: 1.5px solid var(--line);
  border-radius: 18px;
  background: var(--paper);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.bar-row { display: flex; align-items: center; gap: 12px; height: 34px; }
.bar-row__num {
  width: 20px;
  flex: none;
  text-align: center;
  font-size: 16px;
  line-height: 23px;
  color: var(--text-secondary);
}
.bar-row__track {
  flex: 1;
  min-width: 0;
  height: 34px;
  border-radius: 10px;
  background: var(--surface);
  overflow: hidden;
}
.bar-row__fill {
  height: 100%;
  min-width: 34px;
  border-radius: 10px;
  background: var(--chart-bar);
  display: flex;
  align-items: center;
  justify-content: flex-end;
  padding-right: 12px;
  box-sizing: border-box;
  font-size: 14px;
  font-weight: 600;
  line-height: 20px;
  /* Тёмное в обеих темах: столбик пастельный, белое на нём не проходит
     по контрасту ни в светлой, ни в тёмной. Расчёт — в tokens.css. */
  color: var(--chart-ink);
}
.bar-row__fill--best { background: var(--status-correct); }

/* ===================== Правила =====================
   Эталон 10639:4092. Сегмент-контрола здесь нет: «Правила» это
   отдельный раздел, а не вкладка «Результатов».

   Механика показана на настоящих клетках, а не описана словами:
   три разобранных примера с подписями под каждым. */

.rules-intro {
  font-size: 16px;
  line-height: 22px;
  color: var(--ink);
}

.examples { display: flex; flex-direction: column; gap: 10px; }
.example { display: flex; flex-direction: column; gap: 8px; }
.example-row { display: flex; gap: 10px; }
.example__caption {
  font-size: 14px;
  line-height: 20px;
  color: var(--text-secondary);
}

/* Блок-колодец со справкой. Та же конструкция, что у виджета очков:
   surface, радиус 18. */
.info-block {
  box-sizing: border-box;
  padding: 16px;
  border-radius: 18px;
  background: var(--surface);
  display: flex;
  flex-direction: column;
  gap: 10px;
}

/* Строка цены в справке: [название] · [число] [метка] · [условие].
   Число — обычный текст, метка — золотой значок. Символа ✦ нет. */
.hint-line {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 16px;
  line-height: 22px;
  color: var(--ink);
}
.hint-line__name { font-weight: 600; }
.hint-line__price { font-weight: 700; }
.hint-line__tail {
  font-weight: 400;
  color: var(--text-secondary);
}

/* Блок «Что ещё важно» построен как виджет очков: колодец surface с
   карточками paper внутри. Верхняя строка держит собственные 4 —
   итого 16 от края, карточки держат край сами. */
.info-widget {
  box-sizing: border-box;
  padding: 12px;
  border-radius: 18px;
  background: var(--surface);
  display: flex;
  flex-direction: column;
  gap: 8px;
}
/* Флексом, а не строкой текста: иначе строчный бокс тянется по
   шрифту родителя и заголовок блока выходит 19,5 вместо 18. */
.info-widget__head { display: flex; align-items: flex-start; padding: 0 4px; }

/* На 18 те же блоки просторнее: 16 по вертикали и промежуток 12
   против 12 и 8 на 17. Разница из макетов, а не из логики — на
   «Правилах» блок это короткая сноска в конце длинного экрана, на
   «Наградах» он основное содержимое. Без этого экран 18 недобирал
   до габарита: свободного места оставалось 92 из допустимых 60. */
.info-widget--roomy,
.points-widget--legend {
  height: auto;
  padding: 16px 12px;
  gap: 12px;
}
.info-widget--roomy .info-line,
.info-widget--roomy .stella-line {
  min-height: 46px;
  padding: 12px 16px;
  border-radius: 12px;
}
/* Блок без сноски держит строки через 10, со сноской — через 12
   (10640:4120 против 10639:4352). */
.info-widget--dense { gap: 10px; }
.info-line {
  box-sizing: border-box;
  min-height: 42px;
  padding: 10px 16px;
  border-radius: 14px;
  background: var(--paper);
  display: flex;
  align-items: center;
  font-size: 16px;
  line-height: 22px;
  color: var(--ink);
}

/* Строка начисления в «Наградах»: слева за что, справа сколько.
   Стеллы всегда чип или метка, никогда голое число — как очки
   рейтинга всегда обычный текст и никогда чип. Две валюты не
   смешиваются, и это правило из вики, а не вкусовое. */
.stella-line {
  box-sizing: border-box;
  min-height: 46px;
  padding: 12px 16px;
  border-radius: 14px;
  background: var(--paper);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  font-size: 16px;
  line-height: 22px;
  color: var(--ink);
}
.stella-line__amount {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: 700;
  flex: none;
}

/* Пояснение под кикером внутри блока-колодца. */
.widget-note {
  padding: 0 4px;
  font-size: 14px;
  line-height: 20px;
  color: var(--text-secondary);
}

/* Переход в «Награды». Отдельной иконки раздел не заслуживает:
   содержимое справочное, а лесенка очков и так видна в игре. */
.link-row {
  box-sizing: border-box;
  padding: 14px 16px;
  border-radius: 14px;
  background: var(--surface);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  border: none;
  width: 100%;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
  font-family: var(--font-sans);
}
.link-row__copy { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.link-row__title {
  font-size: 16px;
  font-weight: 600;
  line-height: 22px;
  color: var(--ink);
}
.link-row__sub {
  font-size: 14px;
  line-height: 19px;
  color: var(--text-secondary);
}
.link-row__chevron {
  width: 24px;
  height: 24px;
  flex: none;
  color: var(--text-secondary);
}
.link-row__chevron svg { width: 24px; height: 24px; display: block; }

/* ===================== Календарь =====================
   Эталон 10637:4092. Архив слов поглощён этой вкладкой: в шапке
   стоит «Нажмите на день, чтобы увидеть слово».

   ⚠️ Если тап по дню не будет открывать слово, архив придётся
   возвращать отдельным экраном — §8.2 брифа. Подпись в шапке обещает
   действие, которого пока нет ни в API, ни в макетах. */

.cal-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
}
.cal-head__month {
  font-size: 18px;
  font-weight: 700;
  line-height: 23px;
  color: var(--ink);
}
.cal-head__hint {
  font-size: 14px;
  line-height: 20px;
  color: var(--text-secondary);
}
/* Легенда под сеткой — только пока играть не начали. Тот же тихий
   регистр, что у подсказки в шапке календаря.

   Отрицательный отступ подтягивает её к сетке: это подпись к таблице, а
   не следующий блок раздела. Заодно она перестаёт стоить полные 20
   промежутка — с ними раздел на десктопе переставал помещаться в 752 и
   таймер уходил под сгиб на 9 px. */
.cal-legend {
  margin-top: -12px;
  font-size: 14px;
  line-height: 20px;
  color: var(--text-secondary);
}

/* Сетка, а не флекс. На флексе с flex: 1 1 0 колонки расходились —
   пустая клетка получала 101,6, остальные 113,6. Календарь по своей
   природе таблица: grid раздаёт семь равных колонок и не зависит от
   того, что лежит внутри клетки. */
.weekdays,
.calendar {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 8px;
}
.weekdays span {
  text-align: center;
  font-size: 14px;
  line-height: 19px;
  color: var(--text-secondary);
}

/* День 112 × 83: номер сверху, число попыток под ним. Сыгранный день
   залит line-2, проигранный — контур и прочерк, сегодняшняя победа —
   зелёная с обводкой. Будущие дни приглушены. */
.cal-day {
  box-sizing: border-box;
  min-width: 0;
  height: 83px;
  /* Обводка 1 и радиус 12 — как у всякой карточки внутри колодца
     (10783:5493). Полуторапиксельная обводка в системе только у
     клетки поля и клавиши. */
  border: 1px solid transparent;
  border-radius: 12px;
  background: var(--line-2);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  font-family: var(--font-sans);
  cursor: pointer;
}
.cal-day__num {
  font-size: 15px;
  line-height: 19px;
  color: var(--text-secondary);
}
.cal-day__count {
  font-size: 20px;
  font-weight: 700;
  line-height: 22px;
  color: var(--ink);
}
.cal-day--lost   { background: var(--paper); border-color: var(--line); }
.cal-day--today  { background: var(--correct-soft); border-color: var(--correct-line); border-width: 2px; }

/* Пропущенный день — тот, что уже прошёл, но игрок в него не заходил.
   В макетах такого состояния нет: там дни либо сыграны, либо будущие.
   Для вернувшегося через неделю это и была самая частая клетка, а
   выглядела она как будущая — приглушённой и неактивной, хотя слово
   того дня показать можно и нажатие работает.

   Отличается от будущего только полной непрозрачностью, и этого
   довольно: приглушённое читается как «смотреть нечего», обычное —
   как «можно нажать». От проигранного отличается пустотой на месте
   прочерка: прочерк значит «играл и не угадал», пусто — «не играл». */
.cal-day--missed { background: var(--paper); border-color: var(--line); }
.cal-day--future { background: var(--paper); border-color: var(--line); opacity: .4; cursor: default; }
/* Дни соседних месяцев — не пустая карточка, а пустое место. */
.cal-day--blank  { background: none; border-color: transparent; cursor: default; }

/* ===================== Рейтинг =====================
   Эталон 10638:4092. Десять строк по 56 с разделителями в 1 px
   между ними: 10 × 56 + 9 = 569. */

.leaderboard { display: flex; flex-direction: column; }

.rank-row {
  box-sizing: border-box;
  height: 56px;
  padding: 0 14px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  gap: 14px;
  font-size: 16px;
  line-height: 21px;
  color: var(--ink);
}
.rank-row__num {
  width: 34px;
  flex: none;
  text-align: center;
  font-size: 17px;
  font-weight: 600;
  line-height: 22px;
  color: var(--text-secondary);
}
.rank-row__name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* Правая колонка строки: очки и монетки под ними. 80 с выключкой
   вправо — так в макете 21. Ширина фиксирована, чтобы числа разной
   длины стояли столбиком, а не плясали по строке. */
.rank-row__tail {
  flex: none;
  width: 80px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
}
.rank-row__score { flex: none; font-weight: 600; }
/* Монетки приглушены и мельче: бонус рядом с очками, а не вторая
   рейтинговая величина. */
.rank-row__coins {
  font-size: 13px;
  font-weight: 600;
  line-height: 16px;
  color: var(--text-secondary);
  white-space: nowrap;
}

/* Аватар переехал в components.css: компонент DS `Avatar`, размер
   `L · 32`. Заглушка из инициала осталась там же. */

/* Своя строка выделена заливкой и весом, а не цветом: рейтинг не
   место для второго акцента. */
.rank-row--me { background: var(--line-2); }
.rank-row--me .rank-row__name { font-weight: 600; }
.rank-row--me .rank-row__score { font-weight: 700; }
.rank-row--me .avatar { background: var(--ink); color: var(--paper); }

.rank-divider { height: 1px; flex: none; background: var(--line); }
/* Блок настроек удалён вместе с разделом (этап 3): переключатели,
   тумблеры, сноска про сложный режим и строка аккаунта. Вход в раздел
   редакции переехал иконкой в шапку окна. */


/* ===================== Онбординг =====================
   Эталон 10642:4209. Это состояние окна, а не модалка поверх него:
   шапка та же, но в ней только крестик — балансу и разделам тут
   делать нечего, игрок ещё не играл.

   Слой перекрывает окно целиком, поэтому логика показа осталась
   прежней: элемент просто скрывается и показывается. */
/* Шапку слой не перекрывает: вход — первое, что на стартовом экране
   должно быть доступно, иначе новый игрок не может войти вообще, пока
   не закроет онбординг. Так и в макетах 01 и M6.

   Отступ сверху — поле окна плюс шапка плюс промежуток. Числами, а не
   переменной: у окна и шапки разные высоты на платформах, и тач
   переопределяет это значение у себя. */
.onboarding {
  position: absolute;
  /* 84 = поле окна 24 + шапка 40 + промежуток 20, ровно как в 01.
     Раньше стояло 74: слой нёс собственную шапку и начинался выше, из-за
     чего крестиков на экране было два. */
  inset: var(--onb-top, 84px) 0 0;
  z-index: 5;
  box-sizing: border-box;
  padding: 24px;
  background: var(--paper);
  /* Скругление только снизу: сверху слой упирается в шапку, а не в
     край окна, и круглый угол там читался бы как обрыв. */
  border-radius: 0 0 var(--window-radius) var(--window-radius);
  display: flex;
  flex-direction: column;
  /* 20 между шапкой окна и содержимым — так в обоих эталонах
     (01: 64 → 84, M6: 96 → 116). */
  gap: 20px;
}

/* Пока стартовый экран открыт, шапка несёт только вход и крестик:
   иконки разделов и баланс уступают — сохранять и тратить ещё
   нечего (§5.1). Скрываем видимостью, а не display: иначе шапка
   схлопывается и вход с крестиком съезжают друг к другу. */
.game-window.is-onboarding .header-icons,
.game-window.is-onboarding .balance-pill { visibility: hidden; }
.game-window.is-onboarding #view-game { visibility: hidden; }
.onboarding .empty-state { gap: 24px; }

.onb-head {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
}
.onb-title {
  font-size: 34px;
  font-weight: 700;
  line-height: 44px;
  color: var(--ink);
}
.onb-sub {
  font-size: 17px;
  line-height: 23px;
  color: var(--text-secondary);
}

.word-row { display: flex; gap: 10px; }

/* Строка-пример и легенда делят работу: строка показывает, как
   выглядит попытка, свотчи расшифровывают цвета. */
.legend { display: flex; gap: 24px; flex-wrap: wrap; justify-content: center; }
/* Двухклассовый селектор остался с тех пор, когда старый слой объявлял
   `.legend span` весом (0,1,1) и перебивал одноклассовые правила —
   ставил inline-flex и зазор 5 вместо 8. То правило удалено; селектор
   оставлен как есть, чтобы не трогать проверенную геометрию. */
.legend .legend-item {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  line-height: 20px;
  color: var(--ink);
}
.swatch {
  width: 20px;
  height: 20px;
  border-radius: 6px;
  flex: none;
  border: 1.5px solid transparent;
}
.swatch--empty   { background: var(--paper); border-color: var(--line); }
.swatch--present { background: var(--status-present); }
.swatch--correct { background: var(--status-correct); }

/* Кнопки во всю ширину колонки, одна под другой: «Начать игру»
   первичная, «Все правила» — вторичная того же размера. */
.onb-actions {
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding-top: 8px;
  width: 340px;
  max-width: 100%;
}
.onb-actions .btn { width: 100%; min-width: 0; height: 52px; }

/* ===================== Слово недоступно =====================
   Эталон 10641:4324. Шапка окна полная — крестик и иконки на месте:
   это не вложенный экран, а состояние самой игры.

   В макете содержимое отцентровано в окне на все 820. Здесь окно
   идёт по содержимому, поэтому центровать не по чему — экран просто
   компактный. */
.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  text-align: center;
  /* Высота окна снова фиксирована, поэтому содержимое центруется по
     нему — как в макете. */
  flex: 1;
  min-height: 0;
}
.empty-state__head {
  font-size: 30px;
  font-weight: 700;
  line-height: 41px;
  color: var(--ink);
}
.empty-state__text {
  font-size: 17px;
  line-height: 23px;
  color: var(--text-secondary);
  max-width: 560px;
}
.empty-state__copy { display: contents; }
/* Персонаж в этом состоянии есть только на таче (M21): на десктопном
   25 его нет. */
.empty-state__mascot { display: none; }

/* Кнопка 260 и ссылка под ней — своя пара, не онбординговая: там
   колонка 340 с двумя кнопками и отбивкой сверху. */
.empty-state__actions {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  width: 260px;
  max-width: 100%;
}
/* 52 в высоту, радиус по половине — в макете стоит 999. */
.empty-state__actions .btn {
  width: 100%;
  min-width: 0;
  height: 52px;
  border-radius: 26px;
}

.empty-state__link {
  font-size: 15px;
  line-height: 20px;
  color: var(--text-secondary);
  background: none;
  border: none;
  cursor: pointer;
  font-family: var(--font-sans);
}
/* Подписи, которые в макетах различаются между платформами: широкий
   вариант десктопный, узкий — тач. Пара нужна там, где макеты дают
   разный текст, а не разную вёрстку (ссылка на 25 против кнопки в
   M21, средняя строка легенды в 01 против M6). */
.copy--narrow,
.legend .copy--narrow { display: none; }

/* ===================== Секции разделов =====================
   Серых карточек-групп в разделах больше нет (§5.2). Заголовок группы —
   Headers/Title в Text/Primary без подложки; под ним строки на белом;
   между строками одной группы линия Stroke/Primary во всю ширину.

   Строка — компонент Cell с выключенной левой зоной: название и
   пояснение в середине, значение справа. Вертикальные поля 14,
   горизонтальные обнулены — строки выровнены по краю контента окна,
   а не по краю бывшей карточки.

   Между секциями 40 (§5.5): у .section-view свой gap 20, поэтому
   разницу добирает верхнее поле секции. */
.sec { display: flex; flex-direction: column; }
.sec + .sec { padding-top: 20px; }

/* Заголовок и вводный абзац — одна шапка: отступ до первой строки
   задаётся один раз, а не дважды. */
.sec__head {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding-bottom: 14px;
}
.sec__title {
  margin: 0;
  font-size: 19px;
  font-weight: 700;
  line-height: 24px;
  letter-spacing: .12px;
  color: var(--ink);
}
.sec__intro {
  margin: 0;
  font-size: 16px;
  line-height: 20px;
  letter-spacing: .04px;
  color: var(--text-secondary);
}

/* Высота строки набирается полями, а не минимумом: 14 + 20 + 14 = 48
   у однострочной и 72 у строки с пояснением. Минимум 64 сюда попал по
   ошибке — это правило ячейки рейтинга, где слева стоит аватарка 32, а
   здесь левая зона выключена и держать нечего. */
.sec__row {
  box-sizing: border-box;
  padding: 14px 0;
  display: flex;
  align-items: center;
  gap: 12px;
  border-bottom: 1px solid var(--line);
}
.sec__row:last-child { border-bottom: none; }
.sec__name {
  flex: 1;
  min-width: 0;
  font-size: 16px;
  line-height: 20px;
  letter-spacing: .04px;
  color: var(--ink);
}
/* Пояснение второй строкой внутри строки, а не отдельной строкой
   списка: «максимум три за игру» объясняет цену над собой, а рядом с
   ней читалось бы как ещё одно правило того же веса. Строка от этого
   вырастает с 64 до 72 — так в макетах 17 и M14. */
.sec__note {
  display: block;
  margin-top: 8px;
  font-size: 13px;
  line-height: 16px;
  letter-spacing: .04px;
  color: var(--text-secondary);
}
/* Значение справа — Text/Primary, а не приглушённая мета: цена
   подсказки и дневной запас это то, за чем в раздел и приходят. */
.sec__value {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: 16px;
  font-weight: 600;
  line-height: 20px;
  color: var(--ink);
}

/* Таймер — постоянный подвал «Результатов», а не элемент содержимого.
   Правило одно на все вкладки и обе платформы: он последний элемент
   окна и стоит в 24 от нижнего края (§5.7). Раньше он вёл себя
   по-разному на разных вкладках и при переключении прыгал.

   Распорка перед ним — не отдельный элемент, а margin-top: auto: место
   собирается ровно там, где нужно, и при коротком содержимом таймер
   всё равно оказывается внизу. 24 даёт поле окна: раздел кончается
   вместе с ним.

   sticky нужен для второго случая — когда вкладка длиннее окна. Тогда
   свободного места нет, распорка ничего не даёт, и таймер уезжает
   вместе с прокруткой: на «Рейтинге» он вставал в 13 от края вместо
   24, то есть прыгал при переключении вкладок ровно так, как описано
   в §5.7. Место в потоке при этом остаётся за ним — это не абсолютный
   слой: когда список домотан до низа, таймер стоит под ним, а не
   поверх. */
.timer-strip {
  margin-top: auto;
  position: sticky;
  bottom: 0;
  z-index: 1;
  box-sizing: border-box;
  /* Без flex: none полоса сжимается вместо прокрутки раздела: на
     «Статистике» с пятой плиткой она садилась с 57 до 25. */
  flex: none;
  height: 56px;
  padding: 0 20px;
  border-radius: 12px;
  background: var(--accent-soft);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}
.timer-strip__label {
  font-size: 16px;
  line-height: 22px;
  color: var(--text-secondary);
}
.timer-strip__value {
  font-size: 20px;
  font-weight: 700;
  line-height: 25px;
  color: var(--ink);
}

/* ===================== Низ окна ===================== */

.bottom {
  padding-top: 22px;   /* +10 от окна = 32 между игрой и кнопкой */
  display: flex;
  flex-direction: column;
  gap: 12px;
}

/* Кнопка проверки — во всю ширину и на 50, а не на 48 как базовая. */
.btn--check { width: 100%; min-width: 0; height: 50px; }

/* Клавиатура: ряды через 4, клавиши в ряду через 6. Ширина буквенной
   клавиши считается по первому ряду и остаётся одинаковой во всех
   трёх рядах; короткие ряды центрируются как в макетах. */
.keyboard { display: flex; flex-direction: column; gap: 4px; width: auto; }

.keyboard__row { display: flex; gap: 6px; justify-content: center; }
.keyboard__row .key {
  flex: 0 0 calc((100% - 66px) / 12);
  min-width: 0;
  padding: 0;
}

/* «Удалить» шире буквенной в 1,6 раза. */
.keyboard__row .key--wide { flex: none; width: 102px; }

.key__delete-icon {
  width: 24px;
  height: 24px;
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
