/* =====================================================================
   НАРДЫ — ВЕСЬ ВНЕШНИЙ ВИД (по набору владельца, 12 сентября).

   Образец — «эталон/нарды-набор/references/gameplay-original.png».
   Доска на нём не нарисована красками, а сфотографирована: это одна
   картинка «img/нарды/board-empty.png» со своей рамой, петлями и
   деревом. Поэтому здесь больше нет ни CSS-треугольников, ни сетки
   из четвертей — они были нужны прежней, рисованной доске.

   ЧТО ТЕПЕРЬ ГЛАВНОЕ. Всё на доске стоит В ПРОЦЕНТАХ ОТ САМОЙ ДОСКИ,
   а доска держит пропорцию картинки (913 к 793). Значит, на любом
   экране — 360, 390, 430 — стол выглядит как та же фотография, просто
   меньше или больше: фишки не сползают с пунктов, потому что и пункт,
   и фишка меряются одной и той же линейкой — шириной доски.

   ОТКУДА ЧИСЛА. Из набора владельца, файл
   «эталон/нарды-набор/integration/board-geometry.json»:

       доска      913 × 793 точки картинки
       пункт      шаг 65 точек по ширине  → 65 / 913 = 7,1194 %
       фишка      60 точек                → 60 / 65  = 92,31 % ширины пункта
       стопка     шаг 55 точек            → 55 / 65  = 84,62 % ширины пункта
       кубики     центры 591 и 698 по ширине, 400 по высоте
       бар        центр 456 по ширине, 396 по высоте

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

   ЦВЕТА. Свои переменные у нард кончились: страница берёт общие цвета
   сборника («--сб-…» из style.css) — тёмный фон и один салатовый
   акцент. Прежний зелёно-синий вид ушёл вместе с рисованной доской.

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

/* =====================================================================
   ЦВЕТА СТРАНИЦЫ

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

   Переменные подменяются на самом верхнем узле страницы, поэтому все
   готовые правила из style.css (кнопки, подписи, плашки) сами
   переезжают на тёмный вид — переписывать их не нужно. За пределы
   нард это не уходит: файл подключён только к «нарды.html».
   ===================================================================== */

#приложение {
  --фон: var(--сб-фон);
  --панель: var(--сб-поверхность);
  --текст: var(--сб-текст);
  --текст-тихий: var(--сб-текст-тихий);
  --кнопка-фон: var(--сб-акцент);
  --кнопка-текст: var(--сб-акцент-текст);
  --акцент: var(--сб-акцент);
  --подложка: rgba(248, 245, 235, 0.06);
  --край: rgba(248, 245, 235, 0.16);
  --нельзя: #ff3b30;   /* красный для кнопки сдачи и вспышек ошибок */

  color: var(--сб-текст);
  /* Тот же фон, что у витрины и стола дурака: ровный тёмный и едва
     заметное салатовое свечение у верхнего края. */
  background:
    radial-gradient(75% 120px at 50% 0, rgba(210, 247, 107, 0.07), rgba(210, 247, 107, 0) 100%),
    var(--сб-фон);
}

/* БЫЛО: «#приложение .кнопка:not(.кнопка--мелкая):not(.кнопка--выбор)» —
   плоский салатовый без притемнения (color-mix из общего style.css) сразу
   у ВСЕХ обычных кнопок сборника. Из-за веса «#приложение» это красило
   не только партию, но и лобби: «Создать игру» на экране «Играть онлайн»
   выходила ровной заливкой, не как у дурака (замечание штаба 24.09: у
   дурака та же кнопка с лёгким переливом).

   ЧТО СДЕЛАНО. Селектор сужен до самой партии (#экран-игры) — там и
   правда две кнопки хотят плоский цвет без притемнения: «Бросить кубики»
   и «Подтвердить» (см. #кнопка-бросить и #кнопка-закончить-ход ниже,
   раздел «КНОПКИ ХОДА»). Все кнопки вне партии — лобби, «Играть онлайн»,
   экран выбора бота, итог — снова берут обычный вид из style.css,
   как у дурака и шашек. */
#экран-игры .кнопка:not(.кнопка--мелкая):not(.кнопка--выбор) {
  background: var(--сб-акцент);
  color: var(--сб-акцент-текст);
}

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

   Сверху вниз, как на макете: строка «‹ · ⋯», крупное название с
   режимом партии, соперник, доска, свой игрок, плашка хода,
   подсказка, кнопки, счёт. Кубики стоят НА доске (см. раздел
   «КУБИКИ»), как в наборе владельца, — своей строки они не занимают.

   Лишнюю высоту, которая остаётся под доской на высоком телефоне,
   раскладка раздаёт по просветам — см. «КУДА ДЕВАТЬ ЛИШНЮЮ ВЫСОТУ».

   ГЛАВНЫЙ РАЗМЕР — «--д-ширина», ширина доски. От неё считается всё
   остальное на доске: и высота (пропорция картинки), и фишки, и
   кубики. Ширина берётся наименьшей из трёх:

     1) ширина колонки — экран без полей и безопасных краёв;
     2) «--д-потолок» — чтобы на компьютере доска не расползалась.
        На телефоне и на узком окне это 520 (тот же потолок, что
        у стола дурака). На широком окне, от 700 точек, — 880: на
        планшете (жалоба владельца 16.09 — «стол очень маленький»)
        колонка легко даёт 700–900 точек ширины, а потолок 520
        обрезал доску до пятой части экрана, хотя места хватало.
        Меняет значение медиа-запрос «ШИРОКОЕ ОКНО» ниже.
     3) сколько остаётся по ВЫСОТЕ, если вычесть всё, что стоит выше
        и ниже доски («--прочее»). Без третьего пункта на невысоком
        окне (шторка Telegram, 390×568) нижние кнопки уезжали
        за нижний край — это уже случалось в шахматах. Он же не даёт
        доске раздуться на широком, но НИЗКОМ окне (1280×800): там
        потолок 880 не помеха, доску всё равно остановит высота.

   У ЭТОЙ ШИРИНЫ ЕСТЬ ПОЛ (решение штаба, 16.09 — жалоба «в нардах нет
   совсем кубиков» с планшета в Telegram). Мини-приложение на планшете
   иногда открывается НИЗКИМ окном: третье слагаемое из списка выше
   тогда уходит в ноль или в минус, «min()» выбирает его, и доска
   схлопывается — а вместе с ней и кубики, они меряются той же
   «--д-ширина». Поэтому высотное слагаемое остаётся только потолком
   СВЕРХУ у пола не меньше 320 точек (или колонки стола, если она уже
   320, — на совсем узком окне доска не должна стать шире экрана).
   Пол посчитан снаружи всего «min()» через «max()»: доска либо
   помещается по высоте без сжатия, либо стоит на полу и уезжает
   за нижний край — там её достаёт прокрутка экрана (см. «overflow-y»
   у «#экран-игры» ниже), а не сплющивание в невидимую полоску. */

#экран-игры {
  /* Поля и промежутки — как у витрины и стола дурака: на 390 это 14 и 8. */
  --поле: clamp(12px, 3.6vw, 18px);
  --зазор-рядов: clamp(6px, 2vw, 10px);

  /* Потолок доски. 520 по умолчанию (телефон и узкое окно), медиа-запрос
     «ШИРОКОЕ ОКНО» ниже поднимает его до 880 от 700 точек ширины. */
  --д-потолок: 520px;

  /* Сколько высоты занято всем, кроме доски: поля экрана, название,
     две панели игроков, полки выноса, плашка хода, подсказка, ряд
     кнопок, счёт и нижняя панель вместе с промежутками между ними.
     Число посчитано по этому же файлу; если ряд отсюда убрать или
     добавить — поправить и здесь, иначе доска станет мельче или,
     наоборот, вылезет за экран. */
  --прочее: calc(415px + var(--отступ-сверху) + var(--отступ-снизу));

  --колонка-стола: calc(100vw - 2 * var(--поле) - var(--отступ-слева) - var(--отступ-справа));
  /* Пол доски — 320 точек (или уже колонка, если она сама уже 320).
     «max()» снаружи не даёт высотному слагаемому утащить доску ниже
     пола ни при каком низком окне. */
  --д-ширина: max(
    min(
      var(--колонка-стола),
      var(--д-потолок),
      calc((var(--доступно) - var(--прочее)) * 913 / 793)
    ),
    min(320px, var(--колонка-стола))
  );
  --д-высота: calc(var(--д-ширина) * 793 / 913);

  /* Полки вынесенных под доской: высота задана числом нарочно —
     от неё считается, насколько поднять кубики на доску. */
  --полка-высота: 26px;
  --полка-отступ: 6px;

  justify-content: flex-start;
  gap: var(--зазор-рядов);
  /* Горизонтальное поле — 8px, как у общего «.экран» в style.css:
     поле как у всех игр, не своё «--поле». */
  padding: calc(6px + var(--отступ-сверху)) calc(8px + var(--отступ-справа))
           calc(8px + var(--отступ-снизу))  calc(8px + var(--отступ-слева));

  /* ЗАЧЕМ. У доски теперь есть пол (320 точек, см. «--д-ширина» выше),
     а «--прочее» знает высоту рядов не идеально точно — на низком окне
     стол вместе с рядами может стать выше, чем само окно. Экран стола
     («.экран») стоит «position: absolute; inset: 0» без своей прокрутки,
     и без этого правила нижние кнопки просто обрезались бы невидимо —
     достать их было бы нечем. Тот же приём уже решён у шашек
     (см. «#экран-шашек» в style-шашки.css: «доска не мельчает, лишнее
     уходит под прокрутку»). На обычном телефоне, где всё помещается,
     прокрутки не будет вовсе — полоса появляется, только когда
     содержимое и правда выше окна. */
  overflow-y: auto;
  /* Без этой строки браузер сам включает прокрутку и по горизонтали,
     как только «overflow-y» стал «auto» (правило CSS: если одна ось
     не «visible», то и другая перестаёт быть «visible»). Любой лишний
     пиксель по ширине — например, строка «‹ ⋯» у «#экран-игры > .верх-игры»,
     она нарочно на 16px шире экрана, чтобы стрелка встала у самого
     края, — тогда превращается в настоящую горизонтальную полосу.
     Тот же урок уже записан ниже, у «#экран-как-играть». */
  overflow-x: hidden;
}

/* Верхняя строка «‹ · ⋯» и заголовок «Нарды» со строкой режима своих
   правил здесь не имеют вовсе: и то и другое нарисовано в общем
   style.css («.верх-игры», «.шапка-игры»), теми же правилами, что над
   столом дурака. Это и есть единый стандарт сборника: человек,
   пришедший из дурака, находит те же кнопки на тех же местах.

   Прежняя строка «.заголовок--доска» (одна серая строчка над доской)
   отсюда убрана: такого узла в разметке больше нет. */

/* =====================================================================
   ПАНЕЛИ ИГРОКОВ

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

   Своя панель отличается салатовым: обод аватара и точка «в сети».
   Это тот же приём, что на макете, где своё место подсвечено, а
   чужое — серое.
   ===================================================================== */

.игрок-нард {
  flex: 0 0 auto;
  align-self: center;
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  /* Той же ширины, что доска (решение штаба, 16.09): на телефоне это
     520 не отличить, а на планшете панель растёт вместе с доской,
     а не остаётся узкой колонкой рядом с широким столом. */
  max-width: var(--д-ширина);
  min-height: 52px;
  padding: 5px 14px 5px 5px;
  border-radius: 999px;
  background: rgba(248, 245, 235, 0.04);
  border: 1px solid rgba(248, 245, 235, 0.08);
}

.игрок-нард--свой {
  background: rgba(210, 247, 107, 0.05);
  border-color: rgba(210, 247, 107, 0.22);
}

/* Аватар — картинка человечка на прозрачном фоне, круг под ним рисуем
   здесь: в наборе владельца круга в картинке нет. */
.игрок-нард__аватар {
  flex: 0 0 auto;
  width: 42px;
  height: 42px;
  padding: 8px;
  border-radius: 50%;
  object-fit: contain;
  background: rgba(248, 245, 235, 0.07);
  border: 1.5px solid rgba(248, 245, 235, 0.14);
}

.игрок-нард--свой .игрок-нард__аватар {
  background: rgba(210, 247, 107, 0.10);
  border-color: var(--сб-акцент);
}

.игрок-нард__сведения {
  display: flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.игрок-нард__имя {
  font-size: 16px;
  font-weight: 700;
  line-height: 1.2;
  color: var(--сб-текст);
}

.игрок-нард__статус {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  line-height: 1.2;
  color: var(--сб-текст-тихий);
}

/* Точка «в сети». У соперника серая, у себя салатовая — как на макете. */
.игрок-нард__статус::before {
  content: '';
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--сб-текст-тихий);
}

.игрок-нард--свой .игрок-нард__статус::before {
  background: var(--сб-акцент);
  box-shadow: 0 0 6px rgba(210, 247, 107, 0.55);
}

/* =====================================================================
   ДОСКА

   Одна картинка на всю доску, поверх неё — слои: метки допустимых
   пунктов, фишки, кольцо выбора, кубики. Порядок слоёв взят из
   инструкции набора («docs/IMPLEMENTATION.md»).
   ===================================================================== */

.обёртка-доски {
  position: relative;
  flex: 0 0 auto;
  width: var(--д-ширина);
  margin: 0 auto;
}

.доска-нард {
  position: relative;
  width: 100%;
  /* Пропорция картинки доски. Растягивать её по осям нельзя — дерево
     и петли сразу выдают подделку. */
  aspect-ratio: 913 / 793;
  border-radius: 12px;
  /* Доска лежит на странице, а не наклеена на неё. */
  box-shadow: 0 10px 26px rgba(0, 0, 0, 0.5);
  touch-action: manipulation;
}

.доска__фон {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  pointer-events: none;   /* картинка декоративная, нажатия ловят пункты */
  user-select: none;
}

/* ---------------------------------------------------------------------
   ПУНКТ — СТОЛБИК, А НЕ ТРЕУГОЛЬНИК.

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

   РАЗМЕР. Ширина — ровно один шаг пункта (65 из 913, то есть
   7,1194 % доски). Высота — половина игрового поля (350 из 793),
   задана через «aspect-ratio»: так она считается от ширины и потому
   растёт вместе с доской. На экране 390 это около 26 × 139 точек.
   Шире столбик не сделать — двенадцать пунктов стоят в ряд и
   упираются друг в друга; зато он высокий, и попасть в него пальцем
   легко.

   ГДЕ ОН СТОИТ. Владелец даёт одну точку — центр ПЕРВОЙ фишки
   (у нижних пунктов это низ стопки, у верхних — верх). Столбик
   сдвигается от неё отрицательным полем так, чтобы его край пришёлся
   ровно на край этой фишки: у нижних вверх на 320 точек доски
   (35,05 %), у верхних вниз на 30 (3,285 %). Дальше фишки внутри
   считаются от края столбика, и первая всегда встаёт центром на
   точку владельца.

   Ни одного «transform» на пункте нет НАРОЧНО: он завёл бы свой слой,
   и летящая фишка ныряла бы под чужие стопки. Поэтому и середина
   ищется отрицательным полем — «margin-left».
   --------------------------------------------------------------------- */

.пункт,
.бар__половина {
  position: absolute;
  left: var(--лево);
  top: var(--верх);
  width: 7.1194%;              /* шаг пункта: 65 из 913 */
  margin-left: -3.5597%;       /* половина шага — встать по центру */
  cursor: pointer;

  /* Шаг стопки. Обычно 55 точек из 65 ширины пункта, но если фишек
     много — ужимается ровно настолько, чтобы стопка не вылезла из
     столбика. Ради этого код и сообщает «--шашек»: на голове длинных
     нард их пятнадцать. 446 % — это 290 точек запаса (столбик 350
     минус сама фишка 60), посчитанные в ширинах пункта. */
  --шаг: min(84.615%, calc(446% / max(var(--шашек, 1) - 1, 1)));
}

.пункт {
  aspect-ratio: 65 / 350;
  border-radius: 4px;
}

.пункт--снизу  { margin-top: -35.05%; }   /* 320 из 913 ширины доски */
.пункт--сверху { margin-top: -3.285%; }   /*  30 из 913 */

/* Пункт, с которого фишку подняли: тихая салатовая подсветка столбика.
   Громко звать в него не надо — фишка и так уже в руке. */
.пункт--выбран {
  background: rgba(210, 247, 107, 0.10);
  box-shadow: inset 0 0 0 1px rgba(210, 247, 107, 0.35);
}

/* Так ходить нельзя — красная вспышка на столбике. Класс держится
   меньше трети секунды, его ставит и снимает код. */
.пункт--отказ {
  background: rgba(224, 39, 60, 0.28);
  box-shadow: inset 0 0 0 1.5px rgba(224, 39, 60, 0.75);
}

/* ---------- Метка «сюда можно пойти» ----------

   Отдельный слой, как велит инструкция набора: не срез фишки и не
   краска поверх пункта.

   Стоит она там, куда фишка ВСТАНЕТ, то есть поверх стопки. Номер
   этого места — сколько фишек уже лежит; у пустого пункта код
   присылает «--шашек: 1», поэтому пустой разбираем отдельно
   («:not(:has(…))» — «внутри которого нет фишек»). Браузер старше
   2023 года «:has» не знает: там метка на пустом пункте встанет
   на один шаг выше — заметно, но не мешает. */
/* САМ РИСУНОК — СТРОКОЙ, А НЕ ОТДЕЛЬНЫМ ФАЙЛОМ (почему — см. ниже).

   Было кольцо — та же толщина и тот же приём, что у кольца выбора
   выше, и смотритель их путал («выбранную шашку и доступные ходы
   одним взглядом не различить — оба одинаковое салатовое кольцо той
   же толщины»). Теперь цель хода — ДРУГОЙ знак: сплошная полупрозрачная
   точка в центре пункта, без единой обводки (как точки ходов в
   шахматных приложениях) — у выбранной шашки кольцо ПУСТОЕ внутри,
   у цели хода — заливка без кольца, спутать не с чем. Цвет — тот же
   салатовый акцент (#d7ff56), новых цветов нет.

   Почему не файлом. Круг прозрачный снаружи, и когда файл .svg не
   приезжает, вокруг нет ничего, кроме битой картинки. Так и вышло
   на стенде: его сервер отдаёт .svg неверным типом. Вписанный рисунок
   не зависит ни от сервера, ни от сети — а в сборнике так сделаны все
   значки оформления (см. «--значок-…» в style.css).

   Узел и его «src» при этом остаются как были: «content» подменяет
   только то, что нарисовано, — разметку и код править не пришлось. */
.пункт__цель {
  position: absolute;
  left: 3.846%;
  width: 92.308%;
  aspect-ratio: 1;
  /* Было 2 — ниже, чем шашка-цель (z-index 4): при взятии одиночной
     фишки соперника метка пряталась под ней целиком. Теперь метка
     выше любой обычной фишки и видна поверх неё (обычная фишка стоит
     на 4, поднятая — на 5, см. «.пункт > .шашка.шашка--поднята» выше;
     совпадать по месту с поднятой меткa не может — это разные пункты). */
  z-index: 5;
  opacity: 0;
  pointer-events: none;
  --слой-цели: var(--шашек, 0);
  transition: opacity 0.14s ease-out;
  content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Ccircle cx='32' cy='32' r='13' fill='%23d7ff56' fill-opacity='.55'/%3E%3C/svg%3E");
}

.пункт:not(:has(> .шашка)) > .пункт__цель,
.бар__половина:not(:has(> .шашка)) > .пункт__цель { --слой-цели: 0; }

.пункт--снизу  > .пункт__цель { bottom: 0; margin-bottom: calc(var(--слой-цели) * var(--шаг)); }
.пункт--сверху > .пункт__цель { top: 0;    margin-top:    calc(var(--слой-цели) * var(--шаг)); }

/* Видна метка только там, куда сейчас разрешено пойти. Свечение
   вокруг — чтобы кольцо не терялось на светлом пункте: на кремовом
   треугольнике одно салатовое кольцо читалось слабо. */
.пункт--можно > .пункт__цель,
.полка.пункт--можно > .пункт__цель {
  opacity: 1;
  filter: drop-shadow(0 0 5px rgba(210, 247, 107, 0.75));
  animation: цель-дышит 1.6s ease-in-out infinite;
}

@keyframes цель-дышит {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.08); }
}

/* =====================================================================
   ФИШКИ

   Узел фишки создаётся один раз на партию и живёт до её конца: он
   переезжает, а не рождается заново. Внутри два слоя картинок набора:
   сама фишка и кольцо выбора.

   Размеры — доли ширины пункта: фишка 60 из 65 (92,308 %), поля
   по бокам по 2,5 точки (3,846 %). Круглой её делает сама картинка
   набора, но скругление задано и здесь — по нему рисуются ободки.
   ===================================================================== */

.шашка {
  position: relative;
  border-radius: 50%;
  transition: box-shadow 0.14s ease-out, transform 0.14s ease-out;
}

.пункт > .шашка,
.бар__половина > .шашка {
  position: absolute;
  left: 3.846%;
  width: 92.308%;
  aspect-ratio: 1;
  z-index: 4;
}

/* Поднятая (выбранная) фишка — z-index ВЫШЕ обычной. Правило ниже
   нарочно повторяет те же два селектора с добавленным классом: у
   «.пункт > .шашка» уже две вложенные группы (2 класса в селекторе),
   и одиночный класс «.шашка--поднята» проигрывал бы ему по CSS-
   специфичности — так и было: поднятая фишка молча оставалась
   на z-index 4, кольцо выбора пряталось под соседями по стопке. */
.пункт > .шашка.шашка--поднята,
.бар__половина > .шашка.шашка--поднята {
  z-index: 5;
}

.шашка__рисунок {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  /* Фишка лежит на доске: собственной тени у картинки нет,
     её добавляем здесь — так велит инструкция набора. */
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.55));
  pointer-events: none;
  user-select: none;
}

/* Стопка. Первая фишка прижата к краю столбика — то есть встаёт
   центром ровно на точку владельца, — каждая следующая на шаг
   дальше от края доски. */
.пункт--снизу  > .шашка { bottom: 0; margin-bottom: calc(var(--слой, 0) * var(--шаг)); }
.пункт--сверху > .шашка { top: 0;    margin-top:    calc(var(--слой, 0) * var(--шаг)); }

/* Этой фишкой сейчас можно пойти — тонкий салатовый ободок.

   Он нарочно тише кольца выбора: таких фишек на доске бывает пять
   сразу, и если каждую обвести ярко, поднятую фишку среди них будет
   не найти. Тёмная линия снаружи нужна не для красоты — на кремовом
   дереве светлого пункта салатовый ободок без неё сливается с фоном. */
.шашка--можно-взять {
  box-shadow:
    0 0 0 1.5px rgba(215, 255, 86, 0.7),
    0 0 0 2.5px rgba(0, 0, 0, 0.5);
}

/* ---------- Поднятая фишка ----------
   Кольцо выбора — рисунок набора (selection-ring.svg), доработанный:
   смотритель по снимку заметил, что выбранная фишка ничем не
   отличалась от соседок по стопке — старое кольцо было тонким и на
   светлой фишке почти не читалось, к тому же путалось с кольцами
   целей. Теперь у кольца три слоя, крупнее и с тёмным контуром:

     1) тёмный контур снаружи (радиус 36, обводка 7, чёрный полупрозрачный)
        — держит границу кольца на ЛЮБОЙ фишке, светлой или тёмной;
     2) салатовое свечение (радиус 34, обводка 11, прозрачность .35);
     3) чёткое салатовое кольцо (радиус 33, обводка 5).

   Оно на треть больше фишки и потому выходит за её край — отсюда
   отрицательные отступы. Цвет — тот же салатовый акцент (#d7ff56),
   что и у кольца целей ниже, новых цветов нет.

   Почему не файлом — объяснено выше, у метки допустимого пункта. */
.шашка__кольцо {
  position: absolute;
  left: -16.667%;
  top: -16.667%;
  width: 133.334%;
  height: 133.334%;
  opacity: 0;
  pointer-events: none;
  filter: drop-shadow(0 0 6px rgba(210, 247, 107, 0.6));
  transition: opacity 0.12s ease-out;
  content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 80 80'%3E%3Ccircle cx='40' cy='40' r='36' fill='none' stroke='%230b130b' stroke-opacity='.6' stroke-width='7'/%3E%3Ccircle cx='40' cy='40' r='34' fill='none' stroke='%23d7ff56' stroke-opacity='.35' stroke-width='11'/%3E%3Ccircle cx='40' cy='40' r='33' fill='none' stroke='%23d7ff56' stroke-width='5'/%3E%3C/svg%3E");
}

.шашка--поднята > .шашка__кольцо { opacity: 1; }

/* Поднятая фишка ещё и чуть подрастает — видно, что она «в руке»,
   даже если кольцо попало на пёстрый кусок дерева. Сам z-index задаёт
   более специфичное правило у «.пункт > .шашка.шашка--поднята» выше
   (см. пояснение там) — здесь он ничего не решил бы. */
.шашка--поднята {
  transform: scale(1.06);
}

/* Пока фишка едет, она идёт поверх остальных: иначе на полпути
   ныряет под чужую стопку и выглядит, будто исчезла. */
.шашка--едет { z-index: 6; }

/* =====================================================================
   БАР — середина доски, куда уезжают побитые (короткие нарды).

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

.бар { position: static; }

/* Половины бара — столбики покороче пункта (200 точек доски из 793),
   поставленные впритык к средней линии: чёрные над ней, белые под
   ней. Точка у обеих одна и та же, поэтому чёрную половину поднимаем
   на всю её высоту (200 из 913 ширины доски — 21,9 %). */
.бар__половина {
  aspect-ratio: 65 / 200;
  border-radius: 4px;
}

.бар--чёрные { margin-top: -21.9%; }

/* На баре фишек редко бывает больше двух-трёх, и полоса узкая,
   поэтому шаг здесь теснее пунктового: фишки лежат внахлёст стопкой,
   как жетоны. */
.бар--чёрные > .шашка,
.бар--чёрные > .пункт__цель { bottom: 0; margin-bottom: calc(var(--слой, 0) * 40%); }

.бар--белые > .шашка,
.бар--белые > .пункт__цель  { top: 0;    margin-top:    calc(var(--слой, 0) * 40%); }

/* Побитые фишки стоят на самой середине доски, где под ними петля и
   тёмное дерево. Тонкая тёмная подложка отделяет их от рамы — иначе
   чёрная фишка на тёмной планке пропадает. */
.бар__половина:has(> .шашка) {
  background: rgba(0, 0, 0, 0.28);
  box-shadow: inset 0 0 0 1px rgba(248, 245, 235, 0.10);
}

/* =====================================================================
   ПОЛКИ ВЫНЕСЕННЫХ

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

   Высота задана числом («--полка-высота»): от неё считается, на
   сколько поднять кубики на доску, и гулять она не должна.
   ===================================================================== */

.полки {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-top: var(--полка-отступ);
  height: var(--полка-высота);
}

.полка {
  position: relative;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 8px;
  border-radius: 8px;
  background: rgba(0, 0, 0, 0.30);
  border: 1px solid rgba(248, 245, 235, 0.10);
  box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.45);
  overflow: hidden;
  cursor: pointer;
}

.полка__подпись {
  flex: 0 0 auto;
  font-size: 9.5px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--сб-текст-тихий);
  white-space: nowrap;
}

/* Пустая полка объясняет себя сама: пунктирная рамка — общепонятный
   знак «сюда положат», и тихая приписка словами. Появится первая
   фишка — исчезнут обе: объяснять уже нечего. */
.полка:not(:has(> .шашка)) {
  border-style: dashed;
  border-color: rgba(248, 245, 235, 0.18);
}

.полка:not(:has(> .шашка))::after {
  content: "сюда лягут вынесенные";
  font-size: 9.5px;
  color: var(--сб-текст-тихий);
  opacity: 0.75;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

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

   Нахлёст не постоянный: при паре шашек он такой же, как раньше
   (-9px, половина ширины), но чем их больше на полке — тем плотнее
   они ложатся, чтобы все пятнадцать остались видимыми, а не обрезались
   через overflow: hidden за правым краем полки (баг с обхода игр:
   на 320 px последняя шашка вылезала на 129 px за экран).

   Формула — то же самое «сколько шашек, столько и шаг», что у пункта
   («--шаг» через «--шашек»), только по ширине, а не по высоте:
   100% — ширина полки (без padding, он не входит в базу для margin),
   минус 68px запаса — 18px под саму первую шашку и 50px под подпись
   «БЕЛЫЕ»/«ЧЁРНЫЕ» с зазором до неё (длиннее слова не бывает).
   Остаток делится на 14 промежутков между пятнадцатью шашками —
   так получается шаг, а из него, за вычетом ширины шашки и ещё
   одного зазора «gap: 6px» у самой полки (flex-gap ложится ПОВЕРХ
   отрицательного margin, а не вместо него — на это и споткнулись
   в первом варианте формулы), — нахлёст.
   min() не даёт шагу стать больше -9px, когда шашек мало. */
.полка > .шашка {
  position: relative;
  flex: 0 0 auto;
  width: 18px;
  height: 18px;
  margin-left: min(-9px, calc((100% - 68px) / max(var(--шашек, 1) - 1, 1) - 24px));
}

.полка > .шашка:first-of-type { margin-left: 0; }

/* Сюда можно вынести — та же салатовая обводка, что у пунктов. */
.полка.пункт--можно {
  border-style: solid;
  border-color: var(--сб-акцент);
  box-shadow:
    inset 0 2px 4px rgba(0, 0, 0, 0.45),
    0 0 8px rgba(210, 247, 107, 0.45);
}

/* =====================================================================
   КУБИКИ — НА ДОСКЕ, КАК В НАБОРЕ ВЛАДЕЛЬЦА

   На макете кубики лежат посреди правой половины доски, а не строкой
   под ней. Строкой было бы проще, но она съедала бы шесть десятков
   точек высоты — тех самых, которых на невысоком телефоне не хватает
   нижним кнопкам.

   Разметку править нельзя (узел кубиков стоит после доски), поэтому
   ряд сделан «без высоты» и поднят на доску:

     height: 0                 — ряд не занимает места в столбце;
     margin: -зазор 0          — и не оставляет после себя просветов;
     top: -(полки + зазор + почти половина доски)
                               — поднимаемся от низа доски к её середине;
     padding-left: 41 %        — сдвигаемся в правую половину, как на макете.

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

.кубики {
  position: relative;
  z-index: 5;
  align-self: center;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: calc(var(--д-ширина) * 0.022);
  width: var(--д-ширина);
  height: 0;
  margin: calc(-1 * var(--зазор-рядов)) 0;
  /* «41% от ширины доски» — НЕ «padding-left: 41%»: проценты в padding
     считаются от ширины РОДИТЕЛЯ (всего экрана), а не от ширины самого
     узла «.кубики», даже если у узла есть своя явная ширина. На телефоне
     это незаметно — колонка экрана и так примерно равна ширине доски.
     На планшете, где доска упирается в высоту и оказывается уже, чем
     колонка экрана (решение штаба, 16.09), «41%» раздувался от широкой
     колонки и выталкивал кубики за правый край их же 406-точечного
     контейнера — они сжимались почти до нуля. «calc()» считает долю
     от «--д-ширина» напрямую, каким бы ни было окно вокруг. */
  padding-left: calc(var(--д-ширина) * 0.41);
  top: calc(-1 * (var(--полка-высота) + var(--полка-отступ)
                  + var(--зазор-рядов) + var(--д-высота) * 0.4956));
  pointer-events: none;   /* сквозь кубики нажимается доска */
}

.кубик {
  position: relative;
  /* Пол — 22 точки: без него на самом полу доски (320 точек — см.
     «--д-ширина» выше) кость ещё читается (27 точек), но «max()»
     защищает и от более тесных случаев, если доска когда-нибудь
     станет уже пола. Точка на кости — не пятно, её должно быть видно. */
  width: max(22px, calc(var(--д-ширина) * 0.085));
  aspect-ratio: 1;
  transition: opacity 0.2s ease-out, filter 0.2s ease-out;

  /* Точка запасной кости (см. ниже). Здесь она объявлена потому, что
     отсюда её видно обоим псевдоэлементам картинки. */
  --точка: radial-gradient(circle at 46% 42%,
    #171a18 0 26%, rgba(84, 76, 60, 0.9) 27% 31%, transparent 32%);
}

.кубик__рисунок {
  position: relative;
  display: block;
  width: 100%;
  height: 100%;
  /* Тень под костью — её на картинке нет, так велит инструкция
     набора: «визуальную тень добавить CSS». */
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.55));
}

/* ---------- ЗАПАСНАЯ КОСТЬ: ТОЛЬКО ЕСЛИ КАРТИНКА НЕ ПРИЕХАЛА ----------

   Кубик набора («shared/dice/die-1…6.svg») — непрозрачная картинка,
   и рисовать что-то под ней бессмысленно. Но браузер показывает
   «::before» и «::after» у картинки ровно тогда, когда сама картинка
   не загрузилась, — вот там эта заготовка и появляется. На стенде
   сервер отдаёт .svg неверным типом, и без неё вместо кубиков висят
   значки битой картинки.

   Кремовый цвет кости и скругление 17 из 100 взяты из того же файла
   набора, поэтому подмена в глаза не бросается. */
.кубик__рисунок::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: 17%;
  background: linear-gradient(148deg, #fff8de, #eed7b0 60%, #c4a175);
  box-shadow: inset 0 0 0 1px rgba(255, 242, 207, 0.8);
}

.кубик__рисунок::after {
  content: '';
  position: absolute;
  inset: 0;
  background-repeat: no-repeat;
  background-size: 33.34% 33.34%;
}

.кубик[data-очки="1"] .кубик__рисунок::after {
  background-image: var(--точка);
  background-position: 50% 50%;
}
.кубик[data-очки="2"] .кубик__рисунок::after {
  background-image: var(--точка), var(--точка);
  background-position: 15% 15%, 85% 85%;
}
.кубик[data-очки="3"] .кубик__рисунок::after {
  background-image: var(--точка), var(--точка), var(--точка);
  background-position: 15% 15%, 50% 50%, 85% 85%;
}
.кубик[data-очки="4"] .кубик__рисунок::after {
  background-image: var(--точка), var(--точка), var(--точка), var(--точка);
  background-position: 15% 15%, 85% 15%, 15% 85%, 85% 85%;
}
.кубик[data-очки="5"] .кубик__рисунок::after {
  background-image: var(--точка), var(--точка), var(--точка), var(--точка), var(--точка);
  background-position: 15% 15%, 85% 15%, 50% 50%, 15% 85%, 85% 85%;
}
.кубик[data-очки="6"] .кубик__рисунок::after {
  background-image: var(--точка), var(--точка), var(--точка), var(--точка), var(--точка), var(--точка);
  background-position: 15% 12%, 85% 12%, 15% 50%, 85% 50%, 15% 88%, 85% 88%;
}

/* Сыгранный кубик гаснет — видно, что от хода осталось. Не в ноль:
   на тёмном дереве кость при 0,3 превращалась в бурое пятно, и было
   не разобрать, что за число уже сыграно. */
.кубик--сыгран { opacity: 0.5; filter: grayscale(0.5); }

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

/* ---------- Кубик не появляется, а падает ----------

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

   Второй кубик отстаёт на десятую долю секунды: два предмета никогда
   не падают из руки одновременно, и эта мелочь убирает ощущение
   механизма. */
.кубик--катится {
  animation: кубик-падает 0.62s cubic-bezier(0.3, 0, 0.7, 1) infinite;
}

.кубик--катится:nth-child(2) { animation-delay: 0.1s; }

@keyframes кубик-падает {
  0%   { transform: translateY(-0.9rem) rotate(-26deg) scale(1.06); }
  34%  { transform: translateY(0) rotate(84deg) scale(0.97); }
  56%  { transform: translateY(-0.42rem) rotate(168deg) scale(1.02); }
  74%  { transform: translateY(0) rotate(232deg) scale(0.98); }
  88%  { transform: translateY(-0.16rem) rotate(286deg) scale(1); }
  100% { transform: translateY(0) rotate(330deg) scale(1); }
}

/* =====================================================================
   ПЛАШКА ХОДА И ПОДСКАЗКА

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

#строка-хода {
  flex: 0 0 auto;
  align-self: center;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 40px;
  margin: 0;
  padding: 8px 22px;
  border-radius: 999px;
  font-size: 17px;
  font-weight: 700;
  line-height: 1.1;
  color: var(--сб-текст);
  background: rgba(248, 245, 235, 0.07);
  border: 1px solid rgba(248, 245, 235, 0.12);

  /* Молния набора владельца двумя видами: цветной рисунок для
     салатовой пилюли и такой же силуэт под маску для тёмной
     (см. «.строка-хода__значок» ниже). */
  --знак-молния: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cpath d='M36 3 12 36h17l-3 25 27-36H35Z' fill='%230b130b'/%3E%3C/svg%3E");
  --маска-молния: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cpath d='M36 3 12 36h17l-3 25 27-36H35Z' fill='%23000'/%3E%3C/svg%3E");
}

/* Ход белых — то есть ваш ход в игре с ботом. */
#строка-хода.строка-хода--белые {
  color: var(--сб-акцент-текст);
  background: var(--сб-акцент);
  border-color: var(--сб-акцент);
  box-shadow: 0 4px 14px rgba(210, 247, 107, 0.22);
}

/* Молния из набора владельца («img/нарды/lightning.svg»). Рисунок
   вписан прямо сюда строкой: это ровно тот же путь из того же файла,
   просто не отдельной картинкой. Так в сборнике сделаны все значки
   в оформлении (см. «--значок-…» в style.css) — и заодно значок
   виден на стенде, где сервер отдаёт .svg неверным типом.

   Молния почти чёрная — под салатовую пилюлю; на тёмной плашке
   (ход чёрных) её высветляем маской, чтобы не пропала. */
.строка-хода__значок {
  flex: 0 0 auto;
  width: 17px;
  height: 17px;
  background: var(--знак-молния) center / contain no-repeat;
}

#строка-хода.строка-хода--чёрные .строка-хода__значок {
  background: var(--сб-текст-тихий);
  -webkit-mask: var(--маска-молния) center / contain no-repeat;
          mask: var(--маска-молния) center / contain no-repeat;
}

#подсказка-хода {
  flex: 0 0 auto;
  margin: 0;
  font-size: 14px;
  line-height: 1.25;
  text-align: center;
  color: var(--сб-текст-тихий);
}

/* Объяснение отказа («почему эта шашка не идёт») стоит в той же строке,
   но живёт пару секунд и отвечает на вопрос, который у человека прямо
   сейчас. Тихим серым его бы не заметили, поэтому текст обычной яркости
   и пожирнее — тем же способом, каким у шашек выделено «есть бой, брать
   обязательно». Новых картинок и цветов не заводим. */
#подсказка-хода.подсказка-хода--объяснение {
  color: var(--сб-текст);
  font-weight: 600;
}

/* =====================================================================
   КНОПКИ ХОДА

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

/* Общее правило сборника «.экран > .кнопка» держит кнопку в колонке
   360 точек (см. style.css, «ОДНА КОЛОНКА НА ВСЕ ИГРЫ») — здесь эта
   ширина перебита: «Бросить кубики» стоит в том же ряду, что кнопки
   хода, и должна быть той же ширины, что доска, как и они. */
#экран-игры > #кнопка-бросить {
  flex: 0 0 auto;
  width: 100%;
  max-width: var(--д-ширина);
  min-height: 52px;
  border-radius: 16px;
}

.действия-хода {
  flex: 0 0 auto;
  align-self: center;
  display: flex;
  gap: 10px;
  width: 100%;
  /* Той же ширины, что доска — см. пояснение у «.игрок-нард» выше. */
  max-width: var(--д-ширина);
}

/* «Отменить ход» — не выключенная кнопка, а тихая: рамка и белая
   подпись. Пустой прямоугольник читался бы как «сейчас нельзя». */
.действия-хода .кнопка.кнопка--мелкая#кнопка-отменить-ход {
  flex: 1 1 46%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-width: 0;
  min-height: 52px;
  padding: 8px 10px;
  /* Подпись в одну строку: «Отменить ход», разорванное на два ряда,
     читается как две разные кнопки. Поэтому кегль здесь мельче, чем
     у главной, — 14 против 16. */
  font-size: 14px;
  font-weight: 700;
  white-space: nowrap;
  color: var(--сб-текст);
  background: rgba(248, 245, 235, 0.04);
  border: 1.5px solid rgba(248, 245, 235, 0.18);
  border-radius: 16px;
}

.кнопка__значок {
  width: 20px;
  height: 20px;
  flex: 0 0 auto;
}

.действия-хода #кнопка-закончить-ход {
  flex: 1 1 54%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-width: 0;
  min-height: 52px;
  padding: 8px 10px;
  font-size: 16px;
  line-height: 1.15;
  border-radius: 16px;
}

/* Галочка перед «Подтвердить». Своего узла под неё в разметке нет,
   поэтому рисуем псевдоэлементом. Рисунок — тот же, что в
   «img/нарды/check.svg», вписанный строкой (объяснение — у молнии
   выше). */
.действия-хода #кнопка-закончить-ход::before {
  content: '';
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'%3E%3Cpath d='m12 33 13 13 28-29' fill='none' stroke='%230b130b' stroke-width='6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / contain no-repeat;
}

/* Подтверждение сдачи: кнопка ждёт второго нажатия и становится красной.
   Правило перенесено из style-шашки.css. Ограничено на экран игры нард,
   чтобы не дублировать в других играх (они берут свои версии из своих файлов).
   Цвет — тот же красный, что вспышка отказа на доске, чтобы не перепутать
   две версии кнопки. */
#экран-игры #кнопка-сдаться.кнопка-сдаться--подтверждение {
  background: var(--нельзя);
  color: #fff;
}

/* Счёт вынесенных — служебная строка, поэтому тихая и мелкая.
   Стоит последней, у самого нижнего края. */
#счёт-нард {
  flex: 0 0 auto;
  margin: 0;
  font-size: 13px;
  text-align: center;
  color: var(--сб-текст-тихий);
}

/* =====================================================================
   КУДА ДЕВАТЬ ЛИШНЮЮ ВЫСОТУ

   Доска у нард шире, чем выше, и шире колонки её делать нельзя —
   значит, на высоком телефоне под столом всегда остаётся запас: на
   390×844 это было около 120 точек, на 430×932 — около 170. Раньше
   весь запас забирала одна строка счёта, и получалось пустое поле
   в треть экрана между кнопкой и нижним краем: стол выглядел
   обрезанным, а кнопка — висящей в воздухе.

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

     • над панелью соперника  — стол отходит от заголовка;
     • над плашкой хода       — «Ваш ход» не липнет к своей панели;
     • над рядом кнопок       — кнопка отделена от подсказки;
     • над строкой счёта      — служебная строка у самого низа.

   Делают это четыре «margin-top: auto»: в колонке они делят всё
   свободное место поровну между собой. На 390×844 остаётся примерно
   по двадцать точек на просвет вместо одной дыры в сто двадцать,
   на 430×932 — по тридцать пять.

   Порядок рядов при этом не меняется ни на одну строку — меняется
   только то, как между ними распределён воздух. */

.игрок-нард--соперник,
#строка-хода,
#кнопка-бросить,
.действия-хода,
#счёт-нард {
  margin-top: auto;
}

/* ---------- Место под кнопки хода занято всегда ----------

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

   Поэтому ряд кнопок держит свою высоту, даже когда кнопок в нём
   нет. Пустое место не видно, зато плашка хода, подсказка и панели
   игроков стоят неподвижно во всех четырёх состояниях. */
.действия-хода { min-height: 52px; }

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

/* =====================================================================
   МЕЛОЧИ ОСТАЛЬНЫХ ЭКРАНОВ
   ===================================================================== */

/* ---------- Экран выбора: главная кнопка одна ----------

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

   Экран целиком переделает лобби по макету владельца (этап Э1),
   до тех пор пусть выглядит по правилам сборника. */
#экран-режимов #кнопка-вдвоём,
#экран-режимов #кнопка-с-другом {
  color: var(--сб-текст);
  background: rgba(248, 245, 235, 0.04);
  border: 1.5px solid rgba(248, 245, 235, 0.18);
  box-shadow: none;
}

/* Строчка о разнице версий в меню. Она важнее, чем кажется: человек,
   знающий одни нарды, про вторые часто не подозревает. */
.подпись--пояснение {
  font-size: 0.82rem;
  opacity: 0.8;
  max-width: 22rem;
  margin: 0.1rem auto 0.7rem;
  line-height: 1.35;
}

/* Экран «Как играть» прокручивается.

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

   «overflow-x: hidden» здесь обязателен, а не для красоты: стоит
   включить «overflow-y: auto», как браузер сам решает, что раз одна
   ось не «visible», то и другая тоже становится «auto» — и любой
   лишний пиксель по ширине (например от строки «‹ ⋯», которая нарочно
   чуть шире экрана, чтобы стрелка встала у самого края) превращается
   в настоящую горизонтальную полосу прокрутки. На столе и на экранах
   без своей прокрутки этого не видно только потому, что там прокрутки
   нет вовсе и лишний край просто прячется под общим «overflow: hidden»
   у html/body. */
#экран-как-играть {
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
}

#экран-как-играть > * { flex: 0 0 auto; }

/* Кнопка «‹» этого экрана — тот же id («кнопка-правила-назад»), что
   у большой кнопки «Назад» под текстом правил в общем style.css
   (там она нужна дураку и шахматам). Здесь она уже не одна на весь
   экран, а маленькая стрелка внутри «.верх-игры», как на столе, но
   старое правило по id всё равно её задевает — оно специфичнее
   класса «.верх-игры__кнопка» (id всегда сильнее класса), и без этой
   правки кнопка становится широкой плашкой в 300 точек, прижатой
   к низу экрана «margin-top: auto», вместо стрелки в углу. Отменяем
   ровно эти два свойства — их и добавляло старое правило. */
#кнопка-правила-назад {
  width: 44px;
  margin-top: 0;
}

/* Текст правил на экране «Как играть». */
.правила-текст {
  text-align: left;
  max-width: 26rem;
  margin: 0 auto 1rem;
  line-height: 1.45;
  font-size: 0.92rem;
}

.правила-текст h3 {
  margin: 0.9rem 0 0.25rem;
  font-size: 1rem;
}

.правила-текст p { margin: 0.25rem 0; }

/* =====================================================================
   ТОН ДОСКИ (сохранённая настройка, без отдельного экрана)

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

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

html[data-доска="камень"] .доска__фон {
  filter: saturate(0.45) brightness(0.92) contrast(1.06);
}

html[data-доска="классика"] .доска__фон {
  filter: saturate(1.18) brightness(1.03) hue-rotate(-4deg);
}

/* Экран «Оформление» у нард получает через общий style.css те же цвета
   и поля, что «Правила»/«Рекорды» у дурака и шахмат: это правильно
   для тёмных плиток фона. Но их строка «‹» устроена по-другому — поле
   экрана шире (14 точек вместо 8), центрирование внутри, а сама
   кнопка превращена в стрелку старым приёмом (ещё до того, как
   появилась обёртка «.верх-игры»): своим положением («position:
   relative», «align-self: flex-start») и своей стрелкой через
   «::before» с маской — второй, поверх той, что уже нарисована в html
   («<svg>»). Из-за этого «‹» стояла на 16 точек правее и на 4 точки
   ниже, чем на «Как играть» и «Вид доски».

   Приводим шапку к общему стандарту, ничего не трогая в плитках ниже:
   поле экрана — как у generic «.экран» (8 точек), «.верх-игры» —
   растянута к самому краю, как на столе, а старое превращение кнопки
   отменено — дальше она обычная «.верх-игры__кнопка». */
#приложение:has(.доска-нард) #экран-оформления {
  align-items: stretch;
  padding: calc(8px + var(--отступ-сверху)) calc(8px + var(--отступ-справа))
           calc(8px + var(--отступ-снизу))  calc(8px + var(--отступ-слева));
}

/* Числа пересчитаны: поле экрана здесь — 8px плюс безопасный отступ,
   не 10px, поэтому старые «-10px»/«+20px» тянули строку на 2px за
   оба края телефона. При align-items:stretch (в отличие от «center»
   у шашек/шахмат) margin ЗАДЕЙСТВОВАН, компенсировать нужно и его,
   и ширину — оба пересчитаны на 8px. */
#приложение:has(.доска-нард) #экран-оформления > .верх-игры {
  width: calc(100% + 16px + var(--отступ-слева) + var(--отступ-справа));
  max-width: none;
  margin: -4px calc(-8px - var(--отступ-справа)) -8px calc(-8px - var(--отступ-слева));
}

#приложение:has(.доска-нард) #экран-оформления #кнопка-оформление-назад {
  position: static;
  align-self: auto;
  margin: 0;
}

#приложение:has(.доска-нард) #экран-оформления #кнопка-оформление-назад::before {
  content: none;
}

/* =====================================================================
   ШИРОКОЕ ОКНО — планшет и компьютер (от 700 точек)

   Жалоба владельца 16.09: «на планшете стол очень маленький, кубики
   очень маленькие и наложены на фишки». Причиной был не размер кубиков
   и не их место — оба считаются в процентах от ширины доски и совпадают
   с координатами набора (591/698 по ширине, 400 по высоте из 913×793)
   при любом размере доски. Причина — сама доска: потолок в 520 точек
   не давал ей вырасти, хотя на планшете колонка и высота легко дают
   больше. На маленькой доске мельчает всё сразу — и кубики, и фишки, —
   и им негде разойтись.

   Поднимаем потолок «--д-ширина» (раздел «РАСКЛАДКА ИГРОВОГО ЭКРАНА»)
   до 880 — доска становится во всю ширину планшетной колонки, а на
   низком широком окне (1280×800) её по-прежнему останавливает высота
   (третий член в «min()» — он не тронут).

   Панели игроков и ряд кнопок хода привязаны к «--д-ширина» же (см.
   «.игрок-нард», «.действия-хода», «#кнопка-бросить» ниже по файлу),
   поэтому на планшете они растут вместе с доской, а не остаются
   в 520-точечной колонке, пока доска шире. */
@media (min-width: 700px) {
  #экран-игры {
    --д-потолок: 880px;
  }
}

/* =====================================================================
   ВЫСОКОЕ ОКНО — обычный телефон стоя

   На 390×844 и тем более на 430×932 доска упирается в ширину колонки,
   а высоты остаётся с запасом. Часть этого запаса лучше отдать не
   воздуху, а самим рядам: панели игроков, плашка хода и кнопки
   становятся заметно крупнее — в них легче попасть пальцем и их
   видно с вытянутой руки. Остаток расходится по четырём просветам
   (см. «КУДА ДЕВАТЬ ЛИШНЮЮ ВЫСОТУ» выше).

   На «--прочее» это не влияет: при такой высоте доску меряет ширина
   колонки, а не остаток высоты.
   ===================================================================== */

@media (min-height: 800px) {
  #экран-игры {
    /* Полки — тоже место, куда целятся пальцем (туда выносят фишки).
       На высоком экране запас высоты есть, и полка растёт с 26 до 36:
       ближе к пальцу и подпись в ней перестаёт жаться. */
    --полка-высота: 36px;
    --полка-отступ: 8px;
  }

  .игрок-нард { min-height: 58px; padding: 6px 16px 6px 6px; }
  .игрок-нард__аватар { width: 46px; height: 46px; }
  .игрок-нард__имя { font-size: 17px; }

  #строка-хода { min-height: 46px; padding: 10px 24px; font-size: 18px; }
  .строка-хода__значок { width: 19px; height: 19px; }

  #подсказка-хода { font-size: 15px; }

  #кнопка-бросить,
  .действия-хода,
  .действия-хода .кнопка.кнопка--мелкая#кнопка-отменить-ход,
  .действия-хода #кнопка-закончить-ход { min-height: 56px; }

  #счёт-нард { font-size: 14px; }
}

/* =====================================================================
   НЕВЫСОКОЕ ОКНО

   Шторка Telegram открывается не во весь рост, и тогда высота дороже
   ширины. Ужимаем всё, что не доска: заголовок сжимается в одну строку
   (это делает общий файл), панели, плашка и кнопки становятся ниже.
   Заодно уменьшается «--прочее» — и доска снова получает ширину экрана,
   а не остаток высоты.
   ===================================================================== */

@media (max-height: 740px) {
  #экран-игры {
    /* Что стоит выше и ниже доски: строка «‹ ⋯», крупный заголовок
       с режимом партии, две панели игроков, полки, плашка хода,
       подсказка, ряд кнопок, счёт, поля экрана и просветы между
       рядами. Сумма посчитана по этому же файлу — меняешь ряд,
       поправь и здесь. */
    --прочее: calc(390px + var(--отступ-сверху) + var(--отступ-снизу));
    --полка-высота: 22px;
    --полка-отступ: 4px;
  }

  .игрок-нард { min-height: 44px; padding: 4px 12px 4px 4px; }
  .игрок-нард__аватар { width: 36px; height: 36px; padding: 6px; }
  .игрок-нард__имя { font-size: 15px; }
  .игрок-нард__статус { font-size: 12px; }

  #строка-хода { min-height: 34px; padding: 6px 16px; font-size: 15px; }
  #подсказка-хода { font-size: 13px; }

  #кнопка-бросить,
  .действия-хода,
  .действия-хода .кнопка.кнопка--мелкая#кнопка-отменить-ход,
  .действия-хода #кнопка-закончить-ход { min-height: 46px; }
}

/* Ниже 700 общий файл сжимает заголовок в одну строку и прячет её
   внутрь строки «‹ ⋯» — над доской освобождается около шестидесяти
   точек, и доска снова может их занять. */
@media (max-height: 700px) {
  #экран-игры {
    --прочее: calc(336px + var(--отступ-сверху) + var(--отступ-снизу));
  }
}

/* Совсем низкое окно: счёт уходит вовсе — вынесенные и так видно
   на полках. */
@media (max-height: 600px) {
  #экран-игры {
    --прочее: calc(310px + var(--отступ-сверху) + var(--отступ-снизу));
  }

  #счёт-нард { display: none; }
}

/* =====================================================================
   ЭКРАН «ОФОРМЛЕНИЕ»

   Сам экран — общий для сборника: заголовок слева, «‹» в углу, тёмные
   плитки. Всё это приехало из style.css, там же он нарисован и для
   дурака (см. «Экраны из листа «Ещё»»).

   Своё у нард одно — ОБРАЗЕЦ. У дурака этот выбор красит сукно стола,
   и в окошке показан кусочек сукна в деревянной раме. У нард сукна
   нет вовсе: тот же выбор красит фон страницы вокруг доски. Поэтому
   в окошке — кусочек НАСТОЯЩЕЙ страницы нард: тот же тёмный фон, то
   же салатовое свечение сверху и тот самый живой слой, что работает
   в игре. Показывать здесь зелёное сукно значило бы обещать то, чего
   после нажатия не случится.
   ===================================================================== */

#экран-оформления .образец-фона {
  border-radius: 10px;
  background:
    radial-gradient(80% 30px at 50% 0, rgba(210, 247, 107, 0.10), rgba(210, 247, 107, 0) 100%),
    var(--сб-фон);
  box-shadow: inset 0 0 0 1px rgba(248, 245, 235, 0.14);
}

/* Пятна в окошке ещё громче обычного. На тёмном фоне нард разница
   между «Дыханием» и «Туманом» при общей силе теряется, и все пять
   вариантов выглядят одним тёмным прямоугольником — выбирать не из
   чего. На самой странице сила остаётся прежней, тихой. */
#экран-оформления .образец-фона .фон-игры {
  --сила-свет: 0.5;
  --сила-тень: 0.5;
}

/* =====================================================================
   КОМУ ВЫКЛЮЧЕНО ДВИЖЕНИЕ — выключено всё. Переезд фишек код в этом
   случае не запускает вовсе, здесь гасим оставшееся.
   ===================================================================== */

@media (prefers-reduced-motion: reduce) {
  .кубик--катится { animation: none; }
  .пункт--можно > .пункт__цель { animation: none; }
  .шашка,
  .шашка__кольцо,
  .пункт__цель { transition: none; }
}

/* =====================================================================
   ЛОББИ НАРД. Карточка профиля, переключатели, карточки входа, рамка
   картинки с подписью и нижняя полоса — общие классы style.css, как у
   дурака (владелец 02.10: все онлайн-игры — в одном стиле). Рамка
   баннера теперь той же пропорции 16:10, что у дурака, — своего
   «aspect-ratio» здесь нет. Панорама доски (528×206) режется «cover»-ом
   по краям; держим центр, где фишки и кубики.
   ===================================================================== */
body #экран-лобби .лобби__картинка .лобби__рисунок {
  object-position: 50% 50%;
}
