/* =============================================================================================
 * game.css — стили ТОЛЬКО для демо-механики (inc/sections/demo.php + assets/js/game.js).
 *
 * Каждый селектор начинается с .cbj-game, поэтому файл физически не может протечь в
 * остальную страницу. Подключается только там, где секция действительно есть: inc/head.php
 * линкует его по флагу $page['demo'].
 *
 * ТОКЕНЫ. Своих цветов у файла НЕТ. Всё, что ниже, — псевдонимы токенов дизайн-системы,
 * которые inc/head.php инлайнит в <head> и повторяет assets/css/main.css: слои почти-чёрного
 * --bg-0/--bg-1/--bg-2, хайрлайн --line, текст --text, вторичный --muted, кольцо фокуса
 * --ring и четыре цвета блоков --c-red/--c-blue/--c-green/--c-yellow. Светлая тема
 * переключается САМА вместе со страницей — второго набора значений здесь нет и быть не
 * должно: он неизбежно разъедется с первым. Запасные литералы в var() нужны ровно на случай,
 * когда game.css почему-то загрузился без критического CSS.
 *
 * Состояние никогда не кодируется одним цветом — у каждого цвета своя форма значка,
 * у льда есть счётчик ударов цифрой, у пройденного уровня — галочка.
 *
 * Содержание
 *   1. Токены
 *   2. Каркас секции
 *   3. Поле, сетка, ворота
 *   4. Блоки, значки формы, лёд
 *   5. Итоговая плашка
 *   6. Панель управления
 *   7. Служебное: скринридер, reduced-motion, печать
 * =========================================================================================== */

/* ---------------------------------------------------------------------------- 1. токены --- */

.cbj-game {
    /* Цвета блоков и ворот — те же четыре, что у фишек в герое, точек секций и постеров
       видео на /prohozhdenie. Один набор на весь сайт: в светлой теме он темнеет вместе
       со страницей, и значки-формы остаются читаемыми на обоих вариантах. */
    --cbj-r: var(--c-red, #e5484d);
    --cbj-b: var(--c-blue, #3e63dd);
    --cbj-g: var(--c-green, #30a46c);
    --cbj-y: var(--c-yellow, #ffb224);

    --cbj-page:    var(--bg-0, #090909);
    --cbj-surface: var(--bg-1, #111111);
    --cbj-raised:  var(--bg-2, #181818);
    --cbj-line:    var(--line, #212121);
    --cbj-text:    var(--text, #ffffff);
    --cbj-muted:   var(--muted, #8f8f8f);
    --cbj-ring:    var(--ring, #ffffff);
    --cbj-ice:     #cbebf7;

    --cbj-cell: 40px;
    --cbj-rim: 14px;
}

/* ------------------------------------------------------------------- 2. каркас секции --- */

/* Отступ под липкую шапку уже задан правилом [id]{scroll-margin-top} в критическом CSS —
   здесь он не повторяется. */
.cbj-game .section__body {
    color: var(--cbj-text);
}

/* Строка состояния: одна и та же для скринридера (role="status") и для зрячих.
   Высота зафиксирована, поэтому меняющийся текст ничего под собой не двигает. */
.cbj-status {
    max-width: 34rem;
    min-height: 2.8em;
    margin: .55rem 0 0;
    color: var(--cbj-muted);
    font-size: .92rem;
    line-height: 1.4;
}

/* Место под поле зарезервировано ДО загрузки скрипта: фиксированное соотношение сторон и
   max-width. ВНИМАНИЕ: position/width/max-width/aspect-ratio/display/align/justify отсюда
   продублированы в критический CSS (inc/head.php, $demoCriticalCss), потому что этот файл
   подключается как preload+onload и не блокирует отрисовку — без дубля секция успевала
   нарисоваться до него и схлопывалась с 878px до 544px (CLS 0.0968 на /#demo). Меняете
   здесь — меняйте и там. То же самое про min-height у .cbj-status и .cbj-game__name. */
.cbj-game__stage {
    position: relative;
    width: 100%;
    max-width: 34rem;
    aspect-ratio: 1 / 1;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--cbj-surface);
    border: 1px solid var(--cbj-line);
    border-radius: var(--radius, 8px);
}

.cbj-game__idle {
    margin: 0;
    padding: 1.5rem;
    max-width: 30ch;
    text-align: center;
    color: var(--cbj-muted);
    font-size: .95rem;
}

.cbj-game[data-cbj-ready] .cbj-game__idle {
    display: none;
}

/* -------------------------------------------------------- 3. поле, сетка, ворота --- */

.cbj-board {
    position: relative;
    /* Только на поле: страница продолжает скроллиться пальцем везде, кроме доски. */
    touch-action: none;
    -webkit-user-select: none;
    user-select: none;
    -webkit-tap-highlight-color: transparent;
}

.cbj-board__gates {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.cbj-board__grid {
    position: absolute;
    inset: var(--cbj-rim);
    border-radius: 4px;
    background-color: var(--cbj-raised);
    background-image:
        linear-gradient(to right, var(--cbj-line) 1px, transparent 1px),
        linear-gradient(to bottom, var(--cbj-line) 1px, transparent 1px);
    background-size: var(--cbj-cell) var(--cbj-cell);
    box-shadow: inset 0 0 0 1px var(--cbj-line);
}

.cbj-gate {
    position: absolute;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--cbj-c);
}

.cbj-gate--left   { left: 0;   border-radius: 6px 0 0 6px; }
.cbj-gate--right  { right: 0;  border-radius: 0 6px 6px 0; }
.cbj-gate--top    { top: 0;    border-radius: 6px 6px 0 0; }
.cbj-gate--bottom { bottom: 0; border-radius: 0 0 6px 6px; }

/* -------------------------------------------------- 4. блоки, значки формы, лёд --- */

.cbj-block {
    position: absolute;
    left: 0;
    top: 0;
    margin: 0;
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    color: inherit;
    cursor: grab;
    transition: transform 150ms cubic-bezier(.22, .61, .36, 1), opacity 200ms linear;
    will-change: transform;
}

.cbj-block:active,
.cbj-block[data-drag] { cursor: grabbing; }

.cbj-block:focus { outline: none; }

.cbj-block:focus-visible {
    outline: 3px solid var(--cbj-ring);
    outline-offset: 3px;
    border-radius: 4px;
}

.cbj-block[data-grab] {
    outline: 3px dashed var(--cbj-ring);
    outline-offset: 3px;
    border-radius: 4px;
}

.cbj-block__cell {
    position: absolute;
    display: block;
    background: var(--cbj-c);
}

/* Светлая фаска только на верхних клетках фигуры — шов внутри фигуры не появляется. */
.cbj-block__cell.is-top {
    box-shadow: inset 0 2px 0 rgba(255, 255, 255, .22);
}

.cbj-block[data-out] {
    opacity: 0;
    pointer-events: none;
}

/* Значок формы: круг / квадрат / треугольник / ромб — дублирует цвет для дальтоников. */
.cbj-mark {
    position: absolute;
    left: 50%;
    top: 50%;
    z-index: 1;                 /* выше инея: значок формы читается и на замороженном блоке */
    width: 42%;
    height: 42%;
    transform: translate(-50%, -50%);
    pointer-events: none;
}

.cbj-mark--gate {
    position: static;
    transform: none;
    width: 62%;
    height: 62%;
    max-width: 16px;
    max-height: 16px;
}

/* Лёд. Иней рисуется в каждой клетке, поэтому корректен и для уголков. */
.cbj-block[data-ice] .cbj-block__cell::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    /* Иней полупрозрачный намеренно: цвет блока должен остаться узнаваемым — по нему
       игрок ищет ворота. Штриховка и счётчик ударов несут состояние без опоры на цвет. */
    background-color: rgba(203, 235, 247, .42);
    background-image: repeating-linear-gradient(135deg,
        rgba(255, 255, 255, .55) 0 4px,
        rgba(255, 255, 255, 0) 4px 10px);
}

.cbj-block__ice {
    position: absolute;
    left: 50%;
    top: 50%;
    display: none;
    align-items: center;
    justify-content: center;
    width: 1.5rem;
    height: 1.5rem;
    transform: translate(-50%, -50%);
    border-radius: 999px;
    background: rgba(9, 9, 9, .78);
    color: var(--cbj-ice);
    font-size: .8rem;
    /* Не bold — ровно по той же причине, что и .cbj-hud b ниже: цифру выделяет цвет и
       тёмный диск под ней, а на этих двух страницах НЕТ жирного текста вообще (это правило
       из research/design-brief.md). Счётчик льда был единственным местом, где оно
       нарушалось, — весом 700 против 400 у всего остального. Контраст от правки не
       страдает: светло-голубой по rgba(9,9,9,.78) читается и так. */
    font-weight: 400;
    line-height: 1;
    pointer-events: none;
}

.cbj-block[data-ice] .cbj-block__ice { display: flex; }

/* Толчок в стену или в чужой блок: короткая отдача, чтобы отказ был виден, а не только слышен. */
.cbj-block[data-bump="left"]  { animation: cbj-bump-x 200ms ease; }
.cbj-block[data-bump="right"] { animation: cbj-bump-x 200ms ease reverse; }
.cbj-block[data-bump="up"]    { animation: cbj-bump-y 200ms ease; }
.cbj-block[data-bump="down"]  { animation: cbj-bump-y 200ms ease reverse; }

@keyframes cbj-bump-x {
    0%, 100% { margin-left: 0; }
    50%      { margin-left: -5px; }
}

@keyframes cbj-bump-y {
    0%, 100% { margin-top: 0; }
    50%      { margin-top: -5px; }
}

/* ------------------------------------------------------------- 5. итоговая плашка --- */

.cbj-over {
    position: absolute;
    inset: 0;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .35rem;
    padding: 1.25rem;
    text-align: center;
    border-radius: 8px;
    background: color-mix(in srgb, var(--cbj-page) 88%, transparent);
}

@supports not (background: color-mix(in srgb, red 50%, blue)) {
    .cbj-over { background: rgba(9, 9, 9, .88); }
}

.cbj-over__title {
    margin: 0;
    font-size: clamp(1.35rem, 1.1rem + 1.1vw, 1.9rem);
    font-weight: 400;
    letter-spacing: -.01em;
    color: var(--cbj-text);
}

.cbj-over__sub {
    margin: 0 0 .9rem;
    color: var(--cbj-muted);
    font-size: .95rem;
}

.cbj-over__actions {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    justify-content: center;
}

/* --------------------------------------------------------------- 6. панель управления --- */

.cbj-game__bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: .6rem 1rem;
    max-width: 34rem;
    margin: .9rem 0 0;
}

.cbj-levels {
    display: flex;
    /* Двадцать кнопок (LEVELS в assets/js/game.js) в одну строку не помещаются нигде: при
       2.5rem это 20 × 40px + 19 × 5.6px ≈ 906px, а панель ограничена 34rem.
       Перенос — единственное, что удерживает ряд внутри доски и на 360px, и на 1280px.
       Ровность ряда держит НЕ этот блок, а фиксированная ширина кнопки ниже
       (.cbj-btn--lvl): пока она была min-width, однозначные номера были 40px, двузначные
       44px, и на 360px ряд ложился 7 / 6 / 6 / 1 — четыре строки и «20» одна на последней.
       Сеткой это не чинится: .cbj-levels — flex-элемент панели без определённой ширины, и
       grid с auto-fill схлопывается в одну колонку (проверено — получилось 20 строк).
       Те же числа продублированы геометрией в inc/sections/hero.php (резерв под CLS):
       менять надо в обоих местах. */
    flex-wrap: wrap;
    gap: .35rem;
    margin-right: auto;
}

.cbj-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    min-height: 2.5rem;
    padding: .45rem 1.05rem;
    border: 1px solid var(--cbj-line);
    border-radius: var(--pill, 9999px);
    background: var(--cbj-raised);
    color: var(--cbj-text);
    font: inherit;
    font-size: .95rem;
    line-height: 1.2;
    cursor: pointer;
}

.cbj-btn:hover:not(:disabled) { border-color: var(--cbj-text); }

.cbj-btn:focus-visible {
    outline: 3px solid var(--cbj-ring);
    outline-offset: 3px;
}

.cbj-btn:disabled {
    opacity: .5;
    cursor: default;
}

.cbj-btn--go {
    background: var(--cbj-text);
    color: var(--cbj-page);
    border-color: var(--cbj-text);
}

.cbj-btn--lvl {
    position: relative;
    /* ФИКСИРОВАННАЯ ширина, не min-width: см. .cbj-levels выше. Все двадцать кнопок одного
       размера — иначе ряд переносится по фактической ширине номера и последняя строка
       достаётся одной кнопке. Горизонтальные отступы убраны: 40px хватает двузначному
       номеру в кегле .95rem с запасом, а с padding .55rem кнопка раздувалась до 44px.
       Ширина = min-height = 2.5rem, то есть кнопка квадратная — и это ровно та геометрия,
       которую резервирует inc/sections/hero.php. */
    width: 2.5rem;
    padding: .45rem 0;
    justify-content: center;
    font-variant-numeric: tabular-nums;
}

.cbj-btn--lvl[aria-current="true"] {
    background: var(--cbj-text);
    color: var(--cbj-page);
    border-color: var(--cbj-text);
}

/* Пройденный уровень помечен галочкой, а не только цветом. */
/* Внутри плашки, а не на её краю: у кнопки border-radius 9999px, и в углу 40-пиксельного
   круга галочка оказывалась ЗА границей — читалась как оторвавшийся значок, а в активном
   состоянии ещё и красилась в цвет страницы поверх самой страницы. */
.cbj-btn--lvl[data-cbj-done]::after {
    content: "\2713";
    position: absolute;
    right: .35rem;
    top: .2rem;
    font-size: .7rem;
    line-height: 1;
    color: var(--cbj-g);
}

.cbj-btn--lvl[aria-current="true"][data-cbj-done]::after { color: var(--cbj-page); }

.cbj-hud {
    margin: 0;
    color: var(--cbj-muted);
    font-size: .95rem;
    white-space: nowrap;
}

.cbj-hud b {
    color: var(--cbj-text);
    /* Не bold: цифру выделяет цвет и tabular-nums, как везде на этой странице. */
    font-weight: 400;
    font-variant-numeric: tabular-nums;
}

.cbj-game[data-cbj-state="lose"] .cbj-hud b { color: var(--cbj-r); }

/* Строка заполняется скриптом. min-height держит её высоту с самого первого кадра —
   пустой <p> имеет нулевую высоту, и без этого появление названия уровня сдвинуло бы
   всё, что ниже. */
.cbj-game__name {
    width: 100%;
    min-height: 1.5em;
    margin: .1rem 0 0;
    color: var(--cbj-muted);
    font-size: .9rem;
    line-height: 1.5;
}

.cbj-game__note {
    max-width: 62ch;
    margin: .8rem 0 0;
    color: var(--cbj-muted);
    font-size: .88rem;
}

/* Оговорка «это наша демо-версия, а не сама игра». Выделена цветом текста и хайрлайном,
   а не жирностью: на этой странице ничего не набирается bold — иерархию держат размер,
   цвет и линия (research/design-brief.md). Удалять эту строку нельзя, см. demo.php. */
.cbj-game__note--claim {
    margin-top: 1.1rem;
    padding-top: .8rem;
    border-top: 1px solid var(--cbj-line);
    color: var(--cbj-text);
}

@media (max-width: 27rem) {
    .cbj-levels { margin-right: 0; }
    .cbj-game__bar { gap: .5rem .7rem; }
    .cbj-btn { padding: .45rem .8rem; }
}

/* ---------------------------------------------------- 7. служебное --- */

.cbj-game .cbj-sr {
    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;
}

@media (prefers-reduced-motion: reduce) {
    .cbj-game .cbj-block {
        transition: none;
    }

    .cbj-game .cbj-block[data-bump] {
        animation: none;
    }
}

@media print {
    .cbj-game__stage,
    .cbj-game__bar { display: none; }
}
