/* ================================================================
   Подкидной дурак — оформление.

   Три правила, из которых выведено всё остальное:

   1. Экран телефона держится в высоте окна. Ряды — карты соперника,
      стол в два ряда, подсказка, своя рука, кнопки — считаются честно,
      поэтому не наползают друг на друга даже в шторке Telegram
      высотой 420 точек.
   2. Горизонтальной прокрутки нет никогда: страница зафиксирована,
      всё, что шире экрана, просто не рисуется за его краем.
   3. Цвета берём у Telegram (он присылает свои переменные для светлой
      и тёмной темы), а если их нет — работают наши, «зелёное сукно».

   Ни картинок, ни шрифтов из интернета: масти — обычные символы,
   рубашка карты — узор из полосок средствами CSS. Свой шрифт лежит
   в самом проекте (папка «шрифты»), с чужих сайтов не подгружается —
   см. следующий раздел.
   ================================================================ */

/* ================================================================
   Шрифт игры — Onest
   ================================================================

   Зачем свой шрифт. Раньше текст рисовался тем, что стоит в телефоне
   по умолчанию: на Android это Roboto, и игра выглядела как окно
   настроек телефона, а не как игра. Свой шрифт — самая дешёвая
   вещь, которая делает вид «сделанным нарочно».

   Почему именно Onest. Он рисовался сразу с кириллицей (а не с
   латиницей, к которой русские буквы приделали потом), поэтому «д»,
   «з», «ю» у него нормальной формы, а не выморочной. Буквы широкие
   и открытые — это то, что нужно мелким подписям в 12–13 точек на
   телефоне. Лицензия свободная (OFL), файл переменный, то есть
   одним файлом даёт все степени жирности. Из ровни: Inter и Manrope
   заметно суше и ближе к тому же системному виду, от которого мы
   уходим, Golos Text — хорош, но у него более «деловой» характер,
   для карточной игры Onest дружелюбнее.

   Файлы лежат рядом с игрой, в папке «шрифты», и их четыре, а не два:
   каждое начертание разрезано на русские буквы и латинские. Так
   телефону не приходится тянуть латиницу ради русского текста —
   строка «unicode-range» говорит браузеру, какие буквы лежат в файле,
   и лишний кусок он просто не скачивает. Всего 96 килобайт, из них
   для нашей игры обычно нужны только две русские половинки (30 КБ).

   Из сети не тянется ничего: игра открывается так же быстро и
   работает без интернета.

   Пока файл ещё едет, работает запасная цепочка системных шрифтов
   (см. переменную «--шрифт»): текст виден сразу, пустоты и мигания
   нет — за это отвечает font-display: swap.
   ================================================================ */

@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('шрифты/onest-кириллица-400.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('шрифты/onest-латиница-400.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('шрифты/onest-кириллица-700.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: 'Onest';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('шрифты/onest-латиница-700.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

:root {
  /* Шрифт игры и запасная цепочка на случай, если свой не приехал.
     Порядок такой: system-ui — то, чем телефон пишет сам, дальше
     подписаны Apple, Windows и Android поимённо, в конце — любой
     рубленый шрифт, какой найдётся. */
  --шрифт: "Onest", system-ui, -apple-system, "Segoe UI", Roboto,
           "Helvetica Neue", Arial, sans-serif;

  /* ---------- Палитра ----------
     Слева — наше название, справа — цвет Telegram и запасной вариант.
     Если Telegram цвет не прислал, берётся запасной. */
  --фон:          var(--tg-theme-bg-color, #14532d);          /* сукно стола */
  --панель:       var(--tg-theme-secondary-bg-color, #0b3a20); /* плашка итога */
  --текст:        var(--tg-theme-text-color, #f1f8f2);
  --кнопка-фон:   var(--tg-theme-button-color, #f0b32d);
  --кнопка-текст: var(--tg-theme-button-text-color, #23150a);
  --акцент:       var(--tg-theme-button-color, #ffd66b);      /* чем подсвечиваем выбор */

  /* Приглушённый текст. Своего «серого» у Telegram брать нельзя: в светлой
     теме он даёт контраст около 2 при норме 4,5 — мелкие подписи почти
     не читаются. Поэтому берём основной цвет текста и подмешиваем к нему
     фон: получается тише основного, но всё ещё хорошо читается в любой теме.

     Первая строка — страховка для браузеров старше 2023 года, которые
     не знают color-mix. Там подписи просто берут основной цвет текста:
     выглядит проще, зато читается всегда и в любой теме. Серый цвет
     Telegram в запас не годится — это ровно та бледность, от которой
     мы уходим. Кто понимает color-mix, возьмёт вторую строку.

     Доля основного цвета была 80%, стала 88% — и вот почему.
     Посреди сукна лежит мягкий белый блик (см. фон у body). Над самым
     светлым его местом фон высветляется, и подпись при 80% давала
     контраст 4,25 при норме 4,5 — то есть в самом заметном месте
     экрана она читалась хуже всего. Хуже того: если та же приглушённая
     подпись лежит ещё и на полупрозрачной плашке (строка в таблице
     рекордов, мелкая кнопка), фон под ней светлеет второй раз, и было
     уже 3,9.

     Считали так: сукно 22,91,50 плюс 10% белого от блика даёт 45,107,70;
     та же точка под плашкой — 62,111,82. При 88% подпись выходит
     215,228,218 и даёт 4,90 над бликом и 4,56 над бликом с плашкой.
     Норму прошли обе, а разница с заголовком осталась видимой: подпись
     заметно тише основного текста 241,248,242 и вдвое мельче его.
     Больше 88% не берём — вот тогда подпись и заголовок сравняются. */
  --текст-тихий:  var(--текст);
  --текст-тихий:  color-mix(in srgb, var(--текст) 88%, var(--фон));

  /* Полупрозрачные подложки специально сделаны серыми: на тёмном фоне
     они высветляют, на светлом — притемняют, и работают в любой теме. */
  --подложка:     rgba(128, 128, 128, 0.20);
  --край:         rgba(128, 128, 128, 0.45);

  /* ---------- Цвета самой карты ----------
     Бумага кремовая, как у карт набора владельца, и цвет её подогнан под
     бумагу на картинках фигур (#f6ead5): у валета, дамы и короля бумага
     нарисована прямо в картинке, и другой оттенок у цифр был бы виден
     полосой на стыке. Цвета мастей от темы Telegram не зависят вовсе —
     они всегда лежат на одной и той же бумаге.

     МАСТИ В ДВЕ КРАСКИ, как в наборе (решение штаба 10 сентября): пики
     и трефы почти чёрные, черви и бубны насыщенно-красные. Раньше колода
     была четырёхцветной (бубны синие, трефы зелёные) — её завели, когда
     в тесной руке от карты была видна полоска в десяток точек и форму
     значка было не разобрать. В новой руке полоска втрое шире, значок
     крупный, и владелец выбрал карты как в наборе. Вернуть четыре краски —
     поменять здесь две строки.

     Контраст на бумаге: красная 4,9 при норме 4,5, чёрная — больше 14.
     Цветом красится весь угол карты — и значок масти, и достоинство. */
  --карта-фон:      #f6ead5;
  --карта-край:     #98a1ac;
  --карта-текст:    #1c1a18;
  --карта-красная:  #c8102e;
  --масть-пики:     #1c1a18;
  --масть-трефы:    #1c1a18;
  --масть-черви:    #c8102e;
  --масть-бубны:    #c8102e;

  /* «Можно» и «нельзя». Зелёным «можно» теперь красится только точка
     в строке связи и образец на экране «Как играть»; в руке «можно» —
     салатовая черта под картой (см. раздел стола в конце файла).
     «Отказ» — ответ на тап по карте, которой ходить нельзя. */
  --карта-можно:    #1cc06a;
  --карта-отказ:    #e0273c;
  /* ---------- Рубашка карты ----------
     Рисунок рубашки теперь векторный (его делает js/колода-рисунок.js),
     и настоящих цветов в нём всего два — они здесь. Узор, кант и медальон
     нарисованы белым с прозрачностью, поэтому сами подстраиваются
     под любой цвет поля, менять их не нужно.

     Почему бордовый, а не прежний синий. Рубашка — самое частое, что
     видит игрок: вся колода, весь отбой, вся рука соперника. Она должна
     быть в родстве со столом, но не спорить с ним и не сливаться.
     Тёмно-зелёная рубашка на зелёном сукне пропадает (в тёмной теме сукно
     26,67,53 — рубашка была бы почти того же тона), а синяя с зелёным
     спорит: два холодных цвета рядом тянут одеяло друг у друга.
     Бордовый — старая пара зелёного сукна, та самая, что в клубах: он
     тёплый, поэтому от стола отделяется в любой теме, и при этом не
     кричит, как чистый красный.

     Кайма по краю — тёплая кремовая, а не белая: чисто белая кайма рядом
     с белой лицевой стороной карты сбивает — обе стороны выглядят
     одинаково светлыми. Кремовая отделяет рубашку от лица и заодно
     всегда обводит карту светлым контуром, поэтому рубашка не сливается
     с сукном даже там, где тона близки. */
  --рубашка-фон:    #6e2233;   /* поле рубашки — единственный её цвет */
  --рубашка-поле:   #f2ece0;   /* кремовая кайма по краю карты */

  /* ---------- Размер карты ----------
     Главный размер стола — карта в руке. На макете владельца она 85×119
     при ширине экрана 390, то есть её высота — 30,5 сотых ширины. В низком
     окне она не забирает больше 17 сотых высоты окна: руке нельзя съесть
     стол. Все остальные карты (на столе, в колоде, рубашки соперника)
     задают свой размер сами, у себя в разделе стола.
     Игра меряет готовую карту, а не считает её сама (js/game.js,
     «измеритьКарту»), поэтому других чисел для неё здесь не нужно.
     1,4 — пропорция рисунка карты (250 на 350): рисунок не растягивается. */
  --в-рука: clamp(56px, min(30.5vw, calc(var(--доступно) * 0.17)), 136px);
  --в: var(--в-рука);
  --ш: calc(var(--в) / 1.4);

  /* Высота окна. dvh — «живая» высота: не скачет, когда в Telegram
     выезжает или прячется шапка. Для старых браузеров ниже есть vh. */
  --доступно: 100vh;

  /* ---------- Безопасные поля: часы, вырез, полоса жеста ----------

     В полном экране Telegram игра занимает весь телефон, и сверху над
     ней остаются часы и вырез, а снизу — полоса жеста. Если про них
     не знать, заголовок уедет под часы, а нижний ряд кнопок — под
     полосу.

     Полей два источника, и мы берём больший из двух:
       env(safe-area-inset-…) — знает про сам телефон (вырез, полоса),
         но не знает, сколько сверху занял Telegram своими кнопками;
       var(--безопасно-…) — их кладёт на :root js/telegram.js, и там
         уже СУММА обоих слоёв Telegram («от края экрана» и «от края
         безопасной области»). Вне Telegram и в старых его версиях
         там нули, поэтому max() спокойно берёт env().

     Дальше по файлу эти четыре переменные подставляются в отступы
     экранов. Складывать их между собой не нужно — только прибавлять
     к своему отступу. */
  --отступ-сверху: max(env(safe-area-inset-top,    0px), var(--безопасно-сверху,  0px));
  --отступ-снизу:  max(env(safe-area-inset-bottom, 0px), var(--безопасно-снизу,   0px));
  --отступ-слева:  max(env(safe-area-inset-left,   0px), var(--безопасно-слева,   0px));
  --отступ-справа: max(env(safe-area-inset-right,  0px), var(--безопасно-справа,  0px));

  /* Скругление карты-образца на экране «Как играть». У настоящих карт
     скругление считается от их ширины (см. «.карта»). */
  --скругление: 7px;
}

@supports (height: 100dvh) {
  :root { --доступно: 100dvh; }
}

* {
  box-sizing: border-box;
  -webkit-tap-highlight-color: transparent; /* без серой вспышки при тапе */
}

html, body {
  height: 100%;
  margin: 0;
  overflow: hidden;            /* ничего никуда не прокручивается */
  overscroll-behavior: none;   /* и не «оттягивается» пальцем */
}

body {
  font-family: var(--шрифт);
  /* Сглаживание букв. На тёмном сукне светлый текст без этого выглядит
     жирнее, чем нарисован, и мелкие подписи слипаются. */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: var(--текст);
  /* Сукно. Первая строка — чистый цвет темы, вторая подмешивает к нему
     зелёного: и в светлой теме Telegram, и в тёмной стол остаётся столом,
     а белые карты на нём хорошо видно. Старый браузер возьмёт первую строку. */
  background-color: var(--фон);
  /* Зелёного в замесе было 20%, стало 38%. Причина видна на снимке светлой
     темы: при 20% стол выходил бледно-серым, «больничным» — на стол он был
     не похож вовсе, а игра называется карточной. Промежуточные 30% дела
     не решили: в светлой теме свет и тени физически дают мало, и опираться
     приходится на насыщенность цвета, а не на светотень.
     Теперь светлая тема — (170, 204, 184) вместо прежней (210, 228, 218):
     зелёное сукно, но всё ещё светлое, под стать светлому Telegram.
     Контраст подписей от этого только вырос — тёмный текст лежит
     на чуть более тёмном фоне. */
  background-color: color-mix(in srgb, var(--фон) 62%, #1f7a45);
  /* Мягкий блик посередине — сукно перестаёт быть плоской заливкой.
     Блик белый и очень слабый, поэтому на светлой теме почти незаметен.

     Белого в нём было 10%, стало 8% — и это не косметика, а починка
     читаемости. Самое светлое место блика приходится примерно на верхнюю
     треть экрана, а там как раз живут подписи под заголовками и верхние
     строки таблицы рекордов. При 10% фон под ними высветлялся так, что
     приглушённый текст на полупрозрачной плашке давал контраст 4,43
     при норме 4,5. Лечить это можно было двумя способами: сделать
     подписи ярче — но тогда они сравняются с заголовками и порядок
     чтения пропадёт, — или убавить сам блик. Убавили блик: он и был
     причиной, а сукно на глаз почти не изменилось. */

  /* ---------- Сукно в три слоя ----------
     Плоская заливка одним цветом — главный признак старого вида: настоящий
     стол так не выглядит никогда, потому что на него падает свет и у ткани
     есть фактура. Поэтому фон собран из трёх слоёв. В CSS они записаны
     сверху вниз, то есть первым идёт самый верхний:

       1) зерно ткани — мелкий шум. Картинки-файла нет: шум рисует сам
          браузер по встроенному SVG (feTurbulence — «завихрение»,
          готовый генератор случайных точек). Матрица после него делает
          точки серыми и непрозрачными, иначе шум выходит цветным.
          Плитка 160×160 повторяется по всему экрану;
       2) блик — тон в середине стола светлее (он был и раньше);
       3) виньетка — к краям темнее. Держим её на грани заметности:
          если видно «тёмное пятно по углам», значит перебор.

     Режим смешивания у зерна — soft-light («мягкий свет»): серые точки
     чуть высветляют и чуть притемняют то, что под ними, вместо того чтобы
     лечь сверху серой пылью. Браузер, который такого не умеет, просто
     положит слабое серое зерно — тоже не страшно. */
  background-image:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3'/%3E%3CfeColorMatrix values='1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.6'/%3E%3C/svg%3E"),
    radial-gradient(120% 80% at 50% 28%, rgba(255, 255, 255, 0.08), transparent 70%),
    radial-gradient(115% 95% at 50% 42%, transparent 40%, rgba(0, 0, 0, 0.30) 100%);
  background-repeat: repeat, no-repeat, no-repeat;
  background-size: 160px 160px, auto, auto;
  background-blend-mode: soft-light, normal, normal;
  touch-action: manipulation;  /* тап срабатывает сразу, без ожидания двойного */
  user-select: none;
}

#приложение {
  position: fixed;
  inset: 0;
}

/* ================================================================
   Живой фон — пять видов на выбор
   ================================================================

   Что это. Под всеми экранами лежит пустой слой, и в нём медленно
   двигаются большие мягкие пятна. Какой фон выбран, говорит признак
   «data-фон» на самом верхнем элементе страницы: его ставит игра,
   выбор человека переезжает вместе с ним между устройствами.

   ЧЕМ ЭТО ОТЛИЧАЕТСЯ ОТ «ЖИВЫХ ОБОЕВ ИЗ ДВУХТЫСЯЧНЫХ». Тогда фоном
   были повторяющиеся картинки, резкие звёздочки и бегущие огоньки —
   они кричали «смотри на меня». Здесь наоборот: если человек заметил
   фон во время партии, фон плохой. Отсюда две мерки, которые я держал
   при рисовании и по которым это можно проверить:

     • ни одно пятно не отличается от сукна больше чем на восемь сотых
       по светлоте (в правилах это доли вроде 0.06–0.08);
     • полный круг движения — не быстрее полутора минут, а у тумана
       и вовсе три.

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

   ЧТО ДВИГАЕТСЯ. Только сдвиг, размер и прозрачность — то, что
   браузер рисует видеокартой. Раскладку он при этом не пересчитывает,
   поэтому телефон не греется.

   ДВА СЛУЧАЯ, КОГДА ФОН ЗАМИРАЕТ:
     1. человек попросил в телефоне «меньше движения»;
     2. страница не видна — свёрнутое мини-приложение в кармане.
   Второе игра сообщает признаком «data-страница=скрыта».
   ================================================================ */

.фон-игры {
  position: absolute;
  inset: 0;
  z-index: 0;               /* под всеми экранами */
  overflow: hidden;
  pointer-events: none;     /* сквозь фон нажимается всё, что под ним */
  /* Сила пятен — одним числом на весь фон. На странице она нарочно
     мала: восемь сотых по светлоте, ровно та мерка, по которой фон
     не должен замечаться во время партии. В образце на экране выбора
     то же число берётся крупнее (см. ниже) — иначе в окошке высотой
     в сорок шесть точек все пять фонов выглядят одинаковым зелёным
     прямоугольником, и выбрать нечего. Пятна при этом остаются теми
     же самыми: меняется только громкость, а не рисунок. */
  --сила-свет: 0.07;
  --сила-тень: 0.10;
}

/* ---------- Образец фона на экране «Оформление» ----------

   Внутри маленькой кнопки лежит ровно тот же слой «фон-игры», что
   и на странице, и признак «data-фон» стоит на самом образце. Поэтому
   правила ниже написаны через «:where(html, .образец-фона)» — они
   одинаково срабатывают и когда фон выбран для всей страницы, и когда
   он показан на кнопке.

   Так образец не может разойтись с настоящим фоном: это не картинка
   «как будет», а сам фон, только в окошке. И тему Telegram он берёт
   ту же, что игра, — вписанные в код цвета так не умеют.

   Размер образца задан здесь же: он должен быть заметно шире, чем
   высок, — фон человек видит в первую очередь как ширину экрана,
   и вытянутое окошко читается как «кусочек стола», а не как плитка. */
.образец-фона {
  position: relative;
  overflow: hidden;
  width: 100%;
  height: 46px;
  border-radius: 9px;
  background: var(--фон);
  /* Сукно с зерном рисует само тело страницы, а в окошке его нет —
     поэтому подмешиваем ту же зелень, что у стола, иначе «Сукно»
     выглядело бы серым квадратом, не похожим ни на что. */
  background: color-mix(in srgb, var(--фон) 62%, #1f7a45);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.25);
}

/* В окошке пятна крупнее по силе — иначе все пять фонов выглядят
   одинаковым зелёным прямоугольником. Рисунок тот же, громкость
   другая: так человек видит, чем «Туман» отличается от «Лампы»,
   а на самой странице оба остаются тихими. */
.образец-фона .фон-игры {
  --сила-свет: 0.38;
  --сила-тень: 0.44;
}

/* Движение в образце остановлено, и остановлено НЕ в начале: показывать
   надо середину круга, где пятна разошлись, а не исходное положение,
   в котором все фоны похожи. Отрицательная задержка как раз и значит
   «отмотай на сорок секунд вперёд и замри». Заодно это экономит
   батарею: пять кнопок не двигаются без нужды. */
.образец-фона .фон-игры::before,
.образец-фона .фон-игры::after {
  animation-delay: -40s;
  animation-play-state: paused;
}

/* Оба движущихся пятна — это псевдоэлементы слоя. Своих узлов
   в разметке они не просят: чем меньше узлов, тем дешевле страница.
   Пятна нарочно больше экрана: край размытого круга не должен
   попадать в кадр, иначе получится «шарик ползёт», а не свет. */
.фон-игры::before,
.фон-игры::after {
  content: "";
  position: absolute;
  will-change: transform, opacity;
}

/* ---------- 1. «Сукно» — неподвижный, по умолчанию ----------
   Своих правил у него нет вовсе, и это не забывчивость, а устройство:
   пятна задаются только внутри правил живых фонов, поэтому при
   «Сукне» оба слоя остаются пустыми и невидимыми — остаётся то самое
   сукно с зерном, что было всегда. Так же выглядит игра, пока человек
   ничего не выбрал.

   Раньше здесь стояло правило «не рисовать псевдоэлементы вовсе»
   (content: none), и оно вышло боком: слой фона есть не только
   на странице, но и в каждом образце на экране выбора, а правило
   било по всем слоям разом — образцы получались одинаковыми
   зелёными прямоугольниками, и выбрать было нечего. */

/* ---------- 2. «Дыхание» ----------
   Два огромных пятна — одно светлое, другое тёмное — медленно
   расходятся и сходятся по диагонали. Круг полторы минуты. На глаз
   это не «что-то ползёт», а «картинка не мёртвая». */
:where(html[data-фон="дыхание"] #приложение, .образец-фона[data-фон="дыхание"]) > .фон-игры::before {
  width: 150%;
  height: 110%;
  left: -30%;
  top: -20%;
  background: radial-gradient(closest-side, rgba(255, 255, 255, var(--сила-свет)), transparent 100%);
  animation: фон-дыхание-светлое 96s ease-in-out infinite;
}

:where(html[data-фон="дыхание"] #приложение, .образец-фона[data-фон="дыхание"]) > .фон-игры::after {
  width: 140%;
  height: 120%;
  right: -35%;
  bottom: -25%;
  background: radial-gradient(closest-side, rgba(0, 0, 0, var(--сила-тень)), transparent 100%);
  animation: фон-дыхание-тёмное 116s ease-in-out infinite;
}

@keyframes фон-дыхание-светлое {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1); }
  50%      { transform: translate3d(6%, 5%, 0) scale(1.08); }
}

@keyframes фон-дыхание-тёмное {
  0%, 100% { transform: translate3d(0, 0, 0) scale(1.05); }
  50%      { transform: translate3d(-7%, -4%, 0) scale(1); }
}

/* ---------- 3. «Лампа над столом» ----------
   Одно широкое пятно света сверху по центру, как от лампы над столом.
   Оно очень медленно набирает и теряет силу и чуть ходит вбок —
   будто лампа покачивается. Круг две минуты. Второе пятно — тень
   по нижним углам, она делает свет светом, а не просто белым кругом. */
:where(html[data-фон="лампа"] #приложение, .образец-фона[data-фон="лампа"]) > .фон-игры::before {
  width: 160%;
  height: 130%;
  left: -30%;
  top: -55%;
  background: radial-gradient(closest-side, rgba(255, 255, 255, calc(var(--сила-свет) + 0.01)), transparent 100%);
  animation: фон-лампа 124s ease-in-out infinite;
}

:where(html[data-фон="лампа"] #приложение, .образец-фона[data-фон="лампа"]) > .фон-игры::after {
  inset: 0;
  background: radial-gradient(120% 90% at 50% 40%, transparent 45%, rgba(0, 0, 0, 0.14) 100%);
  animation: фон-лампа-тень 124s ease-in-out infinite;
}

@keyframes фон-лампа {
  0%, 100% { transform: translate3d(-2%, 0, 0); opacity: 0.75; }
  50%      { transform: translate3d(2%, 1%, 0); opacity: 1; }
}

@keyframes фон-лампа-тень {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.8; }
}

/* ---------- 4. «Туман» ----------
   Два слоя очень мягких широких полос ползут в разные стороны
   с разной скоростью — проход около трёх минут. Работают они
   на глубину: становится видно, что стол ближе, а фон дальше.
   Полосы нарочно наклонные и без единого резкого края. */
:where(html[data-фон="туман"] #приложение, .образец-фона[data-фон="туман"]) > .фон-игры::before {
  width: 240%;
  height: 140%;
  left: -70%;
  top: -20%;
  background: linear-gradient(104deg,
    transparent 0%, rgba(255, 255, 255, calc(var(--сила-свет) * 0.8)) 18%, transparent 34%,
    transparent 58%, rgba(255, 255, 255, calc(var(--сила-свет) * 0.6)) 74%, transparent 92%);
  animation: фон-туман-вправо 186s linear infinite;
}

:where(html[data-фон="туман"] #приложение, .образец-фона[data-фон="туман"]) > .фон-игры::after {
  width: 240%;
  height: 140%;
  right: -70%;
  bottom: -20%;
  background: linear-gradient(76deg,
    transparent 0%, rgba(0, 0, 0, calc(var(--сила-тень) * 0.7)) 22%, transparent 42%,
    transparent 66%, rgba(0, 0, 0, calc(var(--сила-тень) * 0.5)) 82%, transparent 100%);
  animation: фон-туман-влево 254s linear infinite;
}

@keyframes фон-туман-вправо {
  from { transform: translate3d(-8%, 0, 0); }
  to   { transform: translate3d(8%, 0, 0); }
}

@keyframes фон-туман-влево {
  from { transform: translate3d(7%, 0, 0); }
  to   { transform: translate3d(-7%, 0, 0); }
}

/* ---------- 5. «Северный отсвет» ----------
   Вдоль верхнего края мягкое холодное свечение, медленно меняющее
   ширину. Самый нарядный из пяти — и всё равно тихий: это подсветка
   у горизонта, а не сияние с лучами. Холод даётся не цветом, а тем,
   что светлая грань стоит вверху, а тёмная внизу: так читается небо
   над столом. */
:where(html[data-фон="отсвет"] #приложение, .образец-фона[data-фон="отсвет"]) > .фон-игры::before {
  width: 180%;
  height: 70%;
  left: -40%;
  top: -28%;
  background: radial-gradient(closest-side, rgba(255, 255, 255, calc(var(--сила-свет) + 0.01)), transparent 100%);
  animation: фон-отсвет 108s ease-in-out infinite;
}

:where(html[data-фон="отсвет"] #приложение, .образец-фона[data-фон="отсвет"]) > .фон-игры::after {
  width: 100%;
  height: 60%;
  left: 0;
  bottom: 0;
  background: linear-gradient(to top, rgba(0, 0, 0, 0.12), transparent 100%);
}

@keyframes фон-отсвет {
  0%, 100% { transform: translate3d(0, 0, 0) scaleX(1);    opacity: 0.7; }
  50%      { transform: translate3d(3%, 2%, 0) scaleX(1.15); opacity: 1; }
}

/* ---------- Когда фон замирает ----------

   Первое: страница не видна. Свёрнутое мини-приложение для самой
   страницы остаётся «видимым», поэтому признак ставит игра — и по
   браузерному событию, и по своим событиям Telegram. Мы просто
   ставим движение на паузу: вернулся человек — оно продолжится
   с того же места, а не дёрнется с начала. */
html[data-страница="скрыта"] .фон-игры::before,
html[data-страница="скрыта"] .фон-игры::after {
  animation-play-state: paused;
}

/* Второе: человек попросил в телефоне «меньше движения». Тогда фоны
   не двигаются вовсе и выглядят как спокойная картинка — пятна
   остаются, дышать перестают. */
@media (prefers-reduced-motion: reduce) {
  .фон-игры::before,
  .фон-игры::after {
    animation: none !important;
  }
}

/* ---------- Экраны ---------- */

/* Общий отступ любого экрана — восемь точек плюс безопасные поля.
   В полном экране Telegram без этого заголовок любого экрана уезжает
   под часы, а нижняя кнопка — под полосу жеста. Экраны со своими
   отступами (стол, витрина, плашки) прибавляют те же переменные
   каждый у себя — см. их правила ниже. */
.экран {
  position: absolute;
  inset: 0;
  display: none;
  flex-direction: column;
  padding: calc(8px + var(--отступ-сверху))
           calc(8px + var(--отступ-справа))
           calc(8px + var(--отступ-снизу))
           calc(8px + var(--отступ-слева));
}

.экран--виден { display: flex; }

.скрыт { display: none !important; }

/* ================================================================
   ОДНА КОЛОНКА НА ВСЕ ИГРЫ

   Владелец сказал коротко и точно: «У дурака всё так узенько,
   в нардах всё максимально широкое». Так и было: в дураке кнопки
   меню жались в 260 точек, а в нардах тянулись во всю ширину окна —
   на компьютере это полосы в полтора экрана длиной. Одна и та же
   кнопка «К выбору игры» в двух играх выглядела как две разные
   программы.

   Теперь ширина у всех одна и живёт ЗДЕСЬ, в общем файле, а не
   в файле каждой игры. Меняется в одном месте — меняется везде.

   360 точек — это ширина обычного телефона. На телефоне колонка
   занимает всё, что есть (ограничение просто не срабатывает),
   а на компьютере содержимое собирается в аккуратный столбик
   посередине вместо растянутых полос.

   Правило намеренно узкое: оно про ПРЯМЫХ детей экрана — кнопки,
   блоки выбора, подписи. Кнопки, которые лежат рядами внутри своих
   полос (кнопки под доской, ряды знаков, панель стола), оно не
   трогает вовсе — там ширину считает сама полоса.
   ================================================================ */
:root {
  --колонка: 360px;
  /* Ширина столбика кнопок на экранах меню. Раньше это число (260)
     было вписано в двенадцать разных правил дурака — от меню
     до рекордов, — и владелец справедливо назвал такую колонку
     «узенькой». Теперь оно одно на весь сборник и стоит здесь:
     300 точек — кнопка стала заметно шире, но столбик всё ещё
     читается как столбик, а не как полоса во весь экран. */
  --колонка-кнопок: 300px;
}

.экран > .кнопка,
.экран > .выбор,
.экран > .правила-текст {
  width: min(100%, var(--колонка));
  /* Поля «auto» ставят столбик посередине даже там, где экран
     растягивает детей по ширине (а так устроены экраны нард
     и шахмат). Без них колонка прилипла бы к левому краю. */
  margin-left: auto;
  margin-right: auto;
}

/* Заголовкам и подписям задаём только выравнивание, но НЕ ширину.
   Проверено на шахматах: стоило дать им ширину колонки, и строка
   «Ходят белые» — а она нарисована пилюлей по размеру текста —
   растянулась со 139 точек до 360 и превратилась в полосу.
   Пусть каждая подпись сама решает, какой ей быть шириной;
   от общего правила ей нужно одно — стоять по центру. */
.экран > .заголовок,
.экран > .подпись {
  text-align: center;
}

/* Заголовок. Буквы стоят чуть теснее обычного (отрицательный
   «letter-spacing»): у крупной надписи широкие просветы между буквами
   читаются как рыхлость, а сжатая на полточки строка выглядит как
   заголовок, набранный нарочно. Раньше здесь было наоборот — просветы
   растянуты на полточки, и это добавляло виду «сделано по умолчанию». */
.заголовок {
  margin: 0;
  font-size: 34px;
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.5px;
}

/* Подпись под заголовком. Строки чуть просторнее по высоте — так
   разница с заголовком читается не только кеглем, но и ритмом. */
.подпись {
  margin: 0;
  font-size: 15px;
  line-height: 1.35;
  color: var(--текст-тихий);
}

/* Правила старого меню дурака («#экран-меню», «#экран-бота») убраны
   11 сентября: его заменили лобби и три шага до партии, разметки меню
   больше нет. Общее правило для слова в кнопке оставлено — его берут
   «Играть с другом» и экраны шашек. */

/* ---------- Слово, которым кнопки различаются ----------

   «Играть с ботом» и «Играть с другом» отличаются одним последним
   словом, а глаз читает подпись целиком — и чтобы понять, где какая,
   приходится дочитать обе до конца. Разметка вынесла это слово
   отдельным узлом; здесь оно делается заметным без чтения.

   Только вес и размер, второго цвета нет нарочно. Цвет надписи —
   цвет текста кнопки Telegram, и любой второй оттенок на этой заливке
   либо спорит с темой, либо в одной из тем теряет контраст. Вес
   и размер работают в любой теме одинаково. Прозрачность на начале
   фразы тоже не взята: она бы съела контраст ровно там, где он
   и так на пределе — в тёмной теме на синей кнопке.

   Начало «Играть с» — 0,8 от кегля кнопки (17 при обычных 21) и вес
   500, само слово — 1,15 (24) и вес 800: разница в полтора раза
   по размеру и в два шага по весу видна с любого расстояния.

   Когда сеть переписывает начало в «Вернуться к игре с», строка
   становится длиннее ширины кнопки, и слово «другом» уходит на вторую
   строчку одно — это не поломка, а даже лучше: крупное слово стоит
   отдельной строкой. Внутри слова перенос невозможен: узел один. */
.кнопка .кнопка__начало {
  font-size: 0.8em;
  font-weight: 500;
}

.кнопка .кнопка__кого {
  font-size: 1.15em;
  font-weight: 800;
  letter-spacing: 0.2px;
}

/* ---------- Серия дней подряд ----------

   «3 дня подряд» на витрине и «День 4 подряд!» на плашке итога — один
   класс, один вид. Это крючок возвращения: строка должна попасться
   на глаза первой после заголовка, но не кричать — поэтому плашка
   на тихой подложке с тонкой рамкой цвета подсветки, кегль 14 против
   34 у заголовка. Звезда перед словами — та же, что у «★ Рекорды»:
   серия дней — из того же ряда достижений, и глаз узнаёт знак.

   Длинная строка «Вчера играли — сыграйте сегодня, чтобы не прервать
   серию из 5» на 360 точках ложится в две строки; text-wrap: balance
   делит их поровну, чтобы не было «длинная плюс одно слово». */
.серия-дней {
  display: inline-block;
  max-width: min(100%, 320px);
  margin: 0;
  padding: 5px 14px 6px;
  font-size: 14px;
  font-weight: 700;
  line-height: 1.3;
  color: var(--текст);
  background: var(--подложка);
  border: 1.5px solid var(--акцент);
  border-radius: 999px;
  text-wrap: balance;
}

.серия-дней::before {
  content: "★ ";
  color: var(--акцент);
}

/* Второй вариант — «вчера играли, сегодня ещё нет» — чуть теплее
   первого, без тревоги. Игра помечает его классом «серия-дней--вчера»
   (js/game.js, «освежитьСериюДней»). Теплее — значит подложка подкрашена
   цветом подсветки, а не рамка толще и не красный: это приглашение,
   а не предупреждение. */
.серия-дней--вчера {
  background: color-mix(in srgb, var(--акцент) 22%, var(--подложка));
}

/* =====================================================================
   ВИТРИНА — по готовому набору владельца (10 сентября, вечер)

   Цель теперь — картинка, а не описание: «эталон/0-витрина-итог.png»
   (941×1672) и вырезки его частей в «эталон/витрина-части/». Числа
   ниже сняты с этой картинки и из README набора
   («эталон/набор-витрины-README.md»), а не придуманы.

   КАК ПЕРЕВОДИТЬ КАРТИНКУ В ТОЧКИ ЭКРАНА. Картинка шириной 941,
   телефон — 390. Значит, всё на ней надо умножать на 390 / 941 ≈ 0,414.
   Пример: поле по краю на картинке 34 → на телефоне 14; промежуток
   между плитками 17 → 7. Поэтому поля и промежутки заданы в долях
   ширины экрана (vw): на 360, 390 и 430 точках экран выглядит как та же
   картинка, просто уменьшенная или увеличенная, а не «растянутая».

   ГЛАВНОЕ ОТЛИЧИЕ ОТ ПРЕЖНЕГО ПОДХОДА: плитки игр — готовые карточки
   владельца (фото, название, стрелка, затемнение и рамка уже внутри
   картинки, см. «img/витрина/»). Мы ничего не рисуем поверх второй
   раз — только ставим картинку фоном кнопки.

   Витрина не подстраивается под тему Telegram: на эталоне ровно один
   вид, тёмный. Поэтому у неё СВОИ переменные «--вт-…», объявленные
   прямо на экране, — другие экраны их не видят и как брали тему
   Telegram, так и берут.

   Один акцент — салатовый «--вт-акцент». Он красит только то, что
   выбрано или включено: активную фишку-фильтр, активную вкладку внизу
   и «вкл» у звука в листе «Ещё» (стрелки на плитках уже нарисованы
   в самих картинках тем же цветом).
   ===================================================================== */

/* ---------- Общие цвета сборника ----------
   Витрина была первой, и её цвета теперь общие: стол дурака (а потом
   шашки, шахматы и нарды) берут ровно их, чтобы сборник выглядел одним
   приложением. Числа прежние, витрина от переезда не изменилась ни на
   точку — она просто ссылается сюда. Меняете цвет — меняется везде. */
:root {
  --сб-фон: #101416;
  --сб-поверхность: #15181b;      /* панели — на тон светлее фона */
  --сб-граница: #51575e;          /* обводка фишек и тихих плашек */
  --сб-текст: #f8f5eb;            /* тёплый белый, как на макете */
  --сб-текст-тихий: #858b94;
  --сб-акцент: #d2f76b;           /* салатовый — единственный акцент */
  --сб-акцент-текст: #10130a;     /* текст на салатовом — почти чёрный */
}

#экран-витрины.витрина {
  /* Цвета из README набора — сняты с макета владельца. Фон обязан
     совпадать с фоном в углах карточек: картинки прямоугольные,
     и в их скруглённых углах остался фон макета. Другой фон страницы
     проступил бы в углах тёмными уголками. */
  --вт-фон: var(--сб-фон);
  --вт-поверхность: var(--сб-поверхность);  /* панель вкладок и лист «Ещё» */
  --вт-граница: var(--сб-граница);          /* обводка фишек-фильтров */
  --вт-текст: var(--сб-текст);
  --вт-текст-тихий: var(--сб-текст-тихий);
  --вт-акцент: var(--сб-акцент);
  --вт-акцент-текст: var(--сб-акцент-текст);

  /* Поле по краю и промежуток между плитками — доли ширины экрана
     (34 и 17 из 941 на макете). На 390 это ровно 14 и 7, как в README.
     «clamp» не даёт им стать смешными на очень узком или широком окне. */
  --вт-поле: clamp(12px, 3.6vw, 18px);
  --вт-зазор: clamp(6px, 1.8vw, 9px);
  /* Между рядами на макете чуть теснее, чем между столбцами:
     15–16 из 941 против 17. На 390 это 6,4 против 7. Мелочь, но за три
     ряда набегает полторы точки, и нижний ряд заметно «съезжает». */
  --вт-зазор-рядов: clamp(5px, 1.65vw, 8px);
  /* Видимая высота фишки-фильтра: 70 из 941 на макете → 29 на 390. */
  --вт-фишка: clamp(27px, 7.45vw, 33px);
  /* Высота нижней панели вкладок без полосы жеста: на макете 135 из
     941 → 56 точек на 390. От неё же считается запас снизу под
     прокрутку. Тоже доля ширины: на 360 панель 52, на 430 — 62, как
     если бы макет просто уменьшили или увеличили. Меньше 52 нельзя —
     вкладка должна оставаться удобной пальцу. */
  --вт-панель-низ: clamp(52px, 14.36vw, 64px);

  align-items: stretch;
  gap: 0;                    /* промежутки заданы у каждого блока свои — по макету */
  /* Фон: ровный тёмный и едва заметное салатовое свечение у верхнего
     края — на макете оно стоит за шапкой «Игры с друзьями» и гаснет
     к заголовку. «local» — чтобы свечение уезжало вместе с содержимым,
     а не висело на месте при прокрутке. */
  background:
    radial-gradient(75% 120px at 50% 0, rgba(210, 247, 107, 0.07), rgba(210, 247, 107, 0) 100%) local,
    var(--вт-фон);
  color: var(--вт-текст);
  /* Сверху — вырез с часами, снизу — место под закреплённую панель
     вкладок (56) и ещё 12, как на макете между баннером и панелью,
     плюс полоса жеста. Без этого запаса баннер «Деберц» уехал бы
     под панель и его нельзя было бы нажать. */
  padding: var(--отступ-сверху)
           calc(var(--вт-поле) + var(--отступ-справа))
           calc(var(--вт-панель-низ) + 12px + var(--отступ-снизу))
           calc(var(--вт-поле) + var(--отступ-слева));
  text-align: left;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  /* Полосу прокрутки не показываем: на телефоне её и так нет, а на
     компьютере она отъедала бы 15 точек ширины у сетки. Колесо мыши
     и палец листают как прежде. */
  scrollbar-width: none;
}

#экран-витрины.витрина::-webkit-scrollbar { display: none; }

#экран-витрины.витрина > * { flex-shrink: 0; }

/* На компьютере содержимое собирается в колонку посередине, а не
   растягивается во весь монитор. На телефоне ограничение не срабатывает.
   Панель вкладок и лист «Ещё» лежат поверх экрана целиком — их не трогаем. */
#экран-витрины.витрина > :not(.нижние-вкладки):not(.лист-ещё) {
  width: 100%;
  max-width: 520px;
  align-self: center;
}

/* ---------- Верхняя строка: «Игры с друзьями» · ⋯ ----------

   На макете эта строка — шапка САМОГО Telegram, а не часть страницы.
   Поэтому внутри Telegram строку прячем целиком — иначе вышло бы две
   шапки подряд. Признак «открыто в Telegram» — класс «в-телеграме»
   на <html>, его ставит js/telegram.js. В обычном браузере строка
   видна: по центру название, справа «⋯» (лист «Ещё»). Своего ✕ нет —
   вкладку браузера скриптом не закрыть.

   Строка — три колонки 44 · остальное · 44: левая пустая, но держит
   название ровно по центру экрана, а не по центру оставшегося места.

   Кнопка — просто значок, без кружка и подложки, как на макете.
   Нажимаемая зона при этом 44×44. Кнопка вынесена полем к самому краю,
   чтобы значок встал там же, где на макете (центр «⋯» — в 25 точках
   от правого края). */
.витрина__панель {
  display: grid;
  grid-template-columns: 44px minmax(0, 1fr) 44px;
  align-items: center;
  min-height: 44px;
  margin-bottom: 2px;
}

html.в-телеграме .витрина__панель { display: none; }

.витрина__панель-кнопка {
  grid-column: 3;
  justify-self: end;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin-right: -10px;
  padding: 0;
  font: inherit;
  line-height: 1;
  color: var(--вт-текст);
  background: none;
  border: none;
  border-radius: 12px;
  cursor: pointer;
}

.витрина__панель-кнопка svg {
  display: block;
  width: 24px;
  height: 24px;
}

.витрина__панель-кнопка:active { transform: scale(0.92); opacity: 0.7; }

.витрина__панель-кнопка:focus-visible {
  outline: 2px solid var(--вт-акцент);
  outline-offset: -4px;
}

.витрина__панель-заголовок {
  grid-column: 2;
  min-width: 0;
  font-size: 16px;
  font-weight: 600;
  text-align: center;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--вт-текст);
}

/* ---------- Шапка: H1 «Во что сыграем?» + подзаголовок ----------
   На макете подзаголовок стоит вплотную под заголовком (зазор 1–2
   точки), а весь блок начинается сразу под шапкой Telegram. */
.витрина__шапка {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0;
  padding-top: 4px;
}

/* Плотный жирный заголовок с чуть сжатым набором. Шрифт системный
   (своих в проекте нет и из интернета мы их не берём), характер даёт
   вес и плотность. Кегль снят с макета по высоте заглавной буквы
   (сверено наложением макета на экран): 32 точки при ширине 390.
   Доля ширины (8,2vw) держит ту же пропорцию на 360 и 430. */
.витрина__заголовок {
  margin: 0;
  font-size: clamp(26px, 8.2vw, 37px);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--вт-текст);
}

/* Подзаголовок — серым и тихо, сразу под H1. На макете высота
   заглавной буквы 9,6 точки → кегль 14. */
.витрина__подзаголовок {
  margin: 0;
  font-size: clamp(13px, 3.6vw, 16px);
  line-height: 1.3;
  color: var(--вт-текст-тихий);
}

/* ---------- Ряд фишек-фильтров ----------
   «Все» / «Настольные» / «Карточные». Прокручивается вбок, если
   не влезает — переносить на вторую строку нельзя, иначе он спорит
   с плитками за высоту.

   ВИДИМАЯ фишка на макете низкая — 29 точек. А палец требует 44.
   Поэтому кнопка сама 44 в высоту и прозрачная, а фишку (заливку
   и обводку) рисует её «::before» — полоса 29 точек посередине.
   Попасть можно и чуть выше, и чуть ниже нарисованной фишки.
   Отсюда и крошечные поля у ряда: 7,5 точки невидимой зоны сверху
   и снизу уже дают тот воздух, что на макете. */
.витрина__фильтры {
  display: flex;
  align-items: center;
  gap: clamp(7px, 2.2vw, 10px);   /* 21 из 941 на макете → 9 на 390 */
  /* Поле сверху растёт с шириной экрана: чем крупнее фишка, тем меньше
     вокруг неё невидимой зоны, и без поправки на 430 фишки прилипали
     к подзаголовку. На 390 выходит ровно 1 точка, на 360 — 0. */
  margin-top: clamp(0px, 5.9vw - 22px, 6px);
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.витрина__фильтры::-webkit-scrollbar { display: none; }

.витрина__фильтр {
  position: relative;
  isolation: isolate;          /* фишка «::before» ложится ПОД текст, но не под фон страницы */
  flex: 0 0 auto;
  min-height: 44px;
  padding: 0 clamp(14px, 4.1vw, 18px);
  font: inherit;
  /* 13 на экране 390, а не 15: на макете высота заглавной буквы в фишке
     8–8,5 точки, и «Настольные» занимает 71 точку. При 15 фишки выходили
     на десятую часть шире макета. Размер — доля ширины, как у заголовка:
     на 430 фишки растут вместе с плитками, а не остаются мелкими. */
  font-size: clamp(12px, 3.35vw, 15px);
  font-weight: 500;
  line-height: 1;
  color: rgba(248, 245, 235, 0.86);
  background: none;
  border: none;
  cursor: pointer;
}

.витрина__фильтр::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: var(--вт-фишка);
  margin-top: calc(var(--вт-фишка) / -2);
  z-index: -1;
  border: 1px solid var(--вт-граница);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.025);
  transition: transform 0.14s ease;
}

.витрина__фильтр:active::before { transform: scale(0.96); }

.витрина__фильтр:focus-visible { outline: none; }
.витрина__фильтр:focus-visible::before {
  box-shadow: 0 0 0 2px var(--вт-фон), 0 0 0 4px var(--вт-акцент);
}

/* Активная фишка — единственное салатовое пятно в этом ряду, текст
   на нём почти чёрный и чуть плотнее, как на макете. */
.витрина__фильтр--активен,
.витрина__фильтр[aria-pressed="true"] {
  color: var(--вт-акцент-текст);
  font-weight: 600;
}

.витрина__фильтр--активен::before,
.витрина__фильтр[aria-pressed="true"]::before {
  background: var(--вт-акцент);
  border-color: var(--вт-акцент);
}

/* ---------- Сетка плиток: строго два столбца ----------
   Высоты рядов на макете разные (325, 297 и 290 из 941) — так и
   должно быть: каждая карточка держит пропорцию своей картинки
   (см. «.плитка-игры»), выравнивать их нельзя, иначе картинки
   сплющатся. «minmax(0, 1fr)» — столбцы ровно пополам, даже если
   внутри что-то длинное. */
.витрина__плитки {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: start;
  gap: var(--вт-зазор-рядов) var(--вт-зазор);
  /* Плюс невидимая зона фишек снизу — вместе 9,5 точки на 390, как на
     макете. Растёт с шириной по той же причине, что поле над фишками. */
  margin-top: clamp(0px, 6.16vw - 22px, 7px);
}

/* Фишки-фильтры прячут чужие плитки классом «скрыт» (js/game.js).
   Сетка от этого не ломается: оставшиеся плитки встают по порядку,
   баннер деберца по-прежнему на всю ширину. Одинокая плитка в ряду
   остаётся в левой колонке своего размера — не растягивается. */

/* ================================================================
   Экран «Оформление» — доски, рубашки, фоны
   ================================================================

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

   Устроен экран разделами: короткий ярлык сверху, под ним сетка
   образцов. Образец — это кнопка, внутри которой кусочек того, что
   человек выбирает (клетки доски, рубашка карты), и подпись именем.
   Показывать надо именно образец: по слову «Песок» никто не поймёт,
   что за доска, а по четырём клеткам — сразу.

   Выбранный вариант помечен ТРЕМЯ признаками, а не цветом: обводка
   цветом темы, жирная подпись и галочка в углу. Одного цвета мало —
   на солнце экран выцветает, а каждый двенадцатый мужчина плохо
   различает оттенки.
   ================================================================ */

.оформление__раздел {
  width: 100%;
  max-width: 420px;
  margin: 0 auto 14px;
  text-align: left;
}

/* Ярлык раздела — «Доска», «Рубашка», «Фон». Тот же приём, что у
   подписей разделов в таблице рейтинга и у слова «Скоро» на витрине:
   мелкие прописные с разрядкой. Это указатель, а не заголовок. */
.оформление__подпись {
  margin: 0 0 7px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  color: var(--текст-тихий);
}

/* Сетка образцов. Ширина колонки — от 92 точек: в неё помещается
   образец и имя в одну-две строки, а на узком телефоне встают три
   штуки в ряд вместо четырёх, само собой и без отдельного правила. */
.оформление__кнопки {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
  gap: 8px;
  width: 100%;
}

/* Сам образец. Класс назван дважды нарочно: у кнопки есть общий класс
   кнопок выбора, и без этого он перебил бы здешние правила и вернул
   бы залитый жёлтый прямоугольник вместо спокойной карточки. */
.оформление__выбор.оформление__выбор {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  gap: 7px;
  min-width: 0;
  min-height: 44px;              /* размер пальца, меньше нельзя */
  padding: 10px 6px 9px;
  font: inherit;
  color: var(--текст);
  background: rgba(128, 128, 128, 0.14);
  background: color-mix(in srgb, var(--текст) 8%, transparent);
  border: 1px solid rgba(128, 128, 128, 0.28);
  border: 1px solid color-mix(in srgb, var(--текст) 16%, transparent);
  border-radius: 14px;
  box-shadow: none;
  cursor: pointer;
}

.оформление__выбор.оформление__выбор:active {
  transform: translateY(1px);
}

/* Выбранный: обводка, жирная подпись и галочка в углу.

   Селектор длинный не от любви к длине: общее правило выбранной кнопки
   («кнопка + кнопка--выбор + кнопка--активная») сильнее короткого, и
   на первом снимке оно заливало образец жёлтым целиком — доски под
   краской было не разглядеть. Здесь заливка не нужна вовсе: образец
   и есть то, что выбирают, красить его нельзя. */
.кнопка.оформление__выбор.оформление__выбор.кнопка--активная {
  color: var(--текст);
  background: color-mix(in srgb, var(--акцент) 14%, transparent);
  border: 2px solid var(--акцент);
  padding: 9px 5px 8px;          /* на точку меньше — рамка стала толще */
}

.кнопка.оформление__выбор.кнопка--активная .оформление__имя {
  font-weight: 800;
  color: var(--текст);
}

.кнопка.оформление__выбор.кнопка--активная::after {
  content: "✓";
  position: absolute;
  top: 3px;
  right: 6px;
  font-size: 12px;
  font-weight: 800;
  line-height: 1;
  color: var(--акцент);
}

/* ---------- Выбранный фон отмечается сам ----------

   У досок галочку ставит игра: она вешает на кнопку признак «активная».
   У фонов такой строки в игре нет, и на экране не было отмечено ни
   одного — хотя выбран всегда какой-то, по умолчанию «Сукно».

   Оформление может ответить на это само, и вот почему: на кнопке фона
   стоит её ключ, и точно такой же ключ стоит на самой странице. Совпали
   — значит эта кнопка и выбрана. Отдельный случай — «Сукно»: он же
   значение по умолчанию, и признака на странице может не быть вовсе,
   поэтому у него две записи.

   Правила ниже повторяют вид выбранной кнопки, поэтому когда игра
   начнёт ставить признак сама, ничего не изменится и не поспорит. */
:is(
  html[data-фон="сукно"]   .оформление__выбор[data-фон="сукно"],
  html:not([data-фон])     .оформление__выбор[data-фон="сукно"],
  html[data-фон="дыхание"] .оформление__выбор[data-фон="дыхание"],
  html[data-фон="лампа"]   .оформление__выбор[data-фон="лампа"],
  html[data-фон="туман"]   .оформление__выбор[data-фон="туман"],
  html[data-фон="отсвет"]  .оформление__выбор[data-фон="отсвет"]
) {
  background: color-mix(in srgb, var(--акцент) 14%, transparent);
  border: 2px solid var(--акцент);
  padding: 9px 5px 8px;
}

:is(
  html[data-фон="сукно"]   .оформление__выбор[data-фон="сукно"],
  html:not([data-фон])     .оформление__выбор[data-фон="сукно"],
  html[data-фон="дыхание"] .оформление__выбор[data-фон="дыхание"],
  html[data-фон="лампа"]   .оформление__выбор[data-фон="лампа"],
  html[data-фон="туман"]   .оформление__выбор[data-фон="туман"],
  html[data-фон="отсвет"]  .оформление__выбор[data-фон="отсвет"]
)::after {
  content: "✓";
  position: absolute;
  top: 3px;
  right: 6px;
  font-size: 12px;
  font-weight: 800;
  line-height: 1;
  color: var(--акцент);
}

:is(
  html[data-фон="сукно"]   .оформление__выбор[data-фон="сукно"],
  html:not([data-фон])     .оформление__выбор[data-фон="сукно"],
  html[data-фон="дыхание"] .оформление__выбор[data-фон="дыхание"],
  html[data-фон="лампа"]   .оформление__выбор[data-фон="лампа"],
  html[data-фон="туман"]   .оформление__выбор[data-фон="туман"],
  html[data-фон="отсвет"]  .оформление__выбор[data-фон="отсвет"]
) .оформление__имя {
  font-weight: 800;
  color: var(--текст);
}

/* Имя варианта. Переносится по словам и не растягивает колонку:
   «Холодный камень» встаёт в две строки, а не режет сетку. */
.оформление__имя {
  max-width: 100%;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  overflow-wrap: break-word;
}

/* «Фоны появятся здесь» — обычная тихая строка на всю ширину раздела,
   пока в нём нечего показывать. */
.оформление__скоро {
  grid-column: 1 / -1;
  margin: 0;
  font-size: 13px;
  line-height: 1.4;
  color: var(--текст-тихий);
}

/* Кусочек доски в образце. Размер и клетки приходят из игры (она же
   знает цвета выбранной доски), здесь — общий вид: аккуратный квадрат
   с каймой того же цвета, что у настоящей доски. Класс назван дважды
   по той же причине, что выше: правило игры вписано в начало страницы
   и иначе спорило бы с этим. */
.образец-доски.образец-доски {
  width: 52px;
  height: 52px;
  border-width: 2px;
  border-radius: 8px;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.28);
}

/* =====================================================================
   ПЛИТКА ИГРЫ — готовая карточка владельца фоном кнопки

   В «img/витрина/» лежат полные карточки: фото, название, салатовая
   стрелка ↗, затемнение снизу и тонкая рамка — всё уже внутри
   картинки. README набора говорит прямо: «Не рисуй эти элементы второй
   раз». Поэтому здесь нет ни градиента, ни подписи, ни стрелки —
   только сама картинка фоном кнопки.

   Картинка растягивается ровно на кнопку («100% 100%»), а кнопка
   держит ТОЧНО ту же пропорцию, что у картинки («aspect-ratio» у
   каждой игры свой, числами из её размера). Раз пропорции равны,
   ничего не сплющивается и не обрезается. Высоты рядов от этого
   разные (325, 297, 290) — на макете так же.

   Скругление кнопки равно скруглению, нарисованному на картинке:
   28 точек на карточке шириной 428. Задано в процентах от сторон
   кнопки — поэтому совпадает на любой ширине экрана: больше —
   срезали бы рамку, меньше — в углах проступил бы фон макета.

   Текст названия в кнопке остаётся — его читает программа чтения
   с экрана и по нему находят кнопку проверки, — но глазу он не виден
   (см. ниже «только для чтения с экрана»): второе название поверх
   нарисованного было бы ровно тем, что README запрещает. */
.плитка-игры {
  position: relative;
  overflow: hidden;
  display: block;
  width: 100%;
  padding: 0;
  font: inherit;
  color: var(--вт-текст);
  text-align: left;
  /* Если картинка не приехала (плохая связь) — ровная тёмная плитка
     того же тона, что поверхность, а не цветное пятно. */
  background-color: #1a1d22;
  background-position: center;
  background-size: 100% 100%;
  background-repeat: no-repeat;
  border: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: transform 0.14s ease, filter 0.14s ease;
}

/* Картинка, пропорция и скругление — у каждой игры свои. Порядок
   («order») — как на макете: Нарды · Шахматы / Дурак · Шашки /
   Домино · Морской бой / баннер Деберца на всю ширину. Порядок задан
   здесь, а не только в разметке: если плитки в разметке однажды
   переставят, на экране они всё равно останутся на местах макета.

   Скругление «X% / Y%»: 28 точек картинки поделить на её ширину
   и высоту. Для 428×325 это 6,54% и 8,62%, и так далее. Проверено
   под шестикратной лупой на розовом фоне: в углах нет ни тёмных
   уголков фона картинки, ни срезанной рамки. */
.плитка-игры[data-игра="нарды"] {
  order: 1;
  aspect-ratio: 428 / 325;
  border-radius: 6.54% / 8.62%;
  background-image: url("img/витрина/backgammon.jpg");
}
.плитка-игры[data-игра="шахматы"] {
  order: 2;
  aspect-ratio: 428 / 325;
  border-radius: 6.54% / 8.62%;
  background-image: url("img/витрина/chess.jpg");
}
.плитка-игры[data-игра="дурак"] {
  order: 3;
  aspect-ratio: 428 / 297;
  border-radius: 6.54% / 9.43%;
  background-image: url("img/витрина/durak.jpg");
}
.плитка-игры[data-игра="шашки"] {
  order: 4;
  aspect-ratio: 428 / 297;
  border-radius: 6.54% / 9.43%;
  background-image: url("img/витрина/checkers.jpg");
}
.плитка-игры[data-игра="домино"] {
  order: 5;
  aspect-ratio: 428 / 290;
  border-radius: 6.54% / 9.66%;
  background-image: url("img/витрина/dominoes.jpg");
}
.плитка-игры[data-игра="морской-бой"] {
  order: 6;
  aspect-ratio: 428 / 290;
  border-radius: 6.54% / 9.66%;
  background-image: url("img/витрина/battleship.jpg");
}
/* Баннер «Деберц» — на обе колонки. Картинка 873×209, скругление
   на ней то же, 28 точек: 3,21% ширины и 13,4% высоты. */
.плитка-игры[data-игра="деберц"] {
  order: 7;
  grid-column: 1 / -1;
  aspect-ratio: 873 / 209;
  border-radius: 3.21% / 13.4%;
  background-image: url("img/витрина/deberts.jpg");
}

/* Нажатие — лёгкое сжатие (масштаб 0,98 за 140 мс) и чуть темнее:
   на фотографии одно сжатие на глаз почти не видно, а игрок должен
   понять, что игра среагировала. */
.плитка-игры:active {
  transform: scale(0.98);
  filter: brightness(0.9);
}

/* Выбор с клавиатуры — салатовое кольцо, единственный акцент экрана. */
.плитка-игры:focus-visible {
  outline: 3px solid var(--вт-акцент);
  outline-offset: 2px;
}

/* Значок-рисунок на плитке больше не нужен: фото уже говорит, что за
   игра. Из разметки он убран; правило оставлено, чтобы вернувшийся
   по ошибке значок не лёг поверх карточки. */
.плитка-игры__значок { display: none; }

/* «Только для чтения с экрана»: текст есть и читается вслух, но
   занимает 1×1 точку и обрезан до нуля — глазу не виден. Классический
   приём: «display: none» не годится, его программа чтения пропускает. */
.плитка-игры__название,
.плитка-игры__описание {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ---------- Пометка на плитке ----------
   Решение штаба (10 сентября): «играли недавно» на витрине не
   показываем — на макете её нет. Узел в разметке остаётся (его
   заполняет js/game.js), но на экран выходит только в двух случаях:
     • «не доиграна» — у дурака висит партия с другом (класс
       «плитка-игры--ждут»): друг ждёт за столом, это нужно видеть;
     • «скоро» — у выключенных плиток (см. ниже, поверх стрелки). */
.плитка-игры__пометка { display: none; }

/* «Не доиграна» — салатовая пилюля с почти чёрным текстом в левом
   верхнем углу: там она не наезжает на нарисованное внизу название.
   Салатовая нарочно — это зов действовать, как активная фишка,
   а не тихая справка. Лёгкая тень отрывает её от фотографии. */
.плитка-игры--ждут .плитка-игры__пометка {
  position: absolute;
  left: 8px;
  top: 8px;
  z-index: 2;
  display: inline-block;
  max-width: calc(100% - 16px);
  padding: 4px 10px 5px;
  font-size: 12px;
  font-weight: 700;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--вт-акцент-текст);
  background: var(--вт-акцент);
  border-radius: 999px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}

.плитка-игры--ждут .плитка-игры__пометка:empty { display: none; }

/* ---------- Плитка «скоро» (домино, морской бой, деберц) ----------
   Игры ещё нет. Карточка та же самая — картинка владельца, — но
   приглушена: поверх неё полупрозрачный слой цвета фона страницы
   (темнее) и серый слой в режиме «насыщенность» (чуть бесцветнее).
   Оба слоя — часть фона той же кнопки, поэтому скругление общее
   и пилюля «скоро» остаётся яркой. Больше поверх ничего нет.

   Картинка задана у каждой игры своя (см. выше), а здесь нужно
   дописать к ней два слоя СВЕРХУ. Поэтому слои вынесены
   в переменную, и для трёх игр «скоро» картинка названа ещё раз. */
.плитка-игры--скоро,
.плитка-игры:disabled {
  --вт-приглушить:
    linear-gradient(rgba(16, 20, 22, 0.38), rgba(16, 20, 22, 0.38)),
    linear-gradient(rgba(128, 128, 128, 0.4), rgba(128, 128, 128, 0.4));
  cursor: default;
  background-blend-mode: normal, saturation, normal;
}

.плитка-игры--скоро[data-игра="домино"],
.плитка-игры[data-игра="домино"]:disabled {
  background-image: var(--вт-приглушить), url("img/витрина/dominoes.jpg");
}
.плитка-игры--скоро[data-игра="морской-бой"],
.плитка-игры[data-игра="морской-бой"]:disabled {
  background-image: var(--вт-приглушить), url("img/витрина/battleship.jpg");
}
.плитка-игры--скоро[data-игра="деберц"],
.плитка-игры[data-игра="деберц"]:disabled {
  background-image: var(--вт-приглушить), url("img/витрина/deberts.jpg");
}
/* Те же правила для четырёх живых игр — на случай, если какую-то
   из них однажды выключат: плитка сразу станет приглушённой, а не
   останется яркой с пометкой «скоро». */
.плитка-игры--скоро[data-игра="нарды"],
.плитка-игры[data-игра="нарды"]:disabled {
  background-image: var(--вт-приглушить), url("img/витрина/backgammon.jpg");
}
.плитка-игры--скоро[data-игра="шахматы"],
.плитка-игры[data-игра="шахматы"]:disabled {
  background-image: var(--вт-приглушить), url("img/витрина/chess.jpg");
}
.плитка-игры--скоро[data-игра="дурак"],
.плитка-игры[data-игра="дурак"]:disabled {
  background-image: var(--вт-приглушить), url("img/витрина/durak.jpg");
}
.плитка-игры--скоро[data-игра="шашки"],
.плитка-игры[data-игра="шашки"]:disabled {
  background-image: var(--вт-приглушить), url("img/витрина/checkers.jpg");
}

.плитка-игры--скоро:active,
.плитка-игры:disabled:active {
  transform: none;
  filter: none;
}

/* Пилюля «скоро» — ровно поверх нарисованной на картинке стрелки ↗
   в правом нижнем углу: на неготовой игре вместо «перейти» написано
   «скоро». Решение штаба (10 сентября).

   Как попадаем в стрелку на любой ширине экрана. Стрелка — часть
   картинки, поэтому её место задано в долях карточки, а не в точках:
   на карточке 428×290 она кончается в 30 точках от правого края
   (7 %) и её середина — на 86 % высоты. Правый край пилюли ставим
   на 5 точек правее стрелки, середину — на середину стрелки.
   Пилюля (57×25) втрое больше стрелки (12×12 на экране 390), поэтому
   закрывает её с запасом со всех сторон — проверено под лупой на 360,
   390 и 430.

   Фон пилюли НЕПРОЗРАЧНЫЙ: сквозь полупрозрачное стекло салатовая
   стрелка просвечивала бы зелёным пятном. Тонкая светлая обводка,
   тёплый белый текст. Не салатовая: салатовым на экране крашено
   только выбранное, включённое и зовущее действовать. */
.плитка-игры--скоро .плитка-игры__пометка,
.плитка-игры:disabled .плитка-игры__пометка {
  position: absolute;
  right: calc(7% - 5px);
  top: 86.2%;
  transform: translateY(-50%);
  z-index: 2;
  display: inline-block;
  max-width: calc(100% - 16px);
  padding: 4px 10px 5px;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: 0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--вт-текст);
  background: #171b1e;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 999px;
}

.плитка-игры--скоро .плитка-игры__пометка:empty,
.плитка-игры:disabled .плитка-игры__пометка:empty { display: none; }

/* На баннере 873×209 стрелка стоит иначе: кончается в 31 точке от
   правого края (3,55 %), середина — на 71 % высоты. */
.плитка-игры[data-игра="деберц"] .плитка-игры__пометка {
  right: calc(3.55% - 5px);
  top: 70.8%;
}

/* ---------- Витрина на большом экране ----------
   Игру открывают и в браузере на компьютере — колонка содержимого
   не шире 520 точек (см. правило экрана выше), плитки держат свои
   пропорции и просто становятся крупнее. Поле и промежуток на
   широком окне упираются в верхнюю границу «clamp» и дальше не растут. */

/* Кому мешает движение — плитка не сжимается совсем. */
@media (prefers-reduced-motion: reduce) {
  .плитка-игры { transition: none; }
  .плитка-игры:active { transform: none; }
}


/* =====================================================================
   НИЖНЯЯ ПАНЕЛЬ ВКЛАДОК — «Игры / Друзья / Профиль»

   По вырезке «эталон/витрина-части/bottom-nav.png»: панель на тон
   светлее фона, верхние углы скруглены (≈20 точек), по верху тонкая
   светлая линия, высота 56 точек на экране 390 (доля ширины, см.
   «--вт-панель-низ») плюс полоса жеста телефона.

   «position: fixed» — панель лежит поверх низа экрана всегда, поэтому
   у «#экран-витрины.витрина» снизу отложен запас (высота панели + 12 +
   полоса жеста, см. выше): без него баннер «Деберц» прятался бы
   под панель.

   На широком окне вкладки не разбегаются по краям монитора: боковые
   поля панели сжимают их в ту же колонку 520, что и содержимое. */
.нижние-вкладки {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 5;
  display: flex;
  align-items: stretch;
  justify-content: space-around;
  height: calc(var(--вт-панель-низ) + var(--отступ-снизу));
  /* Боковые поля 8: на макете центры вкладок стоят на 70, 195 и 320
     точках, а не на трети ширины (65, 195, 325). */
  padding: 0 max(8px, (100% - 520px) / 2) var(--отступ-снизу);
  background: var(--вт-поверхность);
  border-radius: 20px 20px 0 0;
  /* Линия по верху — внутренней тенью, а не рамкой: тень повторяет
     скругление углов и гаснет на них сама, рамка же дала бы ещё
     и вертикальные черты по бокам экрана. Вторая тень — мягкая
     наружу вверх: плитки, уезжающие под панель, темнеют. */
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.08),
    0 -10px 24px rgba(0, 0, 0, 0.35);
}

.нижняя-вкладка {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0;
  min-height: 44px;
  padding: 0 4px 1px;
  font: inherit;
  /* На макете «Профиль» — 42 точки в ширину на 390: это 11, не 12.
     Растёт с шириной экрана вместе со всей панелью, но не мельче 10,5. */
  font-size: clamp(10.5px, 2.82vw, 13px);
  font-weight: 500;
  line-height: 1.27;
  color: var(--вт-текст-тихий);
  background: none;
  border: none;
  cursor: pointer;
}

.нижняя-вкладка__значок {
  display: flex;
  width: clamp(24px, 6.67vw, 30px);    /* 26 на 390 */
  height: clamp(24px, 6.67vw, 30px);
}

.нижняя-вкладка__значок svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* Активная — «Игры» на витрине: значок и подпись разом становятся
   салатовыми, подпись чуть плотнее — как на макете. */
.нижняя-вкладка--активна {
  color: var(--вт-акцент);
  font-weight: 600;
}

/* «Друзья» и «Профиль» пока выключены: таких экранов у нас нет.
   На макете они просто серые — такими и оставлены, без лишнего
   побледнения; нажатие на них ничего не делает и не вжимается. */
.нижняя-вкладка:disabled {
  cursor: default;
}

.нижняя-вкладка:not(:disabled):active { transform: scale(0.94); }

.нижняя-вкладка:focus-visible {
  outline: 2px solid var(--вт-акцент);
  outline-offset: -4px;
  border-radius: 12px;
}

/* Значки вкладок — из набора владельца, вписаны в разметку и красятся
   цветом кнопки (салатовый у активной, серый у остальных). Линию
   делаю чуть толще, чем в файле набора (2 вместо 1,7): на макете
   значки вкладок заметно плотнее. Правило CSS перебивает толщину,
   записанную в самом SVG, — разметку для этого трогать не нужно. */
.нижняя-вкладка__значок svg { stroke-width: 2; }

/* =====================================================================
   ЛИСТ «ЕЩЁ» — выезжает снизу по «⋯» (а в Telegram — по «Настройкам»
   в его меню)

   Та же система, что у витрины: тёмная панель на тон светлее фона,
   скруглённый верх, как у панели вкладок, строки — приподнятые
   карточки, один салатовый акцент (включённый звук). Показывает
   и прячет js/game.js классом «скрыт».

   Лист прижат к низу и не выше экрана: если строк станет много,
   он прокручивается сам, а не уезжает за верхний край. Снизу учтена
   полоса жеста — кнопка «Закрыть» не прячется под неё. */
.лист-ещё {
  position: fixed;
  inset: 0;
  z-index: 30;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  align-items: center;
}

/* Затемнение за листом: нажатие по нему закрывает лист (js/game.js). */
.лист-ещё__фон {
  position: absolute;
  inset: 0;
  background: rgba(5, 7, 8, 0.6);
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
  animation: лист-ещё-фон 0.2s ease-out;
}

.лист-ещё__лист {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
  max-width: 520px;
  max-height: calc(100% - 24px - var(--отступ-сверху));
  overflow-y: auto;
  padding: 22px calc(var(--вт-поле) + var(--отступ-справа))
           calc(14px + var(--отступ-снизу))
           calc(var(--вт-поле) + var(--отступ-слева));
  color: var(--вт-текст);
  background: var(--вт-поверхность);
  border-radius: 20px 20px 0 0;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.08),
    0 -12px 32px rgba(0, 0, 0, 0.45);
  animation: лист-ещё-вверх 0.22s cubic-bezier(0.2, 0.8, 0.2, 1);
}

/* «Ручка» сверху — привычный знак выдвижного листа. */
.лист-ещё__лист::before {
  content: "";
  position: absolute;
  top: 8px;
  left: 50%;
  width: 36px;
  height: 4px;
  margin-left: -18px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.18);
}

.лист-ещё__заголовок {
  margin: 0 0 4px;
  font-size: 17px;
  font-weight: 700;
  line-height: 1.3;
  text-align: center;
  color: var(--вт-текст);
}

/* Строка — приподнятая карточка во всю ширину: подпись слева,
   значение или стрелка справа. Высота 52 — палец попадает уверенно. */
.лист-ещё__строка {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  width: 100%;
  min-height: 52px;
  padding: 0 16px;
  font: inherit;
  font-size: 16px;
  font-weight: 500;
  text-align: left;
  color: var(--вт-текст);
  background: #1e2226;
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 14px;
  cursor: pointer;
  transition: transform 0.12s ease, background-color 0.12s ease;
}

.лист-ещё__строка:active {
  transform: scale(0.98);
  background: #262a2f;
}

/* Строка без значения ведёт на другой экран — справа тихая стрелка.
   Только у открытого листа: снимок доступности Playwright показывает
   нарисованный CSS текст даже у спрятанных узлов, и одинокий «›»
   на витрине сбивал бы проверки. */
.лист-ещё:not(.скрыт) .лист-ещё__строка:not([role="switch"])::after {
  content: "›";
  font-size: 22px;
  line-height: 1;
  color: var(--вт-текст-тихий);
}

/* Значение переключателя «Звук» — маленькая пилюля. Включено —
   салатовая с тёмным текстом (единственный акцент листа), выключено —
   тёмная с серой обводкой: состояние видно, не читая слова. */
.лист-ещё__значение {
  flex: 0 0 auto;
  min-width: 52px;
  padding: 5px 12px 6px;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.2;
  text-align: center;
  color: var(--вт-текст-тихий);
  border: 1px solid var(--вт-граница);
  border-radius: 999px;
}

.лист-ещё__строка[aria-checked="true"] .лист-ещё__значение {
  color: var(--вт-акцент-текст);
  background: var(--вт-акцент);
  border-color: var(--вт-акцент);
}

/* «Закрыть» — тихая, как фишки-фильтры: обводка без заливки.

   ЗАМЕЧАНИЕ ТЕСТИРОВЩИКА (11 сентября): на самом маленьком телефоне
   (320×568) в полном экране Telegram лист со строкой «Вибрация» выше
   окна, начинает прокручиваться — и «Закрыть», последняя в списке,
   уходила под полосу жеста (низ 552 при пределе 534).

   Теперь «Закрыть» прилипает к низу листа («sticky»): пока список
   прокручивается, она стоит над нижним полем листа, а в поле входит
   безопасный отступ полосы жеста. «bottom: 0» считается от края
   прокрутки за вычетом нижнего поля листа — тот же приём, что у
   «Закрыть» панели знаков (см. «#кнопка-эмоции-назад»): там поле
   уводят отрицательным отступом, чтобы полка встала вплотную к краю.
   Когда список помещается целиком, прилипание ничего не меняет.

   Под прилипшей кнопкой проезжают строки, поэтому у неё заливка цвета
   листа (на месте она выглядит так же, как без заливки), а тени того
   же цвета закрывают поле под ней до края листа и мягко гасят строку
   над ней — как у «Далее» на шагах к партии. */
.лист-ещё__закрыть {
  position: sticky;
  bottom: 0;
  z-index: 1;
  flex-shrink: 0;
  width: 100%;
  min-height: 48px;
  margin-top: 6px;
  padding: 0 16px;
  font: inherit;
  font-size: 16px;
  font-weight: 600;
  color: var(--вт-текст);
  background: var(--вт-поверхность);
  border: 1px solid var(--вт-граница);
  border-radius: 14px;
  box-shadow:
    0 -14px 14px -4px var(--вт-поверхность),
    0 calc(14px + var(--отступ-снизу)) 0 0 var(--вт-поверхность);
  cursor: pointer;
}

/* Строки тоже не сплющиваются: в прокручиваемом столбике сжатие
   испортило бы только высоту под палец. */
.лист-ещё__строка { flex-shrink: 0; }

/* Низкое окно (самый маленький телефон, особенно в полном экране
   Telegram, где сверху и снизу отнимают безопасные поля): строки чуть
   ниже — 46 вместо 52, всё ещё больше 44 под палец, — и зазоры меньше.
   Шесть строк с «Закрыть» тогда помещаются без прокрутки и на 320×568
   с полосой жеста; не поместятся — выручит прилипшая «Закрыть». */
@media (max-height: 640px) {
  .лист-ещё__лист {
    gap: 6px;
    padding-top: 18px;
  }

  .лист-ещё__заголовок { margin-bottom: 0; }

  .лист-ещё__строка { min-height: 46px; }

  .лист-ещё__закрыть { min-height: 46px; }
}

.лист-ещё__закрыть:active { transform: scale(0.98); opacity: 0.8; }

.лист-ещё__строка:focus-visible,
.лист-ещё__закрыть:focus-visible {
  outline: 2px solid var(--вт-акцент);
  outline-offset: 2px;
}

@keyframes лист-ещё-вверх {
  from { transform: translateY(100%); }
  to   { transform: translateY(0); }
}

@keyframes лист-ещё-фон {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
  .лист-ещё__лист,
  .лист-ещё__фон { animation: none; }
}

/* ---------- Сноска под кнопкой ----------

   Мелкая строчка, приписанная к кнопке сверху: она предупреждает
   о том, что человеку важно знать ДО нажатия, а не после.

   Ради чего заведена. Кнопка «Играть с другом» ничем не говорит,
   что игра вдвоём держится на включённом компьютере того, кто
   запускает игру. Человек жмёт её и упирается в объяснение —
   а правду честнее сказать заранее.

   Отчего мелкая и притянутая. В меню высота на счету: лишняя строка
   там — это два ряда текста. Поэтому сноска мелкая и подтянута вверх
   отрицательным полем: она стоит в шести точках под кнопкой, к которой
   относится, и в обычных четырнадцати от того, что идёт ниже, —
   сразу видно, к чему она приписана.
   Замерено в браузере: даже в самом тесном случае (320 на 568, да ещё
   с лишней кнопкой «Вернуться к игре с другом») обе строки помещаются
   и ничего не выдавливают за край.

   Ширина — ровно по кнопке: строка не должна быть шире того,
   что объясняет. */

.сноска {
  width: min(100%, var(--колонка-кнопок));
  margin: -6px 0 0;
  font-size: 12.5px;
  line-height: 1.25;
  color: var(--текст-тихий);
}

/* ---------- Выбор соперника ---------- */

.выбор {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: min(100%, var(--колонка-кнопок));   /* ровно по ширине кнопок меню */
}

.выбор__подпись {
  font-size: 13px;
  color: var(--текст-тихий);
}

/* Три уровня всегда в одну строку: кнопки делят ширину поровну
   и сжимаются вместе с экраном, а не переносятся вниз. */
.выбор__кнопки {
  display: flex;
  gap: 6px;
  width: 100%;
}

.кнопка.кнопка--выбор {
  flex: 1 1 0;
  width: auto;
  min-width: 0;
  min-height: 44px;
  padding: 8px 4px;
  font-size: 15px;
  font-weight: 600;
  color: var(--текст);
  background: var(--подложка);
  border: 1px solid var(--край);
  box-shadow: none;
}

/* Выбранный уровень залит цветом кнопки — видно без чтения подписи */
.кнопка.кнопка--выбор.кнопка--активная {
  color: var(--кнопка-текст);
  /* Тот же притемнённый цвет, что у обычной кнопки: подпись уровня мелкая
     (15 точек), и на чистом синем Telegram она читалась хуже нормы.
     Первая строка — запас для старых браузеров без color-mix. */
  background: var(--кнопка-фон);
  background: color-mix(in srgb, var(--кнопка-фон) 86%, #000000);
  border-color: transparent;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.28);
}

/* ---------- Рекорды и звук ---------- */

/* «Рекорды» — не главное действие, поэтому только обводка:
   на экране должна выделяться одна кнопка «Играть». */
#кнопка-рекорды {
  color: var(--текст);
  background: transparent;
  border: 2px solid var(--край);
  box-shadow: none;
}

/* Звук: кружок слева залит — включён, пустой — выключен.
   Видно с одного взгляда, даже не читая надпись.

   Кнопок звука на странице две — по одной на экранах «Игра с ботом»
   и «Игра с другом», — и раньше кружок был только у первой: правило
   искало её по имени. Состояние у звука одно на всю игру, значит
   и выглядеть кнопки обязаны одинаково, иначе человек решит, что это
   две разные настройки. Теперь названы обе. */
/* Выключатель вибрации — родной брат выключателя звука: та же мелкая
   кнопка, та же надпись «включена/выключена», тот же кружок слева.
   Поэтому он просто дописан во все правила звука, а не оформлен
   по-своему: две настройки рядом обязаны выглядеть парой, иначе
   человек решит, что это разные по важности вещи. Кнопок вибрации,
   как и звука, две — по одной на экранах игры с ботом и с другом;
   ставит их js/game.js и только там, где вибрация вообще возможна. */
#кнопка-звук,
#кнопка-звук-друг,
.кнопка--вибрация {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  width: auto;              /* не во всю ширину: это настройка, не действие */
  color: var(--текст);
}

#кнопка-звук::before,
#кнопка-звук-друг::before,
.кнопка--вибрация::before {
  content: "";
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--акцент);
  box-shadow: 0 0 6px var(--акцент);
}

#кнопка-звук.кнопка--выключено,
#кнопка-звук-друг.кнопка--выключено,
.кнопка--вибрация.кнопка--выключено {
  color: var(--текст-тихий);
}

#кнопка-звук.кнопка--выключено::before,
#кнопка-звук-друг.кнопка--выключено::before,
.кнопка--вибрация.кнопка--выключено::before {
  background: transparent;
  border: 2px solid var(--край);
  box-shadow: none;
}

/* ---------- Кнопки ---------- */

.кнопка {
  min-height: 46px;            /* палец попадает наверняка */
  min-width: 116px;
  padding: 10px 22px;
  font: inherit;
  font-size: 17px;
  font-weight: 700;
  /* Волосок между буквами: короткое слово на кнопке («Играть», «Бито»)
     набрано жирным, и без просвета буквы слипаются в пятно. Высота
     кнопки от этого не меняется — 46 точек как были. */
  letter-spacing: 0.2px;
  color: var(--кнопка-текст);
  /* Цвет кнопки берём у Telegram, но притемняем на седьмую часть. Его
     фирменный синий под белой надписью даёт контраст 4,1 в светлой теме
     и 3,7 в тёмной, а для подписи в 17 точек норма — 4,5. После
     притемнения выходит 5,3 и 4,8: надпись читается, а кнопка остаётся
     узнаваемо «телеграмовской», не превращаясь в чёрную.
     Первая строка — для браузеров старше 2023 года, которые не знают
     color-mix: там кнопка просто чистого цвета темы. Вторая строка —
     для всех остальных, они возьмут именно её. Доля 86% та же, что
     у полосы события ниже, — кнопка и полоса одного тона. */
  background: var(--кнопка-фон);
  background: color-mix(in srgb, var(--кнопка-фон) 86%, #000000);
  border: none;
  border-radius: 12px;
  /* Три слоя вместо одной тени: короткая прижимает кнопку к сукну,
     длинная и слабая даёт ей объём, а светлая полоска внутри по верхнему
     краю — блик на выпуклой поверхности. Вместе это «кнопку можно нажать»,
     а не «прямоугольник нарисован». */
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.30),
    0 8px 18px rgba(0, 0, 0, 0.22),
    inset 0 1px 0 rgba(255, 255, 255, 0.22);
  cursor: pointer;
}

/* Нажатие: кнопка садится, длинная тень исчезает — вжалась в стол. */
.кнопка:active {
  transform: translateY(2px);
  box-shadow:
    0 1px 2px rgba(0, 0, 0, 0.32),
    inset 0 1px 3px rgba(0, 0, 0, 0.20);
}

.кнопка--главная {
  font-size: 20px;
  min-width: 190px;
  min-height: 52px;
}

/* «Беру» нарочно НЕ приглушаем. Раньше она была пустой рамкой рядом
   с залитой «Бито», и живой игрок читал её как выключенную: «кнопка
   бледная — значит, сейчас недоступна». На деле взять карты — такое же
   полноправное действие, как отбиться, и выбор между ними делает игрок,
   а не оформление. Отдельного правила у кнопки больше нет: она выглядит
   как обычная кнопка. Спутать их нельзя — «Бито» и «Беру» никогда
   не показываются в один и тот же момент. */

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

   Здесь высота 40 — та, с которой собраны шашки, шахматы и нарды:
   у них свои страницы и свои ряды кнопок, посчитанные под 40. */
.кнопка.кнопка--мелкая {
  min-height: 40px;
  min-width: 0;
  padding: 8px 12px;
  font-size: 13px;
  font-weight: 600;
  color: var(--текст-тихий);
  background: var(--подложка);
  border: 1px solid var(--край);
  box-shadow: none;
}

/* На странице сборника (дурак и витрина) — 44: мелкая кнопка мельче
   ПОДПИСЬЮ и тише цветом, но палец у человека тот же, и попадать в неё
   он должен так же уверенно («Как считается» на рейтинге, «Оформление»
   и «Звук» в меню). Поля по высоте не трогали — прибавка ушла в саму
   коробку, подпись осталась по центру.
   ТОЛЬКО СБОРНИК — отсюда «:has(> #экран-витрины)», тем же приёмом,
   что широкое окно. Общая прибавка задела другие игры: в нардах колонка
   меню сдвинулась на 4 точки, в шахматах выросли ряды под доской,
   и на 320×568 за край уходило пять кнопок вместо трёх. Вес правила
   тот же, что у общего («:where» веса не добавляет), поэтому все более
   точные правила ниже по файлу работают как прежде. */
:where(#приложение:has(> #экран-витрины)) .кнопка.кнопка--мелкая {
  min-height: 44px;
}

/* ---------- Раскладка игрового экрана ----------

   Стол дурака раскладывается в своём разделе в конце файла («СТОЛ ДУРАКА
   ПО ЭТАЛОНУ ВЛАДЕЛЬЦА»). Здесь осталось только общее: поля экрана
   «экран-игры» — ими пользуются нарды (у них игровой экран называется
   так же), — полоска руки и веер. */
#экран-игры {
  gap: 4px;
  padding: calc(6px + var(--отступ-сверху)) calc(8px + var(--отступ-справа))
           calc(6px + var(--отступ-снизу))  calc(8px + var(--отступ-слева));
}

.рука {
  position: relative;
  flex: 0 0 auto;
  width: 100%;
}

.веер {
  position: absolute;
  inset: 0;
}

/* Счётчики, колода с козырем, метка козыря и карты на столе живут
   в разделе стола в конце файла. Здесь осталась только коробка пары:
   её размер — карта и сдвиг накрывающей карты (рост карты объявляет
   поле пар «#стол» там же; насколько раздвинуть пару в ряду, решает
   правило «#стол > .пара» в конце файла). */
.пара {
  position: relative;
  flex: 0 0 auto;
  width: calc(var(--ш) * 1.46);
  height: calc(var(--в) + var(--сдвиг-y));
}

/* ---------- Сама карта ---------- */

/* Кремовая бумага, как у карт набора, — ровная, одним цветом: у фигур
   бумага нарисована прямо в картинке (#f6ead5), и любой перелив на карте
   рядом с ней был бы виден полосой на стыке. Объём карте дают кромка
   и тени: тонкая светлая линия внутри по краю (срез картона), полупрозрачный
   тёмный край снаружи и тень в два слоя — короткая прижимает карту к сукну,
   длинная даёт рассеянный свет вокруг. Скругление — восемь сотых ширины,
   ровно как у рисунка карты, чтобы углы рисунка и бумаги совпадали.
   Цвет текста — почти чёрный; красные масти перекрашивают его правилами
   ниже (они стоят позже нарочно — см. «Запасное правило»). */
.карта {
  position: relative;
  width: var(--ш);
  height: var(--в);
  background: var(--карта-фон);
  border: 1px solid rgba(70, 48, 22, 0.24);
  border-radius: max(3px, calc(var(--ш) * 0.08));
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.35),
    0 1px 2px rgba(0, 0, 0, 0.45),
    0 6px 14px rgba(0, 0, 0, 0.32);
  color: var(--карта-текст);
  overflow: hidden;

  /* Сколько от карты видно игроку.
     У карты на столе, у козыря и у верха колоды видна вся ширина —
     поэтому по умолчанию это вся карта. А в руке карты лежат внахлёст,
     и от каждой видна только узкая левая полоска: всё, что правее,
     накрыто соседкой. Ширину этой полоски присылает сама игра
     (см. «тесная рука» ниже), и от неё считается кегль подписи в углу:
     что не влезло в полоску, игрок просто не увидит. */
  --полоска: var(--ш);
}

/* Запасное правило. Пометку «красная» игра ставила и раньше, до того как
   научилась называть масть поимённо. Она остаётся на месте: если карта
   почему-то придёт без имени масти (например, страница откроется со старым
   сохранённым в памяти телефона js/game.js), черви и бубны всё равно будут
   красными, а не чёрными. Четыре правила ниже стоят после этого нарочно —
   вес у них одинаковый, и побеждает то, что записано позже. */
.карта--красная { color: var(--карта-красная); }

/* Четыре цвета мастей — см. подробное пояснение в начале файла */
.карта--пики  { color: var(--масть-пики); }
.карта--черви { color: var(--масть-черви); }
.карта--бубны { color: var(--масть-бубны); }
.карта--трефы { color: var(--масть-трефы); }

/* ---------- Угол карты: достоинство и под ним масть ----------

   Столбик выбран не для красоты — когда в руке много карт, от каждой
   видна полоска шириной в полтора десятка точек, и «10♦» в строчку
   туда не влезает, а «10» с «♦» под ним влезает и читается.

   ГЛАВНОЕ ПРО МАСТЬ (жалоба живого игрока: «не видно, крест это или
   пика»). В тесной руке крупная масть в середине карты не видна вовсе —
   её накрывает соседняя карта. Значит, весь разговор о мастях идёт
   в этом углу. И масть здесь — не подпись при достоинстве, а главный
   знак: достоинство узнаётся по одной цифре, а масть — по форме значка,
   и значки эти мелкие и похожие. Поэтому масть здесь крупнее
   достоинства (см. ниже) и никогда не срезается краем карты.

   С четырьмя цветами (см. начало файла) у этого угла появился второй
   способ сказать масть: цвет. Он работает даже там, где форму уже
   не разглядеть, — и красит не только значок, но и достоинство.
   В самой тесной руке из-под соседней карты торчит порой одна цифра,
   и её цвет — единственное, что остаётся от масти. */

.карта__угол {
  position: absolute;
  left: 2px;
  top: 1px;
  display: flex;
  flex-direction: column;
  /* Достоинство и масть прижаты к левому краю, а не выровнены по
     середине столбика. Разница видна на столе: карту, которой ходили,
     накрывает карта, которой отбились, и от нижней остаётся узкая
     левая полоска. Пока масть стояла по центру столбика, под широким
     «10» она уезжала вправо — ровно под накрывающую карту. */
  align-items: flex-start;
  font-weight: 800;
  line-height: 1;

  /* Кегль достоинства. Берём самое маленькое из трёх ограничений —
     что не влезло, то у игрока пропадёт:

     1) ШИРИНА ВИДИМОЙ ПОЛОСКИ. В столбике два знака — «10» и значок
        масти; самый широкий из них занимает около 1,1 кегля, ещё
        три точки уходят на отступ от края карты;
     2) ВЫСОТА КАРТЫ. Когда рука лежит в два ряда, карта вдвое ниже,
        а столбик «достоинство + масть» просит примерно 2,4 кегля
        высоты. Этого ограничения тут раньше не было, и вот чем это
        кончалось: при 35 картах на руке масть уезжала за нижний край
        карты и пропадала совсем — на экране оставались одни цифры;
     3) ПРОСТО НЕ КРУПНЕЕ ПРИЛИЧНОГО. У карты, которую видно целиком,
        угол не должен спорить с крупной мастью в середине.

     Ниже 7 точек не опускаемся: при 35 картах на экране в 280 точек
     любой кегль всё равно мал, и пусть лучше краешек знака уйдёт под
     соседнюю карту, чем подпись растает совсем.

     У этого пола есть оговорка, и она про высоту. Уехать под соседнюю
     карту вбок — не беда: там всё равно ничего не видно. А вот уехать
     под СВОЙ нижний край — беда: знак обрезается на глазах у игрока
     и выглядит сломанным. Столбик просит 2,3 кегля высоты, значит при
     карте ниже 18 точек семь точек кегля уже не помещаются: в трёх рядах
     в узкой шторке карта выходит 14 точек, столбику нужно 17, и нижняя
     треть значка масти пропадает (замер предыдущего дизайнера, поэтому
     он тогда и поднял полоску руки до 86).
     Поэтому пол не постоянный, а «семь точек, но не больше, чем влезает
     в высоту карты». На обычной карте (18 точек и выше) он равен прежним
     семи и ничего не меняет — он считается ровно там, где раньше знак
     срезался.

     Запасной строки «для старых браузеров» тут нет нарочно: min() и
     clamp() нужны игре и так — на них держится сам размер карты
     (см. «--в» в начале файла). Браузер, который их не понимает,
     не покажет вообще ничего, и подпись в углу будет наименьшей
     из бед. */
  --кегль: max(min(7px, calc((var(--в) - 2px) / 2.3)),
               min(calc((var(--полоска) - 3px) / 1.1),
                   calc(var(--в) * 0.36),
                   calc(var(--ш) * 0.38)));
}

.карта__номинал {
  font-size: var(--кегль);
  line-height: 1;
  letter-spacing: -0.02em;         /* чтобы «10» было чуть у́же */
  font-variant-numeric: tabular-nums;
}

.карта__масть-угла {
  margin-top: 1px;
  /* Значок масти крупнее достоинства в 1,3 раза. Это не украшение:
     достоинство — это цифра, её узнают с полувзгляда даже мелкой,
     а масть узнают по форме, и мелкая форма не узнаётся никак.
     Место под такой значок есть: в столбике достоинство занимает
     два знака в ширину («10»), а масть — один, и она может быть
     заметно крупнее, оставаясь в той же полоске.
     Верхний предел — 0,34 ширины карты: у карты, видной целиком,
     угол не должен спорить с крупной мастью в середине. */
  font-size: min(calc(var(--кегль) * 1.3), calc(var(--ш) * 0.34));
  line-height: 1;
  /* Начертание нарочно обычное, а не жирное, как у достоинства.
     У трефы три отдельные доли, и жирный шрифт замазывает просветы
     между ними: на мелком значке трефа превращается в такое же
     чёрное пятно, как пика, — то самое, на что жаловался игрок. */
  font-weight: 400;
  /* Просим телефон рисовать масть знаком, а не цветным эмодзи:
     на части телефонов ♥ и ♦ по умолчанию превращаются в картинку,
     и тогда пропадает и наш красный цвет, и привычная форма.
     Свойство новое — браузеры постарше просто его не заметят. */
  font-variant-emoji: text;
}

/* Крупная масть в свободной части карты. Она работает там, где карту
   видно целиком: на столе, в колоде и у карты, которую игрок поднял
   (поднятая карта лежит поверх соседок). Сдвинута вправо-вниз, чтобы
   не лезть в угол. */
.карта__масть {
  position: absolute;
  inset: 30% 4% 4% 32%;
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  font-size: calc(var(--ш) * 0.64);
  line-height: 1;
  font-variant-emoji: text;
}

/* ---------- Рубашка ----------

   Раньше рубашку рисовало само оформление: клетка из двух полосатых
   градиентов и белая рамка внутри. Теперь весь рисунок векторный —
   у него свой узор, свой кант и своё поле по краю, — и старые правила
   только мешали: клетка просвечивала из-под рисунка, а рамка ложилась
   поверх канта, и выходила рамка в рамке. Поэтому здесь остались
   только два цвета, всё остальное рисует вектор.

   Заливка задаётся свойством fill — это «цвет заливки» у рисованных
   фигур, то же самое, что background у обычного элемента. */
.рубашка__фон  { fill: var(--рубашка-фон); }
.рубашка__поле { fill: var(--рубашка-поле); }

/* ---------- Карты в руке ---------- */

/* Позиции карт в веере считает JS, здесь только вид */
.веер .карта {
  position: absolute;
  /* Двигает карту сама игра (она же считает, куда карта подскочит при
     выборе), поэтому плавности по «transform» здесь больше нет: она
     дублировала движение и поднятая карта ехала дважды. Плавно меняются
     только тень и цвет обводки — то, чем карта показывает, что её
     выбрали. */
  transition: box-shadow 0.12s ease, outline-color 0.12s ease;
  /* Тень влево — каждая карта отчёркивается от соседки слева; вторая,
     короткая вниз, прижимает веер к столу. */
  box-shadow:
    -3px 0 7px rgba(0, 0, 0, 0.32),
    0 2px 5px rgba(0, 0, 0, 0.35);
}

/* ---------- Тесная рука: сколько видно от каждой карты ----------

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

   Ширину полоски присылает сама игра — числом, в точках. Она
   раскладывает веер и в конце пишет на нём «--шаг-карт»; если рука
   лежит в два ряда, пишется самый узкий из двух рядов, чтобы подпись
   читалась и там, где карты сжаты сильнее.

   Раньше оформление это число угадывало: считало карты в руке
   лесенкой правил «:nth-last-child» и подставляло заранее прикинутую
   долю ширины карты. Угадывание держалось на трёх допущениях сразу —
   сколько карт влезает по ширине экрана, в один ряд лежит рука или
   в два, какой из двух рядов теснее, — и на каждое допущение
   приходилось отдельное исключение: для низкого окна была написана
   вторая такая же лесенка. Теперь угадывать нечего: игра меряет
   и говорит, а оформление считает от готового числа.

   Ограничение «не шире самой карты» нужно для просторной руки: когда
   карт мало, они не налезают друг на друга вовсе и шаг между ними
   больше карты. Видно при этом всё равно ровно карту, не шире.

   Запасное значение — полная ширина карты. Оно срабатывает в тот
   короткий миг, пока веер ещё не разложен. */

.веер .карта {
  --полоска: min(var(--шаг-карт, var(--ш)), var(--ш));
}

/* В тесной руке угол карты переезжает вплотную к краю: там на счету
   каждая точка ширины. Ступенька спрятана внутрь clamp — большой
   множитель превращает плавный переход в переключатель: пока от карты
   видно меньше 22 точек, отступ равен одной точке, шире — обычным
   двум. Отдельного правила «если карт больше стольких-то» для этого
   больше не нужно. */
.веер .карта__угол {
  left: clamp(1px, (var(--полоска) - 22px) * 100, 2px);
}

/* ---------- Тесная рука: масть крупным знаком ----------

   ЖАЛОБА ЖИВОГО ИГРОКА. «Когда набрал полную руку (8–9 карт), карты
   сжались в узкие полоски — видно только цифру и крошечный значок
   масти, отличал только по цвету». А цвет — подпорка, а не решение:
   его завели для тех, кто не разбирает форму значка, и опираться
   на него одного игра не должна.

   ОТЧЕГО ТАК ВЫХОДИЛО. Крупная масть нарисована в правой половине
   карты. Пока карт мало, она видна и делает всю работу: масть узнаётся
   с полувзгляда. Стоит картам лечь внахлёст — соседка накрывает правую
   половину, крупный знак пропадает, и от карты остаётся левая полоска
   с одним уголком. А уголок меряется по ширине ВСЕЙ карты (0,34 её
   ширины), а не по ширине видимой полоски. Получалась нелепость:
   на телефоне 390 точек от карты видно 35 точек в ширину и 90 в высоту,
   из них под масть отдано 21 точка в самом верху, а вся остальная
   белизна — больше половины видимого места — стоит пустой.
   Хуже того, из-под соседки торчал обрезанный край крупного знака —
   чёрный клин непонятной формы, который только мешал.

   ЧТО ДЕЛАЕМ. Как только соседка закрывает больше 12 точек, крупная
   масть в середине всё равно наполовину срезана — её убираем совсем,
   а значок в углу вырастает во всю ширину видимой полоски и во всю
   высоту, что осталась под достоинством. На телефоне 390 точек это
   27–38 точек вместо прежних 21, на 320 — 21–31 вместо 17. Форму пики,
   трефы и бубны видно, не разглядывая, и масть больше не приходится
   угадывать по цвету. Достоинство не трогаем: цифру игрок читал
   и раньше, и место ей нужнее отдать масти.

   ДВА УСЛОВИЯ, А НЕ ОДНО. Просто «карты лежат внахлёст» тут мало.
   Когда рука ложится в два ряда, карты тоже внахлёст, но они вдвое
   ниже — под достоинством свободного места нет вовсе, зато вбок его
   хватает, и крупная масть там прекрасно видна (именно два ряда игрок
   и похвалил). Поэтому знак раздувается только там, где сошлось
   и то, и другое: карта высокая (выше своей ширины — так бывает
   только в один ряд) И закрыта больше чем на 12 точек. В два ряда,
   на столе, у колоды и у поднятой карты всё остаётся как было.

   КАК ЭТО ЗАПИСАНО. Тем же приёмом, что и ступенька выше: большой
   множитель превращает clamp в переключатель. Пока хоть одно из двух
   условий не выполнено, разность отрицательная и берётся первое
   значение — прежний размер; когда выполнены оба, разность
   положительная и берётся третье — крупный знак. Порог у двух правил
   разный на одну точку нарочно: в этот волосок между ними карта
   выглядит ровно как раньше, и ни при каком стечении чисел не бывает
   так, чтобы пропали оба знака сразу. */

.веер .карта__масть-угла {
  font-size: clamp(
    /* прежний размер — когда карту видно целиком или почти целиком */
    min(calc(var(--кегль) * 1.3), calc(var(--ш) * 0.34)),
    /* переключатель: высокая карта И закрыта больше чем на 12 точек */
    calc(min(var(--в) - var(--ш) - 8px, var(--ш) - var(--полоска) - 12px) * 100),
    /* крупный знак: по ширине видимой полоски, по остатку высоты
       под достоинством и не крупнее, чем имеет смысл на самой карте */
    min(calc((var(--полоска) - 5px) * 1.05),
        calc(var(--в) - var(--кегль) - 6px),
        calc(var(--ш) * 0.62))
  );
}

/* Крупная масть в середине: когда угол взял её работу на себя, она
   тут лишняя — от неё всё равно оставался обрезанный клин под соседней
   картой. Нулевой кегль и есть «не рисуем»: отдельного «скрыть» здесь
   не нужно, а размер и так уже считается формулой. */
.веер .карта__масть {
  font-size: clamp(
    0px,
    calc(max(var(--ш) - var(--в) + 8px, var(--полоска) - var(--ш) + 11px) * 100),
    calc(var(--ш) * 0.64)
  );
}

/* ---------- Светофор в руке: чем можно ходить, а чем нельзя ----------

   Живой игрок сказал главное: «все карты выглядят одинаково белыми
   и одинаково нажимаемыми, приходится в уме вычислять, что легально».
   Считать за него умеет сама игра, а здесь её знание становится видимым:

     карта--можно   этой сейчас ходят;
     карта--нельзя  этой сейчас не сходить;
     карта--выбрана по ней попал палец;
     карта--подхват её можно бросить вне очереди;
     карта--отказ   ответ на тап по запрещённой карте.

   Как выглядят «можно», «нельзя» и «выбрана» на новом столе — в разделе
   стола в конце файла. Здесь остались подхват и отказ: их вид не менялся. */

/* ---------- Карта, которую можно бросить вне очереди ----------

   Подхват заходной: на столе лежит, скажем, семёрка, и у вас семёрка —
   её можно бросить в любой миг подхода, не дожидаясь своего хода.
   Игра ставит на такую карту свой класс ВМЕСТО «можно»/«нельзя».

   Знак — пунктирная обводка цветом подсветки, и вот почему не другой.
   Зелёная черта снизу занята: она значит «сейчас твой ход» и должна
   значить только это — старый игрок, увидев её в чужой ход, решит,
   что игра сломалась. Серая вуаль сказала бы «нельзя». Сплошная
   обводка того же цвета — «выбрана». Остаётся пунктир того же цвета:
   он читается как «можно взять, но не обязательно». После тапа игра
   добавляет «выбрана», и пунктир становится сплошным — переход
   «можно → выбрано» виден сам, ничего объяснять не надо. Ради этого
   правило стоит ВЫШЕ правила «выбрана»: при равной силе побеждает
   записанное ниже, то есть сплошная рамка.

   Карту не приподнимаем: подъём на три точки — тоже язык «твой ход».
   В чужой ход она лежит в ряду со всеми, только обведена. В тесном
   веере от карты видна левая полоска, и обводка по левому краю
   и верхнему левому углу видна всегда. */
.веер .карта--подхват,
.карта--подхват {
  outline: 2px dashed var(--акцент);
  outline-offset: 1px;
  cursor: pointer;
}

/* Та же пунктирная обводка на заходной карте стола — но только пока
   в руке есть что бросить. Так видно, ЧТО именно можно бросать:
   пунктир в руке и пунктир на столе — одно достоинство, глаз связывает
   их без чтения. Метить заходную всегда не стали: стол и так пёстрый,
   а в свой ход метка ничего не говорит — это и есть «не перегружай».
   Обводка тоньше, чем в руке: подсказка к карте, а не второй призыв.
   Если заходная одновременно и цель защиты, сплошная рамка цели
   важнее — в селекторе исключение. */
#экран-игры:has(.карта--подхват) .пара--заходная:not(.пара--цель) .карта--атака {
  outline: 2px dashed var(--акцент);
  outline-offset: 1px;
}

/* Отказ: вздрагивание ловит взгляд движением, красный ободок объясняет
   смысл. Карту поднимаем над соседями — иначе вздрагивание уедет
   под соседнюю карту, и его не заметят. */
.веер .карта--отказ,
.карта--отказ {
  z-index: 60;
  animation: карта-вздрогнула 0.7s ease-in-out, карта-вспыхнула 0.7s ease-out;
}

/* Пока карта отказывает, серую вуаль подменяем красной: видно, что
   ответила именно та карта, по которой попал палец. */
.карта--отказ::after {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(224, 39, 60, 0.26);
  border-radius: inherit;
  pointer-events: none;
}

@keyframes карта-вздрогнула {
  0%   { transform: translate(0, 0)     rotate(0deg); }
  12%  { transform: translate(-5px, 0)  rotate(-3deg); }
  28%  { transform: translate(5px, 0)   rotate(3deg); }
  44%  { transform: translate(-4px, 0)  rotate(-2deg); }
  60%  { transform: translate(3px, 0)   rotate(1.5deg); }
  76%  { transform: translate(-2px, 0)  rotate(0deg); }
  100% { transform: translate(0, 0)     rotate(0deg); }
}

@keyframes карта-вспыхнула {
  0%   { box-shadow: 0 0 0 3px var(--карта-отказ), 0 0 10px 2px rgba(224, 39, 60, 0.85); }
  70%  { box-shadow: 0 0 0 3px var(--карта-отказ), 0 0 9px 2px rgba(224, 39, 60, 0.55); }
  100% { box-shadow: 0 0 0 3px rgba(224, 39, 60, 0); }
}

/* Если в телефоне выключены анимации, вздрагивание не показываем.
   Но без ответа игрока оставлять нельзя, поэтому вспышка остаётся. */
@media (prefers-reduced-motion: reduce) {
  .веер .карта--отказ,
  .карта--отказ {
    animation: карта-вспыхнула 0.7s ease-out;
  }
}

/* ---------- Подсказка ----------

   Строка внизу экрана, которой игра говорит, что случилось и что делать.
   Устроена она из двух частей, и это разделение — главное здесь:

     КОРОБКА (#подсказка) — место на экране. Высота у неё неподвижная,
        и коробка эту высоту держит, что бы игра ни написала;
     ТЕКСТ (вложенный «подсказка__текст») — сами слова. Вся раскраска —
        подложка, рамка, кружок-огонёк — рисуется на нём, поэтому плашка
        обтягивает слова, а не всю коробку.

   ПОЧЕМУ ТАК. Когда коробка облегала текст, одно событие дёргало стол
   дважды: длинное сообщение раздвигало коробку, через три секунды
   остывало и складывалось обратно — стол прыгал вверх и вниз
   (тестировщик описал это как «текст переписался сам»). Отсюда два
   правила, и они в силе:

   1. Коробка неподвижна — 44 точки. Это две строки текста (самая
      длинная фраза игры, 78 знаков, при этом кегле встаёт в две строки
      даже на 360) и немного воздуха; заодно это высота под палец —
      по строке нажимают, чтобы открыть «Что было».

   2. Свежее и остывшее сообщение занимают одинаковое место: вес букв
      у них один и тот же, поля у текста заданы всегда, а огонёк
      на свежем событии не убирается из строки, а только прячется.
      При остывании ни одно слово не переезжает на другую строку.

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

#подсказка {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  /* Именно height, а не min/max: коробка не должна ни расти, ни сжиматься */
  height: 44px;
  padding: 0 6px;
  font-size: clamp(13px, 3.6vw, 15px);
  font-weight: 500;
  line-height: 1.25;
  text-align: center;
  /* Ждём соперника — строка спокойная, приглушённая */
  color: var(--текст-тихий);
  /* Скругление нужно запасному пути (см. ниже): там плашка — сама коробка */
  border-radius: 10px;
  overflow: hidden;
}

/* Сами слова. Плашка рисуется здесь, поэтому она облегает текст:
   под коротким сообщением не остаётся пустого цветного прямоугольника
   в три строки высотой.

   Поля заданы всегда, даже когда плашки не видно. Так ширина, в которую
   ложатся слова, одна и та же во всех состояниях, и перенос слов не
   меняется от того, подсвечено сообщение или уже остыло.

   Два ограничения по краям — страховка: шире коробки плашка не станет
   (max-width), выше коробки не вырастет (max-height). Если игра когда-то
   покажет сообщение длиннее трёх строк, лишнее срежется снизу, как
   у книжной страницы, а не сверху и снизу разом, как было, когда
   текст стоял по центру жёсткой коробки. */
#подсказка .подсказка__текст {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  max-width: 100%;
  max-height: 100%;
  padding: 0 4px;
  border-radius: 10px;
  overflow: hidden;
}

/* Ждут вас: строка белеет, слева салатовая точка-огонёк.
   Селектор «#подсказка .класс» нарочно тяжёлый: цвет строки задан выше
   у «#подсказка», и правило из одного класса ему проиграло бы. */
#подсказка .подсказка--ваш-ход {
  color: var(--текст);
}

#подсказка .подсказка--ваш-ход::before {
  content: "";
  flex: 0 0 auto;
  width: 6px;
  height: 6px;
  margin-right: 7px;
  border-radius: 50%;
  background: var(--акцент);
  box-shadow: 0 0 6px color-mix(in srgb, var(--акцент) 60%, transparent);
}

/* Рассказ о том, что только что случилось («Соперник подкинул Д♦»).
   Висит три секунды: белым и с коротким всплеском при появлении — иначе
   игрок событие не замечает. Правило идёт после «вашего хода» и
   перебивает его: пока висит событие, важнее оно. Начертание нарочно
   не жирнее обычного — жирные буквы шире, и слова перекладывались бы
   на другое число строк, стоило событию остыть. */
#подсказка .подсказка--событие {
  color: var(--текст);
  animation: всплеск 0.3s ease-out;
}

/* На плашке события огонёк не нужен: там и так всё подсвечено.
   Но убираем его именно из вида, а не из строки: «visibility» прячет
   кружок, оставляя за ним место, и слова стоят там же, где будут стоять
   через три секунды, когда огонёк вернётся. Со старым «display: none»
   строка при остывании становилась на 16 точек у́же и текст переносился
   заново. */
#подсказка .подсказка--событие::before { visibility: hidden; }

@keyframes всплеск {
  from { transform: scale(0.92); opacity: 0.25; }
  to   { transform: scale(1);    opacity: 1; }
}

/* ---------- Подсказка: запасной путь для старых страниц ----------

   У части игроков Telegram открывает страницу из своей памяти — вчерашнюю,
   где вложенного элемента для текста ещё нет. Игра это умеет: не найдя его,
   она пишет слова прямо в коробку и вешает обе пометки на неё. Правила ниже
   и написаны для такой страницы — они повторяют то же оформление, только
   плашкой работает сама коробка.

   Удалить их нельзя: без них у таких игроков подсказка осталась бы вовсе
   без подсветки — ни плашки события, ни огонька своего хода, — то есть
   поломка была бы хуже той, которую мы чиним. Мешать друг другу два набора
   не могут: на новой странице пометки висят на тексте, и коробка их
   не получает никогда; на старой странице нет вложенного элемента,
   и правила выше не находят, к чему прицепиться.

   Подсказка при этом стоит на неподвижной коробке, поэтому и здесь стол
   не дёргается. Как только Telegram обновит страницу, игрок получит
   обычный вид. */

#подсказка.подсказка--ваш-ход {
  color: var(--текст);
}

#подсказка.подсказка--ваш-ход::before {
  content: "";
  flex: 0 0 auto;
  width: 6px;
  height: 6px;
  margin-right: 7px;
  border-radius: 50%;
  background: var(--акцент);
}

#подсказка.подсказка--событие {
  color: var(--текст);
  animation: всплеск 0.3s ease-out;
}

/* Тот же случай, что и выше: огонёк прячем, место за ним оставляем,
   иначе при остывании слова перенесутся заново. */
#подсказка.подсказка--событие::before { visibility: hidden; }

/* Кнопки хода («Взять», «Бито», «Сказать») — в разделе стола в конце
   файла («Панель действий»). */

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

   Класс «экран--поверх» — общий: его можно повесить на любой экран,
   который должен показываться поверх игры, не пряча её. */

/* ---------- Кто ловит касания, когда показан итог ----------

   ПОЛОМКА, КОТОРУЮ ВИДЕЛ ВЛАДЕЛЕЦ: «кнопка назад не всегда работает».
   Пока партия шла — всё нажималось; кончилась — нижний ряд кнопок под
   доской переставал отвечать, хотя кнопки видны. Проверка спрашивала
   у страницы, что лежит в точке под пальцем, и отвечала: «экран-итога».
   То есть касание доставалось не кнопке, а самому слою итога.

   Сначала я снял касания только с вуали (она тянется от плашки вверх
   на весь экран) — этого не хватило: ловила сама секция.

   Теперь так, как и надо было:
     • слой итога касаний НЕ принимает вовсе — мимо плашки палец
       проходит насквозь, к кнопкам игры под ним;
     • сама плашка принимает — за это отвечает подложка «::after»
       ниже: она ровно по размеру плашки и лежит под её содержимым.
       Поэтому промах мимо кнопки, но в плашку, никуда не проваливается,
       как было раньше;
     • заголовок, подписи и кнопки внутри принимают тоже.

   Класс общий, значит починка разом действует на все игры сборника. */
.экран--поверх,
#экран-результата {
  pointer-events: none;
  inset: auto 0 0 0;           /* прижат к низу, высота — по содержимому */
  height: auto;
  /* Плашка обязана быть выше всего, что есть на игровом экране. Без этой
     строки приподнятая карта из руки (у неё своя высота слоя) вылезала
     поверх плашки и закрывала вопрос — видно на проверке плашки выхода. */
  z-index: 100;
  /* Строки текста — во всю ширину, а две кнопки встают рядом:
     плашка ниже, и из-под неё видно свою руку. */
  flex-flow: row wrap;
  align-items: center;
  justify-content: center;
  gap: 10px;
  /* Плашка прижата к низу, поэтому безопасное поле ей нужно только
     снизу: в полном экране Telegram под ней проходит полоса жеста,
     и без отступа нижняя кнопка оказывается прямо на ней. */
  padding: 18px calc(14px + var(--отступ-справа))
           calc(18px + var(--отступ-снизу)) calc(14px + var(--отступ-слева));
  text-align: center;
  background: var(--панель);
  border-top: 1px solid var(--край);
  border-radius: 18px 18px 0 0;
  box-shadow: 0 -12px 32px rgba(0, 0, 0, 0.45);
}

/* ---------- Вуаль над плашкой ----------

   Всё, что выше плашки, слегка притемнено — так видно, что игра
   остановлена, но стол по-прежнему можно рассмотреть.

   ПОЧИНКА, КОТОРУЮ ВИДЕЛ ВЛАДЕЛЕЦ: «кнопка назад не всегда работает».
   Вуаль тянется от плашки до верха экрана и раньше ловила нажатия.
   Пока партия шла, плашки не было и всё работало; кончилась — и нижний
   ряд кнопок под доской (в шашках это «В меню», «Звук», «Как играть»,
   «Рекорды») оказывался ПОД вуалью: кнопки видны сквозь неё, человек
   в них тычет, а касание достаётся вуали. Отсюда и «не всегда».

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

   Почему не наоборот — не «слой не ловит, содержимое ловит»: тогда
   перестала бы ловить и площадь самой плашки между кнопками, и тап
   мимо кнопки проходил бы на стол под ней вслепую. */
.экран--поверх.экран--виден::before,
#экран-результата.экран--виден::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 100%;
  height: 100vh;
  background: rgba(0, 0, 0, 0.34);
  pointer-events: none;
}

/* ---------- Плашка итога приподнята над рядом кнопок ----------

   Последняя половина той же поломки. Собственная кнопка плашки
   («Другая игра», «Играть ещё») приходилась ровно на то место, где
   под доской стоят «В меню» и «Рекорды». Перекрытие тут честное —
   это настоящая видимая кнопка, и нажатия она ловит по праву;
   касаниями такое не лечится, только раскладкой. Прятать «В меню»
   нельзя: без неё человек заперт на экране итога — это уже проверено
   и получено красным.

   Просвет считаю от самого высокого нижнего ряда в сборнике: кнопка
   46 точек плюс поля экрана и небольшой запас — выходит 62, и сверху
   ещё безопасное поле телефона. Между нижней кнопкой плашки и рядом
   под доской остаётся видимая полоса: промахнуться пальцем с одной
   на другую трудно.

   Раз плашка больше не касается краёв — у неё скруглены все углы
   и появились поля по бокам: теперь это карточка, лежащая поверх
   стола, а не полка, приклеенная к низу экрана.

   Правило нарочно только для плашек ИТОГА, а не для всего, что
   «поверх»: тем же общим классом пользуются лента новостей и панель
   знаков у карт, и их поднимать нельзя — у панели знаков «Закрыть»
   рассчитана ровно на то, что панель прижата к низу. */
#экран-результата.экран--поверх,
#экран-результата,
#экран-итога.экран--поверх {
  inset: auto 8px calc(62px + var(--отступ-снизу)) 8px;
  padding-bottom: 18px;
  border: 1px solid var(--край);
  border-radius: 18px;
  box-shadow: 0 12px 34px rgba(0, 0, 0, 0.45);
}

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

/* Подложка плашки: невидимая, ровно по её размеру, лежит под всем
   содержимым. Она и возвращает плашке способность ловить касания —
   включая просветы между кнопками. Без неё промах на пару точек мимо
   кнопки уходил бы вслепую на стол под плашкой. */
.экран--поверх::after,
#экран-результата::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: auto;
}

/* Всё, что лежит в плашке — заголовок, подписи, кнопки, — касания
   принимает. Правило одно на всех детей: перечислять кнопки поимённо
   значило бы забыть новую, как только её добавят. */
.экран--поверх > *,
#экран-результата > * {
  pointer-events: auto;
}

#экран-результата .заголовок { font-size: 27px; }

/* Серия побед — главная цифра итога. Ставим её сразу под заголовок
   (порядком, а не в разметке — см. раздел о порядке ниже) и обводим
   рамкой цвета подсветки: взгляд попадает на неё первой. Текст обычного
   цвета — так он читается в любой теме, а рамка делает всю работу
   по вниманию. */
.серия {
  margin: 0;
  padding: 5px 14px;
  font-size: 18px;
  font-weight: 800;
  line-height: 1.25;
  color: var(--текст);
  background: var(--подложка);
  border: 2px solid var(--акцент);
  border-radius: 12px;
}

/* ---------- Порядок строк и кнопок на плашке итога ----------

   Плашка — это гибкая раскладка, а в ней можно переставлять части
   местами, не трогая разметку. Тем и пользуемся: серию побед в разметке
   удобно держать рядом с объяснением, а на экране она должна стоять
   сразу под заголовком.

   Здесь была настоящая беда, и вот в чём она. Порядок раньше стоял
   только у тех, кого переставляли: у объяснения и у кнопок. А любой,
   кому порядок не задан, считается нулевым — то есть встаёт ВПЕРЕДИ
   всех, кому задали первый и второй. Про ответ сервера на «Собрать
   стол заново» просто забыли, и он уезжал наверх: в разметке он стоит
   под своей кнопкой, а на экране вклинивался между заголовком
   и объяснением. Выходило так:

       Вы выиграли!
       Вы вышли из этой партии — чтобы играть дальше, начните новую
       Дурак — Константин: карты остались у него…

   Первые две строки спорят друг с другом, и к какой из двух кнопок
   относится ответ — угадать нельзя. А ответ приходит на каждый отказ
   сервера: «Стол собирает тот, кто создал комнату», «Связь пропала».

   Чиним не одну строку, а саму причину. Порядок теперь расписан
   поимённо для КАЖДОГО, кто есть на плашке, а сверху лежит запасное
   правило: всё, про что забудут дальше, встаёт в конец. Уехать в конец
   не страшно — заметят и поправят. Уехать наверх и разорвать заголовок
   с объяснением — беда, которую видит живой игрок.

   Номера идут через десяток нарочно: между любыми двумя всегда есть
   куда вставить новую строку, не переписывая остальные. */

/* Запасной путь: элемент, про который забыли, встаёт последним, а не первым */
#экран-результата > * { order: 90; }

#экран-результата > .заголовок           { order: 10; }  /* «Вы выиграли!»   */
#экран-результата > .серия               { order: 20; }  /* побед подряд     */
#экран-результата > #пояснение-результата { order: 30; }  /* чем кончилось    */
#экран-результата > #кнопка-ещё          { order: 40; }  /* «Играть ещё»     */
#экран-результата > #кнопка-пересобрать  { order: 50; }  /* «Собрать заново» */
/* «Рекорды» приехали на итог позже остальных и порядка не получили,
   а без порядка кнопка встаёт последней — то есть ПОД «В меню». Уход
   обязан быть последним всегда: это край плашки, дальше ничего нет.
   Ставим рекорды перед ним. */
#экран-результата > #кнопка-рекорды-итог { order: 65; }  /* посмотреть серии */
#экран-результата > #кнопка-в-меню-итог  { order: 70; }  /* уход             */

/* Три строки, которые появились на плашке позже и без порядка уехали бы
   в самый конец — под «В меню». Серия дней — сразу за серией побед:
   это два достижения рядом. Итог раздачи дня и сравнение с остальными —
   сразу за объяснением «чем кончилось»: они про ту же партию. */
#экран-результата > #серия-дней-итога    { order: 25; }  /* «День 4 подряд!» */
#экран-результата > #итог-дня            { order: 32; }  /* «Раздача дня: …» */
#экран-результата > #сравнение-дня       { order: 34; }  /* «…выиграли N из M» */
/* «+2 к рейтингу» (или отказ сервера про дневной лимит на ботов) — тоже
   про итог этой партии, а не про следующий шаг. Без своего порядка строка
   попадала под запасное правило и уезжала в конец, под все три кнопки —
   человек видел её последней и не понимал, к чему она относится. Ставим
   сразу за сравнением дня и перед первой кнопкой. */
#экран-результата > #итог-рейтинга       { order: 36; }  /* «+2 к рейтингу» */

/* ---------- Звёздочка у «Рекордов» ----------

   На плашке итога «Рекорды» встали вплотную к «В меню», и обе — мелкие
   тихие кнопки с тонкой серой каймой. Различались они только надписью
   в 13 точек, а цена ошибки разная: одна показывает таблицу и её можно
   закрыть, вторая бросает партию и уводит из игры. Ровно тот же разговор,
   что был про «Собрать стол заново» и «В меню» ниже.

   Разводим их значком, а не цветом: у «Рекордов» впереди звёздочка.
   Звезда во всех системных шрифтах есть, рисовать её картинкой не нужно,
   и означает она везде одно и то же — «лучшее, чего ты добился».
   Цвет подмешанный, не чистый цвет подсветки: чистый на этой плашке даёт
   контраст ниже нормы (так же сделана круговая стрелка ниже). Первая
   строка — для браузеров без color-mix.

   Ту же звёздочку получает и «Рекорды» на экране игры с ботом: одна
   и та же кнопка должна выглядеть одинаково, где бы её ни встретили. */
#кнопка-рекорды,
#кнопка-рекорды-итог {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
}

#кнопка-рекорды::before,
#кнопка-рекорды-итог::before {
  content: "★";
  font-size: 1.05em;
  line-height: 1;
  color: var(--акцент);
  color: color-mix(in srgb, var(--акцент) 60%, var(--текст));
}

/* ---------- Ответ сервера под кнопкой «Собрать стол заново» ----------

   Место. Ответ встаёт сразу под своей кнопкой — там же, где стоит
   в разметке (порядок 60, между пересбором и «В меню»). Он широкий,
   поэтому «В меню» само уходит на следующую строку, и между кнопкой
   и её ответом уже ничего не вклинивается.

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

   Текст по левому краю: отказ читают построчно, а рваные строки
   по центру читаются хуже. Длинные слова разрешаем переносить в любом
   месте — в этих сообщениях попадается адрес сервера одним куском,
   и без разрешения он вылез бы за плашку.

   Сверху прижимаем плотнее, чем снизу (6 точек против 10): так с одного
   взгляда видно, что ответ относится к кнопке НАД ним, а не к «В меню»
   под ним.

   Про ширину. Ниже стоит общее правило «строки итога — во всю ширину»,
   и оно ЭТУ строку не тронет: у правила ниже вес меньше (класс против
   идентификатора), а не «оно позже, значит сильнее». Кегль, наоборот,
   нарочно не задаём — пусть остаётся общий, включая уменьшенный
   в низком окне. */
#экран-результата > #сообщение-пересбора {
  order: 60;
  width: min(100%, 330px);
  margin-top: -4px;
  padding: 9px 12px;
  line-height: 1.4;
  text-align: left;
  overflow-wrap: anywhere;
  color: var(--текст);
  background: var(--подложка);
  border-left: 4px solid var(--акцент);
  border-radius: 4px 10px 10px 4px;
}

#экран-результата > .заголовок,
#экран-результата > .подпись,
#экран-результата > .серия { width: 100%; }

/* Серия дней на плашке — плашка-таблетка по ширине слов, как на витрине,
   а не строка во всю ширину: правило выше её растянуло бы. */
#экран-результата > .серия-дней {
  width: auto;
  align-self: center;
}

/* «Раздача дня: победа за 14 ходов» — это итог соревнования, а не ещё одно
   объяснение, поэтому не тихая подпись, а обычный цвет текста и вес 600.
   Сравнение с остальными («выиграли N из M») остаётся тихим — это
   уточнение к итогу. Обе строки прижаты друг к другу и к объяснению
   отрицательным полем: они про одно и то же. */
#экран-результата > #итог-дня {
  margin-top: -4px;
  font-weight: 600;
  color: var(--текст);
}

#экран-результата > #сравнение-дня {
  margin-top: -6px;
  font-size: 13px;
  line-height: 1.35;
  /* На 320 точках строка переносится; без баланса выходило
     «…вы на 3-м» и одинокое «месте» — место отрывалось от числа. */
  text-wrap: balance;
}

/* «+2 к рейтингу» — хорошая новость, и должна читаться как хорошая
   новость: не тихая серая подпись, а жирный текст цвета подсветки.
   Тот же текст иногда приходит от сервера как отказ («На сегодня очки
   за ботов кончились…») — своего класса под этот случай нет, а
   выдумывать вид под два разных сообщения не задача оформителя. Цвет
   подмешанный (60% подсветки к обычному тексту), а не чистый — та же
   мера, что у значков на этой плашке (звёздочка «Рекордов», стрелка
   «Собрать заново»): чистый акцент на тёмной панели даёт контраст ниже
   нормы. Первая строка — запасной путь для браузеров без color-mix. */
#экран-результата > #итог-рейтинга {
  margin-top: -4px;
  font-weight: 700;
  color: var(--акцент);
  color: color-mix(in srgb, var(--акцент) 60%, var(--текст));
}

/* Сравнение приходит с задержкой — после ответа сервера. Если до ответа
   строки нет вовсе, плашка при её появлении подпрыгивает вместе
   с кнопками, и палец, уже занесённый над «Играть ещё», попадает
   в другое. Поэтому пока итог раздачи дня на плашке, а сравнения ещё
   нет, место под него держится заранее: строка есть, но невидима.
   Две строки, а не одна: «Сегодня эту раздачу выиграли 7 из 12, вы
   на 3-м месте» на 320 точках переносится, и резерв в одну строку
   всё равно давал бы прыжок. В обычной партии (без итога дня) строки
   нет и места она не занимает. Правило сильнее общего «скрыт»
   и потому с !important — иначе его не перебить. */
#экран-результата:has(#итог-дня:not(.скрыт)) > #сравнение-дня.скрыт {
  display: block !important;
  visibility: hidden;
  min-height: calc(2 * 1.35em);
}

/* ---------- Две мелкие кнопки под итогом: пересбор и уход ----------

   У хозяина сетевого стола под итогом стоят рядом «Собрать стол заново»
   и «В меню». Пришли они с одним и тем же видом — тот же серый фон,
   та же тонкая рамка, тот же кегль, — и различались только шириной
   и местом. На узком телефоне обе встают в одну строку, и вот тут
   их путают. Цена ошибки при этом разная: первая собирает стол заново
   с тем же кодом, вторая уводит из партии, и обратно человек попадёт
   только по коду, который придётся заново спрашивать у друзей.

   Разводим их по смыслу, а не по ширине. За столом три вещи, и они
   разного веса:
     «Ещё партию»          — главное действие, залито целиком;
     «Собрать стол заново» — тоже действие с игрой, но второе по счёту:
                             рамка цветом подсветки, обычный цвет текста
                             и круговая стрелка впереди. Ровно так же
                             в прихожей выглядят «Посадить бота»
                             и «Убрать бота» — это уже язык игры;
     «В меню»              — не действие, а уход: тише всех, без заливки
                             вовсе, тонкая серая рамка и тихий текст.

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

#кнопка-пересобрать {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  /* 44 точки — та высота, в которую палец попадает не целясь.
     У «В меню» их по-прежнему 40: промахнуться мимо ухода не жалко. */
  min-height: 44px;
  padding: 9px 14px;
  font-size: 14px;
  font-weight: 700;
  color: var(--текст);
  background: var(--подложка);
  border: 2px solid var(--акцент);
  box-shadow: none;
}

/* Круговая стрелка — единственный значок на этой плашке, и он говорит
   «то же самое, только сначала». Рисуем знаком, а не картинкой: стрелки
   есть в системных шрифтах всех телефонов (они распространены шире, чем
   масти, которыми игра пользуется с первого дня).
   Цвет — тот же смешанный, что у номеров правил: чистый цвет подсветки
   на этой плашке даёт контраст ниже нормы, а подмешанный к нему цвет
   текста вытягивает его в любой теме. Первая строка — для браузеров
   без color-mix. */
#кнопка-пересобрать::before {
  content: "↻";
  font-size: 17px;
  line-height: 1;
  color: var(--акцент);
  color: color-mix(in srgb, var(--акцент) 60%, var(--текст));
}

/* Уход — самое тихое, что есть на плашке: заливку убираем совсем,
   остаётся только тонкий контур. Рядом с рамкой цвета подсветки
   эта кнопка честно читается как «выйти отсюда», а не как действие. */
#экран-результата #кнопка-в-меню-итог {
  background: transparent;
}

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

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

   Оба условия написаны в одном селекторе нарочно: в обычном итоге,
   где «Ещё партию» на месте, это правило молчит, и «В меню» живёт
   по общим правилам мелкой кнопки — включая её размеры на узком
   телефоне, которые заданы отдельно, в самом низу файла. */
#экран-результата:has(#кнопка-ещё.скрыт):has(#кнопка-пересобрать:not(.скрыт))
  #кнопка-в-меню-итог {
  min-height: 44px;     /* палец тот же, что и у главной кнопки */
  min-width: 0;
  padding: 8px 12px;
  font-size: 13px;
  font-weight: 600;
  color: var(--текст-тихий);
  background: transparent;
  border: 1px solid var(--край);
}

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

   Здесь она снова становится обычной кнопкой: 46 точек высоты
   (палец попадает не глядя), обычный цвет текста и рамка цветом
   подсветки — видно, что это действие, а не выключенная надпись.
   Заливку не даём: рядом уже стоит плашка с рамкой того же цвета,
   и две залитые фигуры спорили бы друг с другом.

   Как игра сообщает, что реванша не будет: вешает на кнопку
   «Ещё партию» класс «скрыт». Пока кнопка видна, правило молчит
   и плашка выглядит как раньше. Старый браузер без «:has» просто
   покажет прежнюю мелкую кнопку — выход останется на месте.

   Из-под этого правила выведены две кнопки. «В меню» рядом с видимым
   пересбором (см. оговорку выше): уход не должен вырастать до размера
   действия только потому, что действие рядом изменилось. И «Рекорды»:
   они на этой плашке — не выход из тупика, а «посмотреть, что было
   раньше». Выросши до размера действия, они спорили бы за внимание
   ровно с тем единственным выходом, ради которого правило и написано. */
#экран-результата:has(#кнопка-ещё.скрыт)
  .кнопка.кнопка--мелкая:not(#кнопка-рекорды-итог) {
  min-height: 46px;
  min-width: 160px;
  padding: 10px 20px;
  font-size: 16px;
  font-weight: 700;
  color: var(--текст);
  background: var(--подложка);
  border: 2px solid var(--акцент);
}

/* Пока висит плашка итога, игровой экран остаётся на месте и не
   реагирует на нажатия. Строка нужна до тех пор, пока игра прячет
   игровой экран сама; когда перестанет — она просто ничего не изменит.
   Стол не приподнимаем: плашка итога закрывает только руку и кнопки,
   и стол над ней виден целиком. Поле снизу — прежнее, с полосой жеста. */
#приложение:has(#экран-результата.экран--виден) #экран-игры {
  display: flex;
  pointer-events: none;
  padding-bottom: calc(8px + var(--отступ-снизу));
}

/* Кнопки хода на итоге не нужны: «Бито» и «Беру» уже спрятаны, а «В меню»
   есть на самой плашке. Место за собой оставляют, чтобы стол не прыгал. */
#приложение:has(#экран-результата.экран--виден) #панель-кнопок {
  visibility: hidden;
}

/* ---------- Плашка «точно выйти?» ----------
   «В меню» стоит вплотную к «Бито» и «Беру», прямо под большим пальцем,
   поэтому игра переспрашивает. Сама плашка выглядит как итог партии —
   это общий класс «экран--поверх», — здесь только раскладка внутри.

   Главной сделана та кнопка, которая оставляет игрока в партии:
   она во всю ширину, залита цветом и стоит первой. «Выйти в меню» —
   мелкая и ниже: уйти можно, но для этого надо прицелиться. */

#экран-выхода .заголовок { font-size: 24px; }

#экран-выхода > .заголовок,
#экран-выхода > .подпись,
#экран-выхода > .кнопка {
  width: 100%;
}

#экран-выхода .кнопка--главная {
  max-width: 300px;
}

/* «Выйти в меню» не растягиваем во всю строку, но и не делаем крохотной:
   140 точек ширины и 40 высоты — палец попадает спокойно. */
#экран-выхода .кнопка--мелкая {
  width: auto;
  min-width: 140px;
}

/* ================================================================
   ПЛАШКА «ЧТО БЫЛО» — последние новости стола

   Зачем она. Внизу экрана всего одна строка, и в неё влезают одна-две
   свежие новости. За столом на шестерых между двумя своими ходами
   человек пропускает до пяти чужих: отвлёкся на пару секунд — у
   соперника вдруг двенадцать карт вместо шести. Здесь он может
   догнать пропущенное.

   Плашка собрана на чужих классах: «таблица» одолжила прокрутку,
   «таблица__строка» — саму строку. Но таблица рекордов — список
   достижений, у неё три привычки, которые здесь прямо вредят:

     1) текст в строке обрезается многоточием. В рекордах обрезать
        нечего (там короткое «12 побед подряд»), а тут в строке живая
        фраза, и на 390 точках от неё оставалось «У вас младший
        козырь 2♦ — вы ход…» — то есть пропадало главное;
     2) первая строка обведена как чемпион. Здесь первая — самая
        СТАРАЯ новость, и золотая рамка звала взгляд ровно не туда;
     3) текст стоит по центру. Восемь центрированных строк разной
        длины читать сверху вниз тяжело: глаз каждый раз ищет,
        откуда начинается фраза.

   Поэтому ниже — своя раскладка. Всё до единого правила привязано
   к «#лента-событий» и «#экран-ленты»: те же классы носят таблица
   рекордов и список мест в прихожей, и туда не должно протечь ничего.
   ================================================================ */

/* Сама плашка. Лежит поверх стола, поэтому вид ей задаёт общий
   «экран--поверх»; здесь только раскладка столбиком и потолок высоты.

   Потолок нужен вот зачем: плашка открывается ПОСРЕДИ ПАРТИИ, соперники
   в это время ходят и список пополняется на глазах. Если дать плашке
   вырасти во весь экран, она станет стеной, и человеку покажется, что
   игра встала. 86% — это полоска стола, которая всегда остаётся видна
   сверху: на высоком телефоне из-под плашки видно соперников и колоду,
   а в шторке высотой 420 точек — хотя бы верхний ряд соперников. */
#экран-ленты {
  flex-flow: column nowrap;
  align-items: center;
  justify-content: flex-start;
  gap: 8px;
  max-height: 86%;
  /* Плашка прижата к низу, поэтому безопасное поле нужно только снизу. */
  padding: 12px calc(10px + var(--отступ-справа))
           calc(12px + var(--отступ-снизу)) calc(10px + var(--отступ-слева));
}

/* Заголовок здесь служебный: человек и так знает, что открыл. Крупные
   34 точки отбирали у списка две строки новостей — отдаём их списку. */
#экран-ленты .заголовок {
  flex: none;
  font-size: 23px;
}

#кнопка-лента-назад {
  flex: none;
  width: min(100%, var(--колонка-кнопок));
}

/* ---------- Список ----------
   Ширину и прокрутку даёт «таблица». Здесь — подсказка о том, что
   список прокручивается: у верхнего края лежит тень, а к первой строке
   приклеена «крышка» цвета плашки. Пока список прокручен вниз, тень
   видна и говорит «выше есть ещё»; вернулись наверх — крышка наехала
   на тень, и та пропала. Тот же приём, что в прихожей, только зеркальный:
   там прятались новые строки внизу, а тут вниз смотреть не нужно —
   самая свежая новость и так приклеена к нижнему краю (см. ниже). */
#лента-событий {
  gap: 5px;
  padding-right: 2px;      /* полоска прокрутки не наезжает на текст */
  background:
    linear-gradient(var(--панель), transparent) top / 100% 12px local no-repeat,
    radial-gradient(farthest-side at 50% 0, rgba(0, 0, 0, 0.40), transparent)
      top / 100% 8px scroll no-repeat;
}

/* ---------- Строка новости ----------
   Две колонки: слева порядковый номер, справа сама новость. Номер
   тихий и узкий — он лишь помогает не потерять место в списке;
   главное в строке — фраза, поэтому она читается слева направо
   обычным текстом и переносится на вторую строку, а не обрезается. */
#лента-событий .таблица__строка {
  grid-template-columns: 1.7em minmax(0, 1fr);
  align-items: start;
  gap: 2px 8px;
  padding: 7px 10px 8px;
  text-align: left;
  background: rgba(128, 128, 128, 0.14);
  border-radius: 10px;
  /* Отменяем «чемпионскую» обводку первой строки: старая новость
     ничем не заслужила золотую рамку. */
  box-shadow: none;
}

#лента-событий .таблица__место {
  font-size: 12.5px;
  font-weight: 700;
  line-height: 1.6;                      /* цифра на одной линии с текстом */
  color: var(--текст-тихий);
  font-variant-numeric: tabular-nums;    /* цифры одной ширины — столбик ровный */
}

#лента-событий .таблица__очки {
  font-size: 15px;
  font-weight: 600;
  line-height: 1.35;
  text-align: left;
  /* Главная починка: длинную новость переносим, а не режем многоточием */
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
}

/* ---------- Что случилось давно ----------
   Четвёртая с конца новость и дальше — это уже «было когда-то»:
   заливка бледнее, текст тише и легче. Совсем гасить его нельзя —
   человек пришёл сюда именно читать, — поэтому берём тот же
   приглушённый цвет, что у подписей: он тише основного, но контраст
   с фоном держит с запасом. */
#лента-событий .таблица__строка:nth-last-child(n+4) {
  background: rgba(128, 128, 128, 0.08);
}

#лента-событий .таблица__строка:nth-last-child(n+4) .таблица__очки {
  /* Кегль на точку мельче, чем у недавних, и на две — чем у свежей.
     Получается лесенка 14 — 15 — 16: список будто уходит вдаль, и
     возраст новости виден раньше, чем человек прочтёт её номер.
     Гасить старое прозрачностью нельзя: в светлой теме Telegram
     бледный текст на бледной плашке перестаёт читаться, — поэтому
     возраст показан размером и весом букв, а не яркостью. */
  font-size: 14px;
  font-weight: 500;
  color: var(--текст-тихий);
}

/* ---------- Что случилось только что ----------
   Самая свежая новость — та, ради которой плашку и открыли. Её видно
   по четырём приметам сразу, и это нарочно: одной приметы мало, если
   у человека, скажем, слабое зрение или тёмная тема.

     1) полоса цвета подсветки слева;
     2) заливка с примесью того же цвета — строка теплее соседних;
     3) текст крупнее и жирнее остальных;
     4) метка «только что» словами — самая честная из четырёх.

   И главное: строка ПРИЛИПАЕТ к нижнему краю списка. Новости идут
   сверху вниз по времени, свежая — последняя, и в низком окне она
   оказывалась за нижним краем: человек открывал плашку и видел то,
   что было восемь ходов назад, а самое важное приходилось искать
   прокруткой. Теперь она всегда на виду, а старые новости проезжают
   под ней. Пока список помещается целиком, прилипание ничего не
   меняет — строка и так стоит на своём месте. */
#лента-событий .таблица__строка--свежая {
  position: sticky;
  bottom: 0;
  z-index: 2;
  padding-left: 6px;                 /* минус ширина полосы — текст в колонку */
  border-left: 4px solid var(--акцент);
  /* Заливка обязана быть НЕПРОЗРАЧНОЙ: под приклеенной строкой проезжают
     соседние, и сквозь полупрозрачную было бы видно чужие буквы.
     Первая строка — запасная для браузеров старше 2023 года. */
  background: var(--панель);
  background: color-mix(in srgb, var(--акцент) 18%, var(--панель));
  box-shadow: 0 -6px 12px rgba(0, 0, 0, 0.28);
}

#лента-событий .таблица__строка--свежая .таблица__место {
  color: var(--текст);
}

#лента-событий .таблица__строка--свежая .таблица__очки {
  font-size: 16px;
  font-weight: 800;
  color: var(--текст);
}

/* Метка «только что». Встаёт под текстом отдельной строчкой, а не сбоку:
   сбоку она отняла бы у новости треть ширины, а на 280 точках это
   три-четыре слова. Рисуется оформлением, потому что это не новость,
   а пометка о её свежести. */
#лента-событий .таблица__строка--свежая::after {
  content: "только что";
  grid-column: 2;
  justify-self: start;
  margin-top: 3px;
  padding: 1px 8px 2px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.3px;
  color: var(--кнопка-текст);
  background: var(--акцент);
  border-radius: 999px;
}

/* Пока новостей нет вовсе. Общая плашка «пусто» подходит, ей нужен
   только левый край текста как у строк — по центру короткая фраза
   в широком окне выглядит потерянной. */
#лента-событий .таблица__пусто {
  text-align: left;
}

/* ---------- Экран рекордов ----------
   Список самых длинных серий побед. Десять строк должны помещаться
   целиком на обычном телефоне; на маленьком экране список прокручивается,
   а заголовок и кнопка «Назад» остаются на месте. */

#экран-рекордов {
  align-items: center;
  gap: 10px;
  padding: calc(14px + var(--отступ-сверху)) calc(10px + var(--отступ-справа))
           calc(10px + var(--отступ-снизу))  calc(10px + var(--отступ-слева));
}

#экран-рекордов .заголовок { font-size: 28px; }

#лучший-рекорд {
  font-size: 15px;
  font-weight: 600;
  color: var(--текст-тихий);
  text-align: center;
}

.таблица {
  flex: 0 1 auto;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  display: flex;
  flex-direction: column;
  gap: 4px;
  width: min(100%, 420px);
}

/* Строка: место, серия, дата, уровень — в одну линию */
.таблица__строка {
  display: grid;
  grid-template-columns: 1.9em minmax(0, 1fr) auto auto;
  align-items: center;
  gap: 0 10px;
  padding: 7px 10px;
  background: var(--подложка);
  border-radius: 10px;
}

.таблица__место {
  font-size: 14px;
  font-weight: 700;
  color: var(--текст-тихий);
}

.таблица__очки {
  font-size: 15px;
  font-weight: 700;
  color: var(--текст);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.таблица__дата,
.таблица__сложность {
  font-size: 12px;
  color: var(--текст-тихий);
  white-space: nowrap;
}

/* ---------- Строка рекорда: число побед — на своей строке ----------

   Пока подпись была короткой («сложный»), все четыре ячейки стояли
   в одну линию и всё помещалось. Потом к уровню добавился стол
   («сложный · вшестером» — 19 знаков вместо 7), и линия перестала
   влезать. Отъедала место при этом не подпись: она стоит с шириной
   по содержимому и не сжимается, поэтому ужималась соседняя колонка —
   и обрезалось главное. На 390 точках человек видел «12 побед под…»,
   на 280 — «12 по…», то есть ровно то число, ради которого он таблицу
   и открыл.

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

   Все правила нарочно привязаны к #таблица-рекордов: те же классы
   одолжил себе список мест в прихожей (js/сеть.js), а там строки
   короткие и должны остаться в одну линию. */
#таблица-рекордов .таблица__строка {
  /* Место | дата | подпись стола. Число побед ляжет поверх двух
     последних колонок — во всю ширину строки. */
  grid-template-columns: 1.9em auto minmax(0, 1fr);
  /* Просвет между колонками тесный нарочно: дату и подпись стола
     разделяет ещё и точка, а лишние точки ширины на узком телефоне
     дороже — из них складывается буква, которая не уехала на перенос. */
  gap: 1px 6px;
  padding: 6px 10px 7px;
}

#таблица-рекордов .таблица__место {
  grid-area: 1 / 1 / 3 / 2;   /* номер — слева, по центру обеих строчек */
  align-self: center;
  font-variant-numeric: tabular-nums;   /* цифры одной ширины: столбик ровный */
}

#таблица-рекордов .таблица__очки {
  grid-area: 1 / 2 / 2 / 4;
  font-size: 16px;            /* главное в строке — и кегль у него самый крупный */
  line-height: 1.25;
  /* Многоточие здесь запрещено. Места теперь хватает с запасом, но если
     у человека в системе стоит крупный шрифт, пусть строка лучше
     перенесётся на вторую, чем от числа побед останется «12 по…». */
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
}

#таблица-рекордов .таблица__дата {
  grid-area: 2 / 2 / 3 / 3;
  font-variant-numeric: tabular-nums;
}

#таблица-рекордов .таблица__сложность {
  grid-area: 2 / 3 / 3 / 4;
  justify-self: start;
  white-space: normal;        /* длинной подписи разрешено перенестись */
  line-height: 1.25;
}

/* Точка между датой и подписью. Рисуем её оформлением, а не текстом:
   у старых записей подпись пустая, и тогда точка не появляется вовсе. */
#таблица-рекордов .таблица__сложность:not(:empty)::before {
  content: "· ";
  opacity: 0.7;
}

/* Первое место чуть заметнее остальных */
.таблица__строка:first-child {
  box-shadow: inset 0 0 0 2px var(--акцент);
}

.таблица__пусто {
  margin: 0;
  padding: 14px 12px;
  font-size: 14px;
  line-height: 1.4;
  text-align: center;
  color: var(--текст-тихий);
  background: var(--подложка);
  border-radius: 12px;
}

#кнопка-рекорды-назад {
  margin-top: auto;      /* прижата к низу — большой палец достаёт */
  width: min(100%, var(--колонка-кнопок));
}

/* ================================================================
   Экран «Как я играю» — личный счёт игрока

   Читается он сверху вниз и ровно один раз: крупное число — доля
   побед, под ним строка словами, и только потом подробности.
   Из этого выведено всё остальное.

   Главная опасность здесь — превратить экран в отчёт. Отчёт человек
   не читает: он видит сетку одинаковых чисел и уходит. Поэтому
   подробности собраны плитками с крупными названиями, числа при них
   тихие, а разделы отбиты заголовком с чертой — глазу есть за что
   зацепиться, и видно, где кончается одно и начинается другое.
   ================================================================ */

#экран-рейтинга {
  align-items: center;
  gap: 8px;
  padding: calc(14px + var(--отступ-сверху)) calc(10px + var(--отступ-справа))
           calc(10px + var(--отступ-снизу))  calc(10px + var(--отступ-слева));
}

#экран-рейтинга .заголовок { font-size: 26px; }

/* ---------- Крупное число ----------

   Ради него сюда и заходят: «Побед 53%». Рамку даёт общий класс
   «серия» (та же, что у главного числа на плашке итога), здесь только
   размер и поведение длинной строки.

   Размер задан вилкой, а не числом: в этом же месте бывает не число,
   а фраза — «Пока ни одной партии», «Счёт не прочитался», «Минутку…».
   На узком телефоне такая фраза набором в 34 точки заняла бы три
   строки высотой в треть экрана, поэтому кегль сам съезжает к 26.
   Перенос по словам разрешён и уравновешен (text-wrap: balance):
   фраза ложится двумя ровными строчками, а не «длинная плюс одно
   слово-сирота».

   Цифры одной ширины (tabular-nums) — чтобы число не дёргалось,
   когда счёт меняется с 9% на 53%. */
#рейтинг-главное {
  max-width: min(100%, 340px);
  padding: 7px 18px 8px;
  font-size: clamp(26px, 8.4vw, 34px);
  line-height: 1.12;
  text-align: center;
  text-wrap: balance;
  font-variant-numeric: tabular-nums;
}

/* ---------- Строка словами ----------

   «105 из 200 партий · сейчас 2 подряд · лучшая серия 7». Она
   объясняет крупное число, поэтому стоит вплотную под ним и заметно
   тише его.

   Кегль 13,5, а не обычные 15, — ради того, чтобы строка помещалась
   в один ряд. При 14 точках она рвалась пополам, и разрыв приходился
   на середину куска: «105 из 200 партий · сейчас» и ниже «2 подряд ·
   лучшая серия 7». Прочесть такое можно, но спотыкаешься: части
   разделены точками, а перенос делит их не по точкам. */
#рейтинг-подпись {
  max-width: min(100%, 360px);
  margin-top: -2px;
  font-size: 13.5px;
  line-height: 1.4;
  text-align: center;
  text-wrap: balance;
  font-variant-numeric: tabular-nums;
}

/* ---------- Строка сравнения «а как в последнее время» ----------

   Под крупным числом — две отметки: доля побед за последние партии
   (двадцать и пятьдесят; в подписи игра пишет, сколько учтено на самом
   деле). Разметку кладёт js/game.js («нарисоватьДинамику») в блок
   #рейтинг-динамика: плитка «рейтинг__окно» с подписью и числом,
   пометка «--лучше» или «--хуже», если разница с общим счётом заметна.

   Почему отметки стоят здесь, а не строкой в таблице. Общая доля побед
   меняется медленно: человек, который за месяц заметно вырос, в ней
   этого не увидит — сто старых партий перевесят двадцать новых. Ответ
   на вопрос «я стал играть лучше?» даёт только сравнение свежего
   с общим, и стоять оно должно рядом с тем, что сравнивают, — вплотную
   под крупным числом, а не через полэкрана в таблице.

   Отметок ровно две и они мелкие: это уточнение к главному числу,
   а не второе главное число. Кегль числа 15 против 34 у главного —
   разница больше чем вдвое, спутать их нельзя.

   Пустой блок прячем совсем (:empty). Игра опустошает его, когда
   сравнивать нечего — у новичка без партий или когда в журнале не
   больше партий, чем в счёте целиком, — и без этого правила посреди
   экрана висела бы полоса воздуха ни за чем: ровно то, отчего экран
   выглядит недогруженным. Общий класс «скрыт» тоже сработает, если
   игра когда-нибудь повесит его вместо опустошения: :empty перестаёт
   срабатывать от одного пробела внутри, и запасной путь не лишний.

   Отметки заворачиваются на вторую строчку (flex-wrap), если не влезли:
   на 320 точках «последние 20» и «последние 50» рядом уже тесно, а рвать
   надпись переносом внутри плитки нельзя — число оторвётся от подписи. */
#рейтинг-динамика {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
  max-width: min(100%, 360px);
  margin-top: 2px;
}

#рейтинг-динамика:empty { display: none; }

/* Одна отметка: подпись словами и число рядом, в тихой плашке —
   такой же, как у доли побед в строке таблицы. Так глаз сразу видит,
   что это родня: «название и его отметка». */
.рейтинг__окно {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 4px 11px 5px;
  background: var(--подложка);
  border-radius: 999px;
  white-space: nowrap;
}

.рейтинг__окно-подпись {
  font-size: 12px;
  color: var(--текст-тихий);
}

/* Цифры одной ширины: доля за последние партии скачет чаще всех
   остальных чисел на экране, и плитка не должна от этого дёргаться. */
.рейтинг__окно-число {
  font-size: 15px;
  font-weight: 700;
  color: var(--текст);
  font-variant-numeric: tabular-nums;
}

/* Стало лучше или хуже — показываем стрелкой, а не цветом.
   Цвет здесь не годится по двум причинам сразу: зелёное и красное
   должны читаться в обеих темах Telegram (а тема бывает какая угодно),
   и каждый двенадцатый мужчина эти два цвета путает. Стрелка понятна
   всем и в любой теме. Плитке «стало лучше» вдобавок даём ободок
   цветом подсветки — это единственная хорошая новость на экране,
   пусть её замечают. Плохую новость не подсвечиваем нарочно. */
.рейтинг__окно--лучше { box-shadow: inset 0 0 0 1.5px var(--акцент); }
.рейтинг__окно--лучше .рейтинг__окно-число::after { content: "\00a0↑"; }
.рейтинг__окно--хуже  .рейтинг__окно-число::after { content: "\00a0↓"; }

/* Для справки, как выглядит одна плитка в разметке:
     <span class="рейтинг__окно рейтинг__окно--лучше">
       <span class="рейтинг__окно-подпись">последние 20</span>
       <span class="рейтинг__окно-число">60%</span>
     </span>
   Без пометки — когда разница с общим счётом меньше пяти пунктов:
   это шум, а не новость, и стрелки на такой плитке нет. */

/* ---------- Заголовок раздела ----------

   «С кем играли», «Против каких ботов», «За какими столами».
   Тихий и мелкий: он не сообщение, а указатель. Черта под ним
   отделяет разделы друг от друга — без неё три группы плиток
   сливаются в одну длинную простыню. */
.таблица__раздел {
  margin: 12px 0 2px;
  padding: 0 2px 4px;
  font-size: 12.5px;
  font-weight: 700;
  letter-spacing: 0.3px;
  color: var(--текст-тихий);
  border-bottom: 1px solid var(--край);
}

/* Первому разделу верхний отступ не нужен: над ним и так строка
   словами, а лишний просвет отрывает таблицу от неё. */
#таблица-рейтинга .таблица__раздел:first-child { margin-top: 0; }

/* ---------- Строка счёта ----------

   Три ячейки: за что играли, сколько партий, доля побед.

   Ширины двух правых колонок заданы точно, а не «по содержимому», —
   и это главное здесь. Каждая строка таблицы сама себе сетка, между
   собой строки колонками не связаны: у «13 партий» и «128 партий»
   ширина разная, и при колонках «по содержимому» число процентов
   в каждой строке начиналось бы со своего места. Столбик от этого
   пляшет, и сравнить строки глазом нельзя — а таблицу открывают
   ровно затем, чтобы сравнивать.

   Размер шрифта задан самой строке: колонки считаются в em, то есть
   в буквах этого шрифта. Тогда при крупном системном шрифте колонки
   вырастают вместе с цифрами и числа не обрезаются.

   5,4em — это «128 партий» с запасом на пробел, 6,5em — «100% побед»
   вместе с плашкой вокруг доли: сначала под неё было отдано 5,9em,
   и на снимке плашка упиралась в край строки — в колонке надо считать
   не только цифры, но и поля плашки вокруг них. */
#таблица-рейтинга .таблица__строка {
  grid-template-columns: minmax(0, 1fr) 5.4em 6.5em;
  gap: 2px 8px;
  padding: 8px 12px;
  font-size: 12.5px;
}

/* Первая строка на экране рекордов обведена рамкой — там это «первое
   место». Здесь порядок строк ничего не значит (разделы идут подряд),
   и такая рамка обещала бы значение, которого нет. */
#таблица-рейтинга .таблица__строка:first-child { box-shadow: none; }

/* Название — главное в строке, поэтому оно крупнее чисел рядом.
   Многоточие запрещено: длинные названия («вшестером, парами»)
   должны читаться целиком, а не превращаться в «вшестером, па…».
   Не поместилось — пусть перенесётся на вторую строчку. */
#таблица-рейтинга .рейтинг__название {
  font-size: 15px;
  line-height: 1.25;
  white-space: normal;
  overflow: visible;
  text-overflow: clip;
}

/* Сколько партий — самая тихая часть строки: она объясняет, насколько
   доле побед можно верить (4 партии и 128 партий — разный разговор). */
#таблица-рейтинга .рейтинг__партий {
  justify-self: end;
  align-self: center;
  font-size: 12.5px;
  white-space: nowrap;
  color: var(--текст-тихий);
  font-variant-numeric: tabular-nums;
}

/* Доля побед — то, ради чего строку читают. Она в маленькой плашке:
   так строка перестаёт быть строкой отчёта и читается как «название
   и его отметка». Цифры одной ширины — столбик стоит ровно. */
#таблица-рейтинга .рейтинг__доля {
  justify-self: end;
  align-self: center;
  padding: 2px 7px 3px;
  font-size: 12.5px;
  font-weight: 700;
  color: var(--текст);
  white-space: nowrap;
  background: var(--подложка);
  border-radius: 999px;
  font-variant-numeric: tabular-nums;
}

/* ---------- Сноска под таблицей ----------

   «Счёт ведётся с 01.06.2026.» Это приписка, а не сообщение, поэтому
   плашки под ней быть не должно — иначе она весит столько же, сколько
   строки счёта. Узнаём её по соседству: перед ней есть хотя бы одна
   строка счёта, значит это не пустой экран, а подпись под таблицей.

   Вторая строка правила — про человека, который сыграл две-три партии.
   Разрезов у него ещё нет (разрез из одной строки игра не показывает),
   поэтому строк счёта на экране ноль, а абзаца два: «сыграйте против
   другого соперника» и та же приписка с датой. По первому правилу
   приписка не ловилась, и дата вставала в такую же плашку, как
   сообщение над ней, — на снимке 390×844 это выглядело как два
   одинаковых по важности сообщения подряд.

   Отличаем по строке словами под крупным числом. Если счёта нет вовсе,
   игра её прячет («скрыт»), и тогда второй абзац — настоящее сообщение,
   плашку у него забирать нельзя. Если строка на месте, счёт есть,
   и второй абзац — приписка. */
#таблица-рейтинга .таблица__строка ~ .таблица__пусто,
#экран-рейтинга:not(:has(#рейтинг-подпись.скрыт)) #таблица-рейтинга .таблица__пусто + .таблица__пусто {
  padding: 8px 12px 0;
  font-size: 12.5px;
  background: none;
}

/* ---------- Пустой счёт у новичка ----------

   Партий нет ни одной, и на экране вместо чисел два предложения.
   Это самое опасное место экрана: пустая страница читается как
   поломка, а не как «вы ещё не играли».

   Поэтому первая плашка говорит крупнее обычного и над ней стоит
   полоска мастей — та же, что встречает в меню. Она ничего
   не объясняет словами, но делает главное: страница выглядит частью
   игры, а не пустым местом, куда что-то не догрузилось.

   Селектор нарочно узкий: «первая плашка из ровно двух». Ровно два
   абзаца бывают только там, где счёта ещё нет. У сообщения о беде
   с хранилищем и у «Считаем партии…» плашка одна — на них масти
   не попадут: подмигивать посреди неполадки нельзя. */
#таблица-рейтинга .таблица__пусто:first-child:nth-last-child(2) {
  padding-top: 10px;
  font-size: 15px;
  color: var(--текст);
}

/* Полоска мастей — только на странице дурака. Экран «Как я играю»
   общий на весь сборник, и без этой оговорки масти всплывали на
   страницах шашек и нард, где карт нет вовсе. Страницу дурака узнаём
   по витрине (#экран-витрины есть только в index.html) — тем же
   приёмом, что и другие правила этого файла. «:where» не добавляет
   веса: правило остаётся ровно той же силы, что и раньше. */
:where(:root:has(#экран-витрины)) #таблица-рейтинга .таблица__пусто:first-child:nth-last-child(2)::before {
  content: "♠ ♥ ♦ ♣";
  display: block;
  margin-bottom: 8px;
  font-size: 22px;
  letter-spacing: 4px;
  color: var(--текст-тихий);
}

/* Второй абзац — уточнение к первому: он тише и мельче. */
#таблица-рейтинга .таблица__пусто:first-child + .таблица__пусто:last-child {
  margin-top: 6px;
  font-size: 13px;
}

/* Когда строк счёта нет вовсе, текст ставим по середине свободного места,
   а не оставляем прижатым к верху.

   Зачем. На снимке 390×844 два абзаца кончались на трети экрана, и ниже
   до самой кнопки лежало 420 точек пустоты. Такой экран читается как
   недогруженная страница: человек ждёт, что там вот-вот что-то появится.
   Ровно этого мы и не хотим — счёта у новичка нет, и это не поломка,
   а нормальное начало.

   Сделано пустыми полями сверху и снизу, а не выравниванием всего
   столбца: заголовок должен остаться наверху, а кнопка внизу — там, где
   их ищут на всех остальных экранах. Двигается только середина.

   Правило работает во всех трёх случаях без строк: у новичка, при
   «Считаем партии…» и при сообщении о неполадке. Браузер, который
   не знает :has (старее 2023 года), просто оставит текст сверху —
   как было; ничего не сломается. */
#экран-рейтинга:not(:has(.таблица__строка)) #рейтинг-главное {
  margin-top: auto;
}

#таблица-рейтинга:not(:has(.таблица__строка)) {
  margin-bottom: auto;
}

#кнопка-рейтинг-назад {
  margin-top: auto;      /* прижата к низу, как «Назад» на рекордах */
  width: min(100%, var(--колонка-кнопок));
}

/* ---------- «Стереть счёт партий» — с переспросом ----------

   Необратимое действие, поэтому кнопка выглядит «осторожно»: надпись
   и тонкая кайма красноватые, но не чистым красным — чистый красный
   на сукне и в тёмной теме не дотягивает по контрасту, а на весь
   экран кричать здесь нечего. Красный подмешан к цвету текста: в светлой
   теме выходит тёмно-красный, в тёмной и на сукне — розоватый, и читается
   везде. Первая строка каждого правила — для браузеров без color-mix.

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

   Кнопка и вопрос стоят внизу, над «Назад к рекордам»: стирать счёт
   человек приходит редко, и место этому — у края, а не под таблицей.
   Пустое поле поэтому берёт на себя кнопка (или вопрос, когда он
   виден), а «Назад» под ними уже ни к чему тянуться. */
#кнопка-стереть-счёт {
  margin-top: auto;
  color: var(--карта-отказ);
  color: color-mix(in srgb, var(--карта-отказ) 70%, var(--текст));
  background: var(--подложка);
  border: 1px solid var(--край);
  border-color: color-mix(in srgb, var(--карта-отказ) 45%, var(--край));
  box-shadow: none;
}

#вопрос-стирания {
  margin-top: auto;
  max-width: min(100%, 330px);
  font-size: 13px;
  line-height: 1.35;
  text-align: center;
}

/* Пока виден вопрос, пустое поле держит он, а не кнопка, — иначе они
   разъедутся: вопрос под таблицей, кнопка внизу. */
#экран-рейтинга:has(#вопрос-стирания:not(.скрыт)) #кнопка-стереть-счёт {
  margin-top: 0;
}

#кнопка-стереть-счёт.кнопка--стереть-точно {
  font-weight: 700;
  color: var(--текст);
  background: var(--подложка);
  background: color-mix(in srgb, var(--карта-отказ) 18%, var(--подложка));
  border: 2px solid var(--карта-отказ);
}

#экран-рейтинга:has(#кнопка-стереть-счёт:not(.скрыт)) #кнопка-рейтинг-назад {
  margin-top: 0;
}

/* Шторка Telegram открыта не во весь рост. Высота здесь дороже всего:
   в окне 360×600 заголовок с рамкой съедали 110 точек из 600, и до
   таблицы оставалась половина экрана. Ужимаем всё, что над таблицей, —
   тогда в списке видно на две строки больше. Сами строки не трогаем:
   их всё равно читать. */
@media (max-height: 620px) {
  #экран-рейтинга {
    gap: 6px;
    padding: calc(9px + var(--отступ-сверху)) calc(8px + var(--отступ-справа))
             calc(8px + var(--отступ-снизу))  calc(8px + var(--отступ-слева));
  }
  #экран-рейтинга .заголовок { font-size: 21px; }
  #рейтинг-главное { padding: 5px 14px 6px; font-size: clamp(22px, 7vw, 27px); }
  #рейтинг-подпись { font-size: 13px; }
  #рейтинг-динамика { gap: 5px; margin-top: 1px; }
  .рейтинг__окно { padding: 3px 9px 4px; }
  .рейтинг__окно-число { font-size: 14px; }
  .таблица__раздел { margin-top: 9px; }
}

/* Телефон поуже 390 точек. Отдаём названию всё, что можно отобрать
   у чисел: на 360 точках «вшестером, парами» переносилось на вторую
   строчку, а строка счёта должна читаться одним взглядом. Числа
   от этого не страдают — им и так хватало с запасом. */
@media (max-width: 380px) {
  #таблица-рейтинга .таблица__строка {
    grid-template-columns: minmax(0, 1fr) 5em 6.2em;
    gap: 2px 6px;
    padding: 8px 10px;
  }
  #таблица-рейтинга .рейтинг__название { font-size: 14px; }
}

/* ---------- Кнопка «Как играть» в меню ----------

   Пришла она обычной, залитой — то есть ровно такой же, как «Играть».
   В меню от этого стало две главные кнопки подряд, а главная бывает
   одна: взгляд перестаёт понимать, куда его зовут, и палец бьёт наугад
   (тот же разговор, что про «Создать игру» и «Войти по коду» ниже).

   Поэтому здесь рамка вместо заливки — та же, что у «Играть с другом».
   Кнопку по-прежнему прекрасно видно (а новичку она и нужна заметной,
   он за ней сюда и пришёл), но спорить с «Играть» она перестала.
   Серую рамку «Рекордов» ей не даём нарочно: рекорды человек ищет сам,
   когда захочет, а правила должны попасться на глаза тому, кто их
   не искал. */
#кнопка-как-играть {
  color: var(--текст);
  background: var(--подложка);
  border: 2px solid var(--акцент);
  box-shadow: none;
}

/* ---------- Кнопка «Раздача дня» ----------

   Одна и та же раздача всем игрокам в этот день — соревнование,
   а не ещё одна партия. Стоит сразу под «Играть», и спорить с ней
   не должна: «Играть» — главная, залитая. Но и теряться в ряду
   «Как играть / Рекорды / Звук» ей нельзя — те рамочные и тихие.

   Поэтому рамка та же, что у «Как играть» (это тоже вход, а не
   действие в партии), а надпись — цветом подсветки и с искрой «✦»
   впереди: «сегодняшнее, особенное». Цвет подсветки на подложке
   читается в любой теме: это цвет кнопок Telegram, а на своей теме —
   золото на сукне. Так кнопка заметнее рамочных соседей, но не залита,
   как главная. */
.кнопка.кнопка--раздача-дня {
  color: var(--акцент);
  background: var(--подложка);
  border: 2px solid var(--акцент);
  box-shadow: none;
}

.кнопка.кнопка--раздача-дня::before {
  content: "✦ ";
}

/* Сыграли — та же кнопка до полуночи показывает итог: «Сегодня: победа
   за 14 ходов» — и не нажимается. Общий вид выключенной кнопки здесь
   не годится: серая заглушка говорит «нельзя», а сказать надо
   «сделано, вот результат». Поэтому тихая плашка: подложка, тонкая
   серая кайма вместо цветной, надпись обычным цветом текста, галочка
   впереди цветом подсветки. Кегль чуть меньше и перенос разрешён:
   «Сегодня: поражение за 23 хода» длиннее любой кнопки в ряду.
   Три класса в селекторе — чтобы перебить общее правило «:disabled». */
.кнопка.кнопка--раздача-дня.кнопка--раздача-сыграна,
.кнопка.кнопка--раздача-дня.кнопка--раздача-сыграна:disabled {
  padding: 8px 14px;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.25;
  white-space: normal;
  /* Две строки делятся поровну: без этого на 360 точках выходило
     «Сегодня: поражение за 23» и одинокое «хода» строкой ниже. */
  text-wrap: balance;
  color: var(--текст);
  background: var(--подложка);
  border: 1.5px solid var(--край);
  box-shadow: none;
  cursor: default;
}

.кнопка.кнопка--раздача-дня.кнопка--раздача-сыграна::before {
  content: "✓ ";
  color: var(--акцент);
}

/* ================================================================
   ЭКРАН «КАК ИГРАТЬ»

   Шесть коротких правил для того, кто в дурака не играл. Экран собран
   на чужих классах: «таблица» одолжила ему прокрутку, «подпись» —
   текст. Но подпись в игре — это тихая приписка сбоку, а здесь текст
   правил и есть всё, ради чего человек сюда зашёл: читать его будут
   внимательно и целиком. Поэтому внутри «правил» подпись перестаёт
   быть тихой — цвет обычный, кегль крупнее, — и каждое правило лежит
   на своей плашке, такой же, как строка в рекордах. Так видно, где
   кончается одно правило и начинается другое, а экран остаётся одной
   породы с соседними.

   Всё ниже действует только внутри «.правила». Класс «подпись» стоит
   ещё на десятке экранов, и общий его вид не тронут ни на точку.
   ================================================================ */

#экран-правил {
  align-items: center;
  gap: 10px;
  padding: calc(14px + var(--отступ-сверху)) calc(10px + var(--отступ-справа))
           calc(10px + var(--отступ-снизу))  calc(10px + var(--отступ-слева));
}

/* Заголовок как у рекордов: 34 точки на этом экране лишние — под ним
   идёт длинный текст, и крупная шапка отбирает у него строки. */
#экран-правил .заголовок { font-size: 28px; }

.правила {
  gap: 8px;
  text-align: left;
  counter-reset: правило;

  /* Подсказка «здесь есть ещё» — тот же приём, что у списка мест
     в прихожей: у нижнего края лежит тень, а к последнему правилу
     приклеена «крышка» цвета сукна. Пока список прокручен не до конца,
     тень видна; докрутили до низа — крышка её накрыла. Без этого
     на низком экране список выглядит законченным, и человек не узнает,
     что шестое правило — то самое, про подсветку, — осталось внизу.

     Первая строка — для браузеров старше 2023 года, они не знают
     color-mix и возьмут просто цвет темы. Вторая — точный цвет сукна. */
  background:
    linear-gradient(transparent, var(--фон)) bottom / 100% 16px local no-repeat,
    radial-gradient(farthest-side at 50% 100%, rgba(0, 0, 0, 0.42), transparent)
      bottom / 100% 9px scroll no-repeat;
  background:
    linear-gradient(transparent, color-mix(in srgb, var(--фон) 80%, #1f7a45))
      bottom / 100% 16px local no-repeat,
    radial-gradient(farthest-side at 50% 100%, rgba(0, 0, 0, 0.42), transparent)
      bottom / 100% 9px scroll no-repeat;
}

/* Одно правило — одна плашка.

   Про кегль и цвет. Было 15 точек тихим серым — так в игре выглядят
   приписки, которые можно и не читать. Здесь наоборот: это единственное,
   ради чего человек открыл экран. Поэтому цвет обычный, полный, кегль
   15,5 и строки просторнее (1,45) — текст читают подряд, а не выхватывают
   взглядом, и тесные строки в таком чтении сбивают.

   Про номер. Его рисует сам браузер: каждый абзац объявлен пунктом
   списка, а число ему выдаёт счётчик. Своей рукой номера не проставить —
   текст лежит в чужом файле, — зато так сразу видно, что правил шесть
   и сколько ещё осталось прочесть. Счётчик заведён свой, отдельный:
   общий на всю страницу однажды посчитал бы заодно и чужой список
   и начал бы не с единицы.

   Про отступ слева. Поле в 34 точки и отрицательный «text-indent»
   дают висячий номер: цифра стоит слева, а все строки правила —
   ровным столбиком правее неё. Без этого вторая строка заезжала
   бы под номер, и шесть правил читались бы как одна каша. */
.правила .подпись {
  display: list-item;
  list-style: decimal inside;
  counter-increment: правило;
  margin: 0;
  padding: 10px 12px 11px 34px;
  text-indent: -22px;
  font-size: 15.5px;
  line-height: 1.45;
  color: var(--текст);
  background: var(--подложка);
  border-radius: 12px;
}

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

   Про цвет. Чистый цвет подсветки на плашке даёт контраст 4,2 при норме
   4,5 — цифра в полтора десятка точек на грани читаемости. Поэтому к нему
   подмешаны две пятых цвета основного текста: тот по определению хорошо виден
   на своей теме, и подмешивание всегда тянет цифру в сторону читаемости —
   в тёмной теме высветляет, в светлой притемняет. Замерено: 4,6 в тёмной
   теме и 5,7 в светлой, а цвет по-прежнему узнаётся как «тот самый,
   которым игра подсвечивает выбор». Первая строка — запас для браузеров
   без color-mix. */
.правила .подпись::marker {
  content: counter(правило) ".\00a0\00a0";
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  color: var(--акцент);
  color: color-mix(in srgb, var(--акцент) 60%, var(--текст));
}

/* Образцы карт «можно / нельзя» к правилу про подсветку живут теперь
   в разделе «КАК ИГРАТЬ, РЕКОРДЫ, ОФОРМЛЕНИЕ ДУРАКА» в конце файла.
   Раньше они цеплялись к ПОСЛЕДНЕМУ правилу, а правил стало одиннадцать,
   и последнее — про игру парами: карты стояли не под тем текстом. */

/* «Назад» — единственная кнопка экрана, поэтому обычная, залитая,
   и прижата к низу: большой палец достаёт до неё, не перехватывая
   телефон. Ширина как у кнопок меню — во всю ширину экрана кнопка
   выглядела бы полосой, а не кнопкой. */
#кнопка-правила-назад {
  margin-top: auto;
  width: min(100%, var(--колонка-кнопок));
}

/* ================================================================
   ИГРА ВДВОЁМ: код комнаты, ожидание друга и строка связи

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

/* ---------- Обведённые кнопки: «Войти по коду» и соседи ----------
   Правило простое: на одном экране залита одна кнопка — та, ради
   которой на экран пришли. Всё остальное, что тоже нажимается, берёт
   рамку цветом подсветки: видно и понятно, что кнопка, но за внимание
   она не спорит.

   Так разведены «Создать игру» и «Войти по коду» на экране игры вдвоём:
   залита только первая. Две одинаково залитые кнопки подряд читаются
   как одна большая, и палец попадает не туда.

   Кнопки «Играть с другом» здесь больше нет, и это нарочно. На первом
   экране она стоит рядом с «Играть с ботом», и эти двое равны — там
   залиты обе (см. «Две кнопки первого экрана» выше). Единственное место,
   где две залитые кнопки подряд не мешают, — развилка из двух ответов
   на один вопрос.

   «Скопировать код» — из той же породы, что «Войти по коду». Залитая
   кнопка на экране кода перетягивала бы взгляд с самого кода, а он тут
   главный. Рамка вместо заливки: кнопку видно и по ней понятно, что она
   нажимается, но первым в глаза бросается код. */
#кнопка-войти-по-коду,
#кнопка-копировать-код,
/* «Проверить» стоит в самом техническом слое, рядом с «Сохранить адрес».
   Залитыми они выглядели как два одинаково важных действия подряд,
   хотя проверка — это примерка, а сохранение — дело. Оставляем залитым
   только сохранение. */
#кнопка-проверить-адрес {
  color: var(--текст);
  background: var(--подложка);
  border: 2px solid var(--акцент);
  box-shadow: none;
}

/* ---------- Пока висит «играть с другом сейчас нельзя» ----------

   На этом экране две крупные залитые кнопки оказывались рядом:
   «Создать игру» и «Играть с ботом». Обе кричали «нажми меня», причём
   первая только что отказала — и человек не понимал, какая из них
   теперь настоящая.

   Расставляем по правде. Прямо сейчас игра вдвоём не работает, и жать
   «Создать игру» второй раз бессмысленно, пока не включён нужный
   компьютер, — поэтому кнопка становится обведённой, как «Войти
   по коду»: место, размер и нажимаемость те же, громкость меньше.
   Залитой остаётся одна кнопка на экране — «Играть с ботом», то есть
   ровно то, что сейчас действительно можно сделать.

   Это не запрет: человек, который сам запускает сервер, включит его
   и нажмёт «Создать игру» снова — кнопка на месте и работает. Как
   только беда уходит с экрана, кнопка снова заливается.

   Правило держится на соседстве: «:has» смотрит, висит ли на экране
   блок беды. Браузеры старше 2023 года «:has» не знают — у них
   останется прежний вид с двумя залитыми кнопками, то есть ровно то,
   что было до этой правки, и ничего не ломается. */
#экран-друга:has(#нет-сервера-главное:not(.скрыт)) #кнопка-создать-игру {
  color: var(--текст);
  background: var(--подложка);
  border: 2px solid var(--акцент);
  box-shadow: none;
}

/* ---------- «Вернуться к игре с другом» ----------

   Кнопка появляется вверху экрана, когда партия по сети осталась
   недоигранной. Своего вида у неё не было вовсе — класс «кнопка--возврат»
   стоял в разметке как зацепка для оформления и ни на что не влиял, —
   и она выходила обычной залитой кнопкой, в точности как «Создать игру»
   двумя строками ниже. Две одинаковые залитые кнопки на одном экране,
   и одна из них начинает НОВУЮ игру вместо брошенной: спутать их —
   значит потерять партию, в которой тебя ждут живые люди.

   Поэтому здесь она главная и по виду тоже: чуть выше и заметнее
   соседей, с круговой стрелкой впереди — тем же знаком, каким на итоге
   помечен «Собрать стол заново». Стрелка в этой игре значит «то же
   самое, только вернуться», и значит она это везде одинаково.

   Высота не задана намертво, только наименьшая: подпись длинная,
   на узком телефоне встаёт в две строки — кнопка от этого просто
   вырастет, а не обрежет буквы. */
#кнопка-вернуться-в-игру.кнопка--возврат {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 56px;
  font-size: 19px;
  line-height: 1.2;
}

#кнопка-вернуться-в-игру.кнопка--возврат::before {
  content: "↻";
  font-size: 20px;
  line-height: 1;
}

/* А «Создать игру» на это время уступает: пока брошенная партия жива,
   главное действие экрана — вернуться в неё, а не начать ещё одну.
   Кнопка остаётся на месте и работает — она только тише.
   Старый браузер без «:has» покажет обе залитыми, как было раньше. */
#экран-друга:has(#кнопка-вернуться-в-игру:not(.скрыт)) #кнопка-создать-игру {
  color: var(--текст);
  background: var(--подложка);
  border: 2px solid var(--акцент);
  box-shadow: none;
}

/* ---------- Три экрана игры вдвоём ----------
   Выбор «создать или войти», код комнаты и ввод кода устроены
   одинаково: содержимое стоит столбиком по центру экрана, кнопки
   одной ширины с кнопками меню. */

#экран-друга,
#экран-комнаты,
#экран-входа {
  align-items: center;
  gap: 14px;
  padding: calc(16px + var(--отступ-сверху)) calc(12px + var(--отступ-справа))
           calc(16px + var(--отступ-снизу))  calc(12px + var(--отступ-слева));
  text-align: center;
  /* Длинное объяснение (например, про http и https) на маленьком
     экране не помещается — тогда столбик прокручивается.
     Вбок не прокручивается никогда. */
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* Центрируем столбик пустыми полями сверху и снизу, а не привычным
   justify-content: center. Разница видна, когда содержимое выше
   экрана: justify-content срезал бы заголовок сверху и до него было
   бы уже не докрутить, а пустые поля в этом случае просто сжимаются
   до нуля, и виден весь текст. */
#экран-друга    > :first-child,
#экран-комнаты  > :first-child,
#экран-входа    > :first-child { margin-top: auto; }

#экран-друга    > :last-child,
#экран-комнаты  > :last-child,
#экран-входа    > :last-child { margin-bottom: auto; }

#экран-друга   .заголовок,
#экран-комнаты .заголовок,
#экран-входа   .заголовок { font-size: 28px; }

#экран-друга   > .подпись,
#экран-комнаты > .подпись,
#экран-входа   > .подпись {
  max-width: 330px;
  line-height: 1.35;
}

#экран-друга   .кнопка,
#экран-комнаты .кнопка,
#экран-входа   .кнопка { width: min(100%, var(--колонка-кнопок)); }

/* «Назад» и «Отменить игру» — уводящие кнопки, поэтому они мельче
   и тусклее. Но по высоте всё равно 44 точки: мимо пальцем не
   промахнуться, места на этих экранах хватает. */
#экран-друга   .кнопка.кнопка--мелкая,
#экран-комнаты .кнопка.кнопка--мелкая,
#экран-входа   .кнопка.кнопка--мелкая {
  width: auto;
  min-width: 150px;
  min-height: 44px;
  margin-top: 2px;
}

/* ---------- Две мелкие кнопки внизу комнаты — в один ряд ----------

   Внизу комнаты стоят «Как играть» и «Отменить игру», обёрнутые
   в «кнопки-комнаты». Пока обёртки не было и они были двумя
   отдельными детьми столбика, они вставали одна под другой и съедали
   97 точек (44 + 9 + 44). На снимке 320×568 у хозяина стола ровно
   на столько ужимался список мест: из шести строк видно три, остальное
   прокруткой. Это то самое место, которое отвоёвывали под список.

   В один ряд две кнопки занимают 44, и списку возвращаются полторы
   строки (на снимке 320×568 список вырос со 106 до 159 точек, видно
   пять мест из шести). В столбике два соседних элемента в ряд
   не поставить честно — потому и обёртка.

   Хак с отрицательным полем (вторую кнопку подтянуть на высоту первой
   и развести их по краям) нарочно не взят: он держится на том, что
   обе кнопки ровно 44 точки ростом, а при крупном системном шрифте
   «Отменить игру» переносится в две строки — и ряд разъезжается.

   Ширина у кнопок своя, не половина ряда: «Как играть» и «Отменить
   игру» разной длины, и растянутые до равной ширины они выглядели бы
   одной плашкой с чертой. На 320 точках ряд — 130 + 8 + 130 = 268
   из 300 доступных. У́же 280 точек ряд переносится сам (flex-wrap),
   и это не поломка: кнопки просто встанут как сейчас. */
.кнопки-комнаты {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  width: 100%;
  margin-top: 2px;
}

#экран-комнаты .кнопки-комнаты .кнопка.кнопка--мелкая {
  flex: 0 1 auto;
  margin-top: 0;
}

/* ---------- Знакомые: с кем уже играли и кто сейчас за столом ----------

   Блок стоит на экране «Игра с другом» под «Войти по коду». Открывают
   его ради одного: увидеть, кто из знакомых играет прямо сейчас, —
   к нему и можно зайти. Поэтому играющие сверху (их так ставит игра)
   и помечены так, чтобы читаться с первого взгляда, а остальные тише.

   Блок обведён тонкой рамкой и стоит одним куском: без неё заголовок
   «С кем вы играли», строки и подпись расползались по столбику экрана
   между кнопками и сноской и читались как три разные вещи. */
.знакомые {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
  width: min(100%, 360px);
  padding: 8px 8px 9px;
  border: 1px solid var(--край);
  border-radius: 14px;
  text-align: left;
}

/* Заголовок раздела здесь первый в рамке — верхний отступ ему не нужен. */
.знакомые .таблица__раздел { margin-top: 0; }

.знакомые .таблица {
  width: 100%;
  gap: 4px;
}

/* Строка: метка · имя · «сейчас за столом». Четвёртая ячейка приходит
   пустой (она нужна сетке таблицы рекордов) — прячем, иначе сетка
   отведёт ей колонку и просвет. Три колонки: узкая под точку, имя
   во всю ширину, пометка по содержимому. */
.знакомые .таблица__строка {
  grid-template-columns: 1.1em minmax(0, 1fr) auto;
  gap: 0 8px;
  padding: 7px 10px;
  border: 1px solid transparent;
  text-align: left;
}

.знакомые .таблица__строка .таблица__сложность:empty { display: none; }

/* Рамка чемпиона у первой строки здесь не про то: первый в списке —
   не лучший, а просто играющий сейчас, и у него своя пометка. */
.знакомые .таблица__строка:first-child { box-shadow: none; }

.знакомые__имя {
  font-size: 15px;
  text-align: left;
}

/* Кто не за столом — тише: имя обычным весом и приглушённым цветом.
   Так играющие выделяются не только пометкой, но и самим именем. */
.знакомые__строка:not(.знакомые__строка--за-столом) .знакомые__имя {
  font-weight: 600;
  color: var(--текст-тихий);
}

/* ---------- Сейчас за столом ----------

   Три отличия разом, каждое работает на своём расстоянии:
     • строка обведена цветом подсветки и чуть подкрашена — та же
       краска, что у «это вы» в прихожей: «здесь кто-то живой»;
     • слева зелёная точка — та зелень, которой в игре помечено
       «можно ходить»; её видно боковым зрением раньше слов;
     • справа пометка словами в плашке цвета кнопки Telegram: белым
       по цвету темы, как кнопка, — читается в любой теме и с первого
       взгляда, потому что это единственное залитое пятно в блоке. */
.знакомые__строка--за-столом {
  border-color: var(--акцент);
  background: color-mix(in srgb, var(--акцент) 16%, var(--подложка));
}

.знакомые__метка {
  font-size: 18px;
  line-height: 1;
  color: var(--карта-можно);
  text-align: center;
}

.знакомые__где {
  padding: 2px 9px 3px;
  font-size: 11px;
  font-weight: 700;
  line-height: 1.3;
  white-space: nowrap;
  color: var(--кнопка-текст);
  background: var(--кнопка-фон);
  border-radius: 999px;
}

/* У того, кто не за столом, пометка пустая — плашки быть не должно. */
.знакомые__где:empty { display: none; }

/* «Пока никого» у новичка и «Минутку…» — общая плашка «пусто»:
   тихая, с подложкой, читается как объяснение, а не как ошибка.
   Здесь только кегль поменьше: блок второстепенный. */
.знакомые .таблица__пусто {
  padding: 10px 12px;
  font-size: 13.5px;
}

/* Подпись под списком — сноска: «Видно только тех, кто сейчас играет
   на этом сервере». */
#знакомые-подпись {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.35;
  text-align: center;
}

/* Причина, почему список не свежий: «Сервер игры не ответил. Кто из
   знакомых сейчас за столом — неизвестно». Игра ставит её своим узлом
   перед общей подписью. Заметно, но не тревожно: своя строка, обычный
   цвет текста и вес 600 против тихой сноски — глаз её не пропустит;
   а красного и восклицаний нет — это не поломка, список просто старый. */
.знакомые__причина {
  display: block;
  margin-bottom: 3px;
  font-weight: 600;
  color: var(--текст);
}

/* ---------- Код комнаты — главный предмет этого экрана ----------

   Почему плашка белая в любой теме. Ровно по той же причине, по
   которой в игре белые карты: чёрное на белом читается лучше всего
   и не зависит от того, какие цвета пришлют из Telegram. Код здесь
   не «текст на странице», а вещь, которую переписывают на бумажку
   и диктуют вслух, — ему нужна максимальная разборчивость.

   Шрифт моноширинный: в нём у знаков одинаковая ширина и более
   строгое начертание, поэтому «S» не путается с «5», а «Q» — с «G».
   Сами похожие знаки из кода убраны на сервере (нет нуля и буквы O,
   нет единицы, I и L), шрифт добивает остальное.

   Просветы между знаками (letter-spacing) нужны, чтобы четыре знака
   читались как четыре отдельных, а не как слово. Просвет добавляется
   и после последнего знака, из-за чего строка кажется сдвинутой
   влево, — text-indent ровно на ту же величину возвращает её
   на середину. */

.код-игры {
  max-width: 100%;
  padding: 10px 16px;
  /* Только системные шрифты: ничего не скачивается, работает без сети */
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
               "Liberation Mono", "Courier New", monospace;
  /* Кегль растёт вместе с экраном: на узком телефоне 42–53 точки,
     на обычном около 74. Больше 76 не даём — на широком экране
     код и так виден с вытянутой руки. */
  font-size: clamp(42px, 19vw, 76px);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: 0.16em;
  text-indent: 0.16em;
  text-align: center;
  /* Перенос нарочно не запрещаем: код всегда из четырёх знаков и в
     строку помещается с запасом, но если он когда-нибудь станет
     длиннее, плашка перенесёт его на две строки, а не вылезет
     за край экрана. */
  color: var(--карта-текст);
  background: var(--карта-фон);
  border: 3px solid var(--акцент);
  border-radius: 16px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.38);
  /* По всей игре выделение текста выключено, чтобы карты не
     подсвечивались при долгом нажатии. Коду выделение возвращаем:
     его удобно скопировать и переслать другу сообщением. */
  -webkit-user-select: text;
  user-select: text;
}

/* Кода ещё нет — плашка стоит пустая, с точками. Точки нарочно бледные
   (контраст около 2 к белой плашке), рамка серая вместо цветной, тени
   нет: видно, что это не значение, а место под него, и диктовать пока
   нечего. Как только код приходит, игра снимает этот класс, и плашка
   загорается в полную силу — сама эта перемена и говорит «код готов».
   Читаемость тут нарочно ниже нормы: норма — про текст, который надо
   прочитать, а эти точки читать не нужно и нельзя. */
.код-игры--ждём {
  color: #aab3bd;
  border-color: var(--карта-край);
  box-shadow: none;
}

/* ---------- «Ждём, когда друг войдёт…» ----------
   К словам добавлено вращающееся колечко: без него непонятно,
   ждёт игра чего-то или просто зависла.

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

.сеть-ожидание {
  max-width: 330px;
  margin: 0;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.35;
  text-align: center;
  color: var(--текст);
}

.сеть-ожидание::before {
  content: "";
  display: inline-block;
  /* Чуть ниже базовой линии — так кружок приходится ровно на высоту
     заглавной буквы и не «висит» над строкой. */
  vertical-align: -3px;
  width: 16px;
  height: 16px;
  margin-right: 8px;
  border: 3px solid var(--край);
  border-top-color: var(--акцент);
  border-radius: 50%;
  animation: колечко-ожидания 1.1s linear infinite;
}

@keyframes колечко-ожидания {
  to { transform: rotate(360deg); }
}

/* ---------- Объяснения и ошибки ----------
   Сюда попадают длинные человеческие тексты: сервер не отвечает,
   адрес не подходит, игру уже начали без вас. Бывает до четырёх
   строк, поэтому текст выровнен по левому краю — так его читать
   легче, чем «ёлочкой» по центру, — и лежит на плашке с цветной
   полосой слева: сразу видно, где кончается обычная подпись
   и начинается сообщение игры. */

.сеть-сообщение {
  width: min(100%, 330px);
  margin: 0;
  padding: 10px 12px;
  font-size: 14px;
  line-height: 1.4;
  text-align: left;
  /* В этих сообщениях игра называет адрес сервера целиком, а адрес —
     это одно длинное слово без пробелов. Обычные правила переноса
     такое слово не разрывают: оно вылезло бы за плашку и утащило
     за собой весь экран вбок. Разрешаем перенести его в любом месте —
     лучше адрес в две строки, чем прокрутка вбок. */
  overflow-wrap: anywhere;
  /* Цвет обычного текста на серой подложке: оба берутся из одной
     пары «фон — текст», поэтому читаются и в светлой теме,
     и в тёмной. Смешивать цвет текста с цветом кнопки нельзя —
     на этом в игре уже обжигались. */
  color: var(--текст);
  background: var(--подложка);
  border-left: 4px solid var(--акцент);
  border-radius: 4px 10px 10px 4px;
}

/* ---------- Поле ввода кода ----------
   Кегль 34 точки — и потому, что код должен читаться при наборе,
   и потому, что iPhone сам увеличивает страницу, когда трогаешь
   поле мельче 16 точек: вёрстка после этого уезжает вбок.
   Поле нарочно повторяет вид плашки с кодом: человек видит, что
   вводит ровно то же, что ему продиктовали. */

.поле-кода {
  width: min(100%, var(--колонка-кнопок));
  min-height: 62px;
  padding: 6px 10px;
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
               "Liberation Mono", "Courier New", monospace;
  font-size: 34px;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0.16em;
  text-indent: 0.16em;
  text-align: center;
  text-transform: uppercase;
  color: var(--карта-текст);
  background: var(--карта-фон);
  border: 2px solid var(--карта-край);
  border-radius: 12px;
  caret-color: var(--карта-текст);
  -webkit-appearance: none;
  appearance: none;
  /* Обязательно: по всей игре выделение текста выключено, а без
     разрешения на выделение поле ввода на iPhone не даёт печатать. */
  -webkit-user-select: text;
  user-select: text;
}

.поле-кода::placeholder {
  font-weight: 400;
  /* Серый, но не бледный: контраст на белом поле 4,9 — подсказку
     видно, и при этом её не спутаешь с набранным кодом (он жирный
     и чёрный). Строка opacity нужна Firefox: он сам делает
     подсказку полупрозрачной. */
  color: #6b7480;
  opacity: 1;
}

.поле-кода:focus {
  outline: 3px solid var(--акцент);
  outline-offset: 2px;
  border-color: transparent;
}

/* ---------- Поле для адреса сервера ----------

   ЖАЛОБА ЖИВОГО ИГРОКА: «вылезло поле, в котором огромными буквами
   видно только "HTTP://127", остальное не помещается».

   Отчего так вышло. Поле адреса и поле кода — это один и тот же вид
   в разметке: у поля адреса стоят оба класса. Для кода из четырёх
   знаков всё правильно: 34 точки, заглавные, вразрядку, по центру —
   код диктуют вслух и переписывают на бумажку. Но адрес сервера
   не диктуют, а вставляют или правят, и он длинный: в
   «https://johnny-dense-shield.trycloudflare.com» сорок пять знаков.
   При кегле 34 с разрядкой в поле помещалось десять — то есть человек
   не видел даже, тот это адрес или чужой.

   Что делаем. Адрес — обычная строчка, поэтому: кегль 16 вместо 34,
   без заглавных, без разрядки, по левому краю. Теперь на телефоне
   в 390 точек видно больше тридцати знаков вместо десяти, на 320 —
   около тридцати: имя сервера читается целиком, и понятно, что за
   адрес в поле стоит.

   Кегль ровно 16 и ни точкой меньше — это не вкусовщина. iPhone сам
   увеличивает всю страницу, стоит тронуть поле с подписью мельче 16,
   и после этого вёрстка уезжает вбок. Про это уже написано у поля
   кода выше, и для адреса правило то же.

   Целиком длинный адрес в строку не влезет ни при каком кегле —
   поэтому в конце строки стоит многоточие: видно, что адрес
   продолжается, а не оборвался. Когда в поле печатают, строка едет
   сама и виден хвост — как в любом поле ввода.

   ПОЧЕМУ СЕЛЕКТОР С «input». Ниже, в правилах для низкого и узкого
   экрана, поле кода ужимается до 30 точек — и эти правила стоят
   в файле позже. Обычный класс они бы перебили, и на маленьком
   телефоне адрес снова стал бы огромным. Имя элемента в селекторе
   делает это правило тяжелее, и оно побеждает везде.

   Всё остальное — белая бумага, рамка, свечение при наборе,
   разрешение печатать на iPhone — берётся у «поле-кода»: оба класса
   на поле стоят нарочно, и второй раз то же самое не пишем. */

input.поле-адреса {
  /* Та же ширина, что у объяснений на этом экране, — поле встаёт
     с ними в один столбик, а не выпирает из него. */
  width: min(100%, 330px);
  min-height: 46px;          /* палец попадает: столько же, сколько у кнопки */
  padding: 9px 12px;
  font-size: 16px;
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: normal;
  text-indent: 0;
  text-align: left;
  text-transform: none;
  /* Что не поместилось — многоточием. Пока в поле не печатают, браузер
     показывает его сам, и обрыв адреса не выглядит опечаткой. */
  text-overflow: ellipsis;
  border-radius: 10px;
}

/* ---------- Строка связи над столом ----------

   Одна полоска отвечает на вопрос «а друг вообще там?». У неё три
   состояния, и они должны различаться до чтения текста:

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

   Красное от янтарного отличается цветом, но на цвет полагаться
   нельзя: каждый двенадцатый мужчина путает красное с зелёным.
   Поэтому у тревоги ещё и другая фигура — треугольник вместо
   кружка, — и она видна даже на чёрно-белом экране.

   Высота у полоски постоянная, на две строки текста: длинное
   сообщение о потерянной связи в одну строку не помещается,
   а прыгающая полоска сдвигала бы стол под руками у игрока. */

.связь {
  flex: 0 0 auto;
  align-self: center;
  display: flex;
  align-items: center;
  justify-content: center;
  max-width: 100%;
  height: 34px;
  padding: 0 12px;
  font-size: 13px;
  font-weight: 700;
  line-height: 1.2;
  text-align: center;
  color: var(--текст);
  background: var(--подложка);
  border-radius: 10px;
  overflow: hidden;
}

.связь::before {
  content: "";
  flex: 0 0 auto;
  width: 10px;
  height: 10px;
  margin-right: 8px;
  border-radius: 50%;
  /* Тот же зелёный, что у карты, которой можно ходить: в этой игре
     зелёный везде значит «всё в порядке». */
  background: var(--карта-можно);
}

/* Ожидание: плашка темнеет, кайма и точка янтарные. Свои цвета,
   не из темы: «ждём» должно выглядеть одинаково при любой теме.
   Первая строка фона — для браузеров без color-mix. */
.связь.связь--ожидание {
  color: #ffffff;
  background: rgba(20, 24, 30, 0.88);
  background: color-mix(in srgb, #f0b32d 20%, #10151b);
  box-shadow: inset 0 0 0 2px #f0b32d;
}

.связь--ожидание::before {
  background: #f0b32d;
  animation: связь-дышит 1.4s ease-in-out infinite;
}

/* Тревога: красная плашка и мигающий треугольник. Белый текст
   на этом красном даёт контраст 8,2 — читается при любой теме. */
.связь.связь--тревога {
  color: #ffffff;
  background: rgba(155, 26, 40, 0.94);
  background: color-mix(in srgb, var(--карта-отказ) 62%, #2a0409);
  box-shadow: inset 0 0 0 2px var(--карта-отказ);
}

/* Треугольник нарисован рамками — картинок в проекте нет */
.связь--тревога::before {
  width: 0;
  height: 0;
  border-radius: 0;
  background: transparent;
  border-left: 6px solid transparent;
  border-right: 6px solid transparent;
  border-bottom: 11px solid #ffffff;
  animation: связь-мигает 1.3s ease-in-out infinite;
}

@keyframes связь-дышит {
  0%, 100% { transform: scale(1);    opacity: 1; }
  50%      { transform: scale(0.55); opacity: 0.45; }
}

@keyframes связь-мигает {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.3; }
}

/* Если в телефоне выключены анимации, всё остаётся на месте:
   состояния и без движения различаются цветом и фигурой. */
@media (prefers-reduced-motion: reduce) {
  .сеть-ожидание::before,
  .связь--ожидание::before,
  .связь--тревога::before {
    animation: none;
  }
}

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

/* ================================================================
   ИГРА КОМПАНИЕЙ: выбор стола, прихожая и полоса соперников

   За столом бывает до шести человек, и главный вопрос игрока
   в компании всегда один и тот же: «а что сейчас происходит?».
   Поэтому всё в этом разделе подчинено трём ответам, которые
   должны читаться без чтения — одним взглядом на верх экрана:

     чей сейчас ход   — плашка соперника залита цветом, как
                        нажатая кнопка: она одна такая на полосе;
     кто отбивается   — плашка обведена той же краской, но
                        не залита, и слово состояния лежит
                        на цветной подложке с колечком-щитом;
     кто мой напарник — белая полоска у левого края плашки
                        и белый значок «напарник».

   Всё остальное — «выбыл», «ушёл», «нет связи» — нарочно тише:
   это справка, а не событие. Тише они не цветом (цвет пришлёт
   Telegram, и какой он будет — неизвестно), а отсутствием
   заливки: у выбывшего плашка пустая, с пунктирной каймой.
   ================================================================ */

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

.настройка-стола {
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Девять точек, а не двенадцать: три ряда настроек стоят на самом
     длинном экране игры («Игра с ботом»), и в полном экране Telegram
     каждые сэкономленные три точки — это часть последней кнопки,
     которая иначе уходит под полосу жеста. */
  gap: 9px;
  width: 100%;
}

/* Ряд «2 3 4 5 6» — пять кнопок вместо привычных трёх. Кнопка выбора
   и так делит ширину поровну, но подпись у неё рассчитана на слово;
   здесь это одна цифра, поэтому боковые поля убираем, а саму цифру
   делаем крупнее — по ней целится палец, и её же читают глазами.
   Ширина одной кнопки выходит около 47 точек при высоте 44 — палец
   попадает свободно.

   Ряд — на экране «Игра с другом» («#выбор-мест»). Второй такой ряд
   был в старом меню дурака; меню убрано, правило осталось одно. */
#выбор-мест .кнопка.кнопка--выбор {
  padding: 8px 2px;
  font-size: 18px;
  font-variant-numeric: tabular-nums;
}

/* Строка «что получится при таком выборе». Место под неё отложено
   заранее: без этого кнопки прыгали вверх-вниз каждый раз, когда
   текст менялся с одной строки на три, и палец промахивался.
   Отложено четыре строки — столько занимает почти любой ответ.
   Самое длинное объяснение (парами и переводной разом) всё-таки
   длиннее и растянет плашку: обрезать его нельзя — это как раз
   те правила, ради которых человек сюда и смотрит.

   Строка — на экране «Игра с другом». */
#пояснение-стола {
  box-sizing: border-box;
  width: min(100%, 340px);
  /* Резерв под самое длинное пояснение — три строки: при кегле 13,5
     и междустрочии 1,35 это 55 точек, плюс поля 16. Кнопки от смены
     текста не прыгают: резерв держит самый длинный вариант. */
  min-height: 70px;
  margin: 0;
  padding: 8px 11px;
  font-size: 13.5px;
  line-height: 1.35;
  text-align: left;
  color: var(--текст-тихий);
  background: var(--подложка);
  border-radius: 10px;
}

/* ---------- Прихожая: кто уже сел за стол ----------
   Появляется на экране кода, под самим кодом. Обведена рамкой,
   чтобы список мест не сливался с кодом и кнопкой копирования:
   это отдельный разговор — «кто собрался», а не «какой у нас код». */

.прихожая {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  width: 100%;
  max-width: 360px;
  padding: 10px 9px 11px;
  border: 1px solid var(--край);
  border-radius: 14px;
  /* Разрешаем прихожей сжиматься. Без этой строчки блок упирается
     в высоту своего содержимого и растёт вниз, сколько бы мест
     за столом ни было, — а вместе с ним уезжают за край экрана
     кнопки «Начать игру» и «Отменить игру», которые стоят ниже.
     Ужимается при этом только список мест (см. ниже): он длинный,
     но однообразный, и человеку достаточно видеть его часть.
     У кнопок такого запаса нет — их либо видно, либо нет. */
  min-height: 0;
}

/* Какой получился стол: «Играют шестеро, каждый сам за себя».
   Это заголовок прихожей, а не подпись, поэтому цвет обычный,
   не приглушённый: по этой строке человек проверяет, что создал
   именно то, что хотел. */
#прихожая-правила {
  margin: 0;
  font-size: 14px;
  font-weight: 700;
  line-height: 1.3;
  text-align: center;
  color: var(--текст);
}

/* ---------- Список мест ----------
   Раскладку строке даёт таблица рекордов, но список мест — не
   таблица достижений, и три её привычки здесь мешают:
   строки в нём читают слева направо (а не по центру), первое место
   ничем не лучше прочих, и на узком экране колонки не должны
   переезжать на вторую строку — тут они и так короткие. */

.список-мест {
  gap: 5px;
  width: 100%;
  /* Прокручиваться список уже умеет — это ему досталось от таблицы
     рекордов. Здесь только пол: ужать список меньше чем до двух
     строк нельзя, иначе от него не останется смысла. Если и после
     этого содержимое не помещается (совсем низкое окно), прокрутится
     весь экран, как и раньше. */
  min-height: 74px;

  /* Подсказка «здесь есть ещё»: у нижнего края списка лежит тень,
     а к последней строке приклеена «крышка» цвета сукна. Пока список
     прокручен не до конца, тень видна; докрутили до низа — крышка
     наезжает на тень и та пропадает. Это и есть ответ на находку
     тестировщика: прокрутка была, но выглядел список законченным,
     и человек не догадывался, что под ним есть ещё места.

     Первая строка — для браузеров старше 2023 года, которые не знают
     color-mix: крышка там просто цвета темы, чуть отличного от сукна.
     Вторая — точный цвет сукна, тот же, что у поля игры. */
  background:
    linear-gradient(transparent, var(--фон)) bottom / 100% 14px local no-repeat,
    radial-gradient(farthest-side at 50% 100%, rgba(0, 0, 0, 0.42), transparent)
      bottom / 100% 9px scroll no-repeat;
  background:
    linear-gradient(transparent, color-mix(in srgb, var(--фон) 80%, #1f7a45))
      bottom / 100% 14px local no-repeat,
    radial-gradient(farthest-side at 50% 100%, rgba(0, 0, 0, 0.42), transparent)
      bottom / 100% 9px scroll no-repeat;
}

.список-мест .место-за-столом {
  grid-template-columns: 1.6em minmax(0, 1fr) auto auto;
  gap: 0 8px;
  padding: 7px 9px;
  border: 1px solid transparent;
  text-align: left;
}

/* Отменяем переезд колонок на вторую строку, который таблица
   рекордов включает на узком экране: здесь всё влезает в строку. */
.список-мест .место-за-столом__номер,
.список-мест .место-за-столом__имя,
.список-мест .место-за-столом__роль,
.список-мест .место-за-столом__связь {
  grid-area: auto;
}

.список-мест .место-за-столом__номер {
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}

.список-мест .место-за-столом__имя {
  font-size: 14px;
  text-align: left;
}

/* «хозяин», «бот» — кто это за столом; «на связи», «ждём» — как у него
   дела. Обе подписи мелкие и тихие: главное в строке — имя. */
.список-мест .место-за-столом__роль,
.список-мест .место-за-столом__связь {
  font-size: 11.5px;
  text-align: right;
}

/* Первую строку таблица рекордов обводит как чемпиона. В прихожей
   обводкой отмечено другое — «это вы»: своё место человек должен
   находить мгновенно, и оно далеко не всегда первое. */
.список-мест .место-за-столом:first-child {
  box-shadow: none;
}

.список-мест .место-за-столом--я {
  box-shadow: none;
  border-color: var(--акцент);
  background: color-mix(in srgb, var(--акцент) 16%, var(--подложка));
}

/* Свободное место — это дырка в столе, а не игрок. Поэтому заливки
   у него нет вовсе, кайма пунктирная, а подпись обычного веса:
   строка видна, но взгляд по ней скользит мимо. */
.список-мест .место-за-столом--пусто {
  background: transparent;
  border-style: dashed;
  border-color: var(--край);
}

.список-мест .место-за-столом--пусто .место-за-столом__имя {
  font-weight: 600;
  color: var(--текст-тихий);
}

/* ---------- Кто с кем в паре ----------

   За парным столом рядом с именем стоит подпись «пара 1» или «пара 2».
   Одной подписи мало: чтобы увидеть, кто с кем играет, человеку
   пришлось бы прочитать все четыре строки и сложить их в голове.
   Поэтому у строки появляется ещё и полоса у левого края — глаз
   находит две пары сразу, не читая.

   Полосы РАЗНЫЕ НЕ ЦВЕТОМ, а рисунком: у первой пары она сплошная,
   у второй — из штрихов. Так сделано по двум причинам. Цвет пришлось
   бы выдумывать свой (тема Telegram присылает один акцент, и он уже
   занят пометкой «это вы»), а главное — каждый двенадцатый мужчина
   путает цвета, и для него две цветные полосы были бы одинаковыми.
   Сплошную и штриховую не спутать никому и ни в какой теме.

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

.список-мест .место-за-столом--пара-1,
.список-мест .место-за-столом--пара-2 {
  position: relative;
}

.список-мест .место-за-столом--пара-1::before,
.список-мест .место-за-столом--пара-2::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 5px;
  border-radius: 10px 0 0 10px;
  background: var(--текст);
}

/* Вторая пара — та же полоса, но из штрихов: четыре точки краски,
   четыре пустых. */
.список-мест .место-за-столом--пара-2::before {
  background: repeating-linear-gradient(
    var(--текст) 0 4px, transparent 4px 8px);
}

/* Сама подпись «пара 1» — тихая: она подтверждает полосу словами,
   а не спорит с именем. Стоит внутри ячейки имени, поэтому кегль
   задан долей от него. */
.список-мест .место-за-столом__пара {
  margin-left: 4px;
  padding: 1px 5px;
  font-size: 0.8em;
  font-weight: 700;
  white-space: nowrap;
  color: inherit;
  background: rgba(128, 128, 128, 0.3);
  background: color-mix(in srgb, currentColor 16%, transparent);
  border-radius: 6px;
}

/* ---------- Места, которые можно поменять местами ----------

   Хозяин стола нажимает на два места по очереди, и игроки меняются.
   Отсюда два требования, и оба про «понятно, что нажалось»:

   1) видно, что строка вообще нажимается. У хозяина строка чуть выше
      обычной и отзывается на нажатие; у остальных игроков она
      не меняется вовсе — обещать нажатие, которого не будет, нельзя;

   2) видно, какое место выбрано первым. Пока второе не нажато, игра
      ждёт, и человек должен понимать, что первое нажатие засчиталось.

   Выбранное место помечено не так, как «это вы»: там кайма цвета
   акцента и лёгкая заливка, а тут — толстая рамка внутрь, крупная
   заливка и номер, вывернутый наизнанку (белая цифра на цветном
   кружке). Эти две пометки могут стоять на одной строке разом
   (хозяин выбирает своё же место), и различить их надо с одного
   взгляда. */

.список-мест .место-за-столом--нажимается {
  cursor: pointer;
  /* Нажатие должно попадать пальцем. Полных сорока четырёх точек тут
     нет: тогда шесть мест не поместятся на экран целиком, а увидеть
     весь стол важнее (см. «Прихожая: место отдаём списку»). Строка
     при этом во всю ширину экрана — промахнуться вбок нельзя,
     а сверху и снизу её отделяет просвет. Там, где высоты вдоволь,
     строка подрастает — правило ниже, в разделе про высокий экран. */
  min-height: 30px;
}

/* Палец на строке: она темнеет и слегка вжимается. Отклик короткий —
   он должен успеть показаться до того, как игра перерисует список. */
.список-мест .место-за-столом--нажимается:active {
  background: color-mix(in srgb, var(--акцент) 26%, var(--подложка));
  transform: scale(0.985);
}

/* Два класса в селекторе нарочно. Первую строку списка таблица рекордов
   обводит как чемпиона, а прихожая эту обводку снимает — правилом
   «.место-за-столом:first-child { box-shadow: none }». Оно тяжелее
   обычного класса, и напиши мы здесь просто «выбрано», у ПЕРВОГО места
   рамка выбора не появилась бы вовсе. А хозяин чаще всего первым
   и нажимает на себя, чтобы выбрать напарника. */
.список-мест .место-за-столом.место-за-столом--выбрано {
  box-shadow: inset 0 0 0 2px var(--акцент);
  background: color-mix(in srgb, var(--акцент) 30%, var(--подложка));
}

/* Номер выбранного места — белая цифра на цветном кружке. Кружок
   рисуется полями внутри своей же колонки, поэтому строка от него
   не становится ни выше, ни шире. */
.список-мест .место-за-столом--выбрано .место-за-столом__номер {
  color: var(--кнопка-текст);
  background: var(--акцент);
  border-radius: 999px;
  text-align: center;
  font-weight: 800;
}

/* ---------- Кнопки хозяина стола ----------
   Их три, и раньше все три были одинаково залиты — глаз не находил
   главную. Теперь старшинство видно: «Начать игру» залита и лежит
   отдельной строкой во всю ширину, а «Посадить бота» и «Убрать бота»
   стоят парой над ней и только обведены. Это те же кнопки-обводки,
   что «Играть с другом» в меню, — в игре они уже значат «действие
   есть, но оно не главное». */

.кнопки-хозяина {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  width: 100%;
}

#экран-комнаты .кнопки-хозяина .кнопка {
  flex: 1 1 0;
  width: auto;
  min-width: 0;
  padding: 10px 8px;
  font-size: 15px;
}

#экран-комнаты .кнопки-хозяина #кнопка-посадить-бота,
#экран-комнаты .кнопки-хозяина #кнопка-убрать-бота {
  color: var(--текст);
  background: var(--подложка);
  border: 2px solid var(--акцент);
  box-shadow: none;
}

#экран-комнаты .кнопки-хозяина .кнопка--главная {
  flex: 1 0 100%;
  font-size: 18px;
}

/* ---------- Прихожая: место отдаём списку мест ----------

   ЖАЛОБА ЖИВОГО ВЛАДЕЛЬЦА: «смотри, я не вижу всех 4-х мест, а тем
   более не увижу 6-ти». На его снимке из Telegram видно код, две
   кнопки, строку «Играют четверо, парами, 2 на 2» — и два с половиной
   места из четырёх. Остальные лежали за краем окошка списка.

   Отчего так вышло. Экран кода собран из семи блоков подряд: заголовок,
   объяснение, огромный код, «Позвать друга», «Скопировать код», сама
   прихожая, строка ожидания и «Отменить игру». Каждый из них взял
   столько, сколько просил, а прихожая стоит предпоследней — ей достался
   остаток. Остатка не хватило, список ужался до своего пола и
   прокрутился. В браузере на 844 точках это было почти незаметно
   (влезало пять мест из шести), а в Telegram окно ниже, да ещё и
   появляется кнопка «Позвать друга», которой в браузере нет.

   Что делаем. Отбираем понемногу у всех, кто стоит вокруг списка,
   и отдаём это списку. Считано по замеру на 390×844 с шестью местами:

     промежутки между блоками   14 → 8 точек   (восемь штук — 48)
     код игры                   74 → 49 точек кегля            (35)
     заголовок «Код игры»       28 → 22                         (7)
     объяснение под ним         15 → 13                         (2)
     обе кнопки под кодом       52 и 46 → по 44                (10)
     поля самой прихожей        10/11 → 8/9, просвет 8 → 6      (6)
     строки списка              7 → 5 точек поля, просвет 5 → 4 (29)
     кнопки хозяина             46/52 → 44/48, просвет 8 → 6   (10)

   Итого около полутора сотен точек — при том что шестому месту
   не хватало двадцати семи.

   КОД ПРИ ЭТОМ ОСТАЁТСЯ КРУПНЫМ, и это не переговорная позиция:
   его работа — быть продиктованным вслух и переписанным на бумажку.
   Сорок девять точек на телефоне 390 — это всё ещё вдвое крупнее
   заголовка экрана и втрое крупнее любой подписи; на снимке он
   по-прежнему первое, что видит глаз. Мельче 34 не даём никогда.

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

#экран-комнаты:has(#прихожая:not(.скрыт)) {
  gap: 8px;
  padding: calc(10px + var(--отступ-сверху)) calc(12px + var(--отступ-справа))
           calc(10px + var(--отступ-снизу))  calc(12px + var(--отступ-слева));
}

#экран-комнаты:has(#прихожая:not(.скрыт)) .заголовок { font-size: 22px; }

#экран-комнаты:has(#прихожая:not(.скрыт)) > .подпись { font-size: 13px; }

#экран-комнаты:has(#прихожая:not(.скрыт)) .код-игры {
  font-size: clamp(34px, 12.5vw, 50px);
  padding: 7px 14px;
}

/* Кнопки под кодом. Сорок четыре точки — нижний предел, ниже которого
   в кнопку не попадают пальцем; «Позвать друга» была главной и просила
   пятьдесят две. Здесь ей хватает общей высоты: она и так стоит первой
   и залита цветом, а лишние восемь точек нужнее списку. */
#экран-комнаты:has(#прихожая:not(.скрыт)) #кнопка-позвать-друга,
#экран-комнаты:has(#прихожая:not(.скрыт)) #кнопка-копировать-код {
  min-height: 44px;
  padding: 9px 16px;
  font-size: 16px;
}

#экран-комнаты:has(#прихожая:not(.скрыт)) .прихожая {
  gap: 6px;
  padding: 8px 8px 9px;
}

#экран-комнаты:has(#прихожая:not(.скрыт)) #прихожая-правила {
  font-size: 13.5px;
}

/* Пять точек поля сверху и снизу вместо семи оставляют строке около
   тридцати точек: имя в 14 точек стоит в ней свободно, и строки
   не слипаются. Хозяин по строкам ещё и нажимает (пересадка игроков),
   и там, где высоты хватает, они подрастают до сорока — см. раздел
   «Места, которые можно поменять местами». */
#экран-комнаты:has(#прихожая:not(.скрыт)) .список-мест { gap: 4px; }

#экран-комнаты:has(#прихожая:not(.скрыт)) .место-за-столом {
  padding: 5px 9px;
}

/* А вот кнопки хозяина остаются кнопками: 44 точки — это то,
   во что попадает палец. Убавлен только просвет между ними. */
#экран-комнаты:has(#прихожая:not(.скрыт)) .кнопки-хозяина { gap: 6px; }

#экран-комнаты:has(#прихожая:not(.скрыт)) .кнопки-хозяина .кнопка {
  min-height: 44px;
}

#экран-комнаты:has(#прихожая:not(.скрыт)) .кнопки-хозяина .кнопка--главная {
  min-height: 48px;
  font-size: 17px;
}

/* Строка ожидания под прихожей выросла втрое: к «Скажите друзьям код»
   добавилось объяснение про пересадку игроков. Три строки по 15 точек
   занимают 83 точки — почти три места в списке. Кегль 12,5 оставляет
   те же три строки, но забирает у них 34 точки. Это подпись-объяснение,
   а не то, что читают каждую секунду, и мельче она читается спокойно. */
#экран-комнаты:has(#прихожая:not(.скрыт)) .сеть-ожидание {
  font-size: 12.5px;
  line-height: 1.3;
}

/* ---------- Прихожая, когда окно ниже 780 точек ----------

   Внутри Telegram окно игры всегда ниже, чем экран телефона: сверху
   лежит шапка приложения. На телефоне 390×844 игре достаётся около
   760 точек — и ровно в этой полосе (от 700 до 780) прихожая с шестью
   местами переставала помещаться, хотя по всем правилам выше она уже
   ужата.

   Убираем объяснение «Продиктуйте или перешлите этот код другу»:
   с ним рядом стоят две кнопки — «Позвать друга» и «Скопировать код», —
   которые говорят то же самое и делом. На высоком экране объяснение
   остаётся: там за него не платят местом. */

@media (max-height: 780px) {
  #экран-комнаты:has(#прихожая:not(.скрыт)) > .подпись {
    display: none;
  }
}

/* А на высоком экране, наоборот, отдаём лишнюю высоту строкам списка:
   у хозяина они нажимаются (пересадка игроков), и чем крупнее цель,
   тем меньше он промахнётся. Сорок точек вместо тридцати — это ещё
   шестьдесят точек на шесть мест, и на экране в 844 точки они есть
   с запасом. Ниже 781 этого запаса нет, и там строки остаются
   тесными: увидеть все шесть мест важнее. */
@media (min-height: 781px) {
  #экран-комнаты:has(#прихожая:not(.скрыт)) .место-за-столом--нажимается {
    min-height: 40px;
  }
}

/* ---------- Прихожая на невысоком экране ----------

   Находка тестировщика: окно 320×568, стол на шестерых — кнопка
   «Начать игру» обрезана нижним краем экрана, а «Отменить игру»
   висит совсем за ним. Прокрутка была, но человек про неё
   не догадывался: список мест выглядел законченным.

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

   Основную часть этой работы теперь делает раздел выше — он ужимает
   окружение списка на экране любой высоты. Здесь остаётся то, что
   на большом телефоне делать не за что: там места хватает и так.
   Ради шести мест на экране в 640 точек убираем две надписи:

   1) объяснение «Продиктуйте или перешлите этот код другу». Ровно то же
      самое сказано рядом двумя кнопками — «Позвать друга» и
      «Скопировать код», — а под кодом уже стоит список мест, и человек
      занят им, а не чтением. На высоком экране объяснение остаётся.

   2) строку «Скажите друзьям код. Все собрались — нажмите „Начать
      игру“» — но только у хозяина стола. У него прямо под списком
      лежит сама кнопка «Начать игру», и строка повторяет её словами.
      Гостю, у которого кнопок нет, строка остаётся: для него это
      единственный ответ на вопрос «чего мы ждём», и колечко в ней —
      единственный признак, что игра жива.

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

@media (max-height: 700px) {
  #экран-комнаты:has(#прихожая:not(.скрыт)) {
    gap: 7px;
    padding: calc(8px + var(--отступ-сверху)) calc(10px + var(--отступ-справа))
             calc(8px + var(--отступ-снизу))  calc(10px + var(--отступ-слева));
  }

  /* Код остаётся самым крупным на экране, но в прихожей ему хватает
     сорока с небольшим точек: его диктуют, а не читают через стол. */
  #экран-комнаты:has(#прихожая:not(.скрыт)) .код-игры {
    font-size: clamp(30px, 11vw, 46px);
    padding: 6px 14px;
  }

  #экран-комнаты:has(#прихожая:not(.скрыт)) > .подпись {
    display: none;
  }

  /* Хозяину строку ожидания не показываем: у него есть кнопка. */
  #экран-комнаты:has(#прихожая:not(.скрыт)):has(.кнопки-хозяина:not(.скрыт))
    .сеть-ожидание {
    display: none;
  }

  #экран-комнаты:has(#прихожая:not(.скрыт)) .прихожая {
    gap: 5px;
    padding: 7px 8px 8px;
  }

  /* Строки списка ещё теснее: здесь важнее увидеть все шесть мест,
     чем дать каждому по сорок четыре точки под палец. */
  #экран-комнаты:has(#прихожая:not(.скрыт)) .список-мест { gap: 4px; }

  #экран-комнаты:has(#прихожая:not(.скрыт)) .место-за-столом {
    padding: 4px 8px;
  }

  #экран-комнаты:has(#прихожая:not(.скрыт)) .кнопки-хозяина { gap: 6px; }

  /* А вот кнопки остаются кнопками: 44 точки высоты — это то,
     во что попадает палец, и отнимать у них высоту нельзя. */
  #экран-комнаты:has(#прихожая:not(.скрыт)) .кнопки-хозяина .кнопка {
    min-height: 44px;
  }

  #экран-комнаты:has(#прихожая:not(.скрыт)) .кнопки-хозяина .кнопка--главная {
    min-height: 48px;
  }

  /* Строку ожидания здесь не трогаем: кегль ей уже убавлен разделом
     выше, а у хозяина её и вовсе нет. */

  /* ---------- Правила на невысоком экране ----------

     Сейчас это правила шашек: у дурака свой тёмный экран правил
     со своими правилами для низкого окна (раздел «КАК ИГРАТЬ, РЕКОРДЫ,
     ОФОРМЛЕНИЕ ДУРАКА» в конце файла).

     Невысоких телефонов полно, а в шторке Telegram высоты ещё меньше,
     поэтому ужимаем всё, что вокруг текста, — шапку, поля, просветы
     между плашками. Сам текст оставляем крупным: мельче 15 точек его читать
     неприятно, а читают тут именно его. Прокрутка остаётся только
     на совсем маленьких экранах — обрезанная плашка сама говорит,
     что список продолжается. */
  #экран-правил {
    gap: 8px;
    padding: calc(10px + var(--отступ-сверху)) calc(10px + var(--отступ-справа))
             calc(10px + var(--отступ-снизу))  calc(10px + var(--отступ-слева));
  }
  #экран-правил .заголовок { font-size: 22px; }
  .правила { gap: 6px; }
  .правила .подпись {
    padding: 8px 10px 9px 30px;
    text-indent: -20px;
    font-size: 15px;
    line-height: 1.4;
  }
}

/* ---------- Кнопка, которую сейчас нажимать нечем ----------
   «Начать игру» не работает, пока за столом один человек, а кнопки
   прихожей выключаются на время, пока сервер отвечает. Своего вида
   у выключенной кнопки в игре не было вовсе: она выглядела точно
   как рабочая, человек жал её и решал, что игра зависла.
   Гасим её не прозрачностью (от неё подпись становится нечитаемой),
   а снятием заливки: остаётся спокойная серая плашка — видно, что
   кнопка есть, но сейчас она молчит. */
.кнопка:disabled {
  color: var(--текст-тихий);
  background: var(--подложка);
  border: 1px solid var(--край);
  box-shadow: none;
  cursor: default;
}

.кнопка:disabled:active {
  transform: none;
}

/* ---------- Полоса соперников над столом (компания) ----------
   Компанией чужие карты не рисуем: пять вееров рубашек не помещаются
   на телефон и ничего не сообщают. Вместо них — места: аватар, имя,
   сколько карт и что с человеком происходит.

   Как выглядят места на новом столе — в разделе стола в конце файла
   («Компания: соперники над столом»). Здесь только основа, общая для
   любой раскладки: полоса в ряд, и место — мерка для своих надписей
   («container-type»: кегли внутри считаются от ширины самого места,
   а не экрана — тесно бывает месту, а не телефону). */
.соперники {
  flex: 0 0 auto;
  display: flex;
  width: 100%;
}

.соперник {
  position: relative;
  box-sizing: border-box;
  min-width: 0;
  container-type: inline-size;
}

/* ПРОБЕЛ МЕЖДУ ЧИСЛОМ И СЛОВОМ («6 карт») РИСУЕМ САМИ. В разметке между
   ними стоит настоящий пробел отдельным узлом, но «флекс» пробельные узлы
   выбрасывает молча — на снимке стояло «6карт» слитно. Доля кегля,
   а не точки: на узком месте просвет ужимается вместе с надписью. */
.соперник__число + .соперник__слово { margin-left: 0.35em; }

/* Уровень бота и слово состояния («ходит», «отбивается») стоят в одной
   строке места, и вместе они не влезают: пока соперник ходит, отбивается
   или потерял связь, уровень уступает строку и не показывается вовсе.
   Уровень — справка на всю партию, он одинаков у всех ботов за столом;
   состояние меняется каждый ход, и видно должно быть его. */
.соперник:has(.соперник__метка) .соперник__роль {
  display: none;
}

/* Уровень у выбывшего и ушедшего не показываем совсем: он уже не играет,
   а читать на его месте надо другое — кто теперь ходит с его места
   («играет Бот 4»). */
.соперник--выбыл .соперник__роль,
.соперник--ушёл .соперник__роль {
  display: none;
}

/* Значки перед словом состояния — чтобы два состояния не спутать даже
   краем глаза: у защитника колечко-щит, у того, кто ходит, — стрелка.
   Оба меряются долями кегля («em»): слово то крупнее, то мельче (от
   ширины места), и значок растёт вместе с ним. Нарисованы средствами
   CSS, а не буквой: значки-стрелки на части телефонов подменяются
   цветным эмодзи. В самом узком месте значки убираются (см. раздел
   стола в конце файла) — там слово важнее. */
.соперник--отбивается .соперник__метка::before {
  content: "";
  display: inline-block;
  vertical-align: -0.08em;
  width: 0.72em;
  height: 0.72em;
  margin-right: 0.35em;
  border: 0.16em solid currentColor;
  border-radius: 50%;
}

/* Защитник, чей сейчас черёд (у него обе пометки разом), остаётся
   с колечком-щитом: стрелка на защитнике читалась бы как «он ходит».
   Значок говорит, ЧТО человек делает, салатовый — ЧЕЙ сейчас черёд. */
.соперник--ходит:not(.соперник--отбивается) .соперник__метка::before {
  content: "";
  display: inline-block;
  vertical-align: -0.05em;
  width: 0;
  height: 0;
  margin-right: 0.35em;
  border: 0.38em solid transparent;
  border-right: 0;
  border-left: 0.55em solid currentColor;
}

/* Кнопки хода компанией («Пас», «Перевести», «Бросить») — в разделе
   стола в конце файла («Панель действий»): там у всех кнопок хода
   один вид, а различает их значок перед словом. */

/* ---------- Невысокое окно (шторка Telegram) ---------- */

@media (max-height: 620px) {
  .заголовок { font-size: 26px; }
  #экран-результата .заголовок { font-size: 23px; }

  /* Просветы в низком окне и так сжаты до девяти точек, поэтому сноску
     подтягиваем к своей кнопке слабее — иначе она к ней прилипнет. */
  .сноска { margin-top: -3px; font-size: 12px; }
  #экран-рекордов .заголовок { font-size: 22px; }

  /* Плашка «Что было» в шторке. Собираем высоту по мелочи — с полей,
     просветов и заголовка, — чтобы в список поместилось на новость
     больше. Кегль самих новостей не трогаем: читать их всё равно
     придётся, а мелкий текст в шторке читается хуже всего.
     Заголовок назван с идентификатором нарочно — по той же причине,
     что и у меню тремя строками выше. */
  #экран-ленты {
    gap: 6px;
    padding: 9px calc(8px + var(--отступ-справа))
             calc(9px + var(--отступ-снизу)) calc(8px + var(--отступ-слева));
  }
  #экран-ленты .заголовок { font-size: 20px; }
  #лента-событий { gap: 4px; }
  #лента-событий .таблица__строка { padding: 6px 9px 7px; }
  /* Свежей строке левое поле уменьшено на ширину её полосы — иначе
     текст в ней встанет правее, чем у соседей, и столбик поедет. */
  #лента-событий .таблица__строка--свежая { padding-left: 5px; }

  /* Плашка итога не должна съесть пол-экрана: подписи мельче и теснее */
  #экран-результата {
    gap: 8px 10px;
    padding: 12px calc(12px + var(--отступ-справа))
             calc(12px + var(--отступ-снизу)) calc(12px + var(--отступ-слева));
  }
  #экран-результата .подпись { font-size: 13px; }
  .серия { font-size: 16px; padding: 4px 12px; }
  #экран-результата .кнопка--главная { min-height: 46px; font-size: 18px; }

  /* Плашка «точно выйти?» ужимается так же, как итог: вопрос из двух
     строк и две кнопки должны помещаться в шторку Telegram. */
  #экран-выхода {
    gap: 8px 10px;
    padding: calc(12px + var(--отступ-сверху)) calc(12px + var(--отступ-справа))
             calc(12px + var(--отступ-снизу))  calc(12px + var(--отступ-слева));
  }
  #экран-выхода .заголовок { font-size: 21px; }
  #экран-выхода .подпись { font-size: 13px; }
  #экран-выхода .кнопка--главная { min-height: 46px; font-size: 18px; }

  /* Экраны игры вдвоём в шторке: заголовки и просветы ужимаются,
     чтобы столбик целиком помещался без прокрутки. Селекторы
     повторены с идентификатором — иначе правила выше, у которых
     идентификатор есть, окажутся сильнее и ничего не изменится. */
  #экран-друга,
  #экран-комнаты,
  #экран-входа {
    gap: 10px;
    padding: calc(10px + var(--отступ-сверху)) calc(12px + var(--отступ-справа))
             calc(10px + var(--отступ-снизу))  calc(12px + var(--отступ-слева));
  }

  #экран-друга   .заголовок,
  #экран-комнаты .заголовок,
  #экран-входа   .заголовок { font-size: 22px; }

  #экран-друга   > .подпись,
  #экран-комнаты > .подпись,
  #экран-входа   > .подпись { font-size: 14px; }

  /* Код остаётся самым крупным на экране, но в низком окне ему
     хватает 60 точек: рядом должны поместиться заголовок,
     объяснение и кнопка отмены. */
  .код-игры { font-size: clamp(38px, 16vw, 60px); padding: 8px 14px; }

  .поле-кода { min-height: 54px; font-size: 30px; }

  /* Полоска связи тоже ниже. Две строки по 12,5 точки просят ровно 30,
     но даём 32: у разных телефонов шрифты чуть выше или ниже, и на
     впритык подогнанной полоске второй строке срезало бы нижние хвостики
     букв. Стол под неё подстраивается сам — он забирает остаток высоты. */
  .связь { height: 32px; font-size: 12.5px; }

  /* Прихожая и выбор стола в шторке: просветы и место под пояснение
     ужимаются, иначе список из шести мест не помещается вместе
     с кодом и кнопками. */
  .настройка-стола { gap: 8px; }
  #пояснение-стола { min-height: 68px; font-size: 12.5px; padding: 6px 9px; }
  .прихожая { gap: 6px; padding: 8px 8px 9px; }
  .список-мест .место-за-столом { padding: 5px 8px; }
  .список-мест .место-за-столом__имя { font-size: 13px; }

  /* Стол дурака в низком окне (соперники, стол, рука, подсказка)
     ужимается в своём разделе в конце файла. */
}

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

@media (max-width: 330px) {
  /* Стол дурака на узком экране ужимается сам — его размеры считаются
     от ширины экрана и стола (см. раздел стола в конце файла). */

  .кнопка { min-width: 100px; padding: 10px 14px; font-size: 16px; }
  .кнопка--главная { min-width: 160px; }
  .кнопка.кнопка--мелкая { padding: 8px 9px; font-size: 12px; }
  .кнопка.кнопка--выбор { font-size: 13px; padding: 8px 2px; }

  /* Плашка выхода: кнопка «Продолжить партию» длинная, на 280 точках
     ей нужен весь ряд, поэтому подпись на ней мельче. */
  #экран-выхода .кнопка--главная { font-size: 17px; }

  /* Экраны игры вдвоём на узком телефоне. Код по-прежнему считается
     от ширины экрана (19vw), поэтому сам ужимается; поджимаем всё
     вокруг него, чтобы ничего не выходило за край. */
  #экран-друга,
  #экран-комнаты,
  #экран-входа {
    padding-left: calc(10px + var(--отступ-слева));
    padding-right: calc(10px + var(--отступ-справа));
  }

  #экран-друга   .кнопка.кнопка--мелкая,
  #экран-комнаты .кнопка.кнопка--мелкая,
  #экран-входа   .кнопка.кнопка--мелкая { min-width: 130px; }

  .код-игры { padding: 8px 12px; border-width: 2px; }
  .поле-кода { font-size: 30px; }
  .сеть-сообщение { font-size: 13px; padding: 9px 10px; }
  .сеть-ожидание { font-size: 14px; }
  .связь { font-size: 12px; padding: 0 8px; }

  /* Правила на узком телефоне. Строка тут короче на пять-шесть букв,
     поэтому поля у плашки и висячий отступ номера чуть теснее —
     каждая отвоёванная точка это буква, которая не уехала на новую
     строку. Кегль 15: ниже него текст правил уже не читается спокойно. */
  #экран-правил { padding-left: 8px; padding-right: 8px; }
  .правила .подпись {
    padding: 9px 10px 10px 30px;
    text-indent: -20px;
    font-size: 15px;
  }

  /* В таблице рекордов на узком телефоне сжимаем только поля и мелкий
     текст. Раскладка в две строчки у неё теперь всегда — она задана
     выше, отдельно повторять её здесь не нужно. */
  #таблица-рекордов .таблица__строка { gap: 1px 5px; padding: 6px 8px 7px; }
  #таблица-рекордов .таблица__очки   { font-size: 15px; }
  #таблица-рекордов .таблица__дата,
  #таблица-рекордов .таблица__сложность { font-size: 11.5px; }

  /* Плашка «Что было» на узком телефоне. Ужимаем только поля и колонку
     с номером: каждая отвоёванная точка ширины — это буква новости,
     которая не уехала на вторую строку. Сам текст остаётся прежнего
     размера, читать его придётся в любом окне. */
  #экран-ленты { padding-left: 8px; padding-right: 8px; }
  #лента-событий .таблица__строка {
    grid-template-columns: 1.5em minmax(0, 1fr);
    gap: 2px 7px;
    padding: 7px 8px 8px;
  }
  #лента-событий .таблица__строка--свежая { padding-left: 4px; }

  /* Выбор стола на узком телефоне. Пояснению нужно больше строк —
     строка короче, а текст тот же, — поэтому место под него больше. */
  #пояснение-стола { min-height: 96px; font-size: 13px; padding: 7px 9px; }
  #выбор-мест .кнопка.кнопка--выбор { font-size: 16px; }

  /* Прихожая: поля теснее, подписи мельче. Строка места остаётся
     в одну линию — «Игрок 1 — вы · хозяин · на связи» на 280 точках
     ещё помещается, а длинное имя обрежется многоточием. */
  .прихожая { padding: 9px 7px 10px; }
  .список-мест .место-за-столом { gap: 0 6px; padding: 6px 7px; }
  .список-мест .место-за-столом__имя { font-size: 13px; }
  .список-мест .место-за-столом__роль,
  .список-мест .место-за-столом__связь { font-size: 10.5px; }
  #экран-комнаты .кнопки-хозяина .кнопка { font-size: 13px; padding: 10px 4px; }
  #экран-комнаты .кнопки-хозяина .кнопка--главная { font-size: 17px; }
}

/* ---------- Узкий и невысокий разом ----------
   Такое окно бывает чаще, чем кажется: шторка Telegram на маленьком
   телефоне. Правила для узкого экрана записаны в файле ниже правил для
   низкого окна, поэтому при равном весе побеждают они — и строке
   объяснения под выбором стола доставалось место под четыре строки
   (96 точек), рассчитанное на высокий экран. В окне 320×568 эти
   96 точек и выталкивали кнопку «Играть» за нижний край.

   Здесь возвращаем ей шторочный размер. Строка не обрезается:
   при таком кегле в неё помещается любое обычное объяснение,
   а самое длинное (парами и переводной разом) по-прежнему растянет
   плашку само, ничего не потеряв. */

@media (max-width: 330px) and (max-height: 620px) {
  #пояснение-стола { min-height: 68px; font-size: 12.5px; padding: 6px 9px; }
}

/* =====================================================================
   ЗНАКИ ВНИМАНИЯ: смайлики и готовые фразы

   ЖАЛОБА ЖИВОГО ВЛАДЕЛЬЦА: «смайлики работают, но их плохо видно, пусть
   всплывают по центру экрана справа крупно и через 2 сек медленно
   исчезают».

   Как было. Знак висел маленьким тёмным облачком у плашки того, кто его
   сказал: смайлик в 24 точки, вся плашка около 50 точек на 36 — вчетверо
   мельче игральной карты. Стояло облачко у самого края руки и вдобавок
   наезжало на строку подсказки. Замысел был правильный (видно, КТО
   сказал), но на телефоне это читалось как случайное пятнышко.

   Как стало. Знак всплывает у правого края, ровно по середине высоты
   экрана, и он крупный: смайлик — полсотни точек (это ширина игральной
   карты), фраза — жирной строкой на плашке с каймой и тенью. Полторы
   секунды висит, потом тает — рывком не пропадает.

   ЧЕГО ЗНАК НЕ ЗАКРЫВАЕТ. Это главное ограничение, и оно проверено
   замером на обоих телефонах:
     колода и метка козыря  — стоят у ЛЕВОГО края, знак у правого;
     своя рука              — она в нижней четверти, знак по середине;
     «Беру», «Бито», «Пас»  — нижняя полоса, туда знак не достаёт;
     строка подсказки       — она над кнопками, знак кончается выше.
   Стол знак накрывает, и по-другому не выйдет: середина экрана — это
   и есть стол. Но накрывает он правый край поля и всего на две секунды,
   а взамен человек видит, что ему сказали.

   ===================================================================== */

/* ---------- Полка: где висят знаки ----------

   Игра складывает облачка в столбик («знаки-внимания») и кладёт его
   на игровой экран. Место столбика — здесь, и оно ровно такое, как
   просил владелец: правый край, середина высоты.

   «fixed» — «стой относительно экрана, а не того, во что тебя положили».
   Полка лежит внутри игрового экрана, между столом и рукой, и без этой
   строки она раздвинула бы их обоих. Теперь она ничего не двигает:
   знаки висят поверх сукна и пропадают, не потревожив ни одной карты.

   Столбик растёт от середины в обе стороны: одно облачко стоит точно
   по центру, три (больше игра не показывает) расходятся вверх и вниз
   поровну. Прижат он к правому краю — «align-items: flex-end», —
   поэтому короткий смайлик и длинная фраза выстраиваются по одной
   линии справа, а не пляшут серединами. */
.знаки-внимания {
  position: fixed;
  right: max(10px, var(--отступ-справа));
  top: 50%;
  transform: translateY(-50%);
  /* Выше стола, карт и полосы плашек, но ниже плашки итога и панели
     выбора знаков (у тех 100): пока человек выбирает, что сказать,
     его прошлое облачко не должно лезть поверх кнопок. */
  z-index: 70;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
  /* Сквозь полку нажимается то, что под ней: она висит над столом
     и не должна съедать тычки по картам. */
  pointer-events: none;
}

/* ---------- Само облачко ---------- */

.знак-внимания {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  /* Длинная фраза не растягивается на весь экран: «Спасибо за игру»
     занимает 168 точек из отведённых 230 и встаёт в одну строку,
     а на узком телефоне переносится на две. Шире брать нельзя —
     знак закроет весь стол вместо его края. */
  max-width: min(60vw, 230px);
  padding: 8px 14px 9px;
  text-align: center;
  /* Слово переносим по-живому, а слишком длинное ломаем, но за край
     плашки не выпускаем. */
  overflow-wrap: anywhere;

  color: var(--текст);
  background: var(--панель);
  /* Кайма цветом темы — то самое «бросается в глаза». Своей краски
     не берём: акцент приходит из Telegram и в любой теме контрастен
     и к сукну, и к плашке. */
  border: 2px solid var(--акцент);
  border-radius: 16px;
  /* Тень крупная и мягкая: знак висит над картами, и без тени он
     выглядел бы наклейкой, приклеенной к столу. */
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.5);

  /* Как знак ПОЯВЛЯЕТСЯ — коротким всплытием справа (см. ниже).
     «backwards» вместо «both» выбрано нарочно: «both» оставил бы
     на облачке последний кадр анимации навсегда, а кадр сильнее
     обычного правила — и затухание, которое рисуется переходом,
     просто не сработало бы. */
  animation: знак-всплыл 240ms ease-out backwards;

  /* Как знак ИСЧЕЗАЕТ. Само затухание включает игра, вешая пометку
     «гаснет» (см. ниже); здесь только сказано, за сколько и как.
     Срок вынесен в отдельную строку нарочно: он должен совпадать
     с числом «ЗНАК_ТАЕТ» в js/game.js, и менять его придётся сразу
     в двух местах — пусть в этом файле оно будет одно и на виду. */
  --знак-тает: 400ms;
  transition: opacity var(--знак-тает) linear,
              transform var(--знак-тает) ease-in;
}

/* Кто сказал. Строчка тихая и мелкая: она отвечает на вопрос «чьё это»,
   а читать в облачке нужно не её. Раньше вопроса не было вовсе —
   облачко висело у плашки говорящего, — но у края экрана без имени
   знак превращается в возглас из ниоткуда. */
.знак-внимания__кто {
  font-size: 11.5px;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: 0.02em;
  opacity: 0.75;
}

/* Что сказали. Фраза — жирной строкой; читается с одного взгляда. */
.знак-внимания__что {
  font-size: clamp(15px, 4.6vw, 19px);
  font-weight: 700;
  line-height: 1.25;
}

/* Смайлик — это картинка, а не текст, и читать в нём нечего: даём ему
   вырасти во всю ладонь. Полсотни точек — это примерно ширина игральной
   карты на телефоне 390; крупнее делать некуда, знак начнёт спорить
   со столом. */
.знак-внимания--смайлик {
  max-width: none;
  padding: 5px 14px 7px;
}

.знак-внимания--смайлик .знак-внимания__что {
  font-size: clamp(40px, 13vw, 54px);
  line-height: 1.1;
}

/* Своё слово человек уже знает — оно тише чужого: кайма обычная,
   тень мельче. Кричать должен тот знак, который сказали ТЕБЕ. */
.знак-внимания--свой {
  border-color: var(--край);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.4);
}

/* ---------- Когда заговорили трое разом ----------

   Больше трёх знаков игра не показывает, и это её потолок. Но три
   смайлика в полный рост — это 250 точек столбиком, и на телефоне
   в 640 точек такой столбик достаёт до строки подсказки. Случай редкий
   (три голоса за две секунды бывают только за столом компанией), но
   именно в нём знаки мешали бы игре, а не помогали.

   Поэтому когда на полке третье облачко, смайлики мельчают, а просвет
   между ними ужимается: столбик садится с 263 точек до 223 и снова
   умещается между столом и подсказкой. Фраз это не касается — они
   и втроём занимают меньше.

   «:has(> :nth-child(3))» читается как «у полки есть третий ребёнок».
   Браузеры старше 2023 года этого не поймут: там три смайлика разом
   останутся крупными, то есть будет ровно как сейчас. */
.знаки-внимания:has(> :nth-child(3)) {
  gap: 6px;
}

.знаки-внимания:has(> :nth-child(3)) .знак-внимания--смайлик .знак-внимания__что {
  font-size: clamp(32px, 10vw, 44px);
}

/* ---------- Как знак всплывает ----------
   Четверть секунды: вылетает справа, чуть перерастая себя, и встаёт
   на место. Это и есть «всплывает» — короткое движение с краю,
   от которого глаз сам поворачивается в нужную сторону. */
@keyframes знак-всплыл {
  from {
    opacity: 0;
    transform: translateX(26px) scale(0.84);
  }
  70% {
    opacity: 1;
    transform: translateX(0) scale(1.05);
  }
  to {
    opacity: 1;
    transform: translateX(0) scale(1);
  }
}

/* ---------- Как знак тает ----------

   Пометку «гаснет» вешает игра ровно за 400 миллисекунд до того, как
   снимет облачко со стола («ЗНАК_ТАЕТ» в js/game.js). ЭТИ ЧИСЛА ОБЯЗАНЫ
   СОВПАДАТЬ с длиной перехода выше: сделаем переход длиннее — знак
   оборвётся на полуслове, короче — постоит прозрачным пустым местом.
   Меняете там — поменяйте и здесь, это одно число в двух файлах.

   Тает знак не только прозрачностью, но и движением: уезжает вправо,
   откуда пришёл, и слегка уменьшается. Так понятнее, что он ушёл сам,
   а не мигнул экран. */
.знак-внимания--гаснет {
  opacity: 0;
  transform: translateX(14px) scale(0.96);
}

/* У кого в телефоне выключены движения, тот не должен видеть ни полёта,
   ни таяния: знак просто появляется и пропадает. Прозрачность при этом
   меняется мгновенно — это не движение, а включение и выключение. */
@media (prefers-reduced-motion: reduce) {
  .знак-внимания {
    animation: none;
    transition: none;
  }

  .знак-внимания--гаснет {
    transform: none;
  }
}

/* ---------- Живой смайлик ----------

   Владелец просил «анимированные смайлы». Библиотек и картинок в игре
   нет, поэтому живым делаем обычный символ: он покачивается и чуть
   подпрыгивает, как будто его показывают рукой. Живым бывает только
   смайлик — фразу не трогаем ни при каком классе: качающийся текст
   не прочесть. Пометку «живой» ставит игра; здесь она работает лишь
   на облачке-смайлике.

   Качание мягкое и несимметричное (два подскока разной высоты на цикл):
   ровное маятниковое движение через пару секунд начинает раздражать,
   а неровное читается как живое. Полтора оборота в секунду — медленно,
   взгляд не дёргает. Точка вращения у нижнего края знака: так он
   «стоит» на плашке и покачивается, а не крутится вокруг центра. */
.знак-внимания--смайлик.знак-внимания--живой .знак-внимания__что {
  display: inline-block;   /* строчному узлу transform не задать */
  transform-origin: 50% 85%;
  animation: смайлик-живой 1.5s ease-in-out infinite;
}

@keyframes смайлик-живой {
  0%, 100% { transform: translateY(0)    rotate(-7deg) scale(1); }
  30%      { transform: translateY(-5px) rotate(5deg)  scale(1.06); }
  60%      { transform: translateY(0)    rotate(7deg)  scale(1); }
  80%      { transform: translateY(-3px) rotate(-3deg) scale(1.03); }
}

/* =====================================================================
   ЛЕТЯЩИЙ ПРЕДМЕТ: кинуть смайликом в соперника

   Владелец просил «кинуть какашкой в соперника». Предмет — один символ
   (💩, 🍅, 🥚, 👞, ❤️, 🌹), который летит от плашки бросившего к плашке
   цели над всем столом, шлёпается и тает. Игра кладёт узел на игровой
   экран и пишет ему четыре переменные: --от-x, --от-y, --до-x, --до-y —
   точки относительно игрового экрана. Больше от игры ничего не нужно:
   куда лететь — знает CSS.

   Как устроен полёт. Движение разложено на два свойства, и это главное
   решение здесь. «translate» везёт предмет по прямой от точки к точке.
   «transform» — независимо от него — подбрасывает вверх и опускает
   (дуга) и крутит. Сумма двух — бросок по дуге. В одном свойстве так
   не сделать: прямая и дуга слились бы в одну кривую, которую пришлось
   бы считать заново для каждой пары точек — а точек игра не знает
   заранее.

   Дуга не выше 110 точек и не выше верхнего края экрана: если оба конца
   у самого верха (плашки соперников стоят там), подъём урезается, чтобы
   предмет не улетал за край и не обрезался. Для броска снизу вверх —
   от своей руки к плашке — вертикальная дуга почти нулевая, и бросок
   показывает глубина: предмет вырастает в середине пути и уменьшается
   к цели, как будто пролетает мимо зрителя.

   Сквозь предмет нажимается всё, что под ним (pointer-events: none),
   и висит он не дольше полёта: после шлепка тает и остаётся невидимым
   до тех пор, пока игра его не уберёт. Руку и кнопки он не закрывает
   ничем, кроме себя самого, и то на секунду.
   ===================================================================== */

.летящий-предмет {
  position: absolute;
  left: 0;
  top: 0;
  /* Над столом, полосой плашек и облачками (у тех 70), но под плашкой
     итога и панелью выбора знаков (у тех 100). */
  z-index: 80;
  pointer-events: none;
  user-select: none;
  margin: -0.5em 0 0 -0.5em;   /* точка — центр символа, а не его угол */
  font-size: 40px;
  line-height: 1;
  will-change: translate, transform, opacity;

  /* Подъём дуги: не больше --дуга (по умолчанию 110), и не выше,
     чем 24 точки от верха экрана над самой верхней из двух точек. */
  --подъём: max(0px, min(var(--дуга, 110px),
                         calc(min(var(--от-y, 0px), var(--до-y, 0px)) - 24px)));

  translate: var(--от-x, 50%) var(--от-y, 50%);
  animation:
    предмет-летит var(--полёт, 700ms) linear forwards,
    предмет-дуга  var(--полёт, 700ms) linear forwards;
}

@keyframes предмет-летит {
  from { translate: var(--от-x) var(--от-y); }
  to   { translate: var(--до-x) var(--до-y); }
}

/* Вверх — с замедлением, вниз — с ускорением: так летит брошенное.
   Оборот ровно один: в конце угол снова ноль, и шлепок начинается
   без рывка. Вырастает в середине пути — это «глубина» броска. */
@keyframes предмет-дуга {
  0%   { transform: translateY(0) rotate(0deg) scale(0.75);
         animation-timing-function: ease-out; }
  50%  { transform: translateY(calc(-1 * var(--подъём))) rotate(180deg) scale(1.3);
         animation-timing-function: ease-in; }
  100% { transform: translateY(0) rotate(360deg) scale(1); }
}

/* Попал. Игра вешает пометку в момент прибытия; предмет стоит в точке
   цели (translate задан явно — иначе, потеряв анимацию полёта, он
   отскочил бы к началу), коротко раздувается и тает. Тень под ним
   пропадает вместе с ним. */
.летящий-предмет--попал {
  translate: var(--до-x) var(--до-y);
  animation: предмет-шлёп 300ms ease-out forwards;
}

@keyframes предмет-шлёп {
  0%   { transform: scale(1)   rotate(0deg);   opacity: 1; }
  35%  { transform: scale(1.5) rotate(-12deg); opacity: 1; }
  100% { transform: scale(1.2) rotate(0deg);   opacity: 0; }
}

/* ---------- В плашку попали ----------

   Полсекунды плашка цели вздрагивает: несколько сдвигов по четыре
   точки с лёгким наклоном, затухающих к концу. Заметно — но не мультяшно:
   ни подскока, ни вращения. Движение задано отдельными свойствами
   «translate» и «rotate», а не «transform»: у плашки того, кто ходит,
   transform уже занят увеличением, и тряска не должна его сбивать. */
.плашка--попали {
  animation: плашку-тряхнуло 500ms ease-in-out;
}

@keyframes плашку-тряхнуло {
  0%, 100% { translate: 0 0;    rotate: 0deg; }
  15%      { translate: -4px 0; rotate: -1.5deg; }
  35%      { translate: 4px 1px; rotate: 1.5deg; }
  55%      { translate: -3px 0; rotate: -1deg; }
  75%      { translate: 2px 0;  rotate: 0.6deg; }
}

/* Кому мешает движение — без полёта: предмет появляется у цели,
   тает без раздувания, плашка не трясётся, смайлик не качается.
   Сам предмет при этом виден — человек должен узнать, что в него
   кинули; просто без спецэффектов. */
@media (prefers-reduced-motion: reduce) {
  .летящий-предмет {
    animation: none;
    translate: var(--до-x) var(--до-y);
    transform: none;
  }

  .летящий-предмет--попал {
    animation: предмет-тает 300ms ease-out forwards;
  }

  .плашка--попали { animation: none; }

  .знак-внимания--смайлик.знак-внимания--живой .знак-внимания__что {
    animation: none;
  }
}

@keyframes предмет-тает {
  from { opacity: 1; }
  to   { opacity: 0; }
}

/* ---------- Знаки в невысоком окне (шторка Telegram) ----------
   Высоты мало: три облачка прежнего роста заняли бы почти весь стол
   и достали бы до строки подсказки. Ужимаем и сами знаки, и просвет
   между ними. */
@media (max-height: 620px) {
  .знаки-внимания { gap: 6px; }

  .знак-внимания {
    padding: 6px 12px 7px;
    border-radius: 14px;
  }

  .знак-внимания__кто { font-size: 10.5px; }
  .знак-внимания__что { font-size: clamp(14px, 4.2vw, 17px); }

  .знак-внимания--смайлик { padding: 4px 12px 5px; }
  .знак-внимания--смайлик .знак-внимания__что {
    font-size: clamp(34px, 11vw, 44px);
  }
}

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

/* ---------- Сама панель: потолок высоты и прокрутка внутри ----------

   ЧТО БЫЛО СЛОМАНО. Знаков со временем стало много — 12 смайликов,
   11 фраз и 8 предметов для броска, всего 32 кнопки. Панель — плашка,
   прижатая к нижнему краю, а высота у неё была «сколько попросит
   содержимое». На телефоне 320×568 содержимое попросило 682 точки,
   плашка выросла выше экрана, и её верх — заголовок и десять кнопок —
   оказался ЗА краем. Прокрутки при этом не было никакой: до тех знаков
   нельзя было добраться вовсе.

   Это не про полный экран. Даже без полей под часы верх срезало
   на 62 точки; полный экран лишь делал хуже.

   КАК ПОЧИНЕНО. Три вещи сразу:

   1. У панели появился потолок — она никогда не выше окна за вычетом
      верхнего безопасного поля. Что не поместилось, то прокручивается
      внутри неё, а не уезжает за экран.
   2. Содержимое встаёт столбиком (у общей плашки раскладка «в строку
      с переносом» — она для двух кнопок итога, а не для четырёх рядов).
   3. Кнопка «Закрыть» прилипает к нижнему краю панели и остаётся
      на месте, сколько бы мы ни прокручивали. Без этого закрыть панель
      можно было бы, только домотав до конца, — а это ровно та ловушка,
      из которой мы человека и вытаскиваем.

   Ужатие кнопок на узких и невысоких экранах — ниже, отдельными
   правилами: прокрутка спасает всегда, но чем реже она нужна,
   тем лучше. */
#экран-эмоций {
  flex-flow: column nowrap;
  align-items: center;
  justify-content: flex-start;
  /* Потолок: вся высота окна минус верхнее безопасное поле и небольшой
     зазор, чтобы из-под панели была видна полоска стола — иначе она
     читается как отдельный экран, а не как плашка поверх игры. */
  max-height: calc(var(--доступно) - var(--отступ-сверху) - 10px);
  overflow-y: auto;
  overflow-x: hidden;
  overscroll-behavior: contain;
}

/* Ничего не сплющивается по высоте: в столбике с прокруткой сжатие
   только испортило бы кнопки. */
#экран-эмоций > * { flex-shrink: 0; }

/* «Закрыть» видна всегда, даже когда список знаков прокручен наверх.

   Устроена не кнопкой посреди панели, а полкой по её низу: тянется
   от края до края отрицательными полями, залита фоном панели и отделена
   сверху тонкой чертой. Фон обязателен — без него сквозь надпись
   просвечивали бы уезжающие ряды знаков; а раз фон во всю ширину,
   то и рамка кнопки здесь лишняя, иначе она резала бы панель пополам.

   Нижнее поле уводит полку под нижний отступ панели: тогда прилипшая
   кнопка стоит вплотную к краю, а безопасное поле полного экрана
   отдано её собственному нижнему полю — палец не попадает на полосу
   жеста. */
#экран-эмоций #кнопка-эмоции-назад {
  position: sticky;
  bottom: calc(-1 * var(--отступ-снизу) - 18px);
  z-index: 2;
  width: auto;
  align-self: stretch;
  min-width: 0;
  margin: 2px -14px calc(-1 * var(--отступ-снизу) - 18px);
  padding: 12px 14px calc(12px + var(--отступ-снизу) + 18px);
  background: var(--панель);
  border: none;
  border-top: 1px solid var(--край);
  border-radius: 0;
  box-shadow: none;
}

/* ---------- Вкладки над рядами знаков: «Смайлики», «Фразы», «Кинуть» ----------

   ЗАЧЕМ ОНИ ЗДЕСЬ. Знаков тридцать два, и тремя рядами подряд они на узкий
   телефон не помещались: панель просила 494 точки и приходилось прокручивать.
   Разложили по вкладкам — стало 227 точек без прокрутки. Полоска вкладок
   в эти 227 уже входит, поэтому главное требование к ней — быть скромной
   по высоте: 44 точки (палец) и ни точкой больше.

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

   ПОЧЕМУ ВЕЗДЕ «#экран-эмоций». Тот же приём и те же имена классов есть
   на панели знаков в шашках, а шашки грузят этот файл первым и свой
   («style-шашки.css») вторым. Напиши я правила просто по классу — и они
   перебили бы шашечные, потому что здешние сильнее. Приставка по имени
   экрана держит их строго внутри панели знаков дурака: этого имени нет
   ни в шашках, ни в нардах, ни в шахматах. */

/* Полоска: три вкладки в ряд, каждая занимает треть — так они читаются
   как один переключатель, а не как три отдельные кнопки.

   Своего просвета снизу у полоски нет нарочно: между частями панели уже
   стоит общий просвет в 10 точек, и собственное поле сложилось бы с ним
   вдвое — панель выросла бы ровно там, где высота на счету.

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

   Цвет дорожки — из цвета текста темы, а не из «--край». Первый раз
   я взял именно край (серый с прозрачностью 0,45) и толщину в точку —
   на снимке живой игры такой линии не было видно вовсе: на тёмно-зелёном
   сукне она давала контраст около 1,2. Цвет текста всегда контрастен
   фону в любой теме, поэтому пятая его часть видна и на тёмном, и на
   светлом; вместе с толщиной в две точки линия наконец читается
   (контраст к панели 1,9 — для служебной черты в самый раз: видно,
   но она не спорит с жёлтой чертой выбранной вкладки).
   Первая строка — запас для браузеров старше 2023 года. */
#экран-эмоций .панель-знаков__вкладки {
  display: flex;
  gap: 6px;
  width: 100%;
  box-shadow: inset 0 -2px 0 var(--край);
  box-shadow: inset 0 -2px 0 color-mix(in srgb, var(--текст) 22%, transparent);
}

/* Сама вкладка. Высота 44 точки — размер пальца, меньше нельзя; черта
   снизу считается внутрь этих 44, поэтому полоска от неё не растёт.
   Подпись в одну строку всегда: перенос на две строки съел бы высоту
   и разъехался бы с соседками. Скругление только сверху — низ у вкладки
   прямой, он лежит на дорожке. */
#экран-эмоций .панель-знаков__вкладка {
  flex: 1 1 0;
  width: auto;
  min-width: 0;
  min-height: 44px;
  padding: 8px 6px;
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0;
  /* Подпись в одну строку, а если у человека в системе включён крупный
     шрифт и слово всё-таки не влезло — оно обрезается многоточием, а не
     наезжает на соседнюю вкладку. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--текст-тихий);
  background: transparent;
  border: none;
  border-radius: 10px 10px 0 0;
  box-shadow: none;
  /* Место под черту выбранной вкладки занято всегда — иначе при
     переключении подписи прыгали бы на три точки вверх-вниз. */
  border-bottom: 3px solid transparent;
}

/* ВЫБРАННАЯ ВКЛАДКА ОТЛИЧАЕТСЯ ЧЕТЫРЬМЯ ПРИЗНАКАМИ СРАЗУ, и это не запас
   ради красоты. Цвет пропадает первым: на солнце экран выцветает, а каждый
   двенадцатый мужчина плохо различает оттенки. Поэтому работают ещё три:
   толстая черта снизу (она же показывает, что ряд знаков под ней принадлежит
   именно этой вкладке), жирная подпись (видна и в чёрно-белом) и мягкая
   заливка.

   ПОСЧИТАННЫЙ КОНТРАСТ. Главный признак — черта. Меряем её против того,
   что на этом месте у невыбранной вкладки, то есть против фона панели:
     — запасная тёмная тема (панель 11,58,32, черта 255,220,131) — 9,6;
     — светлая тема Telegram (панель 241,241,241, черта 42,118,193) — 4,2;
     — тёмная тема Telegram (панель 24,24,24, черта 157,141,230) — 6,2.
   Худшее из трёх — 4,2 при нашем пороге 3,0.
   Заливка сама по себе слабее (1,5) — она четвёртый признак, а не первый.

   ПОЧЕМУ ЧЕРТА НЕ ЧИСТЫМ ЦВЕТОМ ТЕМЫ. Так сделано в шашках, и на белом
   фоне светлой темы синий Telegram даёт всего 2,9 — ниже порога. Подмешиваем
   к нему пятую часть цвета текста: текст в теме всегда контрастен фону,
   поэтому примесь всегда двигает черту в сторону контраста — в тёмной теме
   светлее, в светлой темнее. Первые строки в обеих парах — запас для
   браузеров старше 2023 года, которые не умеют смешивать цвета: там черта
   будет цвета текста (контраст наибольший, вид скромнее). */
#экран-эмоций .панель-знаков__вкладка.кнопка--активная {
  color: var(--текст);
  font-weight: 800;
  background: var(--подложка);
  background: color-mix(in srgb, var(--акцент) 18%, transparent);
  border-bottom-color: var(--текст);
  border-bottom-color: color-mix(in srgb, var(--акцент) 82%, var(--текст));
}

/* Нажатие. Обычная кнопка при нажатии садится на две точки вниз — вкладке
   это ни к чему: полоска дёргалась бы целиком. Вместо движения — заливка
   под пальцем, ответ виден сразу. */
#экран-эмоций .панель-знаков__вкладка:active {
  transform: none;
  background: var(--подложка);
  box-shadow: none;
}

/* Узкий телефон (320 точек). Считаем вслух: панель оставляет под полоску
   300 точек, два просвета по 5 забирают 10, значит вкладке достаётся 96.
   Подпись «Смайлики» при кегле 13 занимает около 58 плюс поля — влезает
   с запасом и не режется. */
@media (max-width: 360px) {
  #экран-эмоций .панель-знаков__вкладки { gap: 5px; }

  #экран-эмоций .панель-знаков__вкладка {
    padding: 8px 3px;
    font-size: 13px;
  }
}

/* Ряд кнопок переносится сам, если не влез. Просвет тесноват нарочно:
   шесть смайликов должны вставать в один ряд на телефоне в 360 точек.
   При просвете в 8 шестой переносился на новую строку, и ряд читался
   как «пять и один». */
.ряд-знаков {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 6px;
  width: 100%;
}

/* Класс в селекторе назван дважды нарочно — тем же приёмом, что и
   «.кнопка.кнопка--мелкая» выше: иначе общее правило кнопок окажется
   сильнее, и четырнадцать кнопок шириной по 116 точек займут две трети
   экрана (замер разработчика: панель выросла до 489 точек).

   Смайлик крупный — по нему целятся пальцем, а читать в нём нечего.
   Фраза мельче: в ней слова, и кнопка растёт от их длины. Высота
   у обеих 44 точки: это то, во что попадает палец. */
.кнопка.кнопка--смайлик {
  min-width: 0;
  min-height: 44px;
  padding: 4px 7px;
  font-size: 26px;
  line-height: 1;
}

.кнопка.кнопка--фраза {
  min-width: 0;
  min-height: 44px;
  padding: 8px 12px;
  font-size: 14px;
  font-weight: 600;
}

/* Кнопка «Сказать» живёт в панели действий стола — узкая третья справа
   (см. «Панель действий» в разделе стола в конце файла). */

/* ---------- Панель знаков на узком или невысоком телефоне ----------

   Тридцать две кнопки на экране в 320 точек просят около семисот точек
   высоты — вдвое больше, чем есть. Прокрутка (см. выше) спасает всегда,
   но прокручивать панель выбора неудобно: человек хочет увидеть все
   знаки разом и ткнуть. Поэтому ужимаем всё, что можно ужать, кроме
   одного — высота кнопки остаётся 44 точки, это размер пальца.

   Что даёт ужатие: смайлик у́же на восемь точек, и двенадцать смайликов
   встают в два ряда вместо трёх, восемь предметов — в один вместо двух,
   фразы мельче на точку и садятся плотнее. Вместе с полями и просветами
   набегает около 165 точек — примерно четверть панели. */
@media (max-width: 360px), (max-height: 620px) {
  #экран-эмоций {
    gap: 8px;
    padding-top: 12px;
    padding-left: calc(10px + var(--отступ-слева));
    padding-right: calc(10px + var(--отступ-справа));
  }

  #экран-эмоций .ряд-знаков { gap: 5px; }

  #экран-эмоций .кнопка.кнопка--смайлик {
    padding: 4px 5px;
    font-size: 22px;
  }

  #экран-эмоций .кнопка.кнопка--фраза {
    padding: 7px 9px;
    font-size: 13px;
  }

  /* Поля у прилипшей кнопки считаются от полей панели — раз те стали
     у́же, пересчитываем и здесь, иначе её фон не дотянется до краёв. */
  #экран-эмоций #кнопка-эмоции-назад { margin-left: -10px; margin-right: -10px; }
}


/* ---------- Две двери про себя на экране рекордов ----------

   «Как я играю» и «Рейтинг игроков» отвечают на два соседних вопроса —
   «каков я» и «где я среди остальных», — и по важности равны. Поэтому
   выглядят они одинаково: одна ширина на обе (иначе кнопки по своему
   содержимому встают лесенкой и читаются как разные по весу) и обводка
   вместо заливки. Заливка на этом экране остаётся у одной кнопки —
   «Назад»: когда залито всё подряд, глазу не за что зацепиться. */
#кнопка-мой-счёт,
.кнопка.кнопка--рейтинг {
  width: min(100%, var(--колонка-кнопок));
  color: var(--текст);
  background: transparent;
  border: 2px solid var(--край);
  box-shadow: none;
}

/* ================================================================
   Рейтинг игроков — таблица «кто впереди»
   ================================================================

   Экран собирает js/рейтинг-экран.js, оформления у него не было вовсе:
   место, имя, очки и победы шли простым текстом в столбик, и своя
   строка ничем не отличалась от чужих. Здесь всё это раскладывается
   по четырём колонкам.

   Главное правило этого экрана: человек открывает рейтинг, чтобы
   найти себя. Поэтому своя строка выделена сразу тремя признаками —
   заливкой, обводкой цветом темы и жирным именем: любого одного
   признака мало, если у человека сбита цветопередача или он смотрит
   на экран под солнцем.
   ================================================================ */

/* Весь экран столбиком, с воздухом между частями. */
#экран-рейтинга-игроков {
  gap: 10px;
  align-items: center;
  text-align: center;
}

#экран-рейтинга-игроков .заголовок { font-size: 28px; }

/* Переключатель «Дурак / Шашки» — два одинаковых по ширине кнопки в ряд. */
.рейтинг-выбор {
  display: flex;
  gap: 8px;
  width: min(100%, 420px);
}

/* ---------- Вторая полоска: какая мера показана ----------

   Полосок на экране теперь две подряд — «какая игра» и «какая мера», —
   и выглядеть одинаково они не должны: две одинаковые полоски читаются
   как одна сломанная. Поэтому приёмы разведены. Игра выбирается
   кнопками, как раньше. Мера — переключателем в общей обойме: обе
   надписи лежат в одной утопленной дорожке, а выбранная едет по ней
   светлой пилюлей. Так видно, что это два вида одного и того же,
   а не два разных действия.

   У шашек вкладки в панели знаков устроены иначе (чертой снизу), и это
   тоже нарочно: там вкладки стоят внутри плашки поверх доски, а здесь
   переключатель лежит на экране сам по себе — ему идёт обойма. */
.рейтинг-меры {
  display: flex;
  gap: 4px;
  width: min(100%, 420px);
  padding: 4px;
  background: var(--подложка);
  border-radius: 999px;
}

/* Класс назван дважды нарочно: у кнопки есть общий класс кнопок выбора,
   и без этого он перебил бы здешние правила. */
.рейтинг-меры .кнопка.кнопка--выбор {
  flex: 1 1 0;
  min-width: 0;
  min-height: 44px;                 /* размер пальца, меньше нельзя */
  padding: 8px 6px;
  font-size: 14px;
  font-weight: 600;
  color: var(--текст-тихий);
  background: transparent;
  border: none;
  border-radius: 999px;
  box-shadow: none;
}

/* Выбранная мера отличается не только цветом: она залита пилюлей
   (форма видна и в чёрно-белом), подпись жирнее, и лежит она будто
   приподнятой над дорожкой. */
.рейтинг-меры .кнопка.кнопка--выбор.кнопка--активная {
  color: var(--текст);
  font-weight: 800;
  background: color-mix(in srgb, var(--акцент) 30%, var(--панель));
  box-shadow:
    inset 0 0 0 1px color-mix(in srgb, var(--акцент) 55%, transparent),
    0 1px 3px rgba(0, 0, 0, 0.22);
}

/* Своё место словами — под переключателем. Строка бывает крупной
   («7 место») и обычной («Вас в таблице пока нет»); крупную рисует
   класс «серия», ей ничего добавлять не нужно. */
#рейтинг-моё-место { text-align: center; }

/* Пояснение внутри таблицы («Всего в таблице 40 игроков…») — мельче
   строк, оно справочное, а не главное. */
/* Пояснение внутри таблицы. Выровнено по левому краю нарочно: коротким
   строкам центр не мешает, но когда игру открыли мимо Telegram, здесь
   лежит абзац в шесть строк («рейтинг ведётся по учётной записи…»),
   а длинный текст с рваными краями читается заметно хуже — глазу негде
   зацепиться в начале каждой строки. */
#рейтинг-таблица > .подпись:first-child {
  font-size: 13px;
  line-height: 1.35;
  margin-bottom: 2px;
  text-align: left;
}

/* ---------- Ярлык раздела и обычные фразы — разные вещи ----------

   Мелкие прописные хороши для КОРОТКОГО ЯРЛЫКА: «ВЫ И СОСЕДИ ПО СИЛЕ»,
   «ИГРОК», «СИЛА». Но предложение прописными читается заметно медленнее:
   слова теряют форму, и глаз разбирает их по букве. А ещё это звучит
   как повышенный голос.

   Раньше правило ловило «вторую подпись подряд» — и было верным, пока
   подписей было ровно две. Потом сервер начал присылать в таблицу целые
   фразы («4 место в таблице силы», «сыграно 601 партия…»), и прописными
   стало набрано пять предложений кряду.

   Теперь ярлык узнаётся по своему месту, а не по счёту: это подпись,
   сразу за которой начинается шапка таблицы. Так оно и есть по смыслу —
   ярлык подписывает то, что под ним. Браузер старше 2023 года такого
   не умеет: там ярлык останется обычными буквами. Это не беда —
   предложения важнее, а они правильны везде. */
#рейтинг-таблица > .подпись:has(+ .рейтинг-строка--шапка) {
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.8px;
  text-align: left;
  margin-top: 4px;
}

/* Обычные фразы в таблице — те самые предложения от сервера. Они
   читаются подряд, поэтому набраны как текст: обычные буквы, ровный
   левый край, строки чуть просторнее. Кегль мельче общей подписи —
   это подробности под главным числом, а не заголовок. */
#рейтинг-таблица > .подпись {
  font-size: 13px;
  line-height: 1.4;
  text-align: left;
}

/* ---------- Готовая фраза сервера под главным числом ----------

   Ради неё всё и затевалось. Число силы человек видит сразу, но само
   по себе оно молчит: упало — и непонятно, наказали тебя или так вышло.
   Фраза объясняет: «измерена уверенно» или «ещё приблизительная,
   сыграйте ещё двенадцать партий».

   Поэтому она оформлена не как подпись, а как маленькая карточка:
   своя подложка, полоска цвета темы слева и кегль крупнее обычной
   подписи. Полоска слева — тот приём, которым в тексте отмечают
   выделенное: глаз цепляется за неё раньше, чем начинает читать.
   Селектор нарочно длинный: правило для первого абзаца в таблице
   (см. выше) сильнее короткого и иначе оставило бы фразу мелкой. */
#рейтинг-таблица > .подпись.рейтинг-пояснение {
  margin: 2px 0 6px;
  padding: 9px 12px 9px 11px;
  font-size: 14px;
  line-height: 1.4;
  text-align: left;
  color: var(--текст);
  background: color-mix(in srgb, var(--акцент) 14%, var(--подложка));
  border-left: 3px solid var(--акцент);
  border-radius: 4px 10px 10px 4px;
}

/* ---------- Соперники последней партии ----------

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

   Подложка у всех трёх одинаковая и очень слабая: строки складываются
   в аккуратный список, но ни одна не выделена как «плохая». */
#рейтинг-таблица > .подпись.рейтинг-соперник {
  display: flex;
  align-items: baseline;
  gap: 7px;
  margin: 0;
  padding: 6px 10px;
  font-size: 13px;
  line-height: 1.35;
  text-align: left;
  color: var(--текст);
  background: color-mix(in srgb, var(--текст) 7%, transparent);
  border-radius: 8px;
}

/* Знак перед строкой. Он же держит левый край ровным: ширина у всех
   трёх одна, поэтому имена начинаются на одной вертикали. */
.рейтинг-соперник::before {
  flex: 0 0 auto;
  width: 1.1em;
  font-weight: 700;
  text-align: center;
  color: var(--текст-тихий);
}

.рейтинг-соперник--сильнее::before { content: "↑"; }
.рейтинг-соперник--слабее::before  { content: "↓"; }
.рейтинг-соперник--вровень::before { content: "="; }

/* ---------- Строка таблицы ----------

   Четыре колонки: номер места, имя, очки, победы. Имя занимает всё
   свободное место и обрезается многоточием — длинное имя из Telegram
   («Александр Константинопольский») не должно раздвигать столбцы
   и утаскивать очки за край экрана. Цифры набраны моноширинными
   (tabular-nums): столбик цифр стоит ровно, как в бумажной ведомости. */
.рейтинг-строка {
  display: grid;
  /* Столбец с числом умеет подрасти. Приблизительная сила пишется
     со знаком «≈» впереди, а он шире цифры и в жёсткие 3,4 знака
     не помещался — число ужималось или переносилось. Теперь ширина
     считается по содержимому, но не меньше прежней: столбец не скачет
     от строки к строке, а знак влезает. Имя рядом ужмётся само,
     у него на этот случай многоточие. */
  grid-template-columns: 28px minmax(0, 1fr) minmax(3.4em, auto) 3.6em;
  align-items: center;
  gap: 0 8px;
  min-height: 40px;
  padding: 6px 10px;
  background: var(--подложка);
  border-radius: 10px;
  text-align: left;
}

.рейтинг-место {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  background: var(--подложка);
  font-size: 13px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--текст-тихий);
}

.рейтинг-имя {
  font-size: 15px;
  line-height: 1.2;
  /* Длинное имя обрезается многоточием и никуда не выезжает. */
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.рейтинг-очки {
  font-size: 16px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

/* Побед из партий — справочное число, поэтому тише и мельче очков. */
.рейтинг-победы {
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--текст-тихий);
  text-align: right;
  white-space: nowrap;
}

/* ---------- Шапка ----------
   Не строка, а подписи к столбцам: без плашки, мелко и тихо.

   Она приклеена к верху списка, и это не украшение, а починка. На узком
   телефоне таблица не помещается целиком, человек её прокручивает — и на
   снимке 320 точек было видно, как ярлык «ВЫ И СОСЕДИ ПО СИЛЕ» режется
   верхним краем ровно посередине букв: выглядит как поломка вёрстки.
   Теперь всё, что уезжает вверх, прячется ПОД шапкой, а сама шапка
   стоит на месте — заодно видно, что за столбцы, до какой бы строки
   ни домотал.

   Фон у неё непрозрачный и в тон сукну: сквозь прозрачный просвечивали
   бы уезжающие строки. Первая строка — запас для браузеров без
   color-mix, там шапка будет просто цвета темы. */
.рейтинг-строка.рейтинг-строка--шапка {
  position: sticky;
  top: 0;
  z-index: 2;
  min-height: 0;
  padding: 4px 10px 3px;
  background: var(--фон);
  background: color-mix(in srgb, var(--фон) 62%, #1f7a45);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--текст-тихий);
}

.рейтинг-строка--шапка .рейтинг-место {
  width: 24px;
  height: auto;
  background: none;
  font-size: 11px;
  color: inherit;
}

.рейтинг-строка--шапка .рейтинг-имя,
.рейтинг-строка--шапка .рейтинг-очки,
.рейтинг-строка--шапка .рейтинг-победы {
  font-size: 11px;
  font-weight: 700;
  color: inherit;
}

/* ---------- Своя строка ----------
   Её ищут глазами первой, поэтому она отличается от соседей заливкой,
   рамкой цветом темы и жирным именем разом. */
.рейтинг-строка.рейтинг-строка--я {
  background: var(--подложка);
  background: color-mix(in srgb, var(--акцент) 24%, var(--подложка));
  box-shadow:
    inset 0 0 0 2px var(--акцент),
    0 2px 8px rgba(0, 0, 0, 0.22);
  min-height: 44px;
}

.рейтинг-строка--я .рейтинг-имя {
  font-weight: 700;
  color: var(--текст);
}

.рейтинг-строка--я .рейтинг-очки { font-size: 17px; }

.рейтинг-строка--я .рейтинг-место {
  color: var(--текст);
  background: color-mix(in srgb, var(--акцент) 45%, transparent);
}

.рейтинг-строка--я .рейтинг-победы { color: var(--текст); }

/* ---------- Тройка сильнейших ----------

   Первое, второе и третье место помечены кружком цвета медали. Работает
   это по атрибуту «data-место» на строке, который проставляет игра:
   из самого оформления номер места не виден (он лежит текстом внутри
   ячейки), а считать «первые три строки сверху» нельзя — в разделе
   «Вы и соседи» сверху стоят соседи, скажем, седьмое место.
   Пока атрибута нет, кружки просто одинаковые, ничего не ломается. */
.рейтинг-строка[data-место="1"] .рейтинг-место {
  color: #3a2a05;
  background: linear-gradient(160deg, #ffdc73, #e0a516);
}

.рейтинг-строка[data-место="2"] .рейтинг-место {
  color: #2b2f33;
  background: linear-gradient(160deg, #eef2f6, #b7c1cb);
}

.рейтинг-строка[data-место="3"] .рейтинг-место {
  color: #3a2410;
  background: linear-gradient(160deg, #eab989, #c07f45);
}

/* Верхняя строка списка стоит чуть просторнее — у таблицы появляется
   «шапка списка», а не сплошная лента одинаковых полосок. */
.рейтинг-строка--шапка + .рейтинг-строка { min-height: 44px; }

/* Низ списка мягко тает. Раньше последняя видимая строка резалась
   краем пополам — на снимке 390 точек это «9 Света 1507» с отрубленными
   буквами. Обрез при прокрутке неизбежен, но рубленые буквы читаются
   как поломка, а затухание — как «список продолжается, крутите дальше».
   Полоска короткая, всего 16 точек: длиннее — и последняя строка
   становится блёклой, а её надо читать. */
#рейтинг-таблица {
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 16px), transparent);
  mask-image: linear-gradient(to bottom, #000 calc(100% - 16px), transparent);
}

/* Объяснение «как считаются очки» — обычный текст, а не таблица. */
#рейтинг-объяснение {
  gap: 6px;
  text-align: left;
}

#рейтинг-объяснение .подпись { font-size: 13px; line-height: 1.4; }

/* ---------- Рейтинг на узком телефоне ----------
   На 320 точках колонка побед забирает слишком много: ужимаем кегли
   и просветы, но высоту строки не трогаем — по ней попадают пальцем. */
@media (max-width: 360px) {
  .рейтинг-строка {
    grid-template-columns: 24px minmax(0, 1fr) minmax(3.2em, auto) 3.4em;
    gap: 0 6px;
    padding: 6px 8px;
  }

  .рейтинг-место { width: 22px; height: 22px; font-size: 12px; }
  .рейтинг-имя { font-size: 14px; }
  .рейтинг-очки { font-size: 15px; }
  .рейтинг-победы { font-size: 11px; }
}

/* =====================================================================
   СТОЛ ДУРАКА ПО ЭТАЛОНУ ВЛАДЕЛЬЦА (10 сентября, вечер)

   Цель — картинка «эталон/9-дурак-стол-итог.png» (941×1672). Владелец
   сказал: «не один в один, а как концепт, как витрину». Поэтому с неё
   берём устройство и материалы, а цвета — общие цвета сборника
   («--сб-…», см. раздел витрины), а не числа из README набора.

   Что поменялось против прежнего стола:
     • страница тёмная, как витрина, в любой теме Telegram;
     • стол — отдельный предмет: деревянная рама и бордовое сукно;
     • соперник — тёмная панель с аватаром, а не веер во всю ширину;
     • акцент один — салатовый: чей ход, какая карта выбрана и куда
       её можно положить;
     • карты кремовые, масти в две краски, как в наборе;
     • кнопки тёмные, с контуром и значками из набора.

   КАК ПЕРЕВОДИТЬ КАРТИНКУ В ТОЧКИ — как у витрины: ширина 941 → 390,
   всё умножаем на 0,414. Поэтому высоты рядов заданы долями ширины
   экрана (vw): на 360, 390 и 430 экран выглядит той же картинкой.

   КАК УСТРОЕН ЭКРАН. Столбик рядов сверху вниз: (шапка), соперник,
   стол, (строка «Вы»), подсказка, своя рука, кнопки. У всех рядов,
   кроме стола, высота постоянная. Стол забирает остаток, а карты на нём
   и колода меряются ОТ РАЗМЕРА САМОГО СТОЛА — единицами cqw и cqh,
   «сотая доля ширины и высоты моей коробки». Отсюда главное свойство:
   что бы ни случилось с высотой окна, стол не может наехать на соседей,
   он просто становится меньше — и карты на нём вместе с ним.

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

:root {
  /* Бумага карты, две краски мастей и размер карты в руке — в начале
     файла, в общем списке цветов и размеров. */

  /* ---------- Значки из набора владельца ----------
     Это копии файлов «img/дурак/значки/*.svg» (аватар, «Взять», «Бито»,
     чат), вписанные прямо сюда. Почему копии, а не ссылки
     на файлы: значок рисуется маской, а маску браузер берёт только
     у файла, который сервер назвал картинкой. Проверочный сервер
     проекта называет .svg «неизвестными данными» — и все значки молча
     пропадали. Вписанный значок от сервера не зависит вовсе и не стоит
     ни одного лишнего запроса. Цвет у маски не важен (важна форма),
     поэтому линии здесь просто чёрные — красит их цвет текста кнопки.
     Четыре последних значка («Пас», «Готово», «Перевести», «Бросить»)
     в наборе не нашлись и нарисованы здесь тем же пером: сетка 24,
     линия 1,7–1,8, круглые концы. */
  --значок-аватар: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Ccircle cx='12' cy='9' r='3' fill='black' stroke='none'/%3E%3Cpath d='M6 19v-2c0-5 12-5 12 0v2c-4 2-8 2-12 0Z' fill='black' stroke='none'/%3E%3C/svg%3E");
  --значок-взять: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='5' y='3' width='12' height='18' rx='2' transform='rotate(-12 11 12)'/%3E%3Cpath d='M19 4h2v15h-2'/%3E%3C/svg%3E");
  --значок-бито: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4 3 4 2 12 14M3 4l2 4 14 12M20 3l-4 2L4 19M21 4l-2 4L5 20M3 15l6 6M15 21l6-6'/%3E%3C/svg%3E");
  --значок-чат: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 3h14a3 3 0 0 1 3 3v10a3 3 0 0 1-3 3h-8l-6 4v-4a3 3 0 0 1-3-3V6a3 3 0 0 1 3-3Z'/%3E%3Cpath d='M7 11h.01M12 11h.01M17 11h.01'/%3E%3C/svg%3E");
  --значок-пас: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 12h12M12 7l5 5-5 5M20 5v14'/%3E%3C/svg%3E");
  --значок-готово: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12.5l4.2 4.2L19 7'/%3E%3C/svg%3E");
  --значок-перевести: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4 8h14M14 4l4 4-4 4M20 16H6M10 12l-4 4 4 4'/%3E%3C/svg%3E");
  --значок-бросить: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 3v8M9 6l3-3 3 3'/%3E%3Crect x='6.5' y='11.5' width='11' height='9.5' rx='2'/%3E%3C/svg%3E");
}

/* «:has(> #зона-стола)» — не лишнее. Игровой экран нард называется
   так же, «экран-игры» (нарды.html), и тоже подключает этот файл. Без
   уточнения тёмный фон, поля и салатовые кнопки стола дурака ложились
   и на нарды: их доска становилась у́же, а «Бросить кубики» — салатовой.
   Стол дурака — единственный «экран-игры», внутри которого лежит
   «зона-стола», поэтому правило держится ровно за него. */
#экран-игры:has(> #зона-стола) {
  /* Свои цвета поверх цветов темы — только внутри стола. Все прежние
     правила игры, которые берут «--текст», «--подложка», «--акцент»,
     сами переходят на тёмный вид с салатовым акцентом. Другие экраны
     этих значений не видят и остаются как были. */
  --фон: var(--сб-фон);
  --панель: var(--сб-поверхность);
  --текст: var(--сб-текст);
  --текст-тихий: var(--сб-текст-тихий);
  --кнопка-фон: var(--сб-акцент);
  --кнопка-текст: var(--сб-акцент-текст);
  --акцент: var(--сб-акцент);
  --подложка: rgba(248, 245, 235, 0.06);
  --край: rgba(248, 245, 235, 0.14);
  --граница-тихая: rgba(248, 245, 235, 0.09);

  /* Поля и промежутки — как у витрины: 14 и 8 точек на экране 390. */
  --поле: clamp(12px, 3.6vw, 18px);
  --зазор-рядов: clamp(6px, 2vw, 10px);
  /* Высоты рядов сняты с макета: панель соперника 142 из 1672 → 59
     точек на 390, ряд кнопок 116 → 48. */
  --ряд-соперника: clamp(52px, 15vw, 64px);
  --ряд-кнопок: clamp(46px, 12.3vw, 54px);

  gap: var(--зазор-рядов);
  padding: calc(6px + var(--отступ-сверху)) calc(var(--поле) + var(--отступ-справа))
           calc(8px + var(--отступ-снизу))  calc(var(--поле) + var(--отступ-слева));
  color: var(--сб-текст);
  /* Тот же фон, что у витрины: ровный тёмный и едва заметное салатовое
     свечение у верхнего края. */
  background:
    radial-gradient(75% 120px at 50% 0, rgba(210, 247, 107, 0.07), rgba(210, 247, 107, 0) 100%),
    var(--сб-фон);
}

/* На компьютере столбик не шире, чем у витрины (520 точек), и стоит
   посередине. На телефоне ограничение не срабатывает. */
#экран-игры > .верх-игры,
#экран-игры > .шапка-игры,
#экран-игры > #соперники,
#экран-игры > #рука-бота,
#экран-игры > #строка-меня,
#экран-игры > #подсказка,
#экран-игры > #рука-человека,
#экран-игры > #панель-кнопок {
  width: 100%;
  max-width: 520px;
  align-self: center;
}

/* Пока висит итог партии, стол больше не приподнимается: считать
   «свободное место» по-старому здесь нечем, а плашка итога и так
   закрывает только руку и кнопки — стол над ней виден целиком. */
#приложение:has(#экран-результата.экран--виден) #экран-игры {
  padding-bottom: calc(8px + var(--отступ-снизу));
}

/* ---------- Верхняя строка «‹ · ⋯» — только в браузере ----------
   Внутри Telegram такую строку рисует он сам (его стрелка «Назад»
   и меню «⋯»), поэтому там наша прячется целиком — как у витрины.
   В браузере — две кнопки-значка без подложки по краям, каждая 44×44
   под палец; поля отрицательные, чтобы значки встали у самого края,
   как «⋯» на витрине. */
.верх-игры {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 44px;
  /* Поля экрана по бокам — 8px плюс безопасный отступ (var(--отступ-слева/справа),
     см. начало файла), а не 10px: раньше здесь стояло круглое число,
     и полоса выезжала на 2px за оба края окна на любой ширине. */
  margin: -4px calc(-8px - var(--отступ-справа)) -8px calc(-8px - var(--отступ-слева));
}

html.в-телеграме .верх-игры { display: none; }

#экран-игры > .верх-игры {
  width: calc(100% + 16px + var(--отступ-слева) + var(--отступ-справа));
  max-width: 536px;
}

.верх-игры__кнопка {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  padding: 0;
  font: inherit;
  line-height: 1;
  color: var(--сб-текст);
  background: none;
  border: none;
  border-radius: 12px;
  cursor: pointer;
}

.верх-игры__кнопка svg {
  display: block;
  width: 24px;
  height: 24px;
}

.верх-игры__кнопка:active { transform: scale(0.92); opacity: 0.7; }

.верх-игры__кнопка:focus-visible {
  outline: 2px solid var(--сб-акцент);
  outline-offset: -4px;
}

/* Лист «Ещё» — тот же, что у витрины, но у стола свой узел. Цвета
   витрины («--вт-…») объявлены только на самой витрине, поэтому листу
   даём их здесь же: он выглядит одинаково, где бы его ни открыли. */
/* Лист стола открывается и поверх итога партии — значит, лежит выше
   плашек итога и вопроса о выходе (у тех слой 100). */
#лист-игры { z-index: 110; }

/* Пока показан итог, игровой экран касаний не ловит (см. «Кто ловит
   касания, когда показан итог») — а верхняя строка «‹ ⋯» и лист стола
   лежат внутри него. Без этого правила в браузере на итоге не нажимались
   ни «‹», ни «⋯» (проверено: касание уходило мимо), то есть дорога
   к «Как играть», «Звуку» и «Рекордам» была закрыта. Возвращаем касания
   только им двоим; стол под плашкой по-прежнему не нажимается. */
#приложение:has(#экран-результата.экран--виден) #экран-игры .верх-игры,
#приложение:has(#экран-результата.экран--виден) #лист-игры {
  pointer-events: auto;
}

.лист-ещё {
  --вт-поле: clamp(12px, 3.6vw, 18px);
  --вт-поверхность: var(--сб-поверхность);
  --вт-граница: var(--сб-граница);
  --вт-текст: var(--сб-текст);
  --вт-текст-тихий: var(--сб-текст-тихий);
  --вт-акцент: var(--сб-акцент);
  --вт-акцент-текст: var(--сб-акцент-текст);
}

/* ---------- Шапка: «Дурак» и строка режима ----------
   Та же пара, что «Во что сыграем?» на витрине: жирный заголовок
   и серая строка под ним. В низком окне шапка сжимается в одну мелкую
   строку (см. ниже): стол и рука важнее крупного названия, но режим
   партии («Подкидной · 52 карты») человек должен видеть всегда. */
.шапка-игры {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

.шапка-игры__заголовок {
  margin: 0;
  font-size: clamp(26px, 8.2vw, 37px);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--сб-текст);
}

.шапка-игры__подзаголовок {
  margin: 0;
  font-size: clamp(13px, 3.6vw, 16px);
  line-height: 1.3;
  color: var(--сб-текст-тихий);
}

/* ---------- Шапка в низком окне — одна строка ----------
   Раньше при высоте до 700 шапка пряталась целиком. Но в Telegram без
   полного экрана окно часто ниже 700, и режим партии («Переводной ·
   52 карты») не было видно нигде — человек садился за стол, не зная,
   во что играет. Теперь шапка сжимается в одну строку высотой 24 точки:
   «Дурак · Подкидной · 36 карт», по центру, название белым, режим серым.
   Не влезает по ширине — режим обрезается многоточием, название остаётся.

   Где стоит строка:
     • в браузере — в строке «‹ ⋯», между кнопками, где всё равно пусто.
       Высоты она там не отнимает вовсе: всё ниже стоит, где стояло;
     • в Telegram нашей строки «‹ ⋯» нет — там одна строка над столом,
       это 24 точки плюс обычный просвет.
   Касаний строка не ловит: над ней кнопки «‹» и «⋯», и её коробка
   не должна их перекрывать. */
@media (max-height: 700px) {
  .шапка-игры {
    flex-direction: row;
    align-items: baseline;
    justify-content: center;
    gap: 0.35em;
    box-sizing: border-box;
    height: 24px;
    padding: 0 40px;
    overflow: hidden;
    white-space: nowrap;
    pointer-events: none;
  }

  .шапка-игры__заголовок {
    flex: 0 0 auto;
    font-size: 15px;
    font-weight: 700;
    line-height: 24px;
    letter-spacing: 0;
  }

  .шапка-игры__подзаголовок {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 13px;
    line-height: 24px;
  }

  /* Точка между названием и режимом — только когда режим уже написан. */
  .шапка-игры__подзаголовок:not(:empty)::before {
    content: "· ";
  }

  /* Строка «‹ ⋯» видна (в браузере и в старом Telegram — см. «без-настроек»):
     шапка поднимается в неё. «‹ ⋯» занимает в столбике 32 точки (44 минус
     поля), значит шапка встаёт на 24 точки выше своего места плюс просвет
     между рядами — и следующая за ней полоса остаётся ровно там же. */
  html:not(.в-телеграме) #экран-игры > .верх-игры + .шапка-игры,
  html.в-телеграме.без-настроек #экран-игры > .верх-игры + .шапка-игры {
    margin-top: calc(-24px - var(--зазор-рядов));
  }
}

/* ---------- Старый Telegram (до 7.0): нет пункта «Настройки» ----------
   В новом Telegram лист «Ещё» стола открывается пунктом «Настройки»
   в его меню, поэтому нашу строку «‹ ⋯» мы там прячем. В старом такого
   пункта нет — и лист со звуком, правилами и рекордами было бы открыть
   нечем. Признак ставит игра на <html> (класс «без-настроек»): тогда
   строка снова видна, но только с «⋯» — стрелку «Назад» Telegram рисует
   сам. «‹» не убираем из строки, а делаем невидимой: так «⋯» остаётся
   справа, где её ищут. Витрина — так же: её строка видна, но без
   названия (его пишет шапка Telegram) — только «⋯». */
html.в-телеграме.без-настроек .верх-игры { display: flex; }

/* «‹» — первая кнопка строки: на столе, в лобби и на шагах до партии. */
html.в-телеграме.без-настроек .верх-игры > .верх-игры__кнопка:first-child { visibility: hidden; }

html.в-телеграме.без-настроек .витрина__панель { display: grid; }

html.в-телеграме.без-настроек .витрина__панель-заголовок { visibility: hidden; }

/* ---------- Аватар ----------
   Кружок с человечком — значок «avatar.svg» из набора. Рисуется маской:
   форму даёт значок, цвет — цвет текста. Поэтому один и тот же значок
   бывает серым (ждёт) и салатовым (сейчас его ход) без второй картинки.
   Пока в строке соперника нет настоящего узла «аватар», кружок рисует
   сама строка (::before); появится узел — строка рисовать перестанет. */
.аватар,
#рука-бота:not(:has(> .аватар))::before {
  content: "";
  flex: 0 0 auto;
  display: block;
  width: var(--аватар, 40px);
  height: var(--аватар, 40px);
  color: #8a9199;
  background-color: currentColor;
  -webkit-mask: var(--значок-аватар) center / contain no-repeat;
  mask: var(--значок-аватар) center / contain no-repeat;
}

/* ---------- Строка игрока: соперник вдвоём и «Вы» ----------
   Тёмная панель на тон светлее страницы, тонкая светлая кромка и мягкая
   тень — как панель «Соперник» на макете. Класс общий: такую же строку
   получат шашки, шахматы и нарды. Пока разработчик не поставил класс
   на ряд соперника, правило держится за его идентификатор. */
.строка-игрока,
#экран-игры > #рука-бота {
  --аватар: clamp(34px, 10.5vw, 46px);
  position: relative;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: clamp(9px, 3vw, 14px);
  height: var(--ряд-соперника, 58px);
  max-height: none;
  padding: 0 clamp(8px, 2.6vw, 12px);
  color: var(--сб-текст);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0) 70%),
    var(--сб-поверхность);
  border: 1px solid var(--граница-тихая, rgba(248, 245, 235, 0.09));
  border-radius: 14px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.04),
    0 6px 16px rgba(0, 0, 0, 0.28);
}

/* Чей ход — салатовое кольцо у аватара, как у «Вы» на макете. Кольцо
   одно на весь экран, и оно всегда у того, кто сейчас ходит. */
.строка-игрока--ходит .аватар,
#рука-бота.строка-игрока--ходит:not(:has(> .аватар))::before {
  color: var(--сб-акцент);
}

.строка-игрока--ходит {
  border-color: rgba(210, 247, 107, 0.32);
}

/* Строка «Вы» ниже строки соперника (на макете 39 точек против 59):
   в ней нет веера, только имя и плашка статуса справа. */
.строка-игрока--я {
  --аватар: clamp(28px, 8.5vw, 36px);
  height: clamp(40px, 11.3vw, 50px);
  gap: clamp(8px, 2.6vw, 12px);
  padding: 0 5px 0 clamp(6px, 2vw, 9px);
}

.строка-игрока__имя {
  flex: 0 0 auto;
  font-size: clamp(15px, 4.3vw, 18px);
  font-weight: 700;
  line-height: 1.2;
  white-space: nowrap;
  color: var(--сб-текст);
}

/* ---------- Плашка статуса («пилюля») ----------
   Круглая плашка по размеру слов у правого края строки: «Вы отбиваетесь»,
   «Ваш ход», «Ход соперника». Когда ход ваш — салатовая с почти чёрным
   текстом, как на макете; когда ждём — тихая, только контур. Пустая
   плашка не рисуется вовсе. Класс общий для всех игр. */
.пилюля {
  flex: 0 1 auto;
  min-width: 0;
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  height: calc(100% - 10px);
  max-height: 34px;
  padding: 0 clamp(12px, 3.6vw, 16px);
  font-size: clamp(13px, 3.8vw, 16px);
  font-weight: 600;
  line-height: 1;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: var(--сб-текст-тихий);
  border: 1px solid var(--сб-граница);
  border-radius: 999px;
}

.пилюля:empty { display: none; }

.пилюля--акцент {
  font-weight: 700;
  color: var(--сб-акцент-текст);
  background: var(--сб-акцент);
  border-color: var(--сб-акцент);
}

/* Подпись соперника: имя крупно и белым, «6 карт» — серым под ним.
   Раньше это была пилюля под веером; теперь это текст панели. */
#рука-бота #счётчик-бота {
  position: static;
  order: 1;
  flex: 1 1 auto;
  min-width: 0;
  max-width: none;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 0.3em;
  padding: 0;
  font-size: clamp(13px, 3.6vw, 15px);
  font-weight: 500;
  line-height: 1.3;
  text-align: left;
  white-space: nowrap;
  color: var(--сб-текст-тихий);
  background: none;
  border-radius: 0;
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  overflow: hidden;
}

#рука-бота #счётчик-бота .счётчик__имя {
  flex: 0 0 100%;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: clamp(14px, 4.1vw, 17px);
  font-weight: 700;
  color: var(--сб-текст);
}

/* Веер рубашек справа: карты внахлёст, прижаты к правому краю, как на
   макете. Рубашка — 12,5 сотых ширины экрана (49 точек на 390; на макете
   51, но у нас имя длиннее — «Обычный соперник», — и ему нужна ширина).
   Позиции карт внутри веера считает игра; ширину веера задаём по числу
   рубашек, чтобы короткий веер стоял у правого края, а не посередине. */
#рука-бота > #карты-бота {
  --рубашка-в: clamp(40px, 12.5vw, 54px);
  --в: var(--рубашка-в);
  --ш: calc(var(--рубашка-в) / 1.4);
  --рубашек: 6;
  position: relative;
  inset: auto;
  order: 2;
  flex: 0 0 auto;
  width: min(40%, calc(var(--ш) * (1 + (var(--карт-в-веере, var(--рубашек)) - 1) * 0.5)));
  height: calc(var(--в) + 4px);
}

#карты-бота:not(:has(> :nth-child(2)))                        { --рубашек: 1; }
#карты-бота:has(> :nth-child(2)):not(:has(> :nth-child(3)))   { --рубашек: 2; }
#карты-бота:has(> :nth-child(3)):not(:has(> :nth-child(4)))   { --рубашек: 3; }
#карты-бота:has(> :nth-child(4)):not(:has(> :nth-child(5)))   { --рубашек: 4; }
#карты-бота:has(> :nth-child(5)):not(:has(> :nth-child(6)))   { --рубашек: 5; }

/* ---------- Стол: деревянная рама и бордовое сукно ----------
   Картинок нет: всё рисуется слоями.
     сукно — тёмно-бордовый, светлее к середине и темнее к краям,
             поверх мелкое зерно ткани (тот же шум, что был у зелёного
             стола) и тень от рамы внутрь;
     рама  — рамка элемента, залитая деревом: сверху светлее, снизу
             темнее (свет падает сверху), поверх продольные волокна,
             по внешнему краю фаска — светлая кромка сверху и тёмная
             снизу (её рисует ::before).
   Стол почти касается краёв экрана — на макете рама шире панелей.
   Класс общий («стол-игры»): шашки и нарды получат ту же раму, со своим
   сукном — цвета сукна вынесены в переменные. */
#зона-стола,
.стол-игры {
  --рама: clamp(7px, 2.3vw, 11px);
  --сукно-свет: #6e181c;
  --сукно: #4f0d10;
  --сукно-тень: #2a0507;
  --дерево-свет: #9a6841;
  --дерево: #75492b;
  --дерево-тень: #4a2b17;

  /* Стол — мерка для всего, что на нём лежит (см. начало раздела). */
  container: стол / size;
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  /* Выше этого столу расти незачем: два ряда пар в полный рост уже
     помещаются. Лишняя высота уходит воздухом над столом и под ним. */
  max-height: min(95vw, 480px);
  align-self: center;
  width: min(calc(100% + 2 * (var(--поле, 14px) - 4px)), 540px);
  margin: auto 0;
  border: var(--рама) solid transparent;
  border-radius: calc(var(--рама) + 16px);
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3'/%3E%3CfeColorMatrix values='1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E") padding-box,
    radial-gradient(120% 95% at 50% 32%, var(--сукно-свет) 0%, var(--сукно) 50%, var(--сукно-тень) 100%) padding-box,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='60'%3E%3Cfilter id='d'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.012 0.5' numOctaves='2'/%3E%3CfeColorMatrix values='1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1'/%3E%3C/filter%3E%3Crect width='240' height='60' filter='url(%23d)' opacity='0.7'/%3E%3C/svg%3E") border-box,
    linear-gradient(180deg, var(--дерево-свет) 0%, var(--дерево) 40%, var(--дерево-тень) 100%) border-box;
  background-size: 160px 160px, auto, 240px 60px, auto;
  background-repeat: repeat, no-repeat, repeat, no-repeat;
  background-blend-mode: soft-light, normal, soft-light, normal;
  box-shadow:
    inset 0 0 0 1px rgba(0, 0, 0, 0.55),      /* шов между рамой и сукном */
    inset 0 10px 26px rgba(0, 0, 0, 0.50),    /* тень от верхнего борта */
    inset 0 -8px 20px rgba(0, 0, 0, 0.35),    /* и от нижнего */
    0 0 0 1px rgba(0, 0, 0, 0.60),            /* тёмный край рамы */
    0 14px 30px rgba(0, 0, 0, 0.55);          /* стол отбрасывает тень */
}

/* Фаска рамы: светлая кромка по верхнему внешнему краю, тёмная — по
   нижнему. Лежит под картами и касаний не ловит. */
#зона-стола::before,
.стол-игры::before {
  content: "";
  position: absolute;
  inset: calc(-1 * var(--рама));
  border-radius: inherit;
  pointer-events: none;
  box-shadow:
    inset 0 1.5px 0 rgba(255, 222, 184, 0.34),
    inset 0 -1.5px 0 rgba(0, 0, 0, 0.45),
    inset 1px 0 0 rgba(255, 222, 184, 0.10),
    inset -1px 0 0 rgba(0, 0, 0, 0.25);
}

/* ---------- Колода с козырем и подпись ----------
   Колода — стопка в левом верхнем углу сукна.

   ЖАЛОБА ВЛАДЕЛЬЦА (11 сентября): «колода карт в дураке сильно маленькая
   и плохо видно карту, которая под колодой». Было: рост колоды — 17,5
   сотых ширины ОКНА, не больше 80 точек. На телефоне это 68 точек,
   а на планшете окно широкое, и колода упиралась в свои 80 — на
   увеличенном столе она выглядела спичечным коробком.

   Стало: рост колоды считается от самого сукна — 24 сотых его ширины
   (87 точек на 390), но не больше 36 сотых его высоты и не больше 100
   точек. Почему именно так: каждая точка колоды отнимается у полосы пар
   под ней. При шести парах (два ряда) на 390×844 карта на столе выходит
   91 точку вместо 99 — всё ещё крупная, угол читается. Дальше растить
   колоду — значит мельчить пары, а они важнее: по ним отбиваются.

   Козырь лежит ПОПЕРЁК, под колодой, как кладут в настоящей игре,
   и выглядывает справа торцом на полкарты («--выгляд»). */
#зона-стола {
  /* Потолок роста колоды. На планшете и мониторе он растёт вместе
     с картой в руке (раздел «ШИРОКОЕ ОКНО» в конце файла). */
  --колода-потолок: 100px;
  --колода-в: min(24cqw, 36cqh, var(--колода-потолок));
  --колода-ш: calc(var(--колода-в) / 1.4);
  --колода-x: clamp(8px, 3vw, 14px);
  --колода-y: clamp(8px, 2.6vw, 12px);
  --выгляд: calc(var(--колода-ш) * 0.5);
  --до-подписи: clamp(10px, 3.4vw, 16px);
}

#зона-стола > #колода {
  --в: var(--колода-в);
  --ш: var(--колода-ш);
  position: absolute;
  left: var(--колода-x);
  top: var(--колода-y);
  width: calc(var(--колода-ш) + var(--выгляд));
  height: calc(var(--колода-в) + 6px);
}

/* Стопка: под верхней рубашкой видны кромки ещё нескольких карт —
   тонкие светлые и тёмные полоски снизу, как на макете. */
#колода #верх-колоды .карта {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 2;
  box-shadow:
    0 1px 0 #d8cfbb, 0 2px 0 #7f735d,
    0 3px 0 #ddd4c0, 0 4px 0 #7f735d,
    0 5px 0 #d4cab5, 0 6px 0 #6f6450,
    0 8px 12px rgba(0, 0, 0, 0.55);
}

/* Козырь поперёк. Сама карта размечена стоймя, как любая, а на бок её
   кладёт «rotate: 90deg» — поворот по часовой вокруг середины. Именно
   «rotate», а не «transform»: полёт карт пользуется «transform», и так
   они друг другу не мешают (как у пар на столе).
   Где лежит: середина козыря — на середине колоды по высоте, правый
   торец выходит из-под колоды на «--выгляд». Отсюда «left»: правый край
   лежачей карты (ширина колоды + выгляд) минус половина её длины (--в / 2)
   минус половина её ширины (--ш / 2) — потому что «left» считается
   от карты, ещё не повёрнутой.
   Тень задана вбок («2px 0»): после поворота на 90° она ложится вниз. */
#колода #козырная-карта .карта {
  position: absolute;
  left: calc(var(--колода-ш) + var(--выгляд) - var(--колода-в) / 2 - var(--колода-ш) / 2);
  top: 2px;
  z-index: 1;
  transform: none;
  rotate: 90deg;
  box-shadow: 2px 0 4px rgba(0, 0, 0, 0.45), 6px 0 12px rgba(0, 0, 0, 0.30);
}

/* Что видно в торце. У лежачей карты углы с достоинством стоят боком —
   читать их пришлось бы, наклонив голову. Поэтому в торце показываем
   третий угол рисунка («угол-козыря», js/колода-рисунок.js): у каждой
   карты он есть, но скрыт. Здесь он разворачивается обратно прямо
   («rotate(-90deg)» гасит поворот карты) и встаёт посередине торца,
   увеличенный так, чтобы занять всю видимую полоску (см. ниже, откуда
   взялись два разных числа масштаба).
   Числа — в точках рисунка карты (он 250 на 350): угол стоит у правого
   края, его середина около x = 219; середина торца — на 125 по x и на
   четверти ширины карты от её верха. Сдвиг «-94» переносит угол с края
   на середину торца.
   Последнюю карту колоды сдают в руку, и там она сама становится
   обычной — правила действуют только под колодой.

   УВЕЛИЧЕНИЕ (11 сентября): было видно плохо — мелкая надпись терялась
   рядом с колодой. У поворота на 90° оси меняются местами, поэтому два
   числа scale() отвечают за разное: первое (по бывшей ширине буквы)
   определяет, насколько знак растянется В ГЛУБИНУ, под колоду, а второе
   (по бывшей высоте столбика «достоинство над мастью») — насколько он
   заполнит полоску ПО ВЫСОТЕ. Полоска узкая (около трети ширины карты),
   а двузначная «10» и без того широкая — тяни оба числа поровну, и «10»
   упёрлась бы в колоду раньше, чем достоинство с мастью заполнили бы
   высоту. Раздельный масштаб снимает этот компромисс: 1,5 — с запасом
   даже для «10», 2 — почти во всю высоту полоски. Проверено расчётом
   по формуле поворота и снимками на 390, 360×640 и 820×1180. */
#колода #козырная-карта .карта-рисунок__угол-козыря {
  visibility: visible;
  transform-box: fill-box;
  transform-origin: center;
  transform: translate(-94px, 4px) rotate(-90deg) scale(1.5, 2);
}

/* Пока на козыре лежат рубашки, в торце — только этот угол. Значки
   середины и картинка фигуры торчали бы из-под него и путали надпись,
   а обычные углы стояли бы боком рядом с прямым. */
#колода:not(:has(#верх-колоды:empty)) #козырная-карта .карта-рисунок > g > :not(.карта-рисунок__угол-козыря) {
  visibility: hidden;
}

/* В колоде остался один козырь — рубашки над ним нет, карта видна
   целиком, со своими углами и значками. Добавочный угол был бы лишним
   и лёг бы поверх значков. Прячем. */
#колода:has(#верх-колоды:empty) #козырная-карта .карта-рисунок__угол-козыря {
  visibility: hidden;
}

/* Подпись справа от колоды: «Козырь ♥» белым, под ним серым «В колоде:
   21». Обе части уже есть в разметке, их просто переставили. По метке
   козыря нажимают (игра объясняет, что это такое), поэтому её коробка —
   44 точки в высоту, хотя буквы занимают меньше. */
#зона-стола > #метка-козыря {
  position: absolute;
  left: calc(var(--колода-x) + var(--колода-ш) + var(--выгляд) + var(--до-подписи));
  top: calc(var(--колода-y) - 2px);
  width: auto;
  max-width: calc(100% - var(--колода-x) - var(--колода-ш) - var(--выгляд) - var(--до-подписи) - 8px);
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  gap: 0.35em;
  padding: 0;
  font-size: clamp(14px, 4vw, 17px);
  font-weight: 600;
  color: var(--сб-текст);
  background: none;
  border: none;
  border-radius: 8px;
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  align-content: center;
}

#метка-козыря .метка__слово {
  font-size: 1em;
  line-height: 1;
  letter-spacing: 0;
  color: var(--сб-текст);
}

/* Знак масти — как на самой карте (чёрный у пик и треф, красный у червей
   и бубён: цвет берётся из тех же классов «карта--…», ничего своего тут
   не красим). На тёмном сукне чёрный значок один потерялся бы, поэтому
   под него — маленькая кремовая плашка цвета лица карты, с той же тонкой
   окантовкой и тенью, что у карт на столе. Так масть узнаётся с одного
   взгляда, на любом из пяти сукон. */
#метка-козыря .метка__масть {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.05em;
  line-height: 1;
  padding: 0.16em 0.4em;
  background: var(--карта-фон);
  border: 1px solid rgba(70, 48, 22, 0.28);
  border-radius: 5px;
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, 0.35),
    0 1px 2px rgba(0, 0, 0, 0.45),
    0 2px 5px rgba(0, 0, 0, 0.3);
}

#метка-козыря:active {
  transform: translateY(1px);
  box-shadow: none;
  opacity: 0.8;
}

#зона-стола #колода #счётчик-колоды {
  position: absolute;
  left: calc(100% + var(--до-подписи));
  top: clamp(26px, 7.6vw, 34px);
  width: auto;
  height: auto;
  max-width: none;
  max-height: none;
  padding: 0;
  font-size: clamp(12px, 3.5vw, 15px);
  font-weight: 500;
  line-height: 1.2;
  white-space: nowrap;
  text-align: left;
  /* Серый на бордовом: тёплый белый с прозрачностью — контраст около 6 */
  color: rgba(248, 245, 235, 0.62);
  background: none;
  border-radius: 0;
  box-shadow: none;
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  overflow: visible;
}

/* ---------- Карты на столе ----------
   Поле пар — под колодой (или справа от неё), во всю оставшуюся ширину
   сукна. Оно — мерка: размер карты считается от его ширины и высоты.

   ЖАЛОБА ВЛАДЕЛЬЦА (11 сентября): «когда больше трёх карт на столе,
   карты становятся сильно маленькими!». Причина была в арифметике:
   поле пар всегда считалось на ТРИ пары в ряд, даже когда пара одна,
   а с четвёртой пары колода уходила в столбик, отнимала ширину — и
   карта падала скачком на треть (на 390×740 — с 99 до 66 точек,
   на 390×844 с полной рукой — до 60).

   Стало — три ступени, по порядку:
     1) РЯДЫ. Для своего числа пар пробуем раскладки в один ряд, в два
        и в три и берём ту, где карта крупнее. Четыре пары — это два
        ряда по две, а не ряд на три пары и одна внизу.
     2) НАЛОЖЕНИЕ. Отбивающая карта сдвинута вправо на 46 сотых карты,
        когда места хватает, и до 30 сотых — когда тесно. Угол побитой
        карты с достоинством и мастью виден и при 30. Решает сама
        раскладка: ряд собирается по плотной ширине пары, а свободное
        место в ряду раздаётся парам обратно — до свободного наложения
        (см. «.пара» ниже).
     3) И только потом карта уменьшается — ровно настолько, насколько
        не хватает места, без скачков.
   Потолок прежний — девять десятых карты в руке: карта на столе
   не крупнее своей.

   Числа в формулах:
     0,989 — ширина пары на единицу роста карты при плотном наложении,
       с запасом на поворот: (1 + 0,30) / 1,4 × 1,065;
     1,13 — рост пары на единицу роста карты: карта, сдвиг отбивающей
       вниз на 7 сотых и запас на поворот.
   Сотые доли «cqw» и «cqh» здесь — от самого поля пар: переменные
   считаются там, где их берут пары и карты, а их мерка — это поле. */
#зона-стола > #стол {
  container-type: size;
  --пары-зазор: clamp(8px, 3vw, 14px);
  /* Предел роста карты, когда в ряду 1…6 пар (по ширине поля)… */
  --по-ширине-1: calc(100cqw / 0.989);
  --по-ширине-2: calc((100cqw - 1 * var(--пары-зазор)) / 1.978);
  --по-ширине-3: calc((100cqw - 2 * var(--пары-зазор)) / 2.967);
  --по-ширине-4: calc((100cqw - 3 * var(--пары-зазор)) / 3.956);
  --по-ширине-5: calc((100cqw - 4 * var(--пары-зазор)) / 4.945);
  --по-ширине-6: calc((100cqw - 5 * var(--пары-зазор)) / 5.934);
  /* …и когда рядов 1, 2 или 3 (по высоте поля). */
  --по-высоте-1: calc(100cqh / 1.13);
  --по-высоте-2: calc((100cqh - 1 * var(--пары-зазор)) / 2.26);
  --по-высоте-3: calc((100cqh - 2 * var(--пары-зазор)) / 3.39);
  --потолок-стола: calc(var(--в-рука) * 0.9);
  /* Одна пара: один ряд. */
  --в: min(var(--потолок-стола), var(--по-ширине-1), var(--по-высоте-1));
  --ш: calc(var(--в) / 1.4);
  --сдвиг-y: calc(var(--в) * 0.07);
  position: absolute;
  left: 6px;
  right: 6px;
  top: calc(var(--колода-y) + var(--колода-в) + 14px);
  bottom: 6px;
  display: flex;
  flex-wrap: wrap;
  align-content: center;
  justify-content: center;
  gap: var(--пары-зазор);
}

/* Две пары и больше: из раскладок «в один ряд», «в два», «в три» —
   та, где карта крупнее. Правила идут по возрастанию числа пар, вес
   у них одинаковый — срабатывает последнее подходящее. */
#зона-стола > #стол:has(> .пара:nth-child(2)) {
  --в: min(var(--потолок-стола),
           max(min(var(--по-ширине-2), var(--по-высоте-1)),
               min(var(--по-ширине-1), var(--по-высоте-2))));
}

#зона-стола > #стол:has(> .пара:nth-child(3)) {
  --в: min(var(--потолок-стола),
           max(min(var(--по-ширине-3), var(--по-высоте-1)),
               min(var(--по-ширине-2), var(--по-высоте-2))));
}

#зона-стола > #стол:has(> .пара:nth-child(4)) {
  --в: min(var(--потолок-стола),
           max(min(var(--по-ширине-4), var(--по-высоте-1)),
               min(var(--по-ширине-2), var(--по-высоте-2))));
}

#зона-стола > #стол:has(> .пара:nth-child(5)) {
  --в: min(var(--потолок-стола),
           max(min(var(--по-ширине-5), var(--по-высоте-1)),
               min(var(--по-ширине-3), var(--по-высоте-2)),
               min(var(--по-ширине-2), var(--по-высоте-3))));
}

#зона-стола > #стол:has(> .пара:nth-child(6)) {
  --в: min(var(--потолок-стола),
           max(min(var(--по-ширине-6), var(--по-высоте-1)),
               min(var(--по-ширине-3), var(--по-высоте-2)),
               min(var(--по-ширине-2), var(--по-высоте-3))));
}

/* Больше шести пар в дураке не бывает, но если правила когда-нибудь
   позволят — два ряда по четыре или три по три, а не обрыв. */
#зона-стола > #стол:has(> .пара:nth-child(7)) {
  --в: min(var(--потолок-стола),
           max(min(var(--по-ширине-4), var(--по-высоте-2)),
               min(var(--по-ширине-3), var(--по-высоте-3))));
}

/* Пара на столе. Ряд собирается по ПЛОТНОЙ ширине пары (отбивающая
   сдвинута на 30 сотых карты), потом свободное место ряда раздаётся
   парам обратно — каждая раздвигается до свободных 46 сотых. Так
   наложение становится плотнее только там и тогда, где тесно.
   Отбивающая карта прижата к правому краю пары — её сдвиг и есть
   «ширина пары минус карта». */
#зона-стола > #стол > .пара {
  flex: 1 1 calc(var(--ш) * 1.3);
  max-width: calc(var(--ш) * 1.46);
}

/* ---------- Колода кончилась ----------
   Стопки больше нет, и подпись («Козырь ♣ / Колода пуста») встаёт
   в левый верхний угол сукна, а поле пар поднимается на освободившееся
   место: в конце партии карт на столе как раз больше всего. */
#зона-стола:has(#верх-колоды:empty):has(#козырная-карта:empty) > #метка-козыря {
  left: var(--колода-x);
  top: calc(var(--колода-y) - 6px);
  height: 36px;
}

#зона-стола:has(#верх-колоды:empty):has(#козырная-карта:empty) #колода #счётчик-колоды {
  left: 0;
  top: 24px;
}

#зона-стола:has(#верх-колоды:empty):has(#козырная-карта:empty) > #стол {
  top: calc(var(--колода-y) + 48px);
}

/* ---------- Низкий и широкий стол: колода встаёт столбиком слева ----------
   Полоса с колодой сверху съедает у стола почти сотню точек высоты.
   Пока стол высокий, это не жалко. В низком окне (или когда пар четыре
   и больше и нужны два ряда) выгоднее поставить колоду с подписью
   столбиком у левого края, а пары — справа во всю высоту: карты на
   столе выходят крупнее. Решает форма стола, а не размер окна:
     • пар до трёх — столбик, если сукно шире своей высоты больше чем
       вдвое;
     • пар четыре и больше — если сукно просто шире своей высоты
       (до 11 сентября порог был «шире на треть»).
   Пороги посчитаны так, чтобы из двух раскладок всегда бралась та,
   где карта на столе крупнее. Сверено замером в окне 390×568: сукно
   364×179 (в 2,03 раза шире), полосой карта выходила 72 точки, столбиком —
   73; ниже этого окна столбик выигрывает всё заметнее.
   Почему порог для четырёх пар опустился. Раньше поле пар всегда
   считалось на три пары в ряд, и столбик колоды, отнимая ширину, почти
   никогда не окупался. Теперь четыре пары — это два ряда по две, и им
   ширины у столбика хватает: на 390×844 (сукно 364×340) карта выходит
   107 точек столбиком против 93 полосой. При шести парах на том же
   сукне полоса была бы чуть крупнее (93 против 90), но колода, которая
   на пятой паре прыгает обратно наверх, путает сильнее трёх точек. */
@container стол (min-aspect-ratio: 2 / 1) {
  /* В низком столе колода стоит столбиком и пары под собой не теснит,
     поэтому её рост ограничен не 36, а 42 сотыми высоты сукна — как
     было до 11 сентября, чтобы в низком окне колода не стала мельче
     прежней. Ширину и выгляд объявляем заново здесь же: переменная
     считается там, где объявлена, и прежние унаследовались бы готовыми. */
  #зона-стола > :is(#колода, #метка-козыря, #стол) {
    --колода-в: min(24cqw, 42cqh, var(--колода-потолок));
    --колода-ш: calc(var(--колода-в) / 1.4);
    --выгляд: calc(var(--колода-ш) * 0.5);
  }

  #зона-стола > #стол {
    left: calc(var(--колода-x) + max(calc(var(--колода-ш) + var(--выгляд)), 74px) + 10px);
    top: 6px;
  }

  #зона-стола > #метка-козыря {
    left: var(--колода-x);
    top: calc(var(--колода-y) + var(--колода-в) + 4px);
    height: 32px;
    max-width: none;
    font-size: clamp(12px, 3.4vw, 14px);
  }

  #зона-стола #колода #счётчик-колоды {
    left: 0;
    top: calc(100% + 34px);
    font-size: clamp(11px, 3.1vw, 13px);
  }

  /* Колода кончилась, а стол низкий: пары остаются справа во всю высоту,
     подпись — в углу слева. */
  #зона-стола:has(#верх-колоды:empty):has(#козырная-карта:empty) > #стол {
    top: 6px;
  }
}

/* Столбик для четырёх пар и больше — только пока колода на столе
   (в «верх-колоды» или «козырная-карта» что-то лежит). Колода кончилась —
   столбик пустой, и отступ под него (около 107 точек) пропадал зря:
   шесть пар полосой на 390×844 выходят 107 точек, в оставшейся справа
   ширине — 90. Тогда пары встают полосой под подписью «Колода пуста»
   (см. «Колода кончилась» выше). */
@container стол (min-aspect-ratio: 1 / 1) {
  #зона-стола:has(> #стол > .пара:nth-child(4)):has(:is(#верх-колоды, #козырная-карта):not(:empty)) > #стол {
    left: calc(var(--колода-x) + max(calc(var(--колода-ш) + var(--выгляд)), 74px) + 10px);
    top: 6px;
  }

  #зона-стола:has(> #стол > .пара:nth-child(4)):has(:is(#верх-колоды, #козырная-карта):not(:empty)) > #метка-козыря {
    left: var(--колода-x);
    top: calc(var(--колода-y) + var(--колода-в) + 4px);
    height: 32px;
    max-width: none;
    font-size: clamp(12px, 3.4vw, 14px);
  }

  #зона-стола:has(> #стол > .пара:nth-child(4)):has(:is(#верх-колоды, #козырная-карта):not(:empty)) #колода #счётчик-колоды {
    left: 0;
    top: calc(100% + 34px);
    font-size: clamp(11px, 3.1vw, 13px);
  }
}

/* Пара: побитая карта чуть повёрнута влево, накрывающая — вправо,
   как кладут рукой. Повороты у пар немного разные, чтобы стол не
   выглядел отпечатанным штампом. Поворот задан свойством «rotate»,
   а не «transform»: движение карт пользуется «transform», и они
   друг другу не мешают. */
#стол .пара .карта--атака {
  position: absolute;
  left: 0;
  top: 0;
  rotate: -2deg;
}

#стол .пара .карта--защита {
  position: absolute;
  left: auto;
  right: 0;
  top: var(--сдвиг-y);
  transform: none;
  rotate: 6deg;
  box-shadow:
    -3px -1px 6px rgba(0, 0, 0, 0.35),
    3px 6px 12px rgba(0, 0, 0, 0.45);
}

#стол .пара:nth-child(3n + 2) .карта--атака  { rotate: 1.5deg; }
#стол .пара:nth-child(3n + 2) .карта--защита { rotate: 4deg; }
#стол .пара:nth-child(3n) .карта--атака      { rotate: -0.5deg; }
#стол .пара:nth-child(3n) .карта--защита     { rotate: 7deg; }

/* Неотбитая карта — тихая белая рамка вокруг: «эту ещё надо крыть».
   Оформление само видит пару без накрывающей карты, разметки не нужно. */
#стол .пара:not(:has(> .карта--защита)) > .карта--атака {
  outline: 1.5px solid rgba(248, 245, 235, 0.5);
  outline-offset: 4px;
}

/* Куда можно положить выбранную карту — салатовая рамка с отступом,
   как у десятки пик на макете, и мягкое свечение. Салатовый здесь
   значит то же, что у выбранной карты в руке: «вот сюда». */
#стол .пара.пара--цель:not(:has(> .карта--защита)) > .карта--атака {
  outline: 2px solid var(--сб-акцент);
  outline-offset: 5px;
  box-shadow:
    0 2px 4px rgba(0, 0, 0, 0.45),
    0 6px 14px rgba(0, 0, 0, 0.32),
    0 0 22px 3px rgba(210, 247, 107, 0.35);
}

/* Бумага, кромка и тени карты — в самом правиле «.карта» (раздел «Сама
   карта» выше по файлу), одним местом.

   ВНИМАНИЕ тому, кто захочет задать карте вид здесь, в конце файла:
   ЦВЕТ КАРТЕ НИЖЕ ПРАВИЛ МАСТЕЙ НЕ ЗАДАВАТЬ. Цвет карты — это цвет её
   масти («карта--черви», «карта--красная» и прочие), и рисунок красит им
   и номинал, и значки. Правило «.карта { color: … }» с тем же весом, но
   ниже по файлу, перебивает их все: так 10 сентября черви и бубны стали
   чёрными, и владелец написал «красные и тёмные сливаются». */

/* ---------- Своя рука ----------
   Карта в руке — самая крупная на экране (85×119 на телефоне 390).
   Полоска руки — рост карты и 24 точки запаса: 14 сверху, чтобы
   выбранной карте было куда подняться, и 10 снизу — под салатовую
   черту «этой можно ходить».

   Когда карт дюжина и больше, игра кладёт руку в два ряда, и полоска
   забирает у стола высоту на второй ряд (карта в ряду — 78 сотых
   обычной), но не больше четверти окна. Решает, класть ли ряды, сама
   игра — по высоте, которую ей здесь дали. Полы 70 и 86 точек — прежние:
   ниже них ряды не включаются вовсе (см. «Наименьшая высота руки»). */
#приложение #экран-игры #рука-человека {
  height: calc(var(--в) + 24px);
  max-height: calc(var(--в) + 24px);
}

#приложение #экран-игры #рука-человека:has(#карты-человека > :nth-child(12)) {
  height: max(70px, min(calc(var(--в) * 1.56 + 26px), calc(var(--доступно) * 0.26)));
  max-height: max(70px, min(calc(var(--в) * 1.56 + 26px), calc(var(--доступно) * 0.26)));
}

#приложение #экран-игры #рука-человека:has(#карты-человека > :nth-child(18)) {
  height: max(86px, min(calc(var(--в) * 1.56 + 26px), calc(var(--доступно) * 0.26)));
  max-height: max(86px, min(calc(var(--в) * 1.56 + 26px), calc(var(--доступно) * 0.26)));
}

/* Обрезку по краю с карты руки снимаем: под картой рисуется черта
   «можно ходить», а рисунок карты и так не выходит за скруглённые углы.
   (Тень, которой карта отчёркивается от соседки, — в «.веер .карта»
   выше по файлу.) */
#карты-человека > .карта {
  overflow: visible;
}

/* Лёгкая дуга, как веер в руке на макете: крайние карты наклонены
   (не больше чем на 5 градусов) и чуть опущены. Номер карты и число
   карт присылает игра («--номер-в-веере», «--карт-в-веере»); пока их
   нет, рука лежит ровным рядом. Когда карт дюжина и больше, дуги нет:
   там рука может лечь рядами, а в рядах наклон только мешает. */
#карты-человека > .карта {
  --от-середины: calc(var(--номер-в-веере, 0) - (var(--карт-в-веере, 1) - 1) / 2);
  transform-origin: 50% 100%;
  rotate: calc(var(--от-середины) * min(2deg, 10deg / max(1, var(--карт-в-веере, 1) - 1)));
  translate: 0 calc(var(--от-середины) * var(--от-середины) * 6px
                    / max(1, (var(--карт-в-веере, 1) - 1) * (var(--карт-в-веере, 1) - 1) / 4));
}

#карты-человека:has(> :nth-child(12)) > .карта {
  rotate: none;
  translate: none;
  /* В рядах игра делает карту ниже (пишет ей свою высоту), а ширину
     не трогает — и рисунок сплющивался: король выходил вдвое шире,
     чем выше. Ширину считаем от высоты ряда, пропорция остаётся
     карточной. Пока рука лежит одним рядом, высота обычная, и это
     правило ничего не меняет. */
  width: calc(var(--в) / 1.4);
}

/* Можно ходить — короткая салатовая черта под картой, ровно под той
   полоской, которую от неё видно (её ширину присылает игра). Черта
   снаружи карты, а не на бумаге: салатовый на кремовом почти не виден. */
.веер .карта--можно,
.карта--можно {
  transform: translateY(-3px);
  box-shadow:
    -3px 0 7px rgba(0, 0, 0, 0.32),
    0 4px 8px rgba(0, 0, 0, 0.40);
  cursor: pointer;
}

#карты-человека > .карта--можно::before {
  content: "";
  position: absolute;
  left: 5px;
  top: calc(100% + 5px);
  width: max(10px, calc(var(--полоска) - 10px));
  height: 3px;
  border-radius: 2px;
  background: var(--сб-акцент);
  box-shadow: 0 0 6px rgba(210, 247, 107, 0.55);
  pointer-events: none;
}

/* Нельзя ходить — карта притушена и чуть осела. На тёмной странице
   притушенная карта сама читается как «сейчас не она», а номинал
   и масть на ней всё ещё видны. Прежняя серая плёнка больше не нужна.
   Притушаем ТОЛЬКО яркостью, цвет не трогаем: обесцвеченная черва
   становится бурой и сливается с пикой, а красное обязано отличаться
   от чёрного с первого взгляда на любой карте, в том числе на этой. */
.веер .карта--нельзя,
.карта--нельзя {
  filter: brightness(0.74);
  transform: translateY(2px);
  box-shadow: -2px 0 4px rgba(0, 0, 0, 0.30);
}

.карта--нельзя::after { background: transparent; }

/* Выбрана — поднята над соседками, обведена салатовым и светится,
   как валет на макете. Без этого игрок не понимает, среагировала ли
   игра на палец. */
.веер .карта--выбрана,
.карта--выбрана {
  transform: translateY(-14px);
  outline: 2.5px solid var(--сб-акцент);
  outline-offset: 2px;
  box-shadow:
    0 8px 18px rgba(0, 0, 0, 0.55),
    0 0 18px rgba(210, 247, 107, 0.55);
  z-index: 50;
  --полоска: var(--ш);
}

/* Подсказка (тихая серая строка под строкой «Вы») — в разделе «Подсказка»
   выше по файлу, одним местом: её коробка, цвета и запасной путь. */

/* ---------- Панель действий: «Взять», «Бито», «Сказать» ----------
   Как на макете: две равные кнопки и узкая третья справа. Тёмные,
   с тонкой светлой обводкой и значком перед словом. Недоступная —
   серая, без обводки: видно, что кнопка есть, но сейчас молчит.
   Значки — из набора владельца («img/дурак/значки/»), рисуются маской
   цветом текста. Для «Пас», «Готово», «Перевести» и «Бросить» в наборе
   значков нет — они нарисованы здесь же, тем же пером.

   Какой значок у кнопки, решает её «data-действие» (его ставит игра),
   а пока его нет — сам идентификатор кнопки. */
#панель-кнопок,
.панель-действий {
  position: relative;
  flex: 0 0 auto;
  display: flex;
  align-items: stretch;
  justify-content: center;
  gap: clamp(6px, 1.8vw, 9px);
  height: var(--ряд-кнопок, 48px);
  padding: 0;
}

#экран-игры #панель-кнопок > .кнопка,
.панель-действий > .кнопка {
  position: relative;
  order: 2;
  flex: 1 1 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  min-width: 0;
  min-height: 0;
  height: 100%;
  padding: 0 10px;
  font-size: clamp(15px, 4.2vw, 18px);
  font-weight: 600;
  letter-spacing: 0;
  white-space: nowrap;
  color: var(--сб-текст);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0) 60%),
    #171b1e;
  border: 1.5px solid rgba(248, 245, 235, 0.55);
  border-radius: 14px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.05),
    0 4px 12px rgba(0, 0, 0, 0.30);
}

/* Место под значок есть у каждой кнопки панели, но показывается он
   только у тех, для кого значок выбран (список ниже): у незнакомой
   кнопки пустого квадрата перед словом не будет. */
#экран-игры #панель-кнопок > .кнопка::before,
.панель-действий > .кнопка::before {
  content: "";
  display: none;
  flex: 0 0 auto;
  width: 1.3em;
  height: 1.3em;
  background-color: currentColor;
  -webkit-mask: var(--значок) center / contain no-repeat;
  mask: var(--значок) center / contain no-repeat;
}

#экран-игры #панель-кнопок > :is(#кнопка-беру, #кнопка-завершить, #кнопка-перевести,
                                  #кнопка-бросить, #кнопка-эмоции,
                                  [data-действие])::before {
  display: block;
}

#экран-игры #панель-кнопок > .кнопка:active {
  transform: translateY(1px);
  background: #121518;
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.35);
}

#экран-игры #панель-кнопок > .кнопка:disabled,
.панель-действий > .кнопка:disabled {
  color: #5f656c;
  background: #14171a;
  border-color: rgba(248, 245, 235, 0.10);
  box-shadow: none;
  cursor: default;
}

#экран-игры #панель-кнопок > .кнопка:disabled:active { transform: none; }

/* Порядок как на макете: «Взять» слева, «Бито» (или то, что встаёт
   на его место) посередине, «Сказать» справа. */
#панель-кнопок > #кнопка-беру                 { order: 1; --значок: var(--значок-взять); }
#панель-кнопок > #кнопка-завершить            { --значок: var(--значок-бито); }
#панель-кнопок > #кнопка-завершить.кнопка--пас { --значок: var(--значок-пас); }
#панель-кнопок > #кнопка-перевести            { --значок: var(--значок-перевести); }
#панель-кнопок > #кнопка-бросить              { --значок: var(--значок-бросить); }

/* Метка игры сильнее имени кнопки: одна и та же кнопка бывает «Бито»,
   «Пас», «Готово», «Перевести» и «Бросить», и значок идёт за ней. */
#экран-игры #панель-кнопок > .кнопка[data-действие="взять"]     { --значок: var(--значок-взять); }
#экран-игры #панель-кнопок > .кнопка[data-действие="сказать"]   { --значок: var(--значок-чат); }
#экран-игры #панель-кнопок > .кнопка[data-действие="бито"]      { --значок: var(--значок-бито); }
#экран-игры #панель-кнопок > .кнопка[data-действие="пас"]       { --значок: var(--значок-пас); }
#экран-игры #панель-кнопок > .кнопка[data-действие="готово"]    { --значок: var(--значок-готово); }
#экран-игры #панель-кнопок > .кнопка[data-действие="перевести"] { --значок: var(--значок-перевести); }
#экран-игры #панель-кнопок > .кнопка[data-действие="бросить"]   { --значок: var(--значок-бросить); }

/* «Бросить» — пара к поднятой карте: та же салатовая обводка, что
   у карты над ней. Видно без чтения: «вот эта карта, вот её кнопка». */
#экран-игры #панель-кнопок > #кнопка-бросить,
#экран-игры #панель-кнопок > .кнопка[data-действие="бросить"] {
  border-color: var(--сб-акцент);
  box-shadow: 0 0 12px rgba(210, 247, 107, 0.30);
}

/* Узкая кнопка знаков справа — место «Чата» на макете. */
#экран-игры #панель-кнопок > #кнопка-эмоции {
  --значок: var(--значок-чат);
  position: relative;
  right: auto;
  order: 3;
  flex: 0 0 auto;
  padding: 0 clamp(10px, 3.4vw, 16px);
  font-size: clamp(13px, 3.6vw, 15px);
  gap: 7px;
}

/* «В меню» из панели ушла: в Telegram это его стрелка «Назад», в браузере —
   «‹» в верхней строке, а служебные кнопки — в листе «⋯» (решение штаба). */

/* ---------- Компания: соперники над столом ----------
   Та же тёмная панель, что у соперника вдвоём, только поделена на места.
     • Двое соперников — два широких места, в каждом аватар слева, справа
       имя, «6 карт» и плашка состояния («ходит», «отбивается», «пас»).
     • Трое и больше — места поуже: аватар и число карт рядом (перед
       числом маленькая рубашка — чтобы число читалось как «карт»),
       под ними имя и плашка состояния во всю ширину места. Широкая
       раскладка на троих не помещалась: на экране 390 месту остаётся
       117 точек, тексту из них — 54, и «отбивается» обрезалось до «от…»
       (видно на снимке 390×844, стол на четверых).
   Кто ходит — салатовое кольцо у аватара и салатовая плашка «ходит»;
   это тот же знак, что у «Вы». Отбивается — белая обводка места
   и плашка с колечком-щитом. Выбывший — место гаснет.
   Высота полосы постоянная при любом числе соперников — стол под ней
   не прыгает, когда состояние переходит от одного к другому. */
#соперники {
  flex-wrap: nowrap;
  align-content: stretch;
  gap: clamp(5px, 1.6vw, 8px);
}

#соперники .соперник {
  --аватар: clamp(30px, 9.5vw, 40px);
  position: relative;
  flex: 1 1 0;
  min-width: 0;
  max-width: none;
  min-height: 0;
  height: clamp(58px, 16.5vw, 70px);
  display: grid;
  grid-template-columns: var(--аватар) minmax(0, 1fr);
  grid-template-rows: auto auto auto;
  align-content: center;
  align-items: center;
  justify-items: start;
  column-gap: clamp(7px, 2.2vw, 10px);
  row-gap: 1px;
  padding: 0 clamp(7px, 2.2vw, 10px);
  color: var(--сб-текст);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0) 70%),
    var(--сб-поверхность);
  border: 1px solid var(--граница-тихая);
  border-radius: 14px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.04),
    0 6px 16px rgba(0, 0, 0, 0.28);
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  transform: none;
  overflow: hidden;
}

#соперники .соперник::before {
  content: "";
  position: static;
  inset: auto;
  grid-column: 1;
  grid-row: 1 / -1;
  width: var(--аватар);
  height: var(--аватар);
  color: #8a9199;
  background: currentColor;
  -webkit-mask: var(--значок-аватар) center / contain no-repeat;
  mask: var(--значок-аватар) center / contain no-repeat;
}

#соперники .соперник__имя {
  grid-column: 2;
  grid-row: 1;
  display: block;
  max-width: 100%;
  -webkit-line-clamp: unset;
  font-size: clamp(13px, 3.8vw, 16px);
  font-weight: 700;
  line-height: 1.2;
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

#соперники .соперник__карт {
  grid-column: 2;
  grid-row: 2;
  display: flex;
  align-items: baseline;
  justify-content: flex-start;
  height: auto;
  font-size: clamp(12px, 3.4vw, 14px);
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: 0;
  color: var(--сб-текст-тихий);
  white-space: nowrap;
}

#соперники .соперник__число {
  font-size: 1.2em;
  font-weight: 700;
  line-height: 1;
  color: var(--сб-текст);
}

#соперники .соперник__слово { font-size: 1em; }
#соперники .соперник__слово:only-child { font-size: 1em; }

#соперники .соперник__метка,
#соперники .соперник__роль {
  grid-column: 2;
  grid-row: 3;
  justify-self: start;
  max-width: 100%;
  margin-top: 2px;
  padding: 1px 7px;
  font-size: clamp(10px, 2.9vw, 12px);
  font-weight: 600;
  line-height: 1.3;
  border-radius: 999px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

#соперники .соперник__метка {
  color: var(--сб-текст);
  background: rgba(248, 245, 235, 0.10);
}

#соперники .соперник__роль {
  color: var(--сб-текст-тихий);
  background: transparent;
  box-shadow: inset 0 0 0 1px rgba(248, 245, 235, 0.22);
  opacity: 1;
}

/* Напарник — вывернутая плашка «свой»: светлая с тёмными буквами.
   Прежняя полоса у левого края больше не нужна — там теперь аватар. */
#соперники .соперник--напарник .соперник__роль {
  color: var(--сб-фон);
  background: var(--сб-текст);
  box-shadow: none;
}

/* Ходит — салатовое кольцо у аватара и салатовая плашка «ходит». */
#соперники .соперник--ходит {
  color: var(--сб-текст);
  background:
    linear-gradient(180deg, rgba(210, 247, 107, 0.08), rgba(210, 247, 107, 0) 70%),
    var(--сб-поверхность);
  border: 1px solid rgba(210, 247, 107, 0.45);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.30);
  transform: none;
}

#соперники .соперник--ходит::before { color: var(--сб-акцент); }

#соперники .соперник--ходит .соперник__метка,
#соперники .соперник--ходит.соперник--отбивается .соперник__метка {
  color: var(--сб-акцент-текст);
  background: var(--сб-акцент);
  box-shadow: none;
}

/* Отбивается — белая обводка места и контурная плашка с колечком. */
#соперники .соперник--отбивается {
  border: 1px solid rgba(248, 245, 235, 0.40);
}

#соперники .соперник--отбивается .соперник__метка {
  color: var(--сб-текст);
  background: transparent;
  box-shadow: inset 0 0 0 1px rgba(248, 245, 235, 0.55);
}

/* Если отбивающийся одновременно и ходит — главнее «ходит». */
#соперники .соперник--ходит.соперник--отбивается {
  border-color: rgba(210, 247, 107, 0.45);
}

/* Выбыл или ушёл — место гаснет, кайма пунктиром. */
#соперники .соперник--выбыл,
#соперники .соперник--ушёл {
  background: transparent;
  border-style: dashed;
  border-color: rgba(248, 245, 235, 0.16);
  box-shadow: none;
}

#соперники .соперник--выбыл::before,
#соперники .соперник--ушёл::before { color: #4f555c; }

#соперники .соперник--выбыл .соперник__метка {
  color: var(--сб-текст-тихий);
  background: rgba(248, 245, 235, 0.08);
}

#соперники .соперник--нет-связи::before { opacity: 0.45; }

#соперники .соперник--проиграл {
  border: 1px solid var(--карта-отказ);
}

/* Трое и больше: места поуже, аватар и число карт в одну строку. */
#соперники:has(> .соперник:nth-child(3)) .соперник {
  --аватар: clamp(26px, 8vw, 34px);
  grid-template-columns: auto auto;
  grid-template-rows: auto auto auto;
  justify-content: center;
  justify-items: center;
  column-gap: 5px;
  row-gap: 2px;
  height: clamp(66px, 19vw, 80px);
  padding: 0 4px;
}

#соперники:has(> .соперник:nth-child(3)) .соперник::before {
  grid-column: 1;
  grid-row: 1;
}

#соперники:has(> .соперник:nth-child(3)) .соперник__карт {
  grid-column: 2;
  grid-row: 1;
  align-items: center;
  font-size: clamp(14px, 4.2vw, 17px);
}

/* Маленькая рубашка перед числом: «▯ 6» читается как «шесть карт». */
#соперники:has(> .соперник:nth-child(3)) .соперник__карт::before {
  content: "";
  flex: 0 0 auto;
  width: 0.62em;
  height: 0.86em;
  margin-right: 0.28em;
  border: 1.5px solid var(--рубашка-поле);
  border-radius: 2px;
  background: var(--рубашка-фон);
}

#соперники:has(> .соперник:nth-child(3)) .соперник__число { font-size: 1em; }
#соперники:has(> .соперник:nth-child(3)) .соперник__слово { display: none; }

/* «Всё на столе» — числа нет, слово остаётся одно и мельче. */
#соперники:has(> .соперник:nth-child(3)) .соперник__слово:only-child {
  display: inline;
  font-size: 0.62em;
  white-space: normal;
  line-height: 1.1;
}

#соперники:has(> .соперник:nth-child(3)) .соперник__имя {
  grid-column: 1 / -1;
  grid-row: 2;
  font-size: clamp(11px, 3.3vw, 13px);
  text-align: center;
}

#соперники:has(> .соперник:nth-child(3)) .соперник__метка,
#соперники:has(> .соперник:nth-child(3)) .соперник__роль {
  grid-column: 1 / -1;
  grid-row: 3;
  justify-self: center;
  margin-top: 1px;
  padding: 0 5px;
  /* Кегль — от ширины самого места: на троих место 117 точек и слово
     «отбивается» с колечком встаёт крупно, на шестерых — 62 и мельче,
     но всё ещё целиком. */
  font-size: clamp(9px, 9cqw, 11.5px);
}

#соперники:has(> .соперник:nth-child(3)) .соперник__имя {
  font-size: clamp(10.5px, 10.5cqw, 13px);
}

/* Выбывший: число карт у него всегда ноль, а что с его местом — говорит
   надпись («отыграл», «играет Бот 4»). Число убираем, аватар меньше —
   и длинная надпись («играет Александра-Мария») встаёт в две строки,
   не вылезая за место. Высота места при этом та же, что у соседей:
   полоса не дёргается в тот миг, когда кто-то выходит из игры. */
#соперники:has(> .соперник:nth-child(3)) .соперник--выбыл .соперник__карт { display: none; }
#соперники:has(> .соперник:nth-child(3)) .соперник--выбыл { --аватар: clamp(20px, 6vw, 26px); }

#соперники .соперник--выбыл .соперник__метка {
  white-space: normal;
  overflow-wrap: anywhere;
  text-align: center;
  line-height: 1.15;
  border-radius: 8px;
}

/* Самое узкое место (шестеро за столом, 60–70 точек): слово состояния
   важнее значка перед ним. Колечко-щит и стрелку убираем, поля плашки
   сужаем — и «отбивается» встаёт целиком, а не обрезается до «отбив…».
   Что это защитник, по-прежнему видно по белой обводке места, что ходит —
   по салатовой плашке и кольцу у аватара. «@container» меряет ширину
   самого места, а не экрана: тесно бывает месту, а не телефону. */
@container (max-width: 84px) {
  #соперники .соперник__метка::before { display: none; }
  #соперники .соперник__метка,
  #соперники .соперник__роль {
    max-width: 100%;
    padding: 0 3px;
    letter-spacing: -0.02em;
  }
}

/* Поля самого места в этом случае тоже минимальные: на экране 360
   при шестерых месту достаётся 62 точки, и каждая точка — это буква
   слова «отбивается». */
#соперники:has(> .соперник:nth-child(5)) { gap: 4px; }
#соперники:has(> .соперник:nth-child(5)) .соперник { padding: 0 2px; }
#соперники:has(> .соперник:nth-child(5)) .соперник__метка,
#соперники:has(> .соперник:nth-child(5)) .соперник__роль { padding: 0 2px; }

/* ---------- Низкое окно (шторка Telegram, маленький телефон) ----------
   Ряды ужимаются по мелочи, чтобы стол не стал крошечным: панель
   соперника ниже, кнопки — ровно по пальцу (44), подсказка мельче,
   промежутки теснее. Карты в руке уменьшаются сами (см. «--в-рука»). */
@media (max-height: 620px) {
  #экран-игры:has(> #зона-стола) {
    --ряд-соперника: clamp(46px, 12.5vw, 54px);
    --ряд-кнопок: 44px;
    --зазор-рядов: 5px;
  }

  #экран-игры > #рука-бота { --аватар: clamp(30px, 9vw, 38px); }

  /* Кегль мельче, но коробка прежние 44 точки: по подсказке нажимают
     (открывается «Что было»), и ниже пальца её делать нельзя. */
  #подсказка { font-size: 13px; }

  #соперники .соперник { height: 54px; }
  #соперники:has(> .соперник:nth-child(3)) .соперник { height: 64px; }
}

/* =====================================================================
   ПЛАШКИ ПОВЕРХ СТОЛА: итог партии, «Выйти в меню?», «Что было»
   и панель знаков («Сказать»)

   Все четыре ложатся поверх нового тёмного стола, а были зелёными
   с золотыми кнопками — игрок видел два разных приложения на одном
   экране. Своего макета у владельца для них нет, поэтому они собраны
   из того, что уже есть в системе витрины и стола:
     • тёмная карточка на тон светлее фона, тонкая светлая кромка, тень;
     • крупный жирный заголовок, как «Дурак» и «Во что сыграем?»;
     • ОДНА салатовая кнопка — главное действие плашки («Играть ещё»,
       «Продолжить партию»), остальные тихие: тёмные с тонким контуром;
     • панель знаков — лист снизу, как лист «Ещё» на витрине, вкладки —
       пилюли, как фишки-фильтры витрины: выбранная залита салатовым.

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

   Цвета: внутри плашек объявлены те же переменные, что внутри стола.
   Все прежние правила плашек, которые берут «--текст», «--подложка»,
   «--акцент», сами переходят на тёмный вид — переписывать каждое
   не нужно. */
#экран-результата,
#экран-выхода,
#экран-ленты,
#экран-эмоций {
  --фон: var(--сб-фон);
  --панель: var(--сб-поверхность);
  --текст: var(--сб-текст);
  --текст-тихий: var(--сб-текст-тихий);
  --кнопка-фон: var(--сб-акцент);
  --кнопка-текст: var(--сб-акцент-текст);
  --акцент: var(--сб-акцент);
  --подложка: rgba(248, 245, 235, 0.06);
  --край: rgba(248, 245, 235, 0.14);
  --поле: clamp(12px, 3.6vw, 18px);
  /* Плитка внутри тёмной плашки — на тон светлее её самой, как строки
     листа «Ещё» на витрине. */
  --плитка: #1e2226;
  --плитка-нажата: #262a2f;
  color: var(--сб-текст);
}

/* Вуаль над плашкой — плотнее прежней: на тёмной странице лёгкая вуаль
   почти не видна, и плашка терялась на фоне стола. */
#экран-результата.экран--виден::before,
#экран-выхода.экран--поверх.экран--виден::before,
#экран-ленты.экран--поверх.экран--виден::before,
#экран-эмоций.экран--поверх.экран--виден::before {
  background: rgba(5, 7, 8, 0.55);
}

/* Карточка итога и вопроса о выходе у́же экрана и не касается низа,
   а прежняя вуаль рисовалась только НАД плашкой и по её ширине: по бокам
   и под карточкой из-под неё выглядывала рука. Здесь вуаль — это широкая
   тень самой карточки (см. её правило ниже): она затемняет весь экран
   вокруг, а касаний, как и прежняя вуаль, не ловит — тень не бывает
   целью нажатия. */
#экран-результата.экран--виден::before,
#экран-выхода.экран--поверх.экран--виден::before,
#экран-эмоций.экран--поверх.экран--виден::before {
  background: transparent;
}

/* ---------- Карточка итога и вопроса «Выйти в меню?» ----------
   Тёмная карточка у нижнего края, со скруглением со всех сторон и полями
   по бокам — лежит поверх стола, а не приклеена к экрану. Над ней вуаль,
   стол сквозь неё виден: чем кончилось, рассмотреть можно. Ряд кнопок
   стола под карточкой на итоге спрятан (см. правило игры), поэтому
   поднимать её над ним, как раньше, больше не нужно. */
#экран-результата,
#экран-результата.экран--поверх,
#экран-выхода.экран--поверх {
  left: 0;
  right: 0;
  bottom: calc(12px + var(--отступ-снизу));
  top: auto;
  width: min(calc(100% - 2 * var(--поле) - var(--отступ-слева) - var(--отступ-справа)), 520px);
  margin: 0 auto;
  gap: 10px 8px;
  padding: 22px 16px 16px;
  text-align: center;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.04), rgba(255, 255, 255, 0) 45%),
    var(--сб-поверхность);
  border: 1px solid rgba(248, 245, 235, 0.10);
  border-radius: 22px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.06),
    0 18px 44px rgba(0, 0, 0, 0.60),
    0 0 0 100vmax rgba(5, 7, 8, 0.55);      /* вуаль на весь экран вокруг */
}

/* Итог — самое крупное на карточке: «Вы выиграли!», «Вы — дурак».
   Тот же плотный жирный набор, что у «Дурак» над столом. */
#экран-результата .заголовок {
  font-size: clamp(26px, 7.4vw, 32px);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--сб-текст);
}

#экран-выхода .заголовок {
  font-size: clamp(22px, 6.2vw, 26px);
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--сб-текст);
}

#экран-результата > .подпись,
#экран-выхода > .подпись {
  font-size: clamp(13.5px, 3.7vw, 15px);
  line-height: 1.35;
  color: var(--сб-текст-тихий);
}

/* Серия побед и серия дней — тихие пилюли по размеру слов: это
   достижение, но не кнопка, и спорить с главной кнопкой за салатовый цвет
   оно не должно. Звёздочки перед строкой нет нарочно: в эту же строку
   игра пишет и приглашения («Остальные зовут сыграть ещё»), а звезда
   перед ними читалась бы как награда. */
#экран-результата > .серия {
  width: auto;
  max-width: 100%;
  padding: 6px 14px 7px;
  font-size: clamp(14px, 3.8vw, 16px);
  font-weight: 700;
  line-height: 1.25;
  color: var(--сб-текст);
  background: rgba(248, 245, 235, 0.06);
  border: 1px solid rgba(248, 245, 235, 0.16);
  border-radius: 999px;
}

#экран-результата > .серия-дней {
  background: rgba(248, 245, 235, 0.06);
  border: 1px solid rgba(248, 245, 235, 0.16);
}

/* Главная кнопка — единственная салатовая: «Играть ещё», «Сыграть
   с ботом», «Продолжить партию», «Назад к столу». Во всю ширину
   карточки, 52 точки в высоту. */
#экран-результата .кнопка.кнопка--главная,
#экран-выхода .кнопка.кнопка--главная,
#экран-ленты .кнопка.кнопка--главная {
  width: 100%;
  max-width: none;
  min-width: 0;
  min-height: 52px;
  padding: 10px 16px;
  font-size: clamp(16px, 4.6vw, 18px);
  font-weight: 700;
  letter-spacing: 0;
  color: var(--сб-акцент-текст);
  background: var(--сб-акцент);
  border: none;
  border-radius: 14px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.35),
    0 6px 18px rgba(210, 247, 107, 0.16);
}

#экран-результата .кнопка.кнопка--главная:active,
#экран-выхода .кнопка.кнопка--главная:active,
#экран-ленты .кнопка.кнопка--главная:active {
  transform: translateY(1px);
  filter: brightness(0.94);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.18);
}

/* Остальные — тихие: тёмная плитка с тонким контуром, как строки листа
   «Ещё». Встают в ряд и делят его поровну; не влезают — переносятся. */
#экран-результата .кнопка.кнопка--мелкая,
#экран-выхода .кнопка.кнопка--мелкая {
  flex: 1 1 0;
  min-width: min(100%, 118px);
  min-height: 46px;
  padding: 0 12px;
  font-size: 15px;
  font-weight: 600;
  color: var(--сб-текст);
  background: var(--плитка);
  border: 1px solid rgba(248, 245, 235, 0.14);
  border-radius: 14px;
  box-shadow: none;
}

#экран-результата .кнопка.кнопка--мелкая:active,
#экран-выхода .кнопка.кнопка--мелкая:active {
  transform: translateY(1px);
  background: var(--плитка-нажата);
  box-shadow: none;
}

/* Уход — тише всех: без заливки, только контур. */
#экран-результата #кнопка-в-меню-итог,
#экран-выхода #кнопка-выход-да {
  background: transparent;
}

/* Реванша не будет — «В меню» остаётся единственным выходом и не должна
   выглядеть выключенной: контур салатовый, подпись белая. */
#экран-результата:has(#кнопка-ещё.скрыт) .кнопка.кнопка--мелкая:not(#кнопка-рекорды-итог) {
  min-height: 48px;
  font-size: 16px;
  color: var(--сб-текст);
  background: transparent;
  border: 1.5px solid var(--сб-акцент);
}

@media (max-height: 620px) {
  #экран-результата,
  #экран-результата.экран--поверх,
  #экран-выхода.экран--поверх {
    gap: 8px;
    padding: 16px 14px 12px;
  }
}

/* ---------- «Что было» — лист снизу ----------
   Список новостей стола — лист, выезжающий снизу, как «Ещё» на витрине:
   скруглён только верх, прижат к низу, не шире колонки сборника. */
#экран-ленты.экран--поверх {
  left: 0;
  right: 0;
  width: 100%;
  max-width: 520px;
  margin: 0 auto;
  background: var(--сб-поверхность);
  border: none;
  border-radius: 20px 20px 0 0;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.08),
    0 -12px 32px rgba(0, 0, 0, 0.45),
    0 0 0 100vmax rgba(5, 7, 8, 0.55);     /* вуаль над столом */
}

#экран-ленты.экран--поверх.экран--виден::before { background: transparent; }

#экран-ленты .заголовок {
  font-size: 19px;
  font-weight: 700;
  letter-spacing: -0.01em;
}

#лента-событий .таблица__строка {
  background: var(--плитка);
  border: 1px solid rgba(255, 255, 255, 0.05);
}

#лента-событий .таблица__строка:nth-last-child(n+4) {
  background: rgba(30, 34, 38, 0.6);
}

/* ---------- Панель знаков — лист «Сказать» ----------
   Лист снизу, как «Ещё» на витрине: тёмная панель, скруглённый верх,
   «ручка» сверху (знак выдвижного листа), не шире колонки сборника. */
#экран-эмоций.экран--поверх {
  left: 0;
  right: 0;
  width: 100%;
  max-width: 520px;
  margin: 0 auto;
  gap: 12px;
  padding: 24px calc(var(--поле) + var(--отступ-справа))
           calc(18px + var(--отступ-снизу)) calc(var(--поле) + var(--отступ-слева));
  background:
    linear-gradient(rgba(255, 255, 255, 0.18), rgba(255, 255, 255, 0.18)) top 9px center / 36px 4px no-repeat,
    var(--сб-поверхность);
  border: none;
  border-radius: 20px 20px 0 0;
  /* Последняя тень — вуаль над столом. Прежняя вуаль рисовалась над
     листом отдельным слоем, но лист прокручивается внутри себя и обрезал
     её: стол над листом оставался ярким. Тень лист не обрезает, а касаний
     она не ловит. */
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.08),
    0 -12px 32px rgba(0, 0, 0, 0.45),
    0 0 0 100vmax rgba(5, 7, 8, 0.55);
}

/* Вкладки «Смайлики / Фразы / Кинуть» — пилюли, как фишки-фильтры на
   витрине. Кнопка вкладки сама 44 точки в высоту (палец), а видимая
   пилюля внутри неё ниже — 34 точки; попасть можно и чуть выше, и чуть
   ниже нарисованной. Выбранная залита салатовым, текст почти чёрный. */
#экран-эмоций .панель-знаков__вкладки {
  justify-content: flex-start;
  gap: clamp(7px, 2.2vw, 10px);
  box-shadow: none;
}

#экран-эмоций .кнопка.панель-знаков__вкладка {
  position: relative;
  isolation: isolate;
  flex: 0 0 auto;
  min-height: 44px;
  padding: 0 clamp(14px, 4.1vw, 18px);
  font-size: clamp(14px, 3.8vw, 16px);
  font-weight: 600;
  color: rgba(248, 245, 235, 0.86);
  background: none;
  border: none;
  border-radius: 999px;
  box-shadow: none;
}

#экран-эмоций .кнопка.панель-знаков__вкладка::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 5px;
  bottom: 5px;
  z-index: -1;
  border: 1px solid var(--сб-граница);
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.025);
  transition: transform 0.14s ease;
}

#экран-эмоций .кнопка.панель-знаков__вкладка:active { transform: none; background: none; }
#экран-эмоций .кнопка.панель-знаков__вкладка:active::before { transform: scale(0.96); }

#экран-эмоций .кнопка.панель-знаков__вкладка.кнопка--активная {
  color: var(--сб-акцент-текст);
  font-weight: 700;
  background: none;
}

#экран-эмоций .кнопка.панель-знаков__вкладка.кнопка--активная::before {
  background: var(--сб-акцент);
  border-color: var(--сб-акцент);
}

/* Ряды знаков — сетки из тёмных плиток. Смайлики — по шесть в ряд
   (двенадцать встают в два ряда), каждая плитка квадратная и не меньше
   44 точек: на экране 360 выходит 50. */
#экран-эмоций .ряд-знаков {
  display: grid;
  gap: 6px;
  width: 100%;
}

#экран-эмоций #ряд-эмоций {
  grid-template-columns: repeat(6, minmax(44px, 1fr));
}

#экран-эмоций .кнопка.кнопка--смайлик,
#экран-эмоций .кнопка.кнопка--фраза,
#экран-эмоций .кнопка.кнопка--цель {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  min-height: 44px;
  color: var(--сб-текст);
  background: var(--плитка);
  border: 1px solid rgba(255, 255, 255, 0.06);
  border-radius: 14px;
  box-shadow: none;
}

#экран-эмоций .кнопка.кнопка--смайлик {
  aspect-ratio: 1 / 1;
  padding: 0;
  font-size: clamp(24px, 7vw, 30px);
  line-height: 1;
}

#экран-эмоций .кнопка.кнопка--смайлик:active,
#экран-эмоций .кнопка.кнопка--фраза:active,
#экран-эмоций .кнопка.кнопка--цель:active {
  transform: scale(0.96);
  background: var(--плитка-нажата);
  box-shadow: none;
}

/* Фразы — пилюли по длине слов, переносятся рядами. */
#экран-эмоций #ряд-фраз {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
}

#экран-эмоций .кнопка.кнопка--фраза {
  padding: 8px 14px;
  font-size: clamp(13.5px, 3.7vw, 15px);
  font-weight: 600;
  line-height: 1.2;
  border-radius: 999px;
}

/* ---------- «Кинуть»: пятнадцать предметов картинками, сетка 5×3 ----------
   Владелец прислал свои рисунки предметов (img/бросок/*.webp, 200×200,
   прозрачный фон). Пока бросаются значки телефона — они стоят в тех же
   клетках, крупным знаком. Когда разработчик положит в кнопку картинку
   («img.предмет-броска»), она встанет в клетку сама: на три четверти
   клетки, по центру, не растягиваясь.
   Клетка квадратная: на экране 390 — 64 точки, на 360 — 58, в самом
   узком случае не меньше 44. */
#экран-эмоций #ряд-бросков {
  grid-template-columns: repeat(5, minmax(44px, 1fr));
}

#экран-эмоций .кнопка.кнопка--бросок-предмет {
  aspect-ratio: 1 / 1;
  font-size: clamp(26px, 7.6vw, 32px);
}

#экран-эмоций .кнопка--бросок-предмет > .предмет-броска {
  display: block;
  width: 76%;
  height: 76%;
  object-fit: contain;
  pointer-events: none;
  /* Лёгкая тень — предмет «лежит» в клетке, а не наклеен на неё */
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.45));
}

/* Предмет выбран, игра спрашивает «в кого кинуть?» — клетка обведена
   салатовым и светится, как выбранная карта в руке: видно, чем сейчас
   будут кидать. */
#экран-эмоций .кнопка.кнопка--бросок-предмет.кнопка--выбрана {
  background: var(--плитка-нажата);
  border-color: var(--сб-акцент);
  box-shadow:
    0 0 0 1.5px var(--сб-акцент),
    0 0 14px rgba(210, 247, 107, 0.35);
}

/* Картинка предмета в облачке над игроком растёт от кегля облачка, как
   смайлик рядом. Запасной размер 48 у неё стоит атрибутами — это правило
   его перебивает. */
.знак-внимания__что > .предмет-броска {
  display: inline-block;
  width: 1em;
  height: 1em;
  object-fit: contain;
  vertical-align: middle;
}

/* Летящий предмет картинкой: размер берётся от кегля полёта (1em), поэтому
   все правила полёта — дуга, вращение, шлепок — работают как со значком. */
.летящий-предмет > .летящий-предмет__картинка {
  display: block;
  width: 1em;
  height: 1em;
  object-fit: contain;
}

/* ---------- Рисунок предмета не доехал: название словом ----------
   Если картинка предмета не загрузилась, игра ставит на её место слово —
   «Помидор», «Шарик с водой» (span.название-предмета): в клетку панели
   «Кинуть», в летящий предмет и в облачко над игроком. Везде у слова
   одна задача — читаться и не вылезать за край своей коробки. Кегль
   у всех трёх мест задан для значков (26–54 точки), слову он не годится,
   поэтому у слова свой. */

/* В клетке панели: мелкий жирный текст по центру, не больше трёх строк.
   «Перчатка» встаёт в одну строку уже в клетке 58 точек (экран 360),
   «Шарик с водой» — в две. В самой узкой клетке (44) длинное слово
   переносится, а не торчит за край.

   Правило общее для панелей дурака и шашек (замечание ревьюера,
   11 сентября: у шашек его не было, и слово вставало кеглем смайлика —
   18 точек). У шашек кнопка предмета — «.панель-знаков__знак--бросок»
   (js/шашки-экран.js), сама кнопка и её цвета — в style-шашки.css. */
#экран-эмоций .кнопка--бросок-предмет > .название-предмета,
.панель-знаков__знак--бросок > .название-предмета {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  box-sizing: border-box;
  max-width: 100%;
  padding: 0 3px;
  overflow: hidden;
  font-size: clamp(10px, 2.9vw, 12px);
  font-weight: 700;
  line-height: 1.15;
  letter-spacing: 0;
  text-align: center;
  hyphens: auto;
  overflow-wrap: anywhere;
  color: var(--сб-текст);
  pointer-events: none;
}

/* У шашек клетка не задана сеткой, как у дурака: кнопка растёт под
   содержимое. Без потолка «Шарик с водой» вытянул бы её в полосу
   на весь ряд. Потолок — 5,5 кегля (66 точек при 12): «Перчатка» ещё
   в одну строку, «Шарик с водой» — в две; кнопка остаётся плиткой
   рядом с рисунками. Цвет — от самой кнопки: у шашек своя тема. */
.панель-знаков__знак--бросок > .название-предмета {
  max-width: 5.5em;
  color: inherit;
}

/* В облачке над игроком — как фраза: жирная строка обычного кегля,
   облачко не шире, чем у фраз, длинное название переносится по словам.
   Качать слово нельзя: качающиеся буквы не прочесть (смайлик и рисунок
   в облачке покачиваются — слово стоит). */
.знак-внимания--бросок:has(.название-предмета) {
  max-width: min(60vw, 230px);
  padding: 8px 14px 9px;
}

.знак-внимания--смайлик.знак-внимания--живой .знак-внимания__что:has(> .название-предмета) {
  animation: none;
  transform: none;
}

.знак-внимания__что > .название-предмета {
  display: block;
  font-size: clamp(15px, 4.6vw, 19px);
  font-weight: 700;
  line-height: 1.25;
}

/* Летит слово: тёмная пилюля, как плашки стола, белый жирный текст
   в одну строку. Центр пилюли — в точке полёта: у значка это делает
   поле «-0.5em» (значок квадратный, в 1em), у слова ширина своя, поэтому
   поле снимаем, а пилюлю сдвигаем на половину её собственного размера.
   Точка вращения и роста — та же точка, иначе в середине пути, где
   предмет растёт, слово съезжало бы вбок. */
.летящий-предмет:has(> .название-предмета) {
  margin: 0;
  transform-origin: 0 0;
}

.летящий-предмет > .название-предмета {
  display: block;
  translate: -50% -50%;
  padding: 5px 11px 6px;
  font-size: 14px;
  font-weight: 700;
  line-height: 1.2;
  white-space: nowrap;
  color: var(--сб-текст);
  background: var(--сб-поверхность);
  border: 1px solid rgba(248, 245, 235, 0.18);
  border-radius: 999px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.5);
}

/* Слово в полёте не крутится — крутящееся слово не прочесть. Дуга,
   рост в середине пути и шлепок в конце — прежние. Только для тех, у кого
   движения не выключены: у остальных полёта нет вовсе. */
@media (prefers-reduced-motion: no-preference) {
  .летящий-предмет:not(.летящий-предмет--попал):has(> .название-предмета) {
    animation-name: предмет-летит, предмет-дуга-слово;
  }
}

@keyframes предмет-дуга-слово {
  0%   { transform: translateY(0) scale(0.75);
         animation-timing-function: ease-out; }
  50%  { transform: translateY(calc(-1 * var(--подъём))) scale(1.3);
         animation-timing-function: ease-in; }
  100% { transform: translateY(0) scale(1); }
}

/* Второй шаг броска за столом компанией: «В кого кинуть?» — имена
   соперников плитками в два столбца, чтобы длинное имя не обрезалось. */
#экран-эмоций .выбор-цели {
  display: flex;
  flex-direction: column;
  gap: 8px;
  width: 100%;
}

#экран-эмоций .выбор-цели > .подпись {
  font-size: 15px;
  font-weight: 600;
  text-align: left;
  color: var(--сб-текст);
}

#экран-эмоций .ряд-знаков.ряд-знаков--цели {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

#экран-эмоций .кнопка.кнопка--цель {
  padding: 8px 12px;
  font-size: 15px;
  font-weight: 600;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* «Закрыть» — полка по низу листа, как «Закрыть» у листа «Ещё»:
   тихая, с тонкой чертой сверху. Прилипание к низу — прежнее. */
#экран-эмоций #кнопка-эмоции-назад {
  font-size: 16px;
  font-weight: 600;
  color: var(--сб-текст);
  background: var(--сб-поверхность);
  border-top: 1px solid rgba(248, 245, 235, 0.08);
}

@media (max-width: 360px), (max-height: 620px) {
  #экран-эмоций.экран--поверх {
    gap: 10px;
    padding-top: 22px;
  }

  #экран-эмоций .ряд-знаков { gap: 5px; }
}

/* =====================================================================
   «КАК ИГРАТЬ», «РЕКОРДЫ», «ОФОРМЛЕНИЕ» ДУРАКА — В ТЁМНОЙ СИСТЕМЕ

   Все три открываются из листа «Ещё» прямо посреди партии, а были
   зелёными: с тёмного стола человек попадал на зелёное сукно и обратно —
   два разных приложения за одну минуту. Своего макета у владельца для них
   нет, поэтому они собраны из того, что уже есть на витрине и за столом:
     • ровный тёмный фон с едва заметным салатовым свечением сверху;
     • «‹» в левом верхнем углу — как у стола. Внутри Telegram стрелку
       «Назад» рисует он сам в своей шапке, и наша прячется — тоже как
       у стола;
     • крупный жирный заголовок слева — как «Дурак» над столом;
     • строки — тёмные плитки на тон светлее фона, как в листе «Ещё»;
     • салатовый — одно место на экране: лучший рекорд, выбранный фон,
       черта под картой, которой можно ходить.

   Большой залитой кнопки «Назад» внизу больше нет — её работу делает «‹».
   Это та же самая кнопка из разметки: оформление переносит её в угол
   и рисует стрелкой, а слово «Назад» остаётся для чтеца экрана.

   ТОЛЬКО СТРАНИЦА СБОРНИКА — отсюда «:has(> #экран-витрины)». Экраны
   с теми же именами есть у шашек (правила, рекорды) и шахмат (рекорды,
   оформление). Их столы ещё зелёные, и тёмный экран посреди них резал бы
   глаз точно так же, только наоборот. Когда дойдёт их очередь, хватит
   снять это уточнение.

   С 12 сентября сюда же добавлена СТРАНИЦА НАРД — её узнаём по доске
   («:has(.доска-нард)», такой доски больше нигде нет). Её стол уже
   тёмный, как витрина, и экран «Оформление» на ней должен выглядеть
   ровно как у дурака: заголовок слева, «‹» в углу, тёмные плитки.
   Правила и рекорды у нард зовутся иначе, поэтому список имён ниже
   на них не попадает — меняется только «Оформление». */

:where(#приложение:has(> #экран-витрины), #приложение:has(.доска-нард)) > :is(#экран-правил, #экран-рекордов, #экран-оформления) {
  /* Те же цвета, что внутри стола. Прежние правила экранов, которые
     берут «--текст», «--подложка», «--акцент», сами становятся тёмными
     с салатовым. */
  --панель: var(--сб-поверхность);
  --текст: var(--сб-текст);
  --текст-тихий: var(--сб-текст-тихий);
  --кнопка-фон: var(--сб-акцент);
  --кнопка-текст: var(--сб-акцент-текст);
  --акцент: var(--сб-акцент);
  --подложка: rgba(248, 245, 235, 0.06);
  --край: rgba(248, 245, 235, 0.14);
  --поле: clamp(12px, 3.6vw, 18px);
  /* Плитка — на тон светлее фона, как строки листа «Ещё». */
  --плитка: #1e2226;
  --плитка-край: rgba(255, 255, 255, 0.06);
  --плитка-нажата: #262a2f;

  align-items: center;
  gap: 10px;
  padding: calc(6px + var(--отступ-сверху)) calc(var(--поле) + var(--отступ-справа))
           calc(12px + var(--отступ-снизу)) calc(var(--поле) + var(--отступ-слева));
  overflow-x: hidden;
  color: var(--сб-текст);
  background:
    radial-gradient(75% 120px at 50% 0, rgba(210, 247, 107, 0.07), rgba(210, 247, 107, 0) 100%),
    var(--сб-фон);
}

:where(#приложение:has(> #экран-витрины), #приложение:has(.доска-нард)) > :is(#экран-правил, #экран-рекордов, #экран-оформления) {
  --фон: var(--сб-фон);
}

/* Столбик — не шире, чем у витрины и стола (520 точек), и посередине.
   На телефоне ограничение не срабатывает. */
:where(#приложение:has(> #экран-витрины), #приложение:has(.доска-нард)) > :is(#экран-правил, #экран-рекордов, #экран-оформления) > * {
  box-sizing: border-box;
  width: 100%;
  max-width: 520px;
}

/* Заголовок — тот же плотный жирный набор, что у «Дурак» над столом
   и «Во что сыграем?» на витрине, и так же прижат влево. */
:where(#приложение:has(> #экран-витрины), #приложение:has(.доска-нард)) > :is(#экран-правил, #экран-рекордов, #экран-оформления) > .заголовок {
  flex: 0 0 auto;
  margin: 0;
  text-align: left;
  font-size: clamp(26px, 8.2vw, 37px);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.02em;
  color: var(--сб-текст);
}

/* В Telegram нашей строки «‹» нет — заголовок стоит сразу под его
   шапкой, как на витрине. */
html.в-телеграме :where(#приложение:has(> #экран-витрины), #приложение:has(.доска-нард)) > :is(#экран-правил, #экран-рекордов, #экран-оформления) > .заголовок {
  margin-top: 4px;
}

/* ---------- «‹» — прежняя кнопка «Назад», перенесённая в угол ----------
   Встаёт первой в столбике («order: -1»), 44×44 под палец, значок
   24 точки — один в один «‹» над столом. Поле слева отрицательное,
   чтобы стрелка встала у самого края, как у стола; на широком окне
   оно отсчитывается от края столбика, а не окна.

   У нард в стрелку превращается ТОЛЬКО кнопка «Оформление» — второй
   строкой ниже. Кнопка «Понятно» на её экране правил названа тем же
   именем, что «Назад» у дурака, и попади она сюда — исчезла бы
   единственная дверь с того экрана. */
:where(#приложение:has(> #экран-витрины)) :is(#кнопка-правила-назад, #кнопка-рекорды-назад, #кнопка-оформление-назад, #кнопка-рейтинг-игроков-назад, #кнопка-рейтинг-назад),
#приложение:has(.доска-нард) #кнопка-оформление-назад {
  order: -1;
  position: relative;
  flex: 0 0 auto;
  align-self: flex-start;
  width: 44px;
  min-width: 44px;
  max-width: none;
  height: 44px;
  min-height: 44px;
  margin: -4px 0 -8px max(-10px, calc((100% - 520px) / 2 - 10px));
  padding: 0;
  font-size: 0;              /* слово «Назад» — только для чтеца экрана */
  line-height: 0;
  color: var(--сб-текст);
  background: none;
  border: none;
  border-radius: 12px;
  box-shadow: none;
}

:where(#приложение:has(> #экран-витрины)) :is(#кнопка-правила-назад, #кнопка-рекорды-назад, #кнопка-оформление-назад, #кнопка-рейтинг-игроков-назад, #кнопка-рейтинг-назад)::before,
#приложение:has(.доска-нард) #кнопка-оформление-назад::before {
  content: "";
  position: absolute;
  inset: 0;
  width: 24px;
  height: 24px;
  margin: auto;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m15 4-8 8 8 8'/%3E%3C/svg%3E") center / 24px 24px no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m15 4-8 8 8 8'/%3E%3C/svg%3E") center / 24px 24px no-repeat;
}

:where(#приложение:has(> #экран-витрины)) :is(#кнопка-правила-назад, #кнопка-рекорды-назад, #кнопка-оформление-назад, #кнопка-рейтинг-игроков-назад, #кнопка-рейтинг-назад):active,
#приложение:has(.доска-нард) #кнопка-оформление-назад:active {
  transform: scale(0.92);
  opacity: 0.7;
  box-shadow: none;
}

:where(#приложение:has(> #экран-витрины)) :is(#кнопка-правила-назад, #кнопка-рекорды-назад, #кнопка-оформление-назад, #кнопка-рейтинг-игроков-назад, #кнопка-рейтинг-назад):focus-visible,
#приложение:has(.доска-нард) #кнопка-оформление-назад:focus-visible {
  outline: 2px solid var(--сб-акцент);
  outline-offset: -4px;
}

html.в-телеграме :where(#приложение:has(> #экран-витрины)) :is(#кнопка-правила-назад, #кнопка-рекорды-назад, #кнопка-оформление-назад, #кнопка-рейтинг-игроков-назад, #кнопка-рейтинг-назад),
html.в-телеграме #приложение:has(.доска-нард) #кнопка-оформление-назад {
  display: none;
}

/* ---------- «Как играть» ----------
   Текст здесь читают подряд, поэтому он крупнее обычной подписи
   (16 точек на экране 390), с просторными строками (полторы высоты
   буквы) и полным белым цветом. Ширина строки на телефоне — около
   сорока знаков, на широком окне столбик не шире 520 точек, так что
   строка не растягивается в полосу, которую глаз теряет на переносе.

   Список занимает всё место до низа экрана и прокручивается сам.
   Низ списка тает в фон — так видно, что правила ещё не кончились;
   докрутили до конца — таять нечему, там пустое поле. */
:where(#приложение:has(> #экран-витрины)) #экран-правил {
  /* Образцы карт к правилу про подсветку — два рисунка новой колодой:
     та же кремовая бумага, та же красная черва, те же углы и раскладка
     значков, что у настоящей семёрки червей. Вторая — ровно такая же,
     только притушенная, как карта, которой сейчас ходить нельзя. */
  --образец-можно: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 250 350'%3E%3Crect x='2.5' y='2.5' width='245' height='345' rx='20' fill='%23f6ead5' stroke='%23463016' stroke-opacity='.3' stroke-width='5'/%3E%3Cg fill='%23c8102e' font-family='Times New Roman,Times,serif' font-size='60' font-weight='700' text-anchor='middle'%3E%3Ctext x='31' y='62'%3E7%3C/text%3E%3Cpath transform='translate(15 76) scale(1.3333)' d='M12 21 3 12C-3 4 7-2 12 5c5-7 15-1 9 7Z'/%3E%3Cg transform='rotate(180 125 175)'%3E%3Ctext x='31' y='62'%3E7%3C/text%3E%3Cpath transform='translate(15 76) scale(1.3333)' d='M12 21 3 12C-3 4 7-2 12 5c5-7 15-1 9 7Z'/%3E%3C/g%3E%3Cpath transform='translate(60 52) scale(2)' d='M12 21 3 12C-3 4 7-2 12 5c5-7 15-1 9 7Z'/%3E%3Cpath transform='translate(142 52) scale(2)' d='M12 21 3 12C-3 4 7-2 12 5c5-7 15-1 9 7Z'/%3E%3Cpath transform='translate(101 101) scale(2)' d='M12 21 3 12C-3 4 7-2 12 5c5-7 15-1 9 7Z'/%3E%3Cpath transform='translate(60 151) scale(2)' d='M12 21 3 12C-3 4 7-2 12 5c5-7 15-1 9 7Z'/%3E%3Cpath transform='translate(142 151) scale(2)' d='M12 21 3 12C-3 4 7-2 12 5c5-7 15-1 9 7Z'/%3E%3Cpath transform='rotate(180 84 274) translate(60 250) scale(2)' d='M12 21 3 12C-3 4 7-2 12 5c5-7 15-1 9 7Z'/%3E%3Cpath transform='rotate(180 166 274) translate(142 250) scale(2)' d='M12 21 3 12C-3 4 7-2 12 5c5-7 15-1 9 7Z'/%3E%3C/g%3E%3C/svg%3E");
  /* Притушена так же, как в руке: бумага и масть темнее на четверть,
     но черва остаётся красной — красное отличается от чёрного
     и на такой карте. */
  --образец-нельзя: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 250 350'%3E%3Crect x='2.5' y='2.5' width='245' height='345' rx='20' fill='%23b6ad9e' stroke='%23463016' stroke-opacity='.3' stroke-width='5'/%3E%3Cg fill='%23940c22' font-family='Times New Roman,Times,serif' font-size='60' font-weight='700' text-anchor='middle'%3E%3Ctext x='31' y='62'%3E7%3C/text%3E%3Cpath transform='translate(15 76) scale(1.3333)' d='M12 21 3 12C-3 4 7-2 12 5c5-7 15-1 9 7Z'/%3E%3Cg transform='rotate(180 125 175)'%3E%3Ctext x='31' y='62'%3E7%3C/text%3E%3Cpath transform='translate(15 76) scale(1.3333)' d='M12 21 3 12C-3 4 7-2 12 5c5-7 15-1 9 7Z'/%3E%3C/g%3E%3Cpath transform='translate(60 52) scale(2)' d='M12 21 3 12C-3 4 7-2 12 5c5-7 15-1 9 7Z'/%3E%3Cpath transform='translate(142 52) scale(2)' d='M12 21 3 12C-3 4 7-2 12 5c5-7 15-1 9 7Z'/%3E%3Cpath transform='translate(101 101) scale(2)' d='M12 21 3 12C-3 4 7-2 12 5c5-7 15-1 9 7Z'/%3E%3Cpath transform='translate(60 151) scale(2)' d='M12 21 3 12C-3 4 7-2 12 5c5-7 15-1 9 7Z'/%3E%3Cpath transform='translate(142 151) scale(2)' d='M12 21 3 12C-3 4 7-2 12 5c5-7 15-1 9 7Z'/%3E%3Cpath transform='rotate(180 84 274) translate(60 250) scale(2)' d='M12 21 3 12C-3 4 7-2 12 5c5-7 15-1 9 7Z'/%3E%3Cpath transform='rotate(180 166 274) translate(142 250) scale(2)' d='M12 21 3 12C-3 4 7-2 12 5c5-7 15-1 9 7Z'/%3E%3C/g%3E%3C/svg%3E");
}

:where(#приложение:has(> #экран-витрины)) #экран-правил > .правила {
  flex: 1 1 auto;
  min-height: 0;
  gap: 8px;
  margin-top: 4px;
  padding-bottom: 24px;
  background: none;
  scrollbar-width: thin;
  scrollbar-color: rgba(248, 245, 235, 0.18) transparent;
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 24px), transparent);
  mask-image: linear-gradient(to bottom, #000 calc(100% - 24px), transparent);
}

/* Одно правило — одна тёмная плитка. Номер — в кружке слева, текст
   ровным столбиком правее него: вторая строка не заезжает под номер. */
:where(#приложение:has(> #экран-витрины)) #экран-правил .правила .подпись {
  position: relative;
  display: block;
  margin: 0;
  padding: 12px 14px 13px 48px;
  text-indent: 0;
  font-size: clamp(15.5px, 4.1vw, 17px);
  line-height: 1.5;
  text-align: left;
  color: var(--сб-текст);
  background: var(--плитка);
  border: 1px solid var(--плитка-край);
  border-radius: 14px;
}

/* Номер правила — тихий, серым в тонком кружке: он помогает не сбиться,
   но не спорит с текстом. Кружок стоит вровень с первой строкой. */
:where(#приложение:has(> #экран-витрины)) #экран-правил .правила .подпись::before {
  content: counter(правило);
  position: absolute;
  left: 13px;
  top: 12px;
  box-sizing: border-box;
  width: 24px;
  height: 24px;
  border: 1px solid rgba(248, 245, 235, 0.16);
  border-radius: 50%;
  font-size: 12.5px;
  font-weight: 700;
  line-height: 22px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  color: var(--сб-текст-тихий);
}

/* Правило про подсветку — абзац с классом «правила__подсветка»
   (его ставит разработчик в разметке; найдено по классу, а не по счёту,
   чтобы образцы не уехали, если правила переставят): «Светлую карту
   с салатовой чертой можно выбрать сейчас, серую — нельзя». Словами это понять труднее
   всего, поэтому под текстом лежат две карты — ровно те, что человек
   через минуту увидит у себя в руке: светлая приподнята, под ней
   салатовая черта с лёгким свечением; серая чуть осела.
   Обе карты, черта и свечение нарисованы одной вставкой «после»
   абзаца — четырьмя слоями фона. Тень у неё по контуру рисунка,
   поэтому каждая карта отбрасывает свою. */
:where(#приложение:has(> #экран-витрины)) #экран-правил .правила .подпись.правила__подсветка {
  padding-bottom: 106px;
}

:where(#приложение:has(> #экран-витрины)) #экран-правил .правила .подпись.правила__подсветка::after {
  content: "";
  position: absolute;
  left: 48px;
  bottom: 12px;
  width: 112px;
  height: 84px;
  background:
    var(--образец-можно) 0 0 / 50px 70px no-repeat,
    var(--образец-нельзя) 62px 5px / 50px 70px no-repeat,
    linear-gradient(var(--сб-акцент), var(--сб-акцент)) 5px 75px / 40px 3px no-repeat,
    radial-gradient(closest-side, rgba(210, 247, 107, 0.55), rgba(210, 247, 107, 0)) 0 70px / 50px 13px no-repeat;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.5));
  pointer-events: none;
}

/* ---------- «Рекорды» ----------
   Сверху заголовок и серая строка «Лучшая серия: …», под ними десять
   строк рекордов, внизу в один ряд две равные тихие кнопки — «Как я
   играю» и «Рейтинг игроков». В ряд, а не столбиком: так на экране 390
   все десять строк помещаются целиком, без прокрутки.
   Раскладка — сеткой: список забирает всё свободное место и, если
   строк больше, чем влезает, прокручивается сам; кнопки остаются внизу,
   под большим пальцем. */
:where(#приложение:has(> #экран-витрины)) > #экран-рекордов.экран--виден {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 260px));
  grid-template-rows: auto auto auto minmax(0, 1fr) auto;
  grid-template-areas:
    "назад     назад"
    "заголовок заголовок"
    "подпись   подпись"
    "таблица   таблица"
    "счёт      рейтинг";
  justify-content: center;
  /* Растянуть, а не ставить по центру: общее правило экранов выше
     центрирует детей столбика, а в сетке «по центру» значит «по центру
     своего ряда по высоте» — и в низком окне список, которому не хватило
     места, вылезал вверх поверх заголовка вместо того, чтобы прокручиваться. */
  align-items: stretch;
  justify-items: stretch;
  gap: 0 8px;
}

/* В Telegram строки «‹» нет — и в сетке для неё нет ряда. */
html.в-телеграме :where(#приложение:has(> #экран-витрины)) > #экран-рекордов.экран--виден {
  grid-template-rows: auto auto minmax(0, 1fr) auto;
  grid-template-areas:
    "заголовок заголовок"
    "подпись   подпись"
    "таблица   таблица"
    "счёт      рейтинг";
}

:where(#приложение:has(> #экран-витрины)) #экран-рекордов > #кнопка-рекорды-назад { grid-area: назад; }
:where(#приложение:has(> #экран-витрины)) #экран-рекордов > .заголовок          { grid-area: заголовок; margin-top: 10px; }
:where(#приложение:has(> #экран-витрины)) #экран-рекордов > #лучший-рекорд       { grid-area: подпись; }
:where(#приложение:has(> #экран-витрины)) #экран-рекордов > #таблица-рекордов    { grid-area: таблица; }
:where(#приложение:has(> #экран-витрины)) #экран-рекордов > #кнопка-мой-счёт     { grid-area: счёт; }
:where(#приложение:has(> #экран-витрины)) #экран-рекордов > #кнопка-рейтинг-игроков { grid-area: рейтинг; }

/* Рейтинга игроков нет (нет связи с сервером) — «Как я играю» одна
   и занимает весь ряд. */
:where(#приложение:has(> #экран-витрины)) #экран-рекордов:not(:has(> #кнопка-рейтинг-игроков)) > #кнопка-мой-счёт {
  grid-column: 1 / -1;
}

/* «Лучшая серия: 12 побед» — серая строка под заголовком, как режим
   под «Дурак». */
:where(#приложение:has(> #экран-витрины)) #экран-рекордов > #лучший-рекорд {
  margin: 2px 0 0;
  text-align: left;
  font-size: clamp(14px, 3.8vw, 16px);
  font-weight: 500;
  line-height: 1.3;
  color: var(--сб-текст-тихий);
}

/* Низ списка тает в фон, как у правил: в низком окне видно, что строки
   ещё есть. Докрутили до конца — таять нечему, там пустое поле. */
:where(#приложение:has(> #экран-витрины)) #экран-рекордов > #таблица-рекордов {
  gap: 5px;
  margin-top: 12px;
  padding-bottom: 16px;
  scrollbar-width: thin;
  scrollbar-color: rgba(248, 245, 235, 0.18) transparent;
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 16px), transparent);
  mask-image: linear-gradient(to bottom, #000 calc(100% - 16px), transparent);
}

/* Строка рекорда — тёмная плитка. Раскладка внутри прежняя: номер
   слева, сверху крупно «12 побед подряд», под ним мелко дата и стол. */
:where(#приложение:has(> #экран-витрины)) #таблица-рекордов .таблица__строка {
  grid-template-columns: 2em auto minmax(0, 1fr);
  gap: 2px 8px;
  padding: 8px 14px 9px 8px;
  background: var(--плитка);
  border: 1px solid var(--плитка-край);
  border-radius: 14px;
  box-shadow: none;
}

:where(#приложение:has(> #экран-витрины)) #таблица-рекордов .таблица__место {
  font-size: 15px;
  font-weight: 700;
  text-align: center;
  color: var(--сб-текст-тихий);
}

:where(#приложение:has(> #экран-витрины)) #таблица-рекордов .таблица__очки {
  font-size: clamp(16px, 4.3vw, 18px);
  font-weight: 700;
  line-height: 1.25;
  color: var(--сб-текст);
}

:where(#приложение:has(> #экран-витрины)) #таблица-рекордов :is(.таблица__дата, .таблица__сложность) {
  font-size: 13px;
  line-height: 1.3;
  color: var(--сб-текст-тихий);
}

/* Лучший рекорд — первая строка — единственное салатовое на экране:
   рамка, номер и лёгкий салатовый отлив плитки. */
:where(#приложение:has(> #экран-витрины)) #таблица-рекордов .таблица__строка:first-child {
  background:
    linear-gradient(rgba(210, 247, 107, 0.07), rgba(210, 247, 107, 0.07)),
    var(--плитка);
  border-color: var(--сб-акцент);
  box-shadow: inset 0 0 0 1px var(--сб-акцент);
}

:where(#приложение:has(> #экран-витрины)) #таблица-рекордов .таблица__строка:first-child .таблица__место {
  color: var(--сб-акцент);
}

/* «Здесь пока пусто», «Минутку…» — та же плитка, текст серым. */
:where(#приложение:has(> #экран-витрины)) #таблица-рекордов .таблица__пусто {
  padding: 16px 14px;
  font-size: 15px;
  line-height: 1.45;
  text-align: left;
  color: var(--сб-текст-тихий);
  background: var(--плитка);
  border: 1px solid var(--плитка-край);
  border-radius: 14px;
}

/* «Как я играю» и «Рейтинг игроков» — тихие: тёмная плитка с тонким
   контуром, как тихие кнопки на плашке итога. Равные по ширине. */
:where(#приложение:has(> #экран-витрины)) #экран-рекордов > :is(#кнопка-мой-счёт, #кнопка-рейтинг-игроков) {
  width: 100%;
  min-width: 0;
  min-height: 48px;
  margin: 4px 0 0;           /* над кнопками ещё пустое поле списка (16 точек) */
  padding: 0 10px;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--сб-текст);
  background: var(--плитка);
  border: 1px solid rgba(248, 245, 235, 0.14);
  border-radius: 14px;
  box-shadow: none;
}

:where(#приложение:has(> #экран-витрины)) #экран-рекордов > :is(#кнопка-мой-счёт, #кнопка-рейтинг-игроков):active {
  transform: translateY(1px);
  background: var(--плитка-нажата);
  box-shadow: none;
}

/* ---------- «Оформление» ----------
   Остался один раздел — прежний «Фон», теперь это цвет сукна на столе
   (выбор рубашки разработчик спрятал). Ярлык раздела — мелкими
   прописными серым, под ним сетка тёмных плиток: сверху кусочек сукна
   в раме, под ним имя. Выбранная — салатовая рамка и галочка (их рисуют
   общие правила выбора выше по файлу: они берут «--акцент», а он здесь
   салатовый). Сами образцы — в разделе «ЦВЕТ СУКНА» ниже. */
:where(#приложение:has(> #экран-витрины), #приложение:has(.доска-нард)) > #экран-оформления {
  overflow-y: auto;
  overscroll-behavior: contain;
}

:where(#приложение:has(> #экран-витрины), #приложение:has(.доска-нард)) #экран-оформления > .оформление__раздел {
  margin: 10px 0 0;
}

:where(#приложение:has(> #экран-витрины), #приложение:has(.доска-нард)) #экран-оформления .оформление__подпись {
  margin: 0 0 8px;
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--сб-текст-тихий);
}

:where(#приложение:has(> #экран-витрины), #приложение:has(.доска-нард)) #экран-оформления .оформление__кнопки {
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  gap: 8px;
}

:where(#приложение:has(> #экран-витрины), #приложение:has(.доска-нард)) #экран-оформления .оформление__выбор.оформление__выбор {
  gap: 8px;
  padding: 8px 8px 10px;
  color: var(--сб-текст);
  background: var(--плитка);
  border: 1px solid var(--плитка-край);
  border-radius: 14px;
}

:where(#приложение:has(> #экран-витрины), #приложение:has(.доска-нард)) #экран-оформления .оформление__выбор.оформление__выбор:active {
  background: var(--плитка-нажата);
}

/* Выбранная плитка. Список длинный по той же причине, что у общих
   правил выбора выше: фон выбранным помечает сама страница признаком
   «data-фон», а «Сукно» выбрано и тогда, когда признака нет вовсе. */
:where(#приложение:has(> #экран-витрины), #приложение:has(.доска-нард)) #экран-оформления :is(
  .кнопка.оформление__выбор.кнопка--активная,
  html[data-фон="сукно"]   .оформление__выбор[data-фон="сукно"],
  html:not([data-фон])     .оформление__выбор[data-фон="сукно"],
  html[data-фон="дыхание"] .оформление__выбор[data-фон="дыхание"],
  html[data-фон="лампа"]   .оформление__выбор[data-фон="лампа"],
  html[data-фон="туман"]   .оформление__выбор[data-фон="туман"],
  html[data-фон="отсвет"]  .оформление__выбор[data-фон="отсвет"]
) {
  padding: 7px 7px 9px;      /* на точку меньше — рамка стала толще */
  background:
    linear-gradient(rgba(210, 247, 107, 0.07), rgba(210, 247, 107, 0.07)),
    var(--плитка);
  border: 2px solid var(--сб-акцент);
}

:where(#приложение:has(> #экран-витрины), #приложение:has(.доска-нард)) #экран-оформления .оформление__имя {
  font-size: 13px;
  font-weight: 600;
}

:where(#приложение:has(> #экран-витрины), #приложение:has(.доска-нард)) #экран-оформления .оформление__скоро {
  font-size: 14px;
  color: var(--сб-текст-тихий);
}

/* ---------- Невысокое окно ----------
   Заголовок мельче, плитки теснее. Текст правил — не мельче 15 точек:
   читают здесь именно его. */
@media (max-height: 700px) {
  :where(#приложение:has(> #экран-витрины), #приложение:has(.доска-нард)) > :is(#экран-правил, #экран-рекордов, #экран-оформления) > .заголовок {
    font-size: clamp(22px, 6.6vw, 27px);
  }

  :where(#приложение:has(> #экран-витрины)) #экран-правил > .правила { gap: 6px; }

  :where(#приложение:has(> #экран-витрины)) #экран-правил .правила .подпись {
    padding: 10px 12px 11px 44px;
    font-size: 15px;
    line-height: 1.45;
  }

  :where(#приложение:has(> #экран-витрины)) #экран-правил .правила .подпись::before {
    left: 11px;
    top: 10px;
    width: 22px;
    height: 22px;
    font-size: 12px;
    line-height: 20px;
  }

  :where(#приложение:has(> #экран-витрины)) #экран-правил .правила .подпись.правила__подсветка {
    padding-bottom: 102px;
  }

  :where(#приложение:has(> #экран-витрины)) #экран-правил .правила .подпись.правила__подсветка::after {
    left: 44px;
    bottom: 10px;
  }

  :where(#приложение:has(> #экран-витрины)) #экран-рекордов > #таблица-рекордов {
    gap: 5px;
    margin-top: 10px;
  }

  :where(#приложение:has(> #экран-витрины)) #таблица-рекордов .таблица__строка {
    padding: 7px 12px 8px 6px;
  }
}

/* =====================================================================
   ЛОББИ ДУРАКА И ТРИ ШАГА ДО ПАРТИИ
   (эталон/дурак-01-лобби, -02-правила, -03-игроки, -04-настройки)

   Не один в один, а концепт — как стол: те же тёмный фон, плитки на тон
   светлее, крупный жирный заголовок слева и один салатовый акцент.
   Сукно и дерево — кодом, теми же слоями, что у стола партии, и того же
   цвета, что выбран в «Оформлении».

   Одно сознательное отступление от эталона. Там салатовая карточка —
   «Играть онлайн». У нас онлайна нет, карточка выключена и помечена
   «скоро» — красить её главным цветом значило бы звать туда, куда нельзя.
   Главная, салатовая — «Играть с ботами».

   Кнопка «Далее» на шагах прилипает к низу экрана: в низком окне Telegram
   третий шаг не помещается, и искать главную кнопку прокруткой нельзя.
   ===================================================================== */

/* Фактуры стола — зерно сукна и волокна дерева. Вынесены в переменные,
   чтобы рама картинки лобби, стол рассадки и пример перевода рисовались
   теми же слоями, что стол партии. */
:root {
  --текстура-зерно: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3'/%3E%3CfeColorMatrix values='1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E");
  --текстура-волокна: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='60'%3E%3Cfilter id='d'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.012 0.5' numOctaves='2'/%3E%3CfeColorMatrix values='1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1'/%3E%3C/filter%3E%3Crect width='240' height='60' filter='url(%23d)' opacity='0.7'/%3E%3C/svg%3E");
  --значок-вперёд: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 4 8 8-8 8'/%3E%3C/svg%3E");
  /* Та же стрелка, развёрнутая влево, — для видимой «Назад» на шагах. */
  --значок-назад: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m15 4-8 8 8 8'/%3E%3C/svg%3E");
}

/* ---------- Общее для лобби и шагов ---------- */
#экран-лобби,
.экран.путь {
  --фон: var(--сб-фон);
  --панель: var(--сб-поверхность);
  --текст: var(--сб-текст);
  --текст-тихий: var(--сб-текст-тихий);
  --кнопка-фон: var(--сб-акцент);
  --кнопка-текст: var(--сб-акцент-текст);
  --акцент: var(--сб-акцент);
  --подложка: rgba(248, 245, 235, 0.06);
  --край: rgba(248, 245, 235, 0.14);
  --поле: clamp(12px, 3.6vw, 18px);
  --плитка: #1e2226;
  --плитка-кромка: rgba(248, 245, 235, 0.12);
  --плитка-нажата: #262a2f;
  /* Для панели вкладок — те же имена, что у витрины. */
  --вт-поверхность: var(--сб-поверхность);
  --вт-текст: var(--сб-текст);
  --вт-текст-тихий: var(--сб-текст-тихий);
  --вт-акцент: var(--сб-акцент);
  --вт-панель-низ: clamp(52px, 14.36vw, 64px);
  /* Дерево и сукно — как у стола партии. Цвет сукна меняет выбор
     в «Оформлении» (см. «ЦВЕТ СУКНА» ниже). */
  --дерево-свет: #9a6841;
  --дерево: #75492b;
  --дерево-тень: #4a2b17;

  align-items: center;
  gap: 10px;
  padding: calc(6px + var(--отступ-сверху)) calc(var(--поле) + var(--отступ-справа))
           calc(12px + var(--отступ-снизу)) calc(var(--поле) + var(--отступ-слева));
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: none;
  color: var(--сб-текст);
  text-align: left;
  background:
    radial-gradient(75% 120px at 50% 0, rgba(210, 247, 107, 0.07), rgba(210, 247, 107, 0) 100%) local,
    var(--сб-фон);
}

#экран-лобби::-webkit-scrollbar,
.экран.путь::-webkit-scrollbar { display: none; }

/* Столбик — не шире витрины (520) и посередине; ничего не сжимается —
   не влезло, экран прокручивается. */
#экран-лобби > :not(.нижние-вкладки),
.экран.путь > * {
  flex-shrink: 0;
  box-sizing: border-box;
  width: 100%;
  max-width: 520px;
}

/* У лобби и шагов поля не 8px, а var(--поле) (12–18px, см. «Общее для
   лобби и шагов» выше) — это отдельное решение оформителя, не тот баг,
   что чинили в .верх-игры. Поэтому здесь margin оставлен как раньше,
   своим числом, а не общей формулой базового класса. */
#экран-лобби > .верх-игры,
.экран.путь > .верх-игры {
  margin-left: -10px;
  margin-right: -10px;
  width: calc(100% + 20px);
  max-width: 540px;
}

/* Кнопки экрана: без серой вспышки, с салатовой обводкой с клавиатуры. */
:is(#экран-лобби, .экран.путь) button:focus-visible {
  outline: 2px solid var(--сб-акцент);
  outline-offset: 2px;
}

/* Плитка — общий вид карточек лобби и шагов: на тон светлее фона,
   тонкая светлая кромка, скругление 18. */
:is(.карточка-профиля, .карточка-входа, .вариант, .сводка, .карточка-тренировки) {
  box-sizing: border-box;
  background: var(--плитка);
  border: 1px solid var(--плитка-кромка);
  border-radius: 18px;
}

/* Значки в разметке — тонкие контуры набора; размер задаёт их коробка. */
:is(.карточка-профиля__стрелка, .карточка-входа__значок, .карточка-входа__стрелка,
    .сводка__значок, .карточка-тренировки__значок, .пример-перевода__стрелка) svg {
  display: block;
  width: 100%;
  height: 100%;
}

/* ---------- Лобби ---------- */
#экран-лобби {
  gap: 12px;
  /* Снизу — место под панель вкладок, как у витрины. */
  padding-bottom: calc(var(--вт-панель-низ) + 14px + var(--отступ-снизу));
}

#экран-лобби > .лобби__заголовок {
  margin: 0;
  font-size: clamp(34px, 11vw, 48px);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.025em;
  color: var(--сб-текст);
}

html.в-телеграме #экран-лобби > .лобби__заголовок { margin-top: 4px; }

/* Подпись сразу под заголовком лобби («Классическая игра для двоих»
   у шашек). Весь каркас лобби левосторонний, а общая «.подпись»
   центрирует текст — здесь она возвращается к левому краю и подтянута
   к заголовку. У дурака такой подписи нет, правило просто молчит. */
#экран-лобби > .лобби__заголовок + .подпись {
  margin: -6px 0 0;
  text-align: left;
  color: var(--сб-текст-тихий);
}

/* Недоигранная партия с другом — первой, заметно, но не главной кнопкой. */
#экран-лобби > .плашка-возврата {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 48px;
  padding: 8px 14px;
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.25;
  color: var(--сб-текст);
  background: rgba(210, 247, 107, 0.08);
  border: 1px solid rgba(210, 247, 107, 0.45);
  border-radius: 16px;
  cursor: pointer;
}

#экран-лобби > .плашка-возврата::before {
  content: "↻";
  font-size: 18px;
  line-height: 1;
  color: var(--сб-акцент);
}

/* Карточка профиля: аватар, имя, место в рейтинге, «›». */
.карточка-профиля {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 68px;
  padding: 10px 14px 10px 12px;
  font: inherit;
  text-align: left;
  color: var(--сб-текст);
  cursor: pointer;
}

.карточка-профиля > .аватар {
  --аватар: 48px;
  color: #aab0b6;
}

.карточка-профиля__текст {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.карточка-профиля__имя {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: clamp(16px, 4.6vw, 19px);
  font-weight: 700;
  line-height: 1.2;
}

.карточка-профиля__рейтинг {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 15px;
  line-height: 1.2;
  color: var(--сб-текст-тихий);
}

.карточка-профиля__рейтинг svg {
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  color: var(--сб-акцент);
}

/* Места в рейтинге нет — строки нет вовсе: один кубок без числа
   читался бы как «ноль». */
.карточка-профиля__рейтинг--нет { display: none; }

.карточка-профиля__стрелка,
.карточка-входа__стрелка {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  color: var(--сб-текст-тихий);
}

/* Картинка лобби в деревянной раме — те же слои, что у рамы стола.
   Внутри — фото карт на сукне, по низу подпись с засечками, как на
   эталоне. Затемнение снизу — чтобы подпись читалась поверх карт. */
.лобби__картинка {
  --рама: clamp(7px, 2.3vw, 11px);
  position: relative;
  margin: 0;
  aspect-ratio: 16 / 10;
  border: var(--рама) solid transparent;
  border-radius: calc(var(--рама) + 14px);
  background:
    var(--текстура-волокна) border-box,
    linear-gradient(180deg, var(--дерево-свет) 0%, var(--дерево) 40%, var(--дерево-тень) 100%) border-box;
  background-size: 240px 60px, auto;
  background-repeat: repeat, no-repeat;
  background-blend-mode: soft-light, normal;
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.60),
    0 14px 30px rgba(0, 0, 0, 0.55);
}

/* Фаска рамы — как у стола. */
.лобби__картинка::before {
  content: "";
  position: absolute;
  inset: calc(-1 * var(--рама));
  border-radius: inherit;
  pointer-events: none;
  box-shadow:
    inset 0 1.5px 0 rgba(255, 222, 184, 0.34),
    inset 0 -1.5px 0 rgba(0, 0, 0, 0.45),
    inset 1px 0 0 rgba(255, 222, 184, 0.10),
    inset -1px 0 0 rgba(0, 0, 0, 0.25);
}

/* Картинка лежит поверх рамки целиком, а не в потоке: иначе её родная
   высота (1200×800) растягивала рамку сильнее заданной пропорции. */
.лобби__рисунок {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 42%;
  border-radius: 14px;
}

/* Тень от рамы на сукно и затемнение под подписью. */
.лобби__картинка::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 14px;
  pointer-events: none;
  background: linear-gradient(to top, rgba(22, 4, 6, 0.78) 0%, rgba(22, 4, 6, 0) 50%);
  box-shadow:
    inset 0 0 0 1px rgba(0, 0, 0, 0.55),
    inset 0 10px 24px rgba(0, 0, 0, 0.50),
    inset 0 -8px 20px rgba(0, 0, 0, 0.35);
}

.лобби__подпись {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 9%;
  z-index: 1;
  max-width: 13em;
  margin: 0 auto;
  padding: 0 12px;
  font-family: Georgia, 'Times New Roman', Times, 'Noto Serif', 'Liberation Serif', serif;
  font-size: clamp(18px, 5.4vw, 23px);
  font-weight: 400;
  line-height: 1.2;
  text-align: center;
  text-wrap: balance;
  color: #f8f1e4;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.85);
}

/* Входы: онлайн (скоро), с ботами (главный), раздача дня, друзья, код. */
.лобби__входы {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.карточка-входа {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 68px;
  padding: 10px 16px 10px 14px;
  font: inherit;
  text-align: left;
  color: var(--сб-текст);
  cursor: pointer;
}

.карточка-входа__значок {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  margin: 0 4px;
}

.карточка-входа__текст {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.карточка-входа__название {
  font-size: clamp(17px, 5vw, 21px);
  font-weight: 700;
  line-height: 1.2;
}

.карточка-входа__подпись {
  font-size: clamp(13px, 3.7vw, 15px);
  line-height: 1.25;
  color: var(--сб-текст-тихий);
}

.карточка-входа:not(:disabled):active,
.карточка-профиля:active {
  transform: scale(0.985);
  background-color: var(--плитка-нажата);
}

/* С ботами — главная: салатовая, тёмный текст. */
.карточка-входа.карточка-входа--боты {
  color: var(--сб-акцент-текст);
  background: var(--сб-акцент);
  border-color: var(--сб-акцент);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.35),
    0 8px 22px rgba(210, 247, 107, 0.16);
}

.карточка-входа--боты .карточка-входа__подпись,
.карточка-входа--боты .карточка-входа__стрелка {
  color: rgba(16, 19, 10, 0.68);
}

.карточка-входа.карточка-входа--боты:active {
  background: var(--сб-акцент);
  filter: brightness(0.95);
}

/* Онлайн — есть, но выключен: приглушён, справа «скоро». */
.карточка-входа--онлайн:disabled { cursor: default; }
.карточка-входа--онлайн:disabled > :not(.пометка-скоро) { opacity: 0.5; }

/* Друзья — одна строка, карточка ниже. */
.карточка-входа--друзья { min-height: 58px; }

/* «Вдвоём на этом устройстве» — третий вход, по решению владельца
   заметно скромнее первых двух: это запасной способ сыграть, а не
   главная дорога. Скромность собрана из четырёх признаков сразу:
   карточка ниже, без заливки-плитки (только тонкий контур на фоне
   страницы), значок и название мельче, подпись тише. Высота при этом
   не опускается ниже 52 точек — палец должен попадать так же уверенно,
   как в большие карточки. Класс общий: тот же вход есть у шашек,
   шахмат и нард. */
.карточка-входа.карточка-входа--вдвоём {
  min-height: 52px;
  padding: 8px 16px 8px 14px;
  background: none;
  border-color: var(--плитка-кромка);
  box-shadow: none;
}

.карточка-входа--вдвоём .карточка-входа__значок {
  width: 24px;
  height: 24px;
  color: var(--сб-текст-тихий);
}

.карточка-входа--вдвоём .карточка-входа__название {
  font-size: clamp(15px, 4.3vw, 17px);
  font-weight: 600;
}

.карточка-входа--вдвоём .карточка-входа__подпись {
  font-size: clamp(12px, 3.4vw, 13px);
}

.карточка-входа.карточка-входа--вдвоём:active {
  background-color: var(--плитка-нажата);
}

#экран-лобби .пометка-скоро {
  flex: 0 0 auto;
  padding: 3px 10px 4px;
  font-size: 12.5px;
  font-weight: 700;
  line-height: 1.2;
  color: var(--сб-текст);
  background: rgba(0, 0, 0, 0.45);
  border: 1px solid rgba(248, 245, 235, 0.16);
  border-radius: 999px;
}

/* «Раздача дня» — тихая плитка; салатовая только искра впереди. */
#экран-лобби .кнопка.кнопка--раздача-дня {
  width: 100%;
  min-height: 50px;
  padding: 8px 16px;
  font-size: 16px;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--сб-текст);
  background: var(--плитка);
  border: 1px solid rgba(210, 247, 107, 0.30);
  border-radius: 18px;
  box-shadow: none;
}

#экран-лобби .кнопка.кнопка--раздача-дня::before {
  content: "✦ ";
  color: var(--сб-акцент);
}

#экран-лобби .кнопка.кнопка--раздача-дня.кнопка--раздача-сыграна,
#экран-лобби .кнопка.кнопка--раздача-дня.кнопка--раздача-сыграна:disabled {
  font-size: 15px;
  color: var(--сб-текст);
  background: var(--плитка);
  border: 1px solid var(--плитка-кромка);
}

/* «Есть код? Войти» — тихая ссылка под входами. */
#экран-лобби .лобби__код {
  align-self: center;
  min-height: 44px;
  padding: 0 12px;
  font: inherit;
  font-size: 15px;
  color: var(--сб-текст-тихий);
  background: none;
  border: none;
  text-decoration: underline dotted;
  text-underline-offset: 4px;
  cursor: pointer;
}

/* ---------- Шаги: шапка ---------- */
.путь__шапка {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: 12px;
  row-gap: 2px;
}

html.в-телеграме .экран.путь > .путь__шапка { margin-top: 4px; }

.путь__заголовок {
  flex: 0 1 auto;
  min-width: 0;
  margin: 0;
  font-size: clamp(28px, 8.8vw, 40px);
  font-weight: 800;
  line-height: 1.08;
  letter-spacing: -0.025em;
  color: var(--сб-текст);
}

/* Пилюля режима — «С ботами», «С друзьями». Тихая: салатовый на шаге
   у полосы шагов и у «Далее». */
.путь__режим {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  min-height: 30px;
  padding: 3px 13px 4px;
  font-size: 14px;
  font-weight: 600;
  line-height: 1.2;
  color: var(--сб-текст);
  border: 1px solid var(--сб-граница);
  border-radius: 999px;
}

.путь__режим:empty,
.путь__шаг:empty { display: none; }

.путь__шаг {
  flex: 1 0 100%;
  margin: 0;
  font-size: 15px;
  line-height: 1.3;
  color: var(--сб-текст-тихий);
}

/* ---------- Полоса шагов ----------
   Кружок с цифрой и имя; между шагами черта. Пройденный — салатовый
   контур с галочкой, текущий — залитый салатовым кружок со свечением,
   впереди — серый контур. Черта салатовая, если ведёт к уже
   достигнутому шагу. Черты растягиваются, полоса занимает всю ширину. */
.экран.путь > .шаги {
  display: flex;
  align-items: center;
  margin: 4px 0 4px;
  padding: 0;
  list-style: none;
}

.шаги__шаг {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 0 0 auto;
  font-size: clamp(12.5px, 3.6vw, 14px);
  font-weight: 500;
  line-height: 1.2;
  white-space: nowrap;
  color: var(--сб-текст-тихий);
}

.шаги__шаг + .шаги__шаг { flex: 1 1 auto; }

.шаги__шаг + .шаги__шаг::before {
  content: "";
  flex: 1 1 auto;
  min-width: 8px;
  height: 1.5px;
  margin: 0 8px;
  border-radius: 1px;
  background: rgba(248, 245, 235, 0.22);
}

.шаги__номер {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  box-sizing: border-box;
  width: clamp(28px, 8.2vw, 32px);
  height: clamp(28px, 8.2vw, 32px);
  border: 1.5px solid rgba(248, 245, 235, 0.32);
  border-radius: 50%;
  font-size: 15px;
  font-weight: 700;
  line-height: 1;
}

.шаги__галочка {
  display: none;
  width: 60%;
  height: 60%;
}

.шаги__шаг--пройден,
.шаги__шаг--текущий { color: var(--сб-акцент); }

.шаги__шаг--пройден::before,
.шаги__шаг--текущий::before { background: var(--сб-акцент); }

.шаги__шаг--пройден .шаги__номер { border-color: var(--сб-акцент); }
.шаги__шаг--пройден .шаги__цифра { display: none; }
.шаги__шаг--пройден .шаги__галочка { display: block; }

.шаги__шаг--текущий { font-weight: 600; }

.шаги__шаг--текущий .шаги__номер {
  color: var(--сб-акцент-текст);
  background: var(--сб-акцент);
  border-color: var(--сб-акцент);
  box-shadow: 0 0 14px rgba(210, 247, 107, 0.45);
}

/* ---------- Шаги: вопросы и подписи ---------- */
.путь__вопрос {
  margin: 8px 0 0;
  font-size: clamp(22px, 6.4vw, 28px);
  font-weight: 800;
  line-height: 1.15;
  letter-spacing: -0.015em;
}

.путь__раздел {
  margin: 6px 0 -2px;
  font-size: clamp(17px, 5vw, 21px);
  font-weight: 700;
  line-height: 1.2;
}

.путь__подпись,
.путь__подсказка {
  margin: 0;
  font-size: 14px;
  line-height: 1.35;
  text-align: center;
  text-wrap: balance;
  color: var(--сб-текст-тихий);
}

/* «Включая вас» — сразу под числами. */
.числа + .путь__подпись { margin-top: -4px; }

#путь-блок-сложности {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

#путь-блок-сложности.скрыт { display: none; }

.путь__ссылка {
  align-self: center;
  width: auto;
  min-height: 44px;
  padding: 0 12px;
  font: inherit;
  font-size: 15px;
  color: var(--сб-текст-тихий);
  background: none;
  border: none;
  text-decoration: underline;
  text-decoration-color: rgba(133, 139, 148, 0.5);
  text-underline-offset: 4px;
  cursor: pointer;
}

.экран.путь > .путь__ссылка { width: auto; }

/* ---------- Шаг 1: варианты правил ---------- */
.варианты {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.вариант {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 14px;
  min-height: 96px;
  padding: 12px 16px 12px 14px;
  font: inherit;
  text-align: left;
  color: var(--сб-текст);
  border-width: 1.5px;
  cursor: pointer;
}

.вариант:active { background-color: var(--плитка-нажата); }

.вариант.вариант--выбран {
  background:
    linear-gradient(rgba(210, 247, 107, 0.06), rgba(210, 247, 107, 0.06)),
    var(--плитка);
  border-color: var(--сб-акцент);
  box-shadow: 0 0 18px rgba(210, 247, 107, 0.12);
}

/* Две карты новой колоды внахлёст, чуть веером. */
.вариант__карты {
  --в: clamp(58px, 17vw, 70px);
  --ш: calc(var(--в) / 1.4);
  display: flex;
  align-items: center;
  padding: 0 4px 0 2px;
}

.вариант__карты > .карта {
  flex: 0 0 auto;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.45);
}

.вариант__карты > .карта + .карта { margin-left: calc(var(--ш) * -0.42); }
.вариант__карты > .карта:first-child { rotate: -7deg; }
.вариант__карты > .карта:last-child { rotate: 6deg; translate: 0 2px; }

.вариант__текст {
  display: flex;
  flex-direction: column;
  gap: 3px;
  min-width: 0;
}

.вариант__название {
  font-size: clamp(18px, 5.3vw, 22px);
  font-weight: 700;
  line-height: 1.15;
}

.вариант__описание {
  font-size: clamp(13px, 3.8vw, 15px);
  line-height: 1.3;
  color: var(--сб-текст-тихий);
}

/* Кружок выбора: пустой — серый контур, выбран — салатовый с галочкой. */
.вариант__отметка {
  display: grid;
  place-items: center;
  box-sizing: border-box;
  width: 30px;
  height: 30px;
  border: 1.5px solid rgba(248, 245, 235, 0.35);
  border-radius: 50%;
  color: transparent;
}

.вариант__отметка svg {
  display: block;
  width: 18px;
  height: 18px;
  stroke-width: 2.2;
}

.вариант--выбран .вариант__отметка {
  color: var(--сб-акцент-текст);
  background: var(--сб-акцент);
  border-color: var(--сб-акцент);
}

/* Пример перевода — на сукне в раме, как стол: две карты и стрелка. */
.пример-перевода,
.рассадка {
  --рама: clamp(7px, 2.3vw, 11px);
  --сукно-свет: #6e181c;
  --сукно: #4f0d10;
  --сукно-тень: #2a0507;
  position: relative;
  border: var(--рама) solid transparent;
  background:
    var(--текстура-зерно) padding-box,
    radial-gradient(120% 95% at 50% 38%, var(--сукно-свет) 0%, var(--сукно) 52%, var(--сукно-тень) 100%) padding-box,
    var(--текстура-волокна) border-box,
    linear-gradient(180deg, var(--дерево-свет) 0%, var(--дерево) 40%, var(--дерево-тень) 100%) border-box;
  background-size: 160px 160px, auto, 240px 60px, auto;
  background-repeat: repeat, no-repeat, repeat, no-repeat;
  background-blend-mode: soft-light, normal, soft-light, normal;
  box-shadow:
    inset 0 0 0 1px rgba(0, 0, 0, 0.55),
    inset 0 10px 26px rgba(0, 0, 0, 0.50),
    inset 0 -8px 20px rgba(0, 0, 0, 0.35),
    0 0 0 1px rgba(0, 0, 0, 0.60),
    0 14px 30px rgba(0, 0, 0, 0.55);
}

.пример-перевода::before,
.рассадка::before {
  content: "";
  position: absolute;
  inset: calc(-1 * var(--рама));
  border-radius: inherit;
  pointer-events: none;
  box-shadow:
    inset 0 1.5px 0 rgba(255, 222, 184, 0.34),
    inset 0 -1.5px 0 rgba(0, 0, 0, 0.45),
    inset 1px 0 0 rgba(255, 222, 184, 0.10),
    inset -1px 0 0 rgba(0, 0, 0, 0.25);
}

.пример-перевода {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  padding: 18px 16px 14px;
  border-radius: calc(var(--рама) + 16px);
}

.пример-перевода.скрыт { display: none; }

.пример-перевода__карты {
  --в: clamp(72px, 22vw, 92px);
  --ш: calc(var(--в) / 1.4);
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(14px, 5vw, 26px);
}

.пример-перевода__карты > .карта {
  flex: 0 0 auto;
  box-shadow: 0 3px 8px rgba(0, 0, 0, 0.5), 0 10px 20px rgba(0, 0, 0, 0.3);
}

.пример-перевода__карты > .карта:first-child { rotate: -5deg; }
.пример-перевода__карты > .карта:last-child { rotate: 4deg; }

.пример-перевода__стрелка {
  flex: 0 0 auto;
  width: clamp(38px, 11vw, 48px);
  height: clamp(38px, 11vw, 48px);
  color: #f8f1e4;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.6));
}

.пример-перевода__стрелка svg { stroke-width: 2; }

.пример-перевода__подпись {
  margin: 0;
  font-size: 14px;
  line-height: 1.3;
  text-align: center;
  color: rgba(248, 245, 235, 0.78);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.7);
}

/* ---------- Шаг 2 и 3: переключатель и числа ---------- */
.переключатель {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 4px;
  box-sizing: border-box;
  padding: 4px;
  background: var(--плитка);
  border: 1px solid var(--плитка-кромка);
  border-radius: 18px;
}

.переключатель.скрыт { display: none; }

.переключатель__вариант {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  min-width: 0;
  min-height: 48px;
  padding: 4px 6px;
  font: inherit;
  /* Три ячейки в ряд на 360 — по 106 точек: «Без таймера» при таком
     кегле встаёт в одну строку. */
  font-size: clamp(14px, 4vw, 16.5px);
  font-weight: 600;
  line-height: 1.15;
  text-align: center;
  color: var(--сб-текст);
  background: none;
  border: none;
  border-radius: 14px;
  cursor: pointer;
}

.переключатель__вариант:not(:disabled):not(.переключатель__вариант--выбран):active {
  background: var(--плитка-нажата);
}

.переключатель__вариант.переключатель__вариант--выбран {
  font-weight: 700;
  color: var(--сб-акцент-текст);
  background: var(--сб-акцент);
  box-shadow: 0 4px 14px rgba(210, 247, 107, 0.22);
}

/* Выключенный вариант должен читаться, иначе человек решит, что экран
   сломался. Держим одну меру на всех экранах — примерно 0,6 от белого,
   как у фильтров рейтинга и у подбора игроков в комнате. Прежние 0,38
   на шаге «Настройки» превращали «30 сек» в еле различимую тень. */
.переключатель__вариант:disabled {
  color: rgba(248, 245, 235, 0.6);
  cursor: default;
}

/* Выбранный вариант выключенной пары. Раньше на него падало правило
   выше и текст становился бледно-белым по салатовому — прочесть было
   нельзя. Салатовая пилюля всегда с тёмной надписью, как кнопки лобби;
   свечение убрано — оно звало нажать на то, что не нажимается. */
.переключатель__вариант.переключатель__вариант--выбран:disabled {
  color: var(--сб-акцент-текст);
  box-shadow: none;
}

/* «скоро» внутри переключателя — та же тёмная пилюля, что у «Играть
   онлайн» в лобби, у подбора игроков в комнате и у фильтров рейтинга.
   Стоит второй строкой под названием: ячейка вдвое уже кнопки лобби,
   рядом слово не встанет.

   Раньше здесь был просто бледный текст в 0,45 от белого — на шаге
   «Настройки» («30 сек», «60 сек») его почти не было видно, и одна и
   та же пометка выглядела на трёх экранах по-разному. */
.переключатель__вариант > .пометка-скоро {
  margin-top: 2px;
  padding: 1px 8px 2px;
  font-size: 10px;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(248, 245, 235, 0.62);
  background: rgba(0, 0, 0, 0.4);
  border: 1px solid rgba(248, 245, 235, 0.14);
  border-radius: 999px;
}

.числа {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 8px;
}

.числа__число {
  min-width: 0;
  min-height: 52px;
  padding: 0;
  font: inherit;
  font-size: clamp(18px, 5.4vw, 22px);
  font-weight: 600;
  color: var(--сб-текст);
  background: var(--плитка);
  border: 1px solid var(--плитка-кромка);
  border-radius: 14px;
  cursor: pointer;
}

.числа__число:not(:disabled):not(.числа__число--выбран):active { background: var(--плитка-нажата); }

.числа__число.числа__число--выбран {
  font-weight: 800;
  color: var(--сб-акцент-текст);
  background: var(--сб-акцент);
  border-color: var(--сб-акцент);
  box-shadow: 0 4px 14px rgba(210, 247, 107, 0.22);
}

.числа__число:disabled {
  opacity: 0.35;
  cursor: default;
}

/* ---------- Шаг 2: стол рассадки ----------
   Овальный стол — дерево и сукно, как стол партии. Места — по числу
   игроков, по кругу, начиная с «Вы» наверху и дальше по часовой.
   Угол места считается из его номера и числа мест (их пишет игра:
   «--номер-места» и «--мест»), точка — на овале рамы. Места крупнее
   пальца (48–58 точек) и выступают за край стола наполовину — поэтому
   у стола поля вокруг. */
.рассадка {
  --место: clamp(48px, 14.5vw, 58px);
  --рама: clamp(9px, 2.8vw, 13px);
  box-sizing: border-box;
  align-self: center;
  aspect-ratio: 2.15 / 1;
  margin: calc(var(--место) / 2) auto calc(var(--место) / 2 + 4px);
  border-radius: 999px;
}

/* Стол у́же столбика на одно место: крайние места выступают за край
   стола наполовину и не должны упираться в край экрана. */
.экран.путь > .рассадка {
  width: calc(100% - var(--место));
  max-width: 440px;
}

.рассадка__место {
  --угол: calc(-90deg + var(--номер-места, 0) * 360deg / var(--мест, 4));
  position: absolute;
  left: calc(50% + (50% + var(--рама) / 2) * cos(var(--угол)));
  top: calc(50% + (50% + var(--рама) / 2) * sin(var(--угол)));
  z-index: 1;
  display: grid;
  place-items: center;
  width: var(--место);
  height: var(--место);
  margin: calc(var(--место) / -2) 0 0 calc(var(--место) / -2);
  border-radius: 50%;
  color: #8a9199;
  background: #171a1d;
  box-shadow:
    0 0 0 2px rgba(0, 0, 0, 0.35),
    0 5px 12px rgba(0, 0, 0, 0.55);
}

/* Значок аватара (круг с человеком) — во всё место: его круг и есть
   кольцо места, цветом роли. */
.рассадка__место > .аватар {
  --аватар: var(--место);
  color: inherit;
}

.рассадка__место--я {
  color: var(--сб-акцент);
  box-shadow:
    0 0 0 2px rgba(0, 0, 0, 0.35),
    0 5px 12px rgba(0, 0, 0, 0.55),
    0 0 18px rgba(210, 247, 107, 0.45);
}

/* Напарник «2 на 2» — свой: салатовый, но тише «Вы». */
.рассадка__место--напарник { color: rgba(210, 247, 107, 0.6); }

.рассадка__имя {
  position: absolute;
  top: calc(100% + 3px);
  left: 50%;
  translate: -50% 0;
  font-size: 14px;
  font-weight: 700;
  line-height: 1.2;
  white-space: nowrap;
  color: var(--сб-акцент);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.7);
}

/* ---------- Шаг 3: сводка и карточка тренировки ---------- */
.сводка,
.карточка-тренировки {
  display: flex;
  align-items: center;
  gap: 14px;
  min-height: 72px;
  padding: 12px 16px;
}

.карточка-тренировки.скрыт { display: none; }

.сводка__значок,
.карточка-тренировки__значок {
  flex: 0 0 auto;
  width: 34px;
  height: 34px;
  margin: 0 4px;
  color: #c9ced3;
}

.сводка__текст,
.карточка-тренировки__текст {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.сводка__главное {
  font-size: clamp(17px, 5vw, 20px);
  font-weight: 700;
  line-height: 1.2;
}

.карточка-тренировки__название {
  font-size: clamp(16px, 4.6vw, 18px);
  font-weight: 600;
  line-height: 1.2;
}

.сводка__подпись,
.карточка-тренировки__подпись {
  font-size: 14px;
  line-height: 1.3;
  color: var(--сб-текст-тихий);
}

/* ---------- «Далее» / «Начать игру» ----------
   Салатовая во всю ширину, «›» справа, как на эталоне. Прилипает к низу
   экрана: пока шаг прокручивается, кнопка остаётся под пальцем. Под ней
   и над ней — фон экрана (тени цвета фона), чтобы прокручиваемое
   не просвечивало вокруг кнопки.

   С 11 сентября на шагах «Игроки» и «Настройки» рядом с ней стоит
   видимая «Назад» (владелец: «не хватает кнопки вернуться в предыдущие
   настройки»), и обе лежат в строке «путь__кнопки-шага». Тогда к низу
   прилипает вся строка, а не одна кнопка, и фон под ней — у строки.
   Главная кнопка выглядит одинаково и одна, и в строке. */
.экран.путь > .кнопка.путь__далее,
.экран.путь > .путь__кнопки-шага {
  position: sticky;
  bottom: calc(12px + var(--отступ-снизу));
  z-index: 2;
  margin: auto 0 0;
}

.экран.путь > .кнопка.путь__далее,
.экран.путь > .путь__кнопки-шага > .кнопка.путь__далее {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-width: 0;
  max-width: 520px;
  min-height: 58px;
  padding: 0 56px;
  font-size: clamp(18px, 5.4vw, 22px);
  font-weight: 800;
  letter-spacing: 0;
  color: var(--сб-акцент-текст);
  background: var(--сб-акцент);
  border: none;
  border-radius: 20px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.35),
    0 8px 22px rgba(210, 247, 107, 0.16),
    0 -16px 16px -4px var(--сб-фон),
    0 18px 0 0 var(--сб-фон);
}

/* Строка «Назад · Далее»: «Назад» по своим словам, главная забирает
   остаток. Фон строки — цвет экрана: в просвет между кнопками
   прокручиваемое не просвечивает. Тени цвета фона — у строки, у главной
   внутри неё — только свои (блик и салатовое свечение). */
.экран.путь > .путь__кнопки-шага {
  display: flex;
  align-items: stretch;
  gap: 10px;
  background: var(--сб-фон);
  border-radius: 20px;
  box-shadow:
    0 -16px 16px -4px var(--сб-фон),
    0 18px 0 0 var(--сб-фон);
}

/* Поля у главной в строке уже, чем у одиночной (56): иначе на 360
   «Начать игру» переносилась в две строки. Слева 30, справа 38 —
   под стрелку «›», которая здесь стоит ближе к краю (14 вместо 20).
   Так «Начать игру» в одну строку влезает и на 320. */
.экран.путь > .путь__кнопки-шага > .кнопка.путь__далее {
  position: relative;
  flex: 1 1 auto;
  width: auto;
  max-width: none;
  margin: 0;
  padding: 0 38px 0 30px;
  white-space: nowrap;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.35),
    0 8px 22px rgba(210, 247, 107, 0.16);
}

/* «Назад» — тихая плитка той же высоты и того же скругления, что
   главная, со стрелкой «‹» перед словом. Цвет — как у плиток шага
   (варианты, сводка): видно, что это кнопка, но рука тянется к салатовой. */
.экран.путь > .путь__кнопки-шага > .кнопка.кнопка--мелкая {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  min-width: 0;
  min-height: 58px;
  margin: 0;
  padding: 0 18px 0 12px;
  font-size: clamp(15px, 4.3vw, 17px);
  font-weight: 600;
  letter-spacing: 0;
  color: var(--сб-текст);
  background: var(--плитка);
  border: 1px solid var(--плитка-кромка);
  border-radius: 20px;
  box-shadow: none;
}

.экран.путь > .путь__кнопки-шага > .кнопка.кнопка--мелкая::before {
  content: "";
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  background-color: currentColor;
  -webkit-mask: var(--значок-назад) center / contain no-repeat;
  mask: var(--значок-назад) center / contain no-repeat;
}

.экран.путь > .путь__кнопки-шага > .кнопка.кнопка--мелкая:active {
  transform: translateY(1px);
  background: var(--плитка-нажата);
}

.экран.путь > .кнопка.путь__далее::after,
.экран.путь > .путь__кнопки-шага > .кнопка.путь__далее::after {
  content: "";
  position: absolute;
  right: 20px;
  top: 50%;
  width: 24px;
  height: 24px;
  margin-top: -12px;
  background-color: currentColor;
  -webkit-mask: var(--значок-вперёд) center / contain no-repeat;
  mask: var(--значок-вперёд) center / contain no-repeat;
}

/* В строке «Назад · Далее» стрелка ближе к краю — см. поля главной там. */
.экран.путь > .путь__кнопки-шага > .кнопка.путь__далее::after {
  right: 14px;
}

.экран.путь > .кнопка.путь__далее:active,
.экран.путь > .путь__кнопки-шага > .кнопка.путь__далее:active {
  transform: translateY(1px);
  filter: brightness(0.95);
}

/* ---------- Невысокое окно ----------
   Всё то же, только плотнее: заголовки и плитки ниже, стол рассадки
   меньше. Кнопки — не ниже 44 точек. */
@media (max-height: 700px) {
  #экран-лобби,
  .экран.путь { gap: 8px; }

  #экран-лобби > .лобби__заголовок { font-size: clamp(28px, 9vw, 38px); }
  .лобби__картинка { aspect-ratio: 2 / 1; }
  .карточка-профиля { min-height: 60px; padding-top: 8px; padding-bottom: 8px; }
  .карточка-профиля > .аватар { --аватар: 42px; }
  .карточка-входа { min-height: 60px; padding-top: 8px; padding-bottom: 8px; }
  .карточка-входа--друзья { min-height: 52px; }

  .путь__заголовок { font-size: clamp(24px, 7.6vw, 32px); }
  .путь__вопрос { margin-top: 4px; font-size: clamp(20px, 5.8vw, 24px); }
  .путь__раздел { margin-top: 2px; }
  .вариант { min-height: 84px; padding-top: 10px; padding-bottom: 10px; }
  .вариант__карты { --в: clamp(52px, 15vw, 60px); }
  .пример-перевода { padding: 12px 14px 10px; gap: 8px; }
  .пример-перевода__карты { --в: clamp(60px, 18vw, 74px); }
  .переключатель__вариант { min-height: 44px; }
  .числа__число { min-height: 46px; }
  .рассадка { --место: clamp(44px, 12.5vw, 50px); aspect-ratio: 2.4 / 1; }
  .сводка, .карточка-тренировки { min-height: 62px; padding-top: 10px; padding-bottom: 10px; }
  .экран.путь > .кнопка.путь__далее,
  .экран.путь > .путь__кнопки-шага > .кнопка.путь__далее,
  .экран.путь > .путь__кнопки-шага > .кнопка.кнопка--мелкая { min-height: 52px; }
}

/* =====================================================================
   РЕЙТИНГ ИГРОКОВ И «КАК Я ИГРАЮ» — В СИСТЕМЕ ЛОББИ
   (эталон/дурак-06-рейтинг)

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

   Главное число экрана — «12 место» у рейтинга и «Побед 53%» у «Как
   я играю» — лежит на сукне в деревянной раме, с кубком, как карточка
   «Ваше место» на эталоне. Если числа нет, в той же раме стоит честная
   фраза («Вас в таблице пока нет») и кубок серый — выдуманного места
   не бывает. Отдельных узлов под имя и очки в карточке у разметки пока
   нет — они видны в своей строке списка.

   Строки списка — тёмные плитки: место, аватар, имя, очки (под ними
   тихо — победы). Своя строка в салатовой рамке, у первой тройки —
   кружки цвета медалей (их даёт общее правило рейтинга выше).
   ===================================================================== */

:root {
  /* Кубок из набора (img/дурак/значки/trophy.svg), чаша залита — так он
     читается «наградой», а не пустым контуром. */
  --значок-кубок: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 2h12v7c0 8-12 8-12 0Z' fill='%23000'/%3E%3Cpath d='M6 4H2v3c0 4 3 5 5 5M18 4h4v3c0 4-3 5-5 5M12 15v5M7 22h10M9 20h6'/%3E%3C/svg%3E");
}

#экран-рейтинга-игроков,
#экран-рейтинга {
  --фон: var(--сб-фон);
  --панель: var(--сб-поверхность);
  --текст: var(--сб-текст);
  --текст-тихий: var(--сб-текст-тихий);
  --кнопка-фон: var(--сб-акцент);
  --кнопка-текст: var(--сб-акцент-текст);
  --акцент: var(--сб-акцент);
  --подложка: rgba(248, 245, 235, 0.06);
  --край: rgba(248, 245, 235, 0.14);
  --поле: clamp(12px, 3.6vw, 18px);
  --плитка: #1e2226;
  --плитка-кромка: rgba(248, 245, 235, 0.12);
  --дерево-свет: #9a6841;
  --дерево: #75492b;
  --дерево-тень: #4a2b17;

  align-items: center;
  /* Зазор между блоками тесноват нарочно: на телефоне 390×844 каждые
     две точки здесь — это часть строки списка лидеров внизу. */
  gap: 8px;
  padding: calc(6px + var(--отступ-сверху)) calc(var(--поле) + var(--отступ-справа))
           calc(12px + var(--отступ-снизу)) calc(var(--поле) + var(--отступ-слева));
  overflow-x: hidden;
  text-align: left;
  color: var(--сб-текст);
  background:
    radial-gradient(75% 120px at 50% 0, rgba(210, 247, 107, 0.07), rgba(210, 247, 107, 0) 100%),
    var(--сб-фон);
}

:is(#экран-рейтинга-игроков, #экран-рейтинга) > :not(:is(#кнопка-рейтинг-игроков-назад, #кнопка-рейтинг-назад)) {
  box-sizing: border-box;
  width: 100%;
  max-width: 520px;
}

:is(#экран-рейтинга-игроков, #экран-рейтинга) > .заголовок {
  margin: 0;
  text-align: left;
  font-size: clamp(30px, 9.6vw, 42px);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.025em;
  color: var(--сб-текст);
}

html.в-телеграме :is(#экран-рейтинга-игроков, #экран-рейтинга) > .заголовок { margin-top: 4px; }

/* «‹» у «Как я играю» не должен съезжать, когда внизу видна кнопка
   «Стереть счёт»: прежнее правило экрана обнуляло ей верхнее поле. */
#приложение #экран-рейтинга:has(#кнопка-стереть-счёт) > #кнопка-рейтинг-назад.кнопка {
  margin-top: -4px;
}

/* ---------- Главное число — на сукне в раме, с кубком ---------- */
:is(#рейтинг-моё-место, #рейтинг-главное) {
  /* Сукно — того цвета, что выбран в «Оформлении» (см. «ЦВЕТ СУКНА»). */
  --сукно-свет: #6e181c;
  --сукно: #4f0d10;
  --сукно-тень: #2a0507;
  --рама: clamp(7px, 2.3vw, 11px);
}

#экран-рейтинга-игроков > #рейтинг-моё-место,
#экран-рейтинга > #рейтинг-главное {
  position: relative;
  display: flex;
  align-items: center;
  gap: 16px;
  min-height: 96px;
  margin: 4px 0 0;
  padding: 14px 20px 14px 16px;
  font-size: clamp(26px, 8vw, 34px);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.01em;
  text-align: left;
  text-wrap: balance;
  font-variant-numeric: tabular-nums;
  color: #f8f1e4;
  text-shadow: 0 2px 6px rgba(0, 0, 0, 0.55);
  border: var(--рама) solid transparent;
  border-radius: calc(var(--рама) + 16px);
  background:
    var(--текстура-зерно) padding-box,
    radial-gradient(120% 95% at 50% 38%, var(--сукно-свет) 0%, var(--сукно) 52%, var(--сукно-тень) 100%) padding-box,
    var(--текстура-волокна) border-box,
    linear-gradient(180deg, var(--дерево-свет) 0%, var(--дерево) 40%, var(--дерево-тень) 100%) border-box;
  background-size: 160px 160px, auto, 240px 60px, auto;
  background-repeat: repeat, no-repeat, repeat, no-repeat;
  background-blend-mode: soft-light, normal, soft-light, normal;
  box-shadow:
    inset 0 0 0 1px rgba(0, 0, 0, 0.55),
    inset 0 10px 26px rgba(0, 0, 0, 0.50),
    inset 0 -8px 20px rgba(0, 0, 0, 0.35),
    0 0 0 1px rgba(0, 0, 0, 0.60),
    0 14px 30px rgba(0, 0, 0, 0.55);
}

/* Кубок — золотой, как медаль первого места в списке. */
#экран-рейтинга-игроков > #рейтинг-моё-место::before,
#экран-рейтинга > #рейтинг-главное::before {
  content: "";
  flex: 0 0 auto;
  width: clamp(44px, 13vw, 56px);
  height: clamp(44px, 13vw, 56px);
  background: linear-gradient(160deg, #ffe08a 0%, #f0bd3a 45%, #c98d12 100%);
  -webkit-mask: var(--значок-кубок) center / contain no-repeat;
  mask: var(--значок-кубок) center / contain no-repeat;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.55));
}

/* Фаска рамы — как у стола. */
#экран-рейтинга-игроков > #рейтинг-моё-место::after,
#экран-рейтинга > #рейтинг-главное::after {
  content: "";
  position: absolute;
  inset: calc(-1 * var(--рама));
  border-radius: inherit;
  pointer-events: none;
  box-shadow:
    inset 0 1.5px 0 rgba(255, 222, 184, 0.34),
    inset 0 -1.5px 0 rgba(0, 0, 0, 0.45),
    inset 1px 0 0 rgba(255, 222, 184, 0.10),
    inset -1px 0 0 rgba(0, 0, 0, 0.25);
}

/* Числа нет — в раме честная фраза обычным кеглем, кубок серый. */
#экран-рейтинга-игроков > #рейтинг-моё-место.подпись {
  font-size: clamp(15px, 4.3vw, 17px);
  font-weight: 600;
  line-height: 1.35;
}

#экран-рейтинга-игроков > #рейтинг-моё-место.подпись::before {
  width: 40px;
  height: 40px;
  background: rgba(248, 241, 228, 0.35);
}

/* ---------- Карточка «Ваше место»: кубок, место с именем, очки ----------
   (эталон/дурак-06-рейтинг.png)

   Внутри рамы три части в ряд: слева золотой кубок, посередине столбик
   «место / имя», справа столбик «число очков / очков». Раньше здесь
   правил не было вовсе, и все надписи шли одной строкой подряд —
   получалось «7 местоИван Тестов» и «5очков», а длинное имя вылезало
   за нижний край рамы и наезжало на список.

   Имя обрезаем многоточием, а не переносим: рама держит одну высоту,
   а полное имя человек и так видит в своей строке списка ниже. */
#экран-рейтинга-игроков > #рейтинг-моё-место.рейтинг__карточка {
  gap: clamp(10px, 3.2vw, 16px);
  /* Внутри карточки теперь три строки (подпись, место, имя), поэтому
     поля чуть уже: высоту держит содержимое, а не пустое место. */
  min-height: 88px;
  padding: 10px 16px 10px 14px;
}

/* Середина: тянется, но сжимается — иначе очки справа уезжают за раму. */
#рейтинг-моё-место.рейтинг__карточка > .рейтинг__карточка-текст {
  display: flex;
  flex: 1 1 auto;
  min-width: 0;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
}

/* Тихая подпись «Ваше место» — первой строкой над крупным «7 место»,
   как на макете. Она нарочно мелкая и приглушённая: её задача — назвать
   вопрос, а отвечает на него число под ней. Без неё крупное «7 место»
   читалось само по себе и сливалось с местами из списка ниже. */
#рейтинг-моё-место .рейтинг__карточка-подпись {
  max-width: 100%;
  font-size: clamp(12px, 3.5vw, 14px);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: 0.01em;
  color: rgba(248, 241, 228, 0.74);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.55);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

#рейтинг-моё-место .рейтинг__карточка-заголовок {
  max-width: 100%;
  font-size: clamp(23px, 7.2vw, 31px);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

#рейтинг-моё-место .рейтинг__карточка-имя {
  max-width: 100%;
  font-size: clamp(14px, 4.2vw, 17px);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: 0;
  color: rgba(248, 241, 228, 0.82);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Справа: число салатовое, под ним тихая подпись «очков». Число не
   сжимается — оно и есть главная новость этой карточки. */
#рейтинг-моё-место.рейтинг__карточка > .рейтинг__карточка-очки {
  display: flex;
  flex: 0 0 auto;
  flex-direction: column;
  align-items: flex-end;
  gap: 0;
  text-align: right;
}

#рейтинг-моё-место .рейтинг__карточка-очки-число {
  font-size: clamp(22px, 6.6vw, 30px);
  font-weight: 800;
  line-height: 1.08;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  color: var(--сб-акцент);
}

#рейтинг-моё-место .рейтинг__карточка-очки-подпись {
  font-size: clamp(11px, 3.2vw, 13px);
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: 0.01em;
  color: rgba(248, 241, 228, 0.72);
}

/* «Пока ни одной партии», «Минутку…» у «Как я играю» — тоже без золота. */
#экран-рейтинга:not(:has(.таблица__строка)) > #рейтинг-главное {
  font-size: clamp(20px, 6vw, 26px);
}

#экран-рейтинга:not(:has(.таблица__строка)) > #рейтинг-главное::before {
  background: rgba(248, 241, 228, 0.35);
}

/* Строка словами под главным числом — серым, слева. */
#экран-рейтинга > #рейтинг-подпись {
  max-width: 520px;
  margin: 0;
  font-size: 14px;
  line-height: 1.4;
  text-align: left;
  color: var(--сб-текст-тихий);
}

#экран-рейтинга > #рейтинг-динамика {
  justify-content: flex-start;
  max-width: 520px;
  margin: 0;
}

#экран-рейтинга .рейтинг__окно {
  padding: 5px 12px 6px;
  background: var(--плитка);
  box-shadow: inset 0 0 0 1px var(--плитка-кромка);
}

#экран-рейтинга .рейтинг__окно.рейтинг__окно--лучше {
  box-shadow: inset 0 0 0 1.5px var(--сб-акцент);
}

/* Серия дней — тихая пилюля слева. */
#экран-рейтинга-игроков > .серия-дней {
  align-self: flex-start;
  width: auto;
}

/* ---------- Выбор игры и меры — сегментами, как фильтры эталона ----------
   Этих двух панелей на макете владельца нет, но выбрать игру и меру
   где-то надо. Поэтому они нарочно сделаны низкими и негромкими: раньше
   вдвоём съедали около 120 точек, и пятёрка лидеров не помещалась на
   экран телефона. Теперь каждая — тонкая полоска примерно в 40 точек,
   а палец всё равно попадает: невидимая подушка вокруг кнопки
   (правило «::after» ниже) доводит зону нажатия до 44 точек. */
#экран-рейтинга-игроков > :is(.рейтинг-выбор, .рейтинг-меры) {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  gap: 3px;
  padding: 3px;
  background: var(--плитка);
  border: 1px solid var(--плитка-кромка);
  border-radius: 14px;
}

/* Вторая панель прижата к первой: это один смысловой блок «что смотрим». */
#экран-рейтинга-игроков > .рейтинг-меры { margin-top: -4px; }

#экран-рейтинга-игроков :is(.рейтинг-выбор, .рейтинг-меры) .кнопка.кнопка--выбор {
  position: relative;
  min-width: 0;
  min-height: 34px;
  padding: 4px 6px;
  font-size: clamp(13px, 3.7vw, 14.5px);
  font-weight: 600;
  letter-spacing: 0;
  color: var(--сб-текст);
  background: none;
  border: none;
  border-radius: 11px;
  box-shadow: none;
}

/* Подушка для пальца: кнопка нарисована низкой, а нажимается на 44 точки
   по высоте — за счёт прозрачного слоя, выступающего сверху и снизу.
   Полоски стоят в 6 точках друг от друга, поэтому подушки соседей
   не пересекаются и промахнуться мимо своей кнопки нельзя. */
#экран-рейтинга-игроков :is(.рейтинг-выбор, .рейтинг-меры) .кнопка.кнопка--выбор::after {
  content: "";
  position: absolute;
  inset: -5px 0;
}

#экран-рейтинга-игроков :is(.рейтинг-выбор, .рейтинг-меры) .кнопка.кнопка--выбор.кнопка--активная {
  font-weight: 700;
  color: var(--сб-акцент-текст);
  background: var(--сб-акцент);
  box-shadow: 0 4px 14px rgba(210, 247, 107, 0.22);
}

/* ---------- Три пары фильтров: «Все игроки / Друзья» и другие ----------
   На макете это три ряда одинаковой высоты, вплотную друг к другу.
   Работает пока только левый вариант каждой пары, правый честно помечен
   «скоро» — поэтому вся пара выключена. Выключенное должно читаться,
   иначе человек решит, что игра сломалась: держим ту же меру, что
   у «Открыть подбор игроков» в комнате — примерно 0,6 от белого. */
#экран-рейтинга-игроков > .рейтинг__фильтры {
  display: grid;
  gap: 5px;
}

#экран-рейтинга-игроков > .рейтинг__фильтры > .рейтинг__фильтр {
  margin: 0;
  gap: 3px;
  padding: 3px;
  border-radius: 14px;
}

/* Ряды фильтров ниже обычного переключателя: нажимать их всё равно
   нельзя (обе половины выключены), а на макете владельца они как раз
   такие — тонкие. Освободившиеся точки уходят списку лидеров. */
#экран-рейтинга-игроков .рейтинг__фильтр > .переключатель__вариант {
  min-height: 38px;
  padding: 3px 6px;
  font-size: clamp(13px, 3.8vw, 15px);
  border-radius: 11px;
}

/* Пометка «скоро» — общая тёмная пилюля (см. правило переключателя
   выше). Здесь только зазор поменьше: ряд низкий, и лишние точки
   сверху растягивали бы его обратно. */
#экран-рейтинга-игроков .рейтинг__фильтр > .переключатель__вариант > .пометка-скоро {
  margin-top: 1px;
}

/* ---------- Список ----------
   Список длиннее экрана и прокручивается сам по себе (игра ещё и
   подкручивает его к вашей строке). Поэтому у краёв — лёгкое затухание
   на 14 точек: строка, наполовину ушедшая под верх, читается как
   «дальше есть ещё», а не как обрезанная по ошибке. */
#экран-рейтинга-игроков > #рейтинг-таблица {
  flex: 1 1 auto;
  min-height: 0;
  gap: 5px;
  scrollbar-width: thin;
  scrollbar-color: rgba(248, 245, 235, 0.18) transparent;
  -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 14px);
  mask-image: linear-gradient(180deg, transparent 0, #000 14px);
}

#рейтинг-таблица .рейтинг-строка {
  grid-template-columns: 2.2em 32px minmax(0, 1fr) auto;
  grid-template-areas:
    "место аватар имя очки"
    "место аватар имя победы";
  align-items: center;
  column-gap: 10px;
  row-gap: 0;
  min-height: 50px;
  padding: 6px 14px 6px 8px;
  background: var(--плитка);
  border: 1px solid var(--плитка-кромка);
  border-radius: 14px;
  box-shadow: none;
}

/* Аватар — значком набора, как у соперников за столом. */
#рейтинг-таблица .рейтинг-строка::before {
  content: "";
  grid-area: аватар;
  width: 32px;
  height: 32px;
  color: #aab0b6;
  background-color: currentColor;
  -webkit-mask: var(--значок-аватар) center / contain no-repeat;
  mask: var(--значок-аватар) center / contain no-repeat;
}

#рейтинг-таблица .рейтинг-место {
  grid-area: место;
  justify-self: center;
  width: auto;
  height: auto;
  background: none;
  font-size: 16px;
  font-weight: 700;
  color: var(--сб-текст);
}

#рейтинг-таблица .рейтинг-имя {
  grid-area: имя;
  font-size: 16px;
  font-weight: 600;
}

#рейтинг-таблица .рейтинг-очки {
  grid-area: очки;
  align-self: end;
  font-size: 17px;
  font-weight: 700;
}

#рейтинг-таблица .рейтинг-победы {
  grid-area: победы;
  align-self: start;
  justify-self: end;
  font-size: 12px;
  color: var(--сб-текст-тихий);
}

/* Первая тройка — кружки цвета медалей (цвета — из общего правила). */
#рейтинг-таблица .рейтинг-строка:is([data-место="1"], [data-место="2"], [data-место="3"]) .рейтинг-место {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  font-size: 14px;
}

#рейтинг-таблица .рейтинг-строка[data-место="1"] .рейтинг-место {
  color: #3a2a05;
  background: linear-gradient(160deg, #ffdc73, #e0a516);
}

#рейтинг-таблица .рейтинг-строка[data-место="2"] .рейтинг-место {
  color: #2b2f33;
  background: linear-gradient(160deg, #eef2f6, #b7c1cb);
}

#рейтинг-таблица .рейтинг-строка[data-место="3"] .рейтинг-место {
  color: #3a2410;
  background: linear-gradient(160deg, #eab989, #c07f45);
}

/* Шапка списка — тихие подписи столбцов на фоне экрана. Тоже в две
   строчки справа: «очки» над «побед», как в строках под ней. */
#рейтинг-таблица .рейтинг-строка.рейтинг-строка--шапка {
  min-height: 0;
  padding: 4px 14px 4px 8px;
  background: var(--сб-фон);
  border: none;
  border-radius: 0;
  font-size: 10.5px;
  color: var(--сб-текст-тихий);
}

#рейтинг-таблица .рейтинг-строка--шапка::before { visibility: hidden; height: 0; }

#рейтинг-таблица .рейтинг-строка--шапка :is(.рейтинг-место, .рейтинг-имя, .рейтинг-очки, .рейтинг-победы) {
  font-size: 10.5px;
  font-weight: 700;
  color: inherit;
}

/* Своя строка — салатовая рамка, салатовые место, аватар и очки. */
#рейтинг-таблица .рейтинг-строка.рейтинг-строка--я {
  background:
    linear-gradient(rgba(210, 247, 107, 0.07), rgba(210, 247, 107, 0.07)),
    var(--плитка);
  border: 1.5px solid var(--сб-акцент);
  box-shadow: 0 0 16px rgba(210, 247, 107, 0.12);
}

/* Своя строка внизу списка — приклеена к нижнему краю. На узком телефоне
   (360 точек) она уезжала под край: было видно четверых чужих и салатовую
   дугу вместо себя. Ответ на вопрос «где я» не должен требовать прокрутки.
   Клеим только последнюю строку: если вы попали в пятёрку лидеров, ваша
   строка стоит на своём месте в списке и приклеивать нечего.

   «Последняя» — значит последняя ПЛИТКА, а не последний узел вообще:
   под списком теперь лежит ещё и строка-пояснение («Всего в таблице
   8 игроков…»). Из-за неё прежнее правило «:last-child» перестало
   срабатывать молча, и своя строка снова могла уехать под край. */
#рейтинг-таблица .рейтинг-строка.рейтинг-строка--я:not(:has(~ .рейтинг-строка)) {
  position: sticky;
  bottom: 0;
  z-index: 1;
  /* Тень вверх: сразу видно, что своя строка лежит ПОВЕРХ списка,
     а не просто налезла на чужую. */
  box-shadow:
    0 -10px 16px -6px rgba(0, 0, 0, 0.55),
    0 0 16px rgba(210, 247, 107, 0.12);
}

#рейтинг-таблица .рейтинг-строка--я::before { color: var(--сб-акцент); }

#рейтинг-таблица .рейтинг-строка--я :is(.рейтинг-место, .рейтинг-очки) {
  color: var(--сб-акцент);
}

#рейтинг-таблица .рейтинг-строка--я:not(:is([data-место="1"], [data-место="2"], [data-место="3"])) .рейтинг-место {
  background: none;
}

#рейтинг-таблица .рейтинг-строка--я .рейтинг-победы { color: var(--сб-текст-тихий); }

/* Фразы сервера в списке — серым; ярлыки разделов — мелкими прописными. */
#рейтинг-таблица > .подпись { color: var(--сб-текст-тихий); }

#рейтинг-таблица > .подпись.рейтинг-пояснение {
  color: var(--сб-текст);
  background: var(--плитка);
  border-left-color: var(--сб-акцент);
}

#рейтинг-таблица > .подпись.рейтинг-соперник { background: var(--плитка); }

/* «Как считается» — тихая ссылка под списком. */
#экран-рейтинга-игроков > #кнопка-рейтинг-как-считается.кнопка {
  align-self: center;
  width: auto;
  min-height: 44px;
  padding: 0 12px;
  font-size: 15px;
  font-weight: 500;
  color: var(--сб-текст-тихий);
  background: none;
  border: none;
  box-shadow: none;
  text-decoration: underline;
  text-decoration-color: rgba(133, 139, 148, 0.5);
  text-underline-offset: 4px;
}

#экран-рейтинга-игроков > #рейтинг-объяснение .подпись { color: var(--сб-текст-тихий); }

/* ---------- «Как я играю»: строки счёта ---------- */
#экран-рейтинга > #таблица-рейтинга {
  flex: 1 1 auto;
  min-height: 0;
  gap: 6px;
  scrollbar-width: thin;
  scrollbar-color: rgba(248, 245, 235, 0.18) transparent;
}

#таблица-рейтинга .таблица__раздел {
  margin: 10px 0 0;
  padding: 0 2px 2px;
  font-size: 11.5px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--сб-текст-тихий);
  border-bottom: none;
}

#таблица-рейтинга .таблица__строка {
  min-height: 48px;
  padding: 8px 14px;
  background: var(--плитка);
  border: 1px solid var(--плитка-кромка);
  border-radius: 14px;
}

#таблица-рейтинга .рейтинг__название {
  font-size: 15.5px;
  font-weight: 600;
  color: var(--сб-текст);
}

#таблица-рейтинга .рейтинг__доля {
  color: var(--сб-текст);
  background: rgba(248, 245, 235, 0.08);
}

#таблица-рейтинга .таблица__пусто {
  padding: 14px;
  font-size: 15px;
  line-height: 1.45;
  text-align: left;
  color: var(--сб-текст-тихий);
  background: var(--плитка);
  border: 1px solid var(--плитка-кромка);
  border-radius: 14px;
}

/* Приписка «Счёт ведётся с …» — без плитки (см. общее правило выше). */
#таблица-рейтинга .таблица__строка ~ .таблица__пусто,
#экран-рейтинга:not(:has(#рейтинг-подпись.скрыт)) #таблица-рейтинга .таблица__пусто + .таблица__пусто {
  padding: 8px 2px 0;
  font-size: 12.5px;
  background: none;
  border: none;
}

/* «Стереть счёт партий» — осторожная тихая плитка у низа. */
#экран-рейтинга > #кнопка-стереть-счёт.кнопка {
  align-self: center;
  width: min(100%, 300px);
  min-height: 44px;
  border-radius: 14px;
}

/* ---------- Невысокое окно ---------- */
@media (max-height: 700px) {
  :is(#экран-рейтинга-игроков, #экран-рейтинга) { gap: 8px; }
  :is(#экран-рейтинга-игроков, #экран-рейтинга) > .заголовок { font-size: clamp(26px, 8vw, 34px); }
  #экран-рейтинга-игроков > #рейтинг-моё-место,
  #экран-рейтинга > #рейтинг-главное {
    min-height: 76px;
    padding-top: 10px;
    padding-bottom: 10px;
    font-size: clamp(22px, 6.8vw, 28px);
  }
  #экран-рейтинга-игроков > #рейтинг-моё-место.подпись { font-size: 15px; }
  #рейтинг-таблица .рейтинг-строка { min-height: 48px; padding-top: 5px; padding-bottom: 5px; }
}

/* =====================================================================
   ЦВЕТ СУКНА — ВЫБОР В «ОФОРМЛЕНИИ» ДУРАКА

   Решение владельца (через штаб): прежний выбор «фона» не прячется,
   а становится цветом сукна на столе дурака. Вариантов те же пять,
   и ключи прежние — игра по-прежнему ставит признак «data-фон» на
   страницу. Меняется только сукно внутри деревянной рамы; страница,
   рама и всё вокруг стола остаются как есть.

   Какой ключ — какой цвет:
     «сукно» (и когда выбора нет вовсе) — бордовое, как на макете;
     «дыхание» — зелёное;
     «лампа»   — бирюзовое;
     «туман»   — синее;
     «отсвет»  — фиолетовое.
   Имена на кнопках пока старые — их поменяет разработчик.

   Каждый цвет — три тона, как у бордового: светлее посередине, основной
   и тёмный к бортам. Зерно ткани и тень от рамы внутрь рисует само
   правило стола (раздел «Стол: деревянная рама и бордовое сукно»), оно
   берёт цвет из этих трёх переменных — фактура у всех пяти одна.
   Все варианты насыщенные и тёмные: кремовая карта и белые подписи
   на них читаются так же, как на бордовом.
   ===================================================================== */

html[data-фон="дыхание"] :is(#зона-стола, .рассадка, .пример-перевода, #рейтинг-моё-место, #рейтинг-главное),
:where(#приложение:has(> #экран-витрины)) #экран-оформления .образец-фона[data-фон="дыхание"] {
  --сукно-свет: #17643b;
  --сукно: #0c4224;
  --сукно-тень: #042112;
}

html[data-фон="лампа"] :is(#зона-стола, .рассадка, .пример-перевода, #рейтинг-моё-место, #рейтинг-главное),
:where(#приложение:has(> #экран-витрины)) #экран-оформления .образец-фона[data-фон="лампа"] {
  --сукно-свет: #11686b;
  --сукно: #084547;
  --сукно-тень: #022426;
}

html[data-фон="туман"] :is(#зона-стола, .рассадка, .пример-перевода, #рейтинг-моё-место, #рейтинг-главное),
:where(#приложение:has(> #экран-витрины)) #экран-оформления .образец-фона[data-фон="туман"] {
  --сукно-свет: #1c4f8c;
  --сукно: #113463;
  --сукно-тень: #061a36;
}

html[data-фон="отсвет"] :is(#зона-стола, .рассадка, .пример-перевода, #рейтинг-моё-место, #рейтинг-главное),
:where(#приложение:has(> #экран-витрины)) #экран-оформления .образец-фона[data-фон="отсвет"] {
  --сукно-свет: #5a2d7e;
  --сукно: #3c1a5a;
  --сукно-тень: #1e0a30;
}

/* Раньше здесь была отдельная тёмная обводка для красной масти на зелёном
   и бирюзовом сукне — она подпирала контраст, пока значок красили прямо
   в цвет сукна. Теперь у значка своя кремовая плашка (см. «.метка__масть»
   выше), и контраст одинаково хорош на всех пяти сукнах без спецправил. */

/* ---------- Образец в «Оформлении»: кусочек стола ----------
   Не зелёный экран, а тот же стол в миниатюре: деревянная рамка
   с фаской, внутри сукно своего цвета с тем же зерном и той же тенью
   от рамы. Размер образца (68×96) задаёт игра. Слой живых пятен
   прежнего фона в образце больше не нужен — он прячется. */
:where(#приложение:has(> #экран-витрины)) #экран-оформления .образец-фона {
  --рама: 5px;
  /* Бордовое — по умолчанию; остальные цвета приходят правилами выше. */
  --сукно-свет: #6e181c;
  --сукно: #4f0d10;
  --сукно-тень: #2a0507;
  --дерево-свет: #9a6841;
  --дерево: #75492b;
  --дерево-тень: #4a2b17;

  position: relative;
  box-sizing: border-box;
  flex: 0 0 auto;
  overflow: visible;
  border: var(--рама) solid transparent;
  border-radius: 12px;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3'/%3E%3CfeColorMatrix values='1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E") padding-box,
    radial-gradient(120% 95% at 50% 32%, var(--сукно-свет) 0%, var(--сукно) 50%, var(--сукно-тень) 100%) padding-box,
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='60'%3E%3Cfilter id='d'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.012 0.5' numOctaves='2'/%3E%3CfeColorMatrix values='1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1'/%3E%3C/filter%3E%3Crect width='240' height='60' filter='url(%23d)' opacity='0.7'/%3E%3C/svg%3E") border-box,
    linear-gradient(180deg, var(--дерево-свет) 0%, var(--дерево) 40%, var(--дерево-тень) 100%) border-box;
  background-size: 160px 160px, auto, 240px 60px, auto;
  background-repeat: repeat, no-repeat, repeat, no-repeat;
  background-blend-mode: soft-light, normal, soft-light, normal;
  box-shadow:
    inset 0 0 0 1px rgba(0, 0, 0, 0.55),      /* шов между рамой и сукном */
    inset 0 6px 14px rgba(0, 0, 0, 0.50),     /* тень от верхнего борта */
    inset 0 -5px 12px rgba(0, 0, 0, 0.35),    /* и от нижнего */
    0 0 0 1px rgba(0, 0, 0, 0.60),            /* тёмный край рамы */
    0 4px 10px rgba(0, 0, 0, 0.45);           /* образец лежит на плитке */
}

/* Фаска рамки — как у стола: светлая кромка сверху, тёмная снизу. */
:where(#приложение:has(> #экран-витрины)) #экран-оформления .образец-фона::before {
  content: "";
  position: absolute;
  inset: calc(-1 * var(--рама));
  border-radius: inherit;
  pointer-events: none;
  box-shadow:
    inset 0 1px 0 rgba(255, 222, 184, 0.34),
    inset 0 -1px 0 rgba(0, 0, 0, 0.45);
}

:where(#приложение:has(> #экран-витрины)) #экран-оформления .образец-фона > .фон-игры {
  display: none;
}

/* =====================================================================
   ШИРОКОЕ ОКНО: планшет и монитор — игра на весь экран

   КАК БЫЛО. 10 сентября владелец прислал снимок с компьютера: «у меня
   посередине полоса идёт, а слева справа огромное пространство». Тогда
   колонку шириной с телефон оформили отдельным «экраном» (480 точек,
   скругление, тень), а 11 сентября, после слов «на планшете и на большом
   экране масштаб неверный», стали увеличивать этот «экран» целиком
   (transform: scale) по высоте окна. Владелец после выкладки: «по
   планшету так же и осталось, очень маленькое поле и игра не на весь
   экран». Он прав: увеличенный телефон — всё тот же телефон. Лёжа
   (1180×820) увеличения не было вовсе, и сукно было узкой полосой
   посередине с пустыми краями.

   КАК СТАЛО. Ни увеличения, ни рамки: приложение занимает всё окно,
   как на телефоне, а экраны раскладываются на настоящую ширину.
     • Стол — те же ряды в том же порядке (шапка, соперник или места
       компании, сукно с колодой, «Вы», подсказка, рука, кнопки), но во
       всю ширину окна с обычными полями. Сукно забирает всю свободную
       высоту. Карта в руке, карты на сукне и колода считаются от места,
       которое им досталось, — на планшете они заметно крупнее
       телефонных, а лёжа их держит высота окна.
     • Витрина, лобби и шаги — ШИРОКОЙ колонкой (760 точек), а не во всю
       ширину. Причина — чтение: в карточках входа и вариантах правил
       строка слева, а стрелка или галочка справа; растянутые на 1180–1920
       точек, они разъезжаются так, что глаз теряет, что к чему. У витрины
       картинки плиток держат свои пропорции, и в две колонки шириной
       по 370 они уже крупные. На планшете стоя 760 — это почти вся
       ширина, лёжа и на мониторе — ясная колонка, а не телефонная полоса.
   Кнопки, текст, панели — прежнего размера: на планшете точка экрана
   физически крупнее, чем на телефоне, и те же размеры читаются свободно.
   Крупнеет то, во что играют, — карты.

   ПОЛЁТ КАРТ И БРОСОК. js/game.js («увеличениеЭкрана») и
   js/движение-карт.js («увеличениеВокруг») меряют увеличение сами:
   ширина узла на экране делённая на его ширину в разметке. Увеличения
   больше нет — они получают ровно 1, как на телефоне. Переменная
   «--масштаб» ушла вместе со ступенями: из скриптов её никто не читал.

   ТОЛЬКО СТРАНИЦА СБОРНИКА (index.html) — отсюда «:has(#экран-витрины)»
   в каждом правиле. Шашки, шахматы и нарды открываются своими страницами
   и тоже подключают этот файл; на широком окне у них всё как было.

   ПОРОГ 700×600 — прежний. Уже 700 это телефон или узкое окно — там
   телефонная раскладка и так занимает всё. Ниже 600 по высоте — это
   лежащий на боку телефон, у него своя телефонная раскладка. */
@media (min-width: 700px) and (min-height: 600px) {
  :root:has(#экран-витрины) {
    /* Поле по краям экрана: 21 точка на 700, 35 на 1180, не больше 48. */
    --поле-широкое: clamp(20px, 3vw, 48px);
    /* Широкая колонка витрины, лобби и шагов (почему колонка — см. выше). */
    --колонка-широкая: 760px;
    /* Карта в руке. На телефоне — 30,5 сотых ширины окна, не больше
       17 сотых его высоты и не больше 136 точек. На планшете стоя
       держит ширина: 24 сотых (а не 30,5 — иначе на 768–820 шесть карт
       веера легли бы с сильным нахлёстом): 820×1180 — 197 точек против
       119 на телефоне, 768×1024 — 184. Лёжа держит высота: 20 сотых
       (на телефоне 17 — там над рукой высокий столбик рядов, а лёжа
       шапка в одну строку, см. ниже): 1180×820 — 164, монитор
       1920×1080 — 216. Потолок 220 — на высоком мониторе карта
       не плакат. */
    --в-рука: clamp(56px, min(24vw, calc(var(--доступно) * 0.2)), 220px);
  }

  /* ---------- Стол: те же ряды, на всю ширину ----------
     Ряды (шапка, соперник, «Вы», подсказка, рука, кнопки) — во всю
     ширину экрана, поля по краям шире телефонных. Сукно выступает за
     ряды на 8 точек с каждой стороны, как на телефоне, и забирает всю
     свободную высоту — прежний потолок (480 точек) снят. */
  :root:has(#экран-витрины) #экран-игры:has(> #зона-стола) {
    --поле: var(--поле-широкое);
    --зазор-рядов: 12px;
  }

  :root:has(#экран-витрины) #экран-игры > :is(.верх-игры, .шапка-игры, #соперники, #рука-бота, #строка-меня, #подсказка, #рука-человека) {
    max-width: none;
  }

  /* Три кнопки действий — группой под рукой, не шире 720 точек. Во всю
     ширину 1180–1920 «Взять» и «Бито» вытягивались в полосы по 500–600
     точек, и ряд переставал читаться как три кнопки. */
  :root:has(#экран-витрины) #экран-игры > #панель-кнопок {
    max-width: 720px;
  }

  :root:has(#экран-витрины) #экран-игры > #зона-стола {
    width: calc(100% + 16px);
    max-height: none;
    /* Колода растёт вместе с картой в руке: три четверти её роста
       (на телефоне потолок 100 точек — это 84 сотых руки). */
    --колода-потолок: calc(var(--в-рука) * 0.75);
  }

  /* ---------- Витрина, лобби, шаги — широкой колонкой ----------
     Прежняя колонка 520 точек — телефонная. Здесь 760: на планшете стоя
     это почти вся ширина, лёжа и на мониторе — ясная колонка посередине.
     Почему не во всю ширину — см. начало раздела. Панель вкладок внизу
     по-прежнему во всю ширину, а вкладки на ней — по ширине колонки. */
  :root:has(#экран-витрины) #экран-витрины.витрина > :not(.нижние-вкладки):not(.лист-ещё),
  :root:has(#экран-витрины) :is(#экран-лобби > :not(.нижние-вкладки), .экран.путь > *),
  :root:has(#экран-витрины) .экран.путь > .кнопка.путь__далее {
    max-width: var(--колонка-широкая);
  }

  :root:has(#экран-витрины) :is(#экран-лобби, .экран.путь) > .верх-игры {
    max-width: calc(var(--колонка-широкая) + 20px);
  }

  /* Схема рассадки на шаге «Игроки» держит пропорцию овала (2,15 к 1):
     во всю колонку 760 она вырастала до 353 точек, и лёжа кнопка
     «Далее» уезжала под нижний край. Схеме хватает 560 — места на ней
     крупнее телефонных, а шаг помещается на экран целиком. */
  :root:has(#экран-витрины) #приложение .экран.путь > .рассадка {
    max-width: 560px;
  }

  :root:has(#экран-витрины) .нижние-вкладки {
    padding-left: max(8px, (100% - var(--колонка-широкая)) / 2);
    padding-right: max(8px, (100% - var(--колонка-широкая)) / 2);
  }
}

/* ---------- Лёжа: лобби в две колонки ----------
   Лёжа в одну колонку картинка лобби (16 на 10) занимала весь экран,
   а входы — «Играть онлайн», «С ботами», «Пригласить друзей» — уезжали
   под нижний край: чтобы начать игру, надо было прокручивать. Здесь
   порядок тот же, но слева — профиль и картинка, справа — входы, сразу
   видно всё. Название «Дурак» — над обеими колонками.
   Ширина пары колонок — до 1200 точек, посередине; поля — как у стола. */
@media (min-width: 700px) and (min-height: 600px) and (min-aspect-ratio: 5 / 4) {
  :root:has(#экран-витрины) #экран-лобби.экран--виден {
    display: grid;
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
    grid-template-areas:
      "верх      верх"
      "возврат   возврат"
      "заголовок заголовок"
      "профиль   входы"
      "картинка  входы";
    grid-template-rows: auto auto auto auto 1fr;
    align-content: start;
    column-gap: 28px;
    row-gap: 12px;
    padding-left: calc(max(var(--поле-широкое), (100% - 1200px) / 2) + var(--отступ-слева));
    padding-right: calc(max(var(--поле-широкое), (100% - 1200px) / 2) + var(--отступ-справа));
  }

  :root:has(#экран-витрины) #экран-лобби > :not(.нижние-вкладки) {
    max-width: none;
  }

  :root:has(#экран-витрины) #экран-лобби > .верх-игры {
    grid-area: верх;
    width: auto;
    max-width: none;
  }

  :root:has(#экран-витрины) #экран-лобби > .плашка-возврата { grid-area: возврат; }
  :root:has(#экран-витрины) #экран-лобби > .лобби__заголовок { grid-area: заголовок; }
  :root:has(#экран-витрины) #экран-лобби > .карточка-профиля { grid-area: профиль; }
  :root:has(#экран-витрины) #экран-лобби > .лобби__картинка { grid-area: картинка; align-self: start; }
  :root:has(#экран-витрины) #экран-лобби > .лобби__входы { grid-area: входы; align-self: start; }
}

/* ---------- Лёжа: шапка стола в одну строку ----------
   Лёжа каждая точка высоты на счету: сукно и рука живут под столбиком
   рядов. Шапка «Дурак / Подкидной · 36 карт» в две строки забирала
   у сукна 60 точек. Здесь она та же, что в низком окне телефона
   (см. «Шапка в низком окне — одна строка»): «Дурак · Подкидной ·
   36 карт» по центру строки «‹ ⋯», чуть крупнее — 17 и 15 точек.
   Порог — окно шире своей высоты и не выше 900: на мониторе 1920×1080
   места хватает и двум строкам. */
@media (min-width: 700px) and (min-height: 600px) and (max-height: 900px) and (min-aspect-ratio: 5 / 4) {
  :root:has(#экран-витрины) #экран-игры > .шапка-игры {
    flex-direction: row;
    align-items: baseline;
    justify-content: center;
    gap: 0.35em;
    box-sizing: border-box;
    height: 28px;
    padding: 0 56px;
    overflow: hidden;
    white-space: nowrap;
    pointer-events: none;
  }

  :root:has(#экран-витрины) #экран-игры .шапка-игры__заголовок {
    flex: 0 0 auto;
    font-size: 17px;
    font-weight: 700;
    line-height: 28px;
    letter-spacing: 0;
  }

  :root:has(#экран-витрины) #экран-игры .шапка-игры__подзаголовок {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    font-size: 15px;
    line-height: 28px;
  }

  :root:has(#экран-витрины) #экран-игры .шапка-игры__подзаголовок:not(:empty)::before {
    content: "· ";
  }

  /* Строка «‹ ⋯» видна (браузер, старый Telegram): шапка встаёт в неё.
     «‹ ⋯» занимает в столбике 32 точки, шапка — 28, и поднимается она
     на свою высоту и просвет — середины строк совпадают. */
  html:not(.в-телеграме):has(#экран-витрины) #экран-игры > .верх-игры + .шапка-игры,
  html.в-телеграме.без-настроек:has(#экран-витрины) #экран-игры > .верх-игры + .шапка-игры {
    margin-top: calc(-28px - var(--зазор-рядов));
  }
}

/* =====================================================================
   КОМНАТА ДУРАКА — ЭКРАН 05 (эталон/дурак-05-комната.png)

   Здесь компания собирается перед партией: хозяин видит стол, сажает
   ботов на свободные места, зовёт друзей и нажимает «Начать».

   Вид — тот же, что у лобби и трёх шагов до партии: тёмная страница,
   плитки на тон светлее, крупный заголовок слева, один салатовый акцент.
   Стол — тот же овал из дерева и сукна, что на шаге «Игроки» (класс
   «рассадка»): рама, фаска, тень и цвет сукна из «Оформления» берутся
   оттуда. Здесь только размер стола и то, где стоят места.

   Все правила держатся за «.комната» (и её имя «#комната» там, где
   нужно перебить старые правила экрана кода). Прежняя прихожая списком
   («#комната-старая») — запасной вид; её правила выше по файлу, а здесь
   ей только возвращена раскладка столбиком (см. последний подраздел).
   Экран красится тёмным, только пока «.комната» видна: «:has» — тот же
   приём, каким выше включаются правила прихожей.
   ===================================================================== */

:root {
  /* ---------- Значки комнаты ----------
     Копии «img/дурак/значки/*.svg» из набора владельца — «Пригласить»
     (ссылка), свободное место (плюс), подбор (галочка), режим «С друзьями»
     (группа), бот за столом (робот). Вписаны сюда по той же причине, что
     и значки стола (см. «Значки из набора владельца»): маску браузер
     берёт только у настоящей картинки, а вписанный значок от сервера
     не зависит. Стрелка «›» — уже вписанная «--значок-вперёд». */
  --значок-ссылка: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m10 7 3-3c6-6 13 1 7 7l-3 3M14 17l-3 3C5 26-2 19 4 13l3-3M8 16l8-8'/%3E%3C/svg%3E");
  --значок-плюс: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 4v16M4 12h16'/%3E%3C/svg%3E");
  --значок-галочка: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m5 12 5 5L20 6'/%3E%3C/svg%3E");
  --значок-группа: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='6' r='3'/%3E%3Ccircle cx='4' cy='8' r='2'/%3E%3Ccircle cx='20' cy='8' r='2'/%3E%3Cpath d='M6 21v-5c0-6 12-6 12 0v5ZM1 20v-5c0-2 1-3 3-3M23 20v-5c0-2-1-3-3-3'/%3E%3C/svg%3E");
  /* Робот и корона — не маской, а картинкой своего цвета: они лежат
     на маленьком тёмном кружке-значке у места, а у одного узла маска
     красила бы и кружок, и рисунок в одну краску. Корона хозяина
     в наборе не нашлась и нарисована здесь тем же пером (сетка 24,
     линия 1,7, круглые концы). */
  --значок-робот-светлый: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23e4e6eb' stroke-width='1.9' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='6' width='18' height='15' rx='4'/%3E%3Cpath d='M12 6V3M1 11v6M23 11v6M9 16h6'/%3E%3Ccircle cx='8' cy='11' r='1' fill='%23e4e6eb'/%3E%3Ccircle cx='16' cy='11' r='1' fill='%23e4e6eb'/%3E%3Ccircle cx='12' cy='2' r='1'/%3E%3C/svg%3E");
  --значок-корона-салатовая: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23d2f76b' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M4.5 16 3 7l5.5 4L12 4l3.5 7L21 7l-1.5 9Z' fill='%23d2f76b'/%3E%3Cpath d='M4.5 19.5h15'/%3E%3C/svg%3E");
}

/* ---------- Экран, пока видна комната ----------
   Поля и фон — как у лобби и шагов: тёмный фон сборника и едва заметное
   салатовое свечение сверху. Экран прокручивается сам (это поведение
   включает js/game.js), полоса прокрутки не видна, вбок — никогда. */
#экран-комнаты:has(> #комната:not(.скрыт)) {
  align-items: center;
  gap: 0;
  padding: calc(6px + var(--отступ-сверху)) calc(clamp(12px, 3.6vw, 18px) + var(--отступ-справа))
           calc(12px + var(--отступ-снизу)) calc(clamp(12px, 3.6vw, 18px) + var(--отступ-слева));
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: none;
  color: var(--сб-текст);
  text-align: left;
  background:
    radial-gradient(75% 120px at 50% 0, rgba(210, 247, 107, 0.07), rgba(210, 247, 107, 0) 100%) local,
    var(--сб-фон);
}

#экран-комнаты:has(> #комната:not(.скрыт))::-webkit-scrollbar { display: none; }

/* Столбик — не шире витрины (520) и посередине, как у лобби и шагов.
   Растёт на всю высоту экрана: тогда «Начать» стоит внизу, под пальцем,
   даже когда за столом двое и всё остальное короткое.
   Цвета внутри — те же имена, что у шагов: прежние правила экрана кода,
   которые берут «--текст», «--подложка», «--акцент», сами переходят
   на тёмный вид с салатовым акцентом. */
#экран-комнаты > #комната.комната {
  --поле: clamp(12px, 3.6vw, 18px);
  --фон: var(--сб-фон);
  --панель: var(--сб-поверхность);
  --текст: var(--сб-текст);
  --текст-тихий: var(--сб-текст-тихий);
  --кнопка-фон: var(--сб-акцент);
  --кнопка-текст: var(--сб-акцент-текст);
  --акцент: var(--сб-акцент);
  --подложка: rgba(248, 245, 235, 0.06);
  --край: rgba(248, 245, 235, 0.14);
  --плитка: #1e2226;
  --плитка-кромка: rgba(248, 245, 235, 0.12);
  --плитка-нажата: #262a2f;
  /* Дерево — как у стола партии и схемы рассадки. */
  --дерево-свет: #9a6841;
  --дерево: #75492b;
  --дерево-тень: #4a2b17;
  /* Цвет чужого места — холодный светло-серый с лёгкой сиренью, как
     кольцо «Максима» на макете. Салатовый — только свои: «Вы» и напарник. */
  --комната-чужой: #c3c5d1;

  flex: 1 0 auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
  box-sizing: border-box;
  width: 100%;
  max-width: 520px;
  margin: 0 auto;
  color: var(--сб-текст);
  text-align: left;
}

#комната > * {
  flex-shrink: 0;
  box-sizing: border-box;
  min-width: 0;
  margin: 0;
}

#комната button:focus-visible {
  outline: 2px solid var(--сб-акцент);
  outline-offset: 2px;
}

/* ---------- Шапка: «Комната игры», режим, правила, «Игроки 3/4» ----------
   Как на макете: заголовок слева, крупный и жирный (он чуть крупнее
   заголовков шагов — так на эталоне), всё остальное — по центру. */
#комната > .комната__шапка {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  /* В браузере над шагами стоит строка «‹ ⋯», а над комнатой её нет —
     без этого поля заголовок прилипал к верхнему краю окна. */
  margin-top: 12px;
  text-align: center;
}

/* В Telegram сверху его собственная шапка — там хватает четырёх точек,
   как у шагов. */
html.в-телеграме #комната > .комната__шапка { margin-top: 4px; }

.комната__заголовок {
  align-self: stretch;
  margin: 0 0 4px;
  font-size: clamp(30px, 10vw, 44px);
  font-weight: 800;
  line-height: 1.08;
  letter-spacing: -0.025em;
  text-align: left;
  color: var(--сб-текст);
}

/* Пилюля режима — та же «путь__режим», что на шагах, но здесь она
   главная строка шапки, как на макете: салатовый контур и надпись,
   впереди значок группы («С друзьями»). */
.комната__шапка > .путь__режим {
  gap: 8px;
  min-height: 32px;
  padding: 4px 15px 5px 12px;
  font-size: 15px;
  font-weight: 700;
  color: var(--сб-акцент);
  background: rgba(210, 247, 107, 0.07);
  border: 1.5px solid var(--сб-акцент);
  box-shadow: 0 0 14px rgba(210, 247, 107, 0.14);
}

.комната__шапка > .путь__режим--друзья::before {
  content: "";
  flex: 0 0 auto;
  width: 19px;
  height: 19px;
  background-color: currentColor;
  -webkit-mask: var(--значок-группа) center / contain no-repeat;
  mask: var(--значок-группа) center / contain no-repeat;
}

.комната__правила {
  margin: 0;
  font-size: 15px;
  line-height: 1.3;
  color: var(--сб-текст-тихий);
}

.комната__правила:empty { display: none; }

.комната__игроки {
  margin: 4px 0 0;
  font-size: 17px;
  font-weight: 700;
  line-height: 1.25;
  color: var(--сб-текст);
}

/* ---------- Стол ----------
   Тот же овал, что на шаге «Игроки», только во всю ширину столбика
   и чуть выше (1,8 к 1 против 2,15): за ним сидят живые люди, у каждого
   имя под местом, и имена должны помещаться на сукне.

   Рама толще, чем у схемы на шаге, — как на макете: там борт стола
   примерно вдвое толще кромки плиток и читается как настоящее дерево.

   Поля сверху и снизу — под места: верхнее выступает над бортом
   на полместа, у нижнего под ним ещё и имя. */
#комната > .рассадка.рассадка--комната {
  --место: clamp(48px, 14.5vw, 58px);
  --рама: clamp(12px, 3.8vw, 17px);
  /* Где стоят места. Сверху и снизу — на борту (середина рамы), по бокам —
     на сукне, отступив от борта: иначе имя «Свободно» под боковым местом
     вылезало бы за край экрана. Так и на макете — «Максим» и «Свободно»
     сидят на сукне, «Вы» и «Анна» — на борту. */
  --радиус-x: calc(50% - var(--место) * 0.42);
  --радиус-y: calc(50% + var(--рама) / 2);
  width: 100%;
  max-width: none;
  aspect-ratio: 1.8 / 1;
  margin: calc(var(--место) / 2 + 2px) 0 calc(var(--место) / 2 + 26px);
}

/* Места — по кругу от «Вы» наверху, дальше по часовой. Позицию берём
   из порядка мест на столе, а не из «--номер-места»: код кладёт первым
   «Вы», за ним соседей по часовой (js/дурак-комната.js, «порядокМест»),
   а «--номер-места» у него — номер кресла на сервере, от 1. Хозяин
   обычно сидит в кресле 1, и по этому числу «Вы» уезжало бы вправо.
   Порядок узлов верен всегда, как бы ни пересаживались. */
#комната > .рассадка--комната > .рассадка__место:nth-child(1) { --позиция: 0; }
#комната > .рассадка--комната > .рассадка__место:nth-child(2) { --позиция: 1; }
#комната > .рассадка--комната > .рассадка__место:nth-child(3) { --позиция: 2; }
#комната > .рассадка--комната > .рассадка__место:nth-child(4) { --позиция: 3; }
#комната > .рассадка--комната > .рассадка__место:nth-child(5) { --позиция: 4; }
#комната > .рассадка--комната > .рассадка__место:nth-child(6) { --позиция: 5; }

/* Место — кнопка размером 48–58 точек (палец попадает с запасом, имя
   под местом тоже нажимается — оно внутри кнопки). Тёмный диск со светом
   сверху, кольцо и человечек — значок аватара цветом роли. Значок чуть
   больше диска, чтобы его кольцо легло ровно по краю, как на макете. */
#комната > .рассадка--комната > .рассадка__место {
  --угол: calc(-90deg + var(--позиция, 0) * 360deg / var(--мест, 4));
  left: calc(50% + var(--радиус-x) * cos(var(--угол)));
  top: calc(50% + var(--радиус-y) * sin(var(--угол)));
  -webkit-appearance: none;
  appearance: none;
  padding: 0;
  border: 0;
  font: inherit;
  color: var(--комната-чужой);
  background: radial-gradient(circle at 50% 30%, #2a3036 0%, #181b1f 62%, #111417 100%);
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.45),
    0 6px 14px rgba(0, 0, 0, 0.55);
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.15s ease;
}

#комната > .рассадка--комната > .рассадка__место:disabled { cursor: default; }

#комната > .рассадка--комната > .рассадка__место > .аватар {
  --аватар: 120%;
  position: absolute;
  left: 50%;
  top: 50%;
  translate: -50% -50%;
  color: inherit;
  transition: opacity 0.2s ease;
}

/* «Вы» и напарник — свои: салатовое кольцо со свечением. Напарник чуть
   тише — на макете «Вы» и «Анна» почти одинаковы, но «Вы» ищут первым. */
#комната > .рассадка--комната > .рассадка__место--я,
#комната > .рассадка--комната > .рассадка__место--напарник {
  color: var(--сб-акцент);
}

#комната > .рассадка--комната > .рассадка__место--я {
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.45),
    0 6px 14px rgba(0, 0, 0, 0.55),
    0 0 20px rgba(210, 247, 107, 0.50);
}

#комната > .рассадка--комната > .рассадка__место--напарник {
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.45),
    0 6px 14px rgba(0, 0, 0, 0.55),
    0 0 16px rgba(210, 247, 107, 0.34);
}

/* Свободное место — дырка за столом, а не игрок: полупрозрачный диск,
   пунктирное кольцо и плюс посередине. */
#комната > .рассадка--комната > .рассадка__место--свободно {
  color: rgba(248, 245, 235, 0.88);
  background: rgba(12, 14, 16, 0.5);
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
}

#комната > .рассадка--комната > .рассадка__место--свободно::before {
  content: "";
  position: absolute;
  inset: 0;
  border: 2px dashed rgba(248, 245, 235, 0.72);
  border-radius: 50%;
  pointer-events: none;
}

#комната > .рассадка--комната > .рассадка__место--свободно > .аватар {
  --аватар: 44%;
  -webkit-mask-image: var(--значок-плюс);
  mask-image: var(--значок-плюс);
}

/* Имя под местом. Свои — салатовым, чужие — белым, пустое — тише.
   Длинное имя обрезается многоточием по ширине, в которой боковое место
   ещё не упирается в край экрана. */
#комната > .рассадка--комната .рассадка__имя {
  top: calc(100% + 6px);
  max-width: calc(var(--место) * 1.7);
  overflow: hidden;
  text-overflow: ellipsis;
  font-size: 15px;
  font-weight: 700;
  line-height: 1.2;
  color: var(--сб-текст);
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.85);
}

#комната > .рассадка--комната > .рассадка__место--я .рассадка__имя,
#комната > .рассадка--комната > .рассадка__место--напарник .рассадка__имя {
  color: var(--сб-акцент);
}

#комната > .рассадка--комната > .рассадка__место--свободно .рассадка__имя {
  font-weight: 600;
  color: rgba(248, 245, 235, 0.78);
}

/* Бот — тёмный кружок с роботом у правого нижнего края места: с одного
   взгляда видно, кто за столом живой, а кто нет. */
#комната > .рассадка--комната > .рассадка__место--бот::after {
  content: "";
  position: absolute;
  right: -4px;
  bottom: -4px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--значок-робот-светлый) center / 14px 14px no-repeat, #2a2f35;
  box-shadow: 0 0 0 2px #111417, 0 2px 4px rgba(0, 0, 0, 0.5);
  pointer-events: none;
}

/* Хозяин стола — салатовая корона у правого верхнего края. У себя
   не рисуем: хозяин и так знает, что стол его, а гостю важно видеть,
   кто нажмёт «Начать». */
#комната > .рассадка--комната > .рассадка__место--хозяин:not(.рассадка__место--я)::after {
  content: "";
  position: absolute;
  right: -4px;
  top: -4px;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--значок-корона-салатовая) center / 14px 14px no-repeat, #2a2f35;
  box-shadow: 0 0 0 2px #111417, 0 2px 4px rgba(0, 0, 0, 0.5);
  pointer-events: none;
}

/* Нет связи — человек за столом, но не отвечает: место и имя гаснут.
   Место при этом не пунктирное — оно не свободно. */
#комната > .рассадка--комната > .рассадка__место--нет-связи > .аватар { opacity: 0.38; }

#комната > .рассадка--комната > .рассадка__место--нет-связи .рассадка__имя {
  color: var(--сб-текст-тихий);
}

/* Палец на месте — оно сразу вжимается (класс «--нажимается» код ставит
   на касание, не дожидаясь сервера), свободное ещё и загорается салатовым:
   видно, что нажатие дошло. */
#комната > .рассадка--комната > .рассадка__место--нажимается,
#комната > .рассадка--комната > .рассадка__место:not(:disabled):active {
  transform: scale(0.92);
}

#комната > .рассадка--комната > .рассадка__место--свободно.рассадка__место--нажимается::before,
#комната > .рассадка--комната > .рассадка__место--свободно:not(:disabled):active::before {
  border-color: var(--сб-акцент);
}

@media (hover: hover) {
  #комната > .рассадка--комната > .рассадка__место:not(:disabled):hover > .аватар {
    filter: brightness(1.18);
  }
}

/* Ответ сервера в пути — вокруг нажатого места бежит салатовая дуга,
   у свободного места крутится само пунктирное кольцо. Остальные места
   в это время не нажимаются (их выключает код) и просто стоят. */
#комната > .рассадка--комната > .рассадка__место--ждёт-ответа { cursor: progress; }

#комната > .рассадка--комната > .рассадка__место--ждёт-ответа:not(.рассадка__место--свободно)::before {
  content: "";
  position: absolute;
  inset: -6px;
  border: 2.5px solid transparent;
  border-top-color: var(--сб-акцент);
  border-right-color: var(--сб-акцент);
  border-radius: 50%;
  pointer-events: none;
  animation: комната-ждём-ответа 0.9s linear infinite;
}

#комната > .рассадка--комната > .рассадка__место--свободно.рассадка__место--ждёт-ответа::before {
  border-color: var(--сб-акцент);
  animation: комната-ждём-ответа 2.4s linear infinite;
}

@keyframes комната-ждём-ответа {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  #комната > .рассадка--комната > .рассадка__место--ждёт-ответа::before { animation: none; }
}

/* ---------- Команды при 2 на 2 ----------
   Две плитки рядом: точка команды, название, кто в ней. Своя точка
   салатовая со свечением — того же цвета, что кольца своих мест за
   столом; чужая — серая, как кольца соперников. */
#комната > .комната__команды {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}

.комната__команда {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  grid-template-areas:
    "точка подпись"
    ".     состав";
  align-items: center;
  column-gap: 10px;
  row-gap: 3px;
  min-height: 58px;
  padding: 10px 12px 11px;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0) 70%),
    var(--сб-поверхность);
  border: 1px solid var(--плитка-кромка);
  border-radius: 14px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.04),
    0 6px 16px rgba(0, 0, 0, 0.22);
}

.комната__команда::before {
  content: "";
  grid-area: точка;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--комната-чужой);
}

.комната__команда--наша::before {
  background: var(--сб-акцент);
  box-shadow: 0 0 8px rgba(210, 247, 107, 0.55);
}

.комната__команда-подпись {
  grid-area: подпись;
  min-width: 0;
  font-size: 15px;
  font-weight: 700;
  line-height: 1.2;
  color: var(--сб-текст);
}

.комната__команда-состав {
  grid-area: состав;
  min-width: 0;
  font-size: 13px;
  line-height: 1.3;
  color: var(--сб-текст-тихий);
  overflow-wrap: anywhere;
}

/* ---------- Весть и сообщения ----------
   «Анна вошла», «ждём четвёртого», отказы сервера, ответ на «Позвать»
   и «Скопировать» — плитка во всю ширину с салатовой чертой слева:
   видно, что это слово игры, а не подпись. */
#комната > .сеть-сообщение {
  width: 100%;
  padding: 10px 14px;
  font-size: 14px;
  line-height: 1.35;
  text-align: left;
  color: var(--сб-текст);
  background: var(--плитка);
  border: 1px solid var(--плитка-кромка);
  border-left: 3px solid var(--сб-акцент);
  border-radius: 6px 14px 14px 6px;
}

/* ---------- «Пригласить друга» ----------
   Обведённая плитка во всю ширину, как на макете: значок ссылки слева,
   надпись посередине, «›» справа. Не залита — залита на экране одна
   кнопка, «Начать». */
#комната > .комната__пригласить {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-width: 0;
  min-height: 54px;
  padding: 0 54px;
  font-size: clamp(17px, 4.9vw, 20px);
  font-weight: 700;
  letter-spacing: 0;
  color: var(--сб-текст);
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.045), rgba(255, 255, 255, 0) 65%),
    var(--сб-поверхность);
  border: 1.5px solid rgba(248, 245, 235, 0.55);
  border-radius: 18px;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.28);
}

#комната > .комната__пригласить::before,
#комната > .комната__пригласить::after {
  content: "";
  position: absolute;
  top: 50%;
  background-color: currentColor;
}

#комната > .комната__пригласить::before {
  left: 18px;
  width: 24px;
  height: 24px;
  margin-top: -12px;
  -webkit-mask: var(--значок-ссылка) center / contain no-repeat;
  mask: var(--значок-ссылка) center / contain no-repeat;
}

#комната > .комната__пригласить::after {
  right: 16px;
  width: 22px;
  height: 22px;
  margin-top: -11px;
  opacity: 0.8;
  -webkit-mask: var(--значок-вперёд) center / contain no-repeat;
  mask: var(--значок-вперёд) center / contain no-repeat;
}

#комната > .комната__пригласить:not(:disabled):active {
  transform: translateY(1px);
  background: var(--плитка-нажата);
  box-shadow: none;
}

/* Мест не осталось — звать некого: кнопка гаснет целиком. */
#комната > .комната__пригласить:disabled {
  opacity: 0.4;
  cursor: default;
}

/* ---------- Код комнаты — мелкой строкой ----------
   Вход по коду жив, поэтому код виден, но уже не главный предмет
   экрана: «Код», кремовая бумажка с четырьмя знаками моноширинным
   шрифтом (та же бумага, что у карт и прежней большой плашки)
   и тихая «Скопировать код». */
#комната > .комната__код {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 10px;
  min-height: 44px;
}

/* Слово «Код» — только у видимой комнаты: снимок доступности Playwright
   показывает нарисованный CSS текст и у спрятанных узлов, а лишнее
   «Код» на витрине сбивало бы проверки (тот же приём, что у «›» листа). */
#комната:not(.скрыт) > .комната__код::before {
  content: "Код";
  font-size: 14px;
  font-weight: 600;
  color: var(--сб-текст-тихий);
}

#комната > .комната__код > .код-игры {
  max-width: none;
  padding: 3px 9px 4px;
  font-size: 20px;
  line-height: 1.25;
  letter-spacing: 0.16em;
  text-indent: 0.16em;
  color: var(--карта-текст);
  background: var(--карта-фон);
  border: none;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.45);
}

#комната > .комната__код > .код-игры--ждём {
  color: rgba(248, 245, 235, 0.45);
  background: rgba(248, 245, 235, 0.08);
  box-shadow: none;
}

#комната > .комната__код > #кнопка-копировать-код {
  width: auto;
  min-width: 0;
  min-height: 44px;
  padding: 0 14px;
  font-size: 15px;
  font-weight: 600;
  letter-spacing: 0;
  color: var(--сб-текст);
  background: none;
  border: 1px solid var(--сб-граница);
  border-radius: 12px;
  box-shadow: none;
}

#комната > .комната__код > #кнопка-копировать-код:active {
  transform: translateY(1px);
  background: var(--плитка-нажата);
}

/* ---------- «Открыть подбор игроков» — пока «скоро» ----------
   Кружок-отметка, надпись и справа «скоро» — та же пометка, что
   у «Играть онлайн» в лобби. Подбора ещё нет, поэтому кружок пустой
   и приглушён; когда подбор включат, включённое состояние уже готово —
   салатовое кольцо с галочкой и свечением, как на макете. */
#комната > .комната__подбор {
  position: relative;
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-height: 44px;
  padding: 0 2px;
  font: inherit;
  font-size: 16px;
  font-weight: 500;
  line-height: 1.25;
  text-align: left;
  color: var(--сб-текст);
  background: none;
  border: none;
  cursor: pointer;
}

#комната > .комната__подбор::before {
  content: "";
  flex: 0 0 auto;
  box-sizing: border-box;
  width: 28px;
  height: 28px;
  border: 2px solid rgba(248, 245, 235, 0.42);
  border-radius: 50%;
}

#комната > .комната__подбор > :first-child {
  flex: 1 1 auto;
  min-width: 0;
}

#комната > .комната__подбор[aria-checked="true"]::before {
  border-color: var(--сб-акцент);
  box-shadow: 0 0 12px rgba(210, 247, 107, 0.5);
}

#комната > .комната__подбор[aria-checked="true"]::after {
  content: "";
  position: absolute;
  left: 7px;
  top: 50%;
  width: 18px;
  height: 18px;
  margin-top: -9px;
  background-color: var(--сб-акцент);
  -webkit-mask: var(--значок-галочка) center / contain no-repeat;
  mask: var(--значок-галочка) center / contain no-repeat;
}

#комната > .комната__подбор:disabled { cursor: default; }

/* Приглушаем ровно настолько, чтобы читалось: 0,6 от белого на тёмном
   даёт контраст около 5 при норме 4,5 для подписи в 16 точек. Сама
   пометка «скоро» не гаснет — это она и объясняет, почему выключено. */
#комната > .комната__подбор:disabled::before,
#комната > .комната__подбор:disabled > :not(.комната__скоро) { opacity: 0.6; }

#комната .комната__скоро {
  flex: 0 0 auto;
  margin-left: auto;
  padding: 3px 10px 4px;
  font-size: 12.5px;
  font-weight: 700;
  line-height: 1.2;
  color: var(--сб-текст);
  background: rgba(0, 0, 0, 0.45);
  border: 1px solid rgba(248, 245, 235, 0.16);
  border-radius: 999px;
}

/* ---------- «Начать» ----------
   Та же главная кнопка, что «Далее» на шагах: салатовая во всю ширину,
   58 точек, скругление 20. Прилипает к низу экрана: на тесном телефоне
   стол с командами длиннее окна, и искать главную кнопку прокруткой
   нельзя. Тени цвета фона над ней и под ней — чтобы прокручиваемое
   не просвечивало вокруг прилипшей кнопки.

   Погашенная («Ожидаем игрока…», «Ждём, когда хозяин начнёт») — серая
   плитка с серой надписью, как на макете: видно, что кнопка есть,
   но сейчас она молчит. Цвета непрозрачные — под прилипшей кнопкой
   проезжает стол. */
#комната > .комната__начать {
  position: sticky;
  bottom: calc(12px + var(--отступ-снизу));
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-width: 0;
  min-height: 58px;
  margin-top: auto;
  padding: 0 20px;
  font-size: clamp(18px, 5.4vw, 22px);
  font-weight: 800;
  letter-spacing: 0;
  color: var(--сб-акцент-текст);
  background: var(--сб-акцент);
  border: none;
  border-radius: 20px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.35),
    0 8px 22px rgba(210, 247, 107, 0.16),
    0 -16px 16px -4px var(--сб-фон),
    0 calc(26px + var(--отступ-снизу)) 0 0 var(--сб-фон);
}

#комната > .комната__начать:not(:disabled):active {
  transform: translateY(1px);
  filter: brightness(0.95);
}

#комната > .комната__начать:disabled {
  color: #8d939a;
  background: linear-gradient(180deg, #3b4046 0%, #32363b 100%);
  border: none;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.07),
    0 -16px 16px -4px var(--сб-фон),
    0 calc(26px + var(--отступ-снизу)) 0 0 var(--сб-фон);
  cursor: default;
}

/* Подсказка под кнопкой и «Выйти из комнаты» отодвинуты от неё чуть
   дальше, чем глубина её нижнего укрытия (26 точек плюс безопасное поле
   снизу; со своим просветом столбика выходит 28). Ближе нельзя с обеих
   сторон: у кнопки на своём месте укрытие наезжало бы на их верх,
   а у прилипшей — из-под неё выглядывала бы полоска того, что проезжает
   снизу (было видно на снимках 390×844 и 320×568). */
#комната > .комната__подсказка,
#комната > #кнопка-комната-отмена {
  margin-top: calc(18px + var(--отступ-снизу));
}

#комната > .комната__подсказка:not(.скрыт) + #кнопка-комната-отмена {
  margin-top: -4px;
}

#комната > .комната__подсказка {
  font-size: 14px;
  line-height: 1.35;
  text-align: center;
  text-wrap: balance;
  color: var(--сб-текст-тихий);
}

/* «Выйти из комнаты» — тихая ссылка, как «Подробнее о правилах» на шагах:
   уход не должен спорить с «Начать». В Telegram то же делает его «‹». */
#комната > #кнопка-комната-отмена {
  align-self: center;
  width: auto;
  min-width: 0;
  min-height: 44px;
  padding: 0 14px;
  font-size: 15px;
  font-weight: 500;
  letter-spacing: 0;
  color: var(--сб-текст-тихий);
  background: none;
  border: none;
  box-shadow: none;
  text-decoration: underline;
  text-decoration-color: rgba(133, 139, 148, 0.5);
  text-underline-offset: 4px;
}

#комната > #кнопка-комната-отмена:active {
  transform: none;
  color: var(--сб-текст);
}

/* ---------- Невысокое окно ----------
   Всё то же, только плотнее: заголовок ниже, стол площе и места меньше
   (но не меньше 44 точек), кнопки — не ниже 48. Остальное прокручивается,
   «Начать» при этом стоит у нижнего края. */
@media (max-height: 700px) {
  #экран-комнаты > #комната.комната { gap: 8px; }
  .комната__заголовок { margin-bottom: 2px; font-size: clamp(26px, 8.4vw, 34px); }
  #комната > .комната__шапка { gap: 4px; }
  .комната__игроки { margin-top: 2px; }
  /* Стол чуть площе телефонного, но не слишком: за столом на шесть мест
     боковые места стоят друг над другом, и на плоском овале подпись
     верхнего наезжала на кружок нижнего (замер на 320×568: не хватало
     двух точек). Имена здесь же мельче на точку. */
  #комната > .рассадка.рассадка--комната {
    --место: clamp(44px, 12.5vw, 50px);
    aspect-ratio: 1.95 / 1;
  }

  #комната > .рассадка--комната .рассадка__имя { font-size: 14px; }
  .комната__команда { min-height: 50px; padding-top: 8px; padding-bottom: 9px; }
  #комната > .комната__пригласить { min-height: 48px; }
  #комната > .комната__начать { min-height: 52px; }
}

/* ---------- Широкое окно: планшет и монитор ----------
   Столбик — широкой колонкой, как у лобби и шагов (760). Стол — не шире
   560, как схема рассадки на шаге «Игроки»: во всю колонку овал вырастал
   бы выше половины экрана. Места на нём крупнее телефонных. */
@media (min-width: 700px) and (min-height: 600px) {
  :root:has(#экран-витрины) #экран-комнаты > #комната.комната {
    max-width: var(--колонка-широкая);
  }

  :root:has(#экран-витрины) #комната > .рассадка.рассадка--комната {
    --место: 64px;
    --рама: 18px;
    align-self: center;
    max-width: 560px;
  }
}

/* ---------- Прежняя прихожая — запасной вид ----------
   Её узлы теперь лежат в обёртке «#комната-старая», а не прямо в экране,
   и правила экрана кода «столбик по центру» до них не доставали: блоки
   прижимались к левому краю. Обёртка сама становится тем же столбиком
   с теми же просветами, что у экрана, и стоит посередине по высоте. */
#комната-старая {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: inherit;
  width: 100%;
  margin-top: auto;
  margin-bottom: auto;
}

#комната-старая > .подпись {
  max-width: 330px;
  line-height: 1.35;
}

