/* --- Общие стили --- */
/* Пиксельные ступенчатые углы (2 ступени). Используется через clip-path сразу
   несколькими элементами (внутренний лист, таблица рекордов), чтобы скругления
   у всех были одинаковыми и в едином пиксельном стиле. S — размер ступеньки,
   угол занимает 2·S. Хочешь крупнее/мельче — поменяй 5px и 10px согласованно
   (10px = 2×5px). */
:root {
    --pixel-corner: polygon(
        0 10px, 5px 10px, 5px 5px, 10px 5px, 10px 0,
        calc(100% - 10px) 0, calc(100% - 10px) 5px, calc(100% - 5px) 5px, calc(100% - 5px) 10px, 100% 10px,
        100% calc(100% - 10px), calc(100% - 5px) calc(100% - 10px), calc(100% - 5px) calc(100% - 5px), calc(100% - 10px) calc(100% - 5px), calc(100% - 10px) 100%,
        10px 100%, 10px calc(100% - 5px), 5px calc(100% - 5px), 5px calc(100% - 10px), 0 calc(100% - 10px)
    );
    /* Вариант: верхние углы прямые (кнопка «врастает» в верхнюю границу),
       пиксельные только нижние два угла. */
    --pixel-corner-bottom: polygon(
        0 0, 100% 0,
        100% calc(100% - 10px), calc(100% - 5px) calc(100% - 10px), calc(100% - 5px) calc(100% - 5px), calc(100% - 10px) calc(100% - 5px), calc(100% - 10px) 100%,
        10px 100%, 10px calc(100% - 5px), 5px calc(100% - 5px), 5px calc(100% - 10px), 0 calc(100% - 10px)
    );
}
* {
    /* Убираем синее выделение при тапе (тап-хайлайт) на мобильных */
    -webkit-tap-highlight-color: transparent;
    
    /* Жесткий запрет выделения текста для всех элементов */
    -webkit-user-select: none; 
    -moz-user-select: none;    
    -ms-user-select: none;     
    user-select: none;         
    
    /* Отключаем системное меню при долгом нажатии */
    -webkit-touch-callout: none; 
}

body {
    margin: 0;
    background: #f0f0f0;
    font-family: Arial, sans-serif;
}

/* Глобальный запрет на взаимодействие с картинками (защита от скачивания) */
img {
    -webkit-user-drag: none;
    -khtml-user-drag: none;
    -moz-user-drag: none;
    -o-user-drag: none;
    pointer-events: none; 
}

/* --- Стили для кнопок (общие) --- */
.game-btn {
    padding: 12px 24px;
    font-size: 18px;
    font-weight: bold;
    cursor: pointer;
    border: 3px solid #1E3E66;
    border-radius: 0;
    background: #941B1B;
    color: white;
    transition: all 0.3s ease;
    box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
    text-align: center;
    text-decoration: none;
    display: inline-block;
}

.game-btn:hover {
    background: #7F1714;
    transform: translateY(-2px);
    box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
}

/* --- Боковые кнопки (Скины и Достижения) --- */
/* --- Кнопка "Назад" слева сверху --- */
/* --- Кнопка возврата + тайтл на странице скинов ----------------------
   Используют общий .page-back-btn (см. секцию ниже) — здесь только
   позиционирование под layout страницы. */
.skins-back-btn {
    position: absolute;
    top: 16px;
    left: 12px;
    z-index: 100;
}

.skins-title-banner {
    position: absolute;
    /* По вертикали выравниваем по центру .skins-back-btn:
       у кнопки top:16 + height:48 → её центр y=40.
       Ставим top: 40 + translateY(-50%) — плашка любой высоты центрируется
       ровно по той же линии. */
    top: 40px;
    left: 50%;
    transform: translate(-50%, -50%);
    height: clamp(48px, 13vw, 64px);
    width: auto;
    z-index: 100;
    pointer-events: none;
    image-rendering: pixelated;
}

/* --- Стили для webapp.html (body class="game-page") --- */
body.game-page {
    position: fixed; 
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    width: 100%;
    height: 100%;
    overflow: hidden;
    margin: 0;
}

canvas {
    display: block;
    width: 100%;
    height: 100%;
    transition: transform 0.5s ease-in-out;
    position: relative; /* Добавлено для работы с z-index */
    z-index: 5;         /* Чтобы canvas был поверх праздничного фона */
}

/* --- ПРАЗДНИЧНЫЙ ВИЗУАЛ (5/13 мая) --- */
#holidayBackground {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    z-index: 1; /* Позади canvas */
    pointer-events: none; /* Исключаем перехват кликов/тапов (безопасность UI) */
    overflow: hidden;
    user-select: none;
    
    /* Полностью скрыт на главном экране */
    opacity: 0; 
    /* Плавное появление (настраивается в секундах, сейчас 2s) */
    transition: opacity 2s ease-in-out; 
}

/* Этот класс добавляется через JS при старте игры */
#holidayBackground.active {
    opacity: 1; 
}

#holidayBackground .holiday-confetti {
    position: absolute;
    top: 25%; /* РАСПОЛОЖЕНИЕ: Отступ сверху. Можно менять на px или % */
    width: clamp(80px, 18vw, 150px); /* РАЗМЕР: мин 80px, макс 150px, динамически 18% ширины экрана */
    opacity: 0.85;
}

#holidayBackground .holiday-confetti.left {
    left: 0%; /* РАСПОЛОЖЕНИЕ: Отступ слева от края экрана */
}

#holidayBackground .holiday-confetti.right {
    right: 0%; /* РАСПОЛОЖЕНИЕ: Отступ справа от края экрана */
}

#holidayBackground .holiday-ten {
    position: absolute;
    top: 60%; /* РАСПОЛОЖЕНИЕ: Высота десятки. 70% — ближе к земле (было 55%) */
    left: 50%;
    transform: translate(-50%, -50%); /* Оставляем, чтобы 10-ка была чётко по центру */
    width: clamp(250px, 35vw, 700px); /* РАЗМЕР: мин 150px, макс 300px, динамически 35vw */
    opacity: 0.7;
}
/* ------------------------------------- */

/* --- НОВОЕ МЕНЮ ИГРЫ --------------------------------------------------
   Состоит из трёх независимых блоков, позиционируемых абсолютно:
     #topGroup    — логотип + монетка. ВСЕГДА видим. На старте игры
                    группа ЦЕЛИКОМ уменьшается (scale) и слегка едет вверх
                    — фактически "пиннится" к верхней кромке экрана.
     #scoreDisplay — счёт. Виден ТОЛЬКО при body.in-game, под topGroup.
     #menuCenter  — рекорд + Играть + 4 кнопки. Скрывается при body.in-game.
   ===================================================================== */

/* --- Верхняя группа: лого + монетка ----------------------------------
   flex-row: монетка стоит СПРАВА от логотипа, по вертикальному центру.
   align-items: center — монетка попадает на середину высоты лого.
   На старте игры transform применяется к ВСЕЙ группе — лого с монеткой
   уезжают и пиннятся одновременно. */
/* --- Верхняя группа: только логотип, строго по центру -----------------
   Монетка теперь живёт ОТДЕЛЬНО в правом верхнем углу (см. .coins-display
   из секции скинов) и НЕ входит в эту группу — поэтому лого не уезжает
   из центра из-за её ширины. */
#topGroup {
    position: absolute;
    top: 60px;
    left: 50%;
    z-index: 15;
    display: flex;
    align-items: center;
    transform: translateX(-50%);
    transform-origin: top center;
    transition: transform 0.5s ease-in-out, top 0.5s ease-in-out;
    pointer-events: none;
}

#gameLogo {
    width: clamp(180px, 50vw, 280px);
    height: auto;
    image-rendering: pixelated;
}

/* На главной монетка чёрная (на белом/светлом фоне), не белая как на скинах. */
body.game-page #coinsCount {
    color: #1a1a1a;
    text-shadow: none;
    font-size: 18px;
    font-weight: bold;
}

/* --- Состояние "в игре": topGroup уменьшается и едет к верху ---------- */
body.in-game #topGroup {
    top: 12px;                                /* ближе к верху экрана */
    transform: translateX(-50%) scale(0.90);  /* ~2/3 от исходного — лого видно крупнее */
}

/* --- Счёт во время игры — прямо под уменьшенным лого ----------------
   Логотип имеет width: clamp(180px, 50vw, 280px) и аспект ~2.31:1, поэтому
   его высота линейно масштабируется с шириной экрана. Считаем top счёта
   так, чтобы он был ВСЕГДА чуть ниже нижней кромки лого, независимо
   от viewport. Формула учитывает scale в .in-game (см. ниже).
   В числах: 12px (top лого) + 121px (height@max) * 0.9 (scale) + 7px gap ≈ 130
            12 + 78 (height@min) * 0.9 + 7 ≈ 90. Промежуточно: 20 + 19.5vw. */
#scoreDisplay {
    position: absolute;
    top: clamp(90px, calc(20px + 19.5vw), 130px);
    left: 50%;
    transform: translateX(-50%);
    z-index: 10;
    font-size: clamp(15px, 4vw, 18px);
    font-weight: bold;
    color: #14293E;
    text-shadow: 0 0 3px rgba(255, 255, 255, 0.3);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease-in-out 0.2s;  /* появляется чуть позже */
}
body.in-game #scoreDisplay {
    opacity: 1;
}

/* --- Соперник в «гонке с призраком» ----------------------------------
   Строка под счётом: имя соперника и сколько очков до его результата.
   Живёт по тем же правилам, что #scoreDisplay (виден только в игре), но
   остаётся видимым после смерти — на нём печатается итог дуэли.        */
#ghostBadge {
    position: absolute;
    top: calc(clamp(90px, calc(20px + 19.5vw), 130px) + clamp(20px, 5.5vw, 26px));
    left: 50%;
    transform: translateX(-50%);
    z-index: 10;
    white-space: nowrap;
    font-size: clamp(12px, 3.2vw, 15px);
    font-weight: bold;
    color: #5b6b7d;
    text-shadow: 0 0 3px rgba(255, 255, 255, 0.35);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease-in-out 0.2s, color 0.3s ease;
}
body.in-game #ghostBadge,
#ghostBadge.ghost-beaten {
    opacity: 1;
}
/* Соперник пройден — подсвечиваем тем же янтарным, что и победные плашки. */
#ghostBadge.ghost-beaten {
    color: #d98c1f;
}

/* --- Кнопка «побежать наперегонки» в таблице рекордов -----------------
   На кнопке сам хинкалик из игры (спрайт бега, не рисованный значок): жмёшь
   на хинкалика напротив имени — бежишь против этого игрока. Спрайт 95×95
   ужимается до 16 px, поэтому обязателен pixelated — обычное сглаживание
   превращает пиксель-арт в мыло. */
.ghost-challenge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    margin-left: 6px;
    padding: 0;
    flex: 0 0 auto;
    border: 2px solid #333433;
    border-radius: 0;                 /* пиксельный стиль игры — без скруглений */
    background: #8b1811;
    color: #fff;
    cursor: pointer;
    line-height: 0;
    transition: transform 0.12s ease, background 0.12s ease;
}
/* Значок нарисован клетками 1×1 в системе координат 16×16 и выводится ровно
   в 16 px — клетка ложится в целый пиксель экрана и остаётся резкой на любой
   плотности экрана. Спрайт-картинку сюда ставить нельзя: браузер уменьшает
   растр со сглаживанием, и на обычном мониторе хинкалик расплывается. */
.ghost-challenge-ico {
    display: block;
    width: 16px;
    height: 16px;
    shape-rendering: crispEdges;
}
.ghost-challenge:hover,
.ghost-challenge:focus-visible {
    background: #a81e15;
    transform: scale(1.12);
}
.ghost-challenge:active {
    transform: scale(0.95);
}

/* --- Центральная группа: рекорд + Играть + 4 кнопки ------------------ */
/* Расположение: ниже центра экрана, чтобы под логотипом оставался воздух,
   но выше абсолютного низа. Кнопки сразу под "Играть" — небольшой gap.  */
#menuCenter {
    position: absolute;
    /* top: max(50%, 250px) — на высоких экранах группа по центру (50%),
       на коротких пиннится не выше 250px от верха, чтобы не наезжать на
       лого (которое заканчивается на ~181px от верха). */
    top: max(50%, 250px);
    left: 50%;
    /* translateY(-25%) вместо -40% — менее агрессивный подъём, особенно
       когда группа высокая (после увеличенного margin-top у .menu-buttons). */
    transform: translate(-50%, -25%);
    z-index: 15;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
    transition: opacity 0.4s ease-in-out;
}

#recordTextBig {
    font-size: clamp(24px, 6.5vw, 34px);
    font-weight: bold;
    color: #14293E;
    letter-spacing: 0.5px;
    /* Текст всегда в одну строку. Если "Счёт: X | Рекорд: Y" не влезает —
       game.js (fitRecordText) уменьшит font-size так, чтобы влез. */
    white-space: nowrap;
    text-align: center;
}

.play-btn-img {
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    width: clamp(170px, 55vw, 260px);
    transition: transform 0.1s ease;
}
.play-btn-img:active { transform: scale(0.95); }
.play-btn-img img {
    width: 100%;
    height: auto;
    display: block;
    image-rendering: pixelated;
}

/* --- Ряд из 4 кнопок: сразу под "Играть" --------------------------- */
/* --- Ряд из 4 кнопок: чуть ниже "Играть" --------------------------- */
/* ⚙ Чтобы изменить расстояние между Играть и кнопками — меняй margin-top
   ниже. Чтобы поднять/опустить ВСЮ группу (рекорд + Играть + кнопки) —
   крути transform: translate(-50%, -40%) у #menuCenter (см. выше): второй
   процент это вертикальный сдвиг от 50% экрана. -40% = группа выше центра.
   -20% = группа ниже центра. -50% = ровно центр. */
.menu-buttons {
    display: flex;
    align-items: center;
    gap: clamp(8px, 3vw, 14px);
    margin-top: 58px;                         /* ← зазор от Играть (чуть опустили группу) */
}

.menu-btn {
    background: none;
    border: none;
    padding: 0;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    width: clamp(56px, 14vw, 76px);
    height: clamp(56px, 14vw, 76px);
    transition: transform 0.1s ease;
}
.menu-btn:active { transform: scale(0.92); }
.menu-btn img {
    width: 100%;
    height: 100%;
    display: block;
    image-rendering: pixelated;
}

/* Шахматный сдвиг — 2-я и 4-я кнопки чуть ниже, как в макете.          */
.menu-btn:nth-child(2),
.menu-btn:nth-child(4) {
    transform: translateY(10px);
}
.menu-btn:nth-child(2):active,
.menu-btn:nth-child(4):active {
    transform: translateY(10px) scale(0.92);
}

/* --- Скрытое состояние меню (body.in-game) -------------------------- */
body.in-game #menuCenter {
    opacity: 0;
    pointer-events: none;
}

/* topGroup сам по себе не ловит клики, но дочерние элементы должны.
   Никаких pointer-events на детях не нужно, поскольку они по умолчанию
   наследуют — ставим явно для надёжности (в menu-state можно тапать по
   гипотетическим элементам, в in-game — нет смысла). */

/* --- Чекбокс Австралии --- */
#australiaToggle {
    position: absolute;
    bottom: 75px; 
    right: 20px;
    z-index: 100;
    background: rgba(255, 255, 255, 0.85);
    padding: 6px 10px;
    border-radius: 8px;
    font-size: 14px;
    font-weight: bold;
    color: #333;
    box-shadow: 0 2px 5px rgba(0,0,0,0.2);
    display: flex;
    align-items: center;
    gap: 5px;
    cursor: pointer;
    border: 2px solid #1E3E66;
}

#australiaToggle input {
    cursor: pointer;
    width: 16px;
    height: 16px;
    accent-color: #941B1B;
}

/* ============================================================= */
/* --- ОБЩИЕ ЭЛЕМЕНТЫ ИНТЕРФЕЙСА (back-кнопка / тайтл / спейсер) */
/* --- Используются на records и skins. Достижения пока на своих */
/* --- старых классах (.achievements-back-btn и т.п.) — пара     */
/* --- стилей продублирована для совместимости.                  */
/* ============================================================= */

.page-back-btn {
    flex-shrink: 0;
    width: 48px;
    height: 48px;
    background: transparent;
    border: none;
    padding: 0;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: transform 0.1s ease;
}
.page-back-btn:active { transform: scale(0.9); }
.page-back-btn img {
    width: 100%;
    height: 100%;
    image-rendering: pixelated;
    pointer-events: none;
}

.page-title-img {
    height: clamp(48px, 13vw, 64px);
    width: auto;
    max-width: 100%;
    pointer-events: none;
    image-rendering: pixelated;
}

.page-header-spacer {
    flex-shrink: 0;
    width: 48px;
    height: 48px;
    visibility: hidden;
}

/* ============================================================= */
/* --- СТИЛИ ДЛЯ СТРАНИЦЫ РЕКОРДОВ (records.html) ---           */
/* ============================================================= */

body.records-page {
    background: #d8d8d8;
    min-height: 100vh;
    padding: 12px 8px 24px;
    box-sizing: border-box;
    overflow-x: hidden;
    overflow-y: auto;
}

/* --- Внутренний «лист»: белый фон + пиксельные углы через clip-path ----- */
/* Раньше лист был растровой картинкой (sheet_bg.svg), которая тянулась на всю
   высоту и плыла на длинных страницах; border-image через SVG давал сабпиксельный
   шов. Теперь это просто белый блок, которому clip-path вырезает пиксельные
   ступенчатые углы. Углы фиксированы (в px), центр тянется свободно при любой
   высоте — без картинок, без швов, всегда чётко. Старый <img class="*-sheet-bg">
   скрыт (display:none), правок HTML не требуется.
   Размер угла — переменная --pixel-corner (см. :root): меняешь S — меняется
   ступенька у ВСЕХ элементов разом (лист + таблица рекордов). */
.records-sheet,
.achievements-sheet,
.sound-sheet {
    background: #ffffff;
    clip-path: var(--pixel-corner);
}
.records-sheet-bg,
.achievements-sheet-bg,
.sound-sheet-bg {
    display: none;
}

.records-sheet {
    position: relative;
    padding: 16px 14px 20px;
    max-width: 600px;
    margin: 0 auto;
    box-sizing: border-box;
}

/* Поднимаем содержимое над абсолютным sheet_bg */
.records-header,
.records-sheet > #recordsContainer {
    position: relative;
    z-index: 1;
}

/* --- Шапка: 3 flex-айтема (кнопка | тайтл | спейсер) ------------------ */
.records-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 18px;
    min-height: 56px;
}

/* --- Контейнер с таблицами ------------------------------------------- */
/* Внутри листа отключаем собственный фон/рамку — sheet_bg уже держит   */
/* визуальную форму. Оставляем layout для самих таблиц.                  */
.records-sheet #recordsContainer {
    background: none;
    border-radius: 0;
    box-shadow: none;
    padding: 0;
    text-align: center;
    width: 100%;
    max-width: none;
}

/* --- Поиск игрока на экране рекордов --------------------------------------
   Строка над таблицами: найти знакомого по имени или номеру и позвать на
   гонку, не дожидаясь, пока он попадёт в тройку лидеров. Углы пиксельные,
   как у листов и таблиц (--pixel-corner), рамка — фирменная бордовая. */
.records-search {
    display: flex;
    align-items: center;
    gap: 6px;
    margin: 0 auto 14px;
    padding: 6px 8px;
    background: #ffffff;
    border: 2px solid #941B1B;
    clip-path: var(--pixel-corner);
}
.records-search-ico { color: #941B1B; flex-shrink: 0; }
.records-search input {
    flex: 1 1 auto;
    min-width: 0;
    border: none;
    outline: none;
    background: transparent;
    font-family: Arial, sans-serif;
    font-size: 14px;
    color: #333;
    padding: 4px 2px;
}
.records-search input::placeholder { color: #9aa4ae; }
#playerSearchClear {
    flex-shrink: 0;
    border: none;
    background: transparent;
    color: #941B1B;
    cursor: pointer;
    padding: 4px;
    display: inline-flex;
    align-items: center;
}
/* Пустой результат и ошибка поиска — тем же тоном, что подписи в таблицах. */
.search-note {
    text-align: center;
    color: #555;
    font-size: 14px;
    margin-bottom: 16px;
}

#recordsContainer h2, #searchResults h2 { color: #333; margin-bottom: 10px; }
#recordsContainer table { margin: auto; margin-bottom: 20px; border-collapse: collapse; width: 100%; clip-path: var(--pixel-corner); table-layout: fixed; }
#recordsContainer th, #recordsContainer td { padding: 8px 4px; text-align: center; border: 1px solid #ddd; font-size: 14px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
#recordsContainer th:nth-child(1), #recordsContainer td:nth-child(1) { width: 12%; }
#recordsContainer th:nth-child(2), #recordsContainer td:nth-child(2) { width: 48%; text-align: left; }
#recordsContainer th:nth-child(3), #recordsContainer td:nth-child(3) { width: 20%; }
#recordsContainer th:nth-child(4), #recordsContainer td:nth-child(4) { width: 20%; }
#recordsContainer th { background: #941B1B; color: white; font-weight: bold; font-size: 13px; }
#recordsContainer tr:nth-child(even) { background-color: #f9f9f9; }
#recordsContainer tr:hover { background-color: #f1f1f1; }

/* ============================================================= */
/* --- СТИЛИ ДЛЯ СТРАНИЦЫ ЗВУКА (sound.html) ---                */
/* ============================================================= */

body.sound-page {
    background: #d8d8d8;
    min-height: 100vh;
    padding: 12px 8px 24px;
    box-sizing: border-box;
}

.sound-sheet {
    position: relative;
    padding: 16px 14px 20px;
    max-width: 600px;
    margin: 0 auto;
    box-sizing: border-box;
}
.sound-header,
.audio-rows {
    position: relative;
    z-index: 1;
}
.sound-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 28px;
    min-height: 56px;
}
.sound-title-img {
    height: clamp(48px, 13vw, 64px);
    width: auto;
    image-rendering: pixelated;
}

/* --- Ряды слайдеров: метка сверху, под ней слайдер + цифра справа --- */
.audio-rows {
    padding: 16px 8px 24px;
    display: flex;
    flex-direction: column;
    gap: clamp(28px, 6vw, 44px);
}
.audio-row {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 14px;
}
.audio-row label {
    font-family: 'Polyplast', Arial, sans-serif;
    font-weight: 500;                  /* Polyplast Medium */
    font-size: clamp(20px, 5.5vw, 26px);
    color: #1a1a1a;
    user-select: none;
}
.audio-slider-row {
    display: flex;
    align-items: center;
    gap: 14px;
    width: 100%;
    max-width: 380px;
}

/* --- Сам слайдер: native range с кастомным треком и SVG-кнопкой ---- */
.audio-slider {
    flex: 1;
    -webkit-appearance: none;
    appearance: none;
    height: 6px;
    margin: 0;
    padding: 0;
    border: none;
    border-radius: 0;
    outline: none;
    cursor: pointer;
    /* iOS: убираем полупрозрачную квадратную подсветку-бокс при тапе по ползунку
       (на других устройствах её нет). */
    -webkit-tap-highlight-color: transparent;
    /* Заливка слева от бегунка — тёмная, справа — светлая.
       Процент задаётся JS через --value (например 30%). */
    background: linear-gradient(to right,
        #1a1a1a 0%,
        #1a1a1a var(--value, 50%),
        #d4d4d4 var(--value, 50%),
        #d4d4d4 100%);
}
.audio-slider:focus { outline: none; }
/* Бегунок: используем SVG (Ресурс 3) как фоновое изображение для thumb */
.audio-slider::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 22px;
    height: 22px;
    background: url('assets/img/ui/audio_knob.svg') no-repeat center;
    background-size: contain;
    border: none;
    border-radius: 0;
    box-shadow: none;     /* iOS рисует тень/рамку на thumb даже при appearance:none */
    cursor: pointer;
    margin-top: 0;
}
.audio-slider::-moz-range-thumb {
    width: 22px;
    height: 22px;
    background: url('assets/img/ui/audio_knob.svg') no-repeat center;
    background-size: contain;
    border: none;
    border-radius: 0;
    cursor: pointer;
}
/* Firefox требует отдельное правило для трека */
.audio-slider::-moz-range-track {
    height: 6px;
    background: transparent;       /* фон уже на самом input через gradient */
    border: none;
}

/* --- Цифровое значение справа --- */
.audio-value {
    font-family: 'Polyplast', Arial, sans-serif;
    font-weight: 500;
    font-size: clamp(22px, 5.5vw, 28px);
    color: #941B1B;
    min-width: 48px;
    text-align: right;
    user-select: none;
}

.name-wrapper { display: flex; align-items: center; width: 100%; }
.platform-icon { width: 16px; height: 16px; margin-right: 5px; border-radius: 3px; flex-shrink: 0; }
.player-name { text-align: left; flex-grow: 1; display: block; overflow: hidden; text-overflow: ellipsis; }

#recordsContainer tfoot tr.user-rank-header td { text-align: center; font-weight: bold; color: #555; background-color: #f8f8f8; border-top: 2px solid #941B1B; border-bottom: 1px dashed #ccc; padding: 8px; }
#recordsContainer tfoot tr.user-rank-row td { font-weight: bold; color: #1E3E66; background-color: #e9f5ff; border-bottom: 2px solid #941B1B; }

.floating-message {
    position: absolute; left: 50%; transform: translateX(-50%); top: 200px; 
    z-index: 9; color: #14293E; font-size: 14px; font-weight: bold; text-align: center;
    width: 90%; animation: floatAndFade 3s ease-out forwards;
}

@keyframes floatAndFade {
    0% { opacity: 0; transform: translate(-50%, 0); }
    20% { opacity: 1; }
    80% { opacity: 1; transform: translate(-50%, 40px); }
    100% { opacity: 0; transform: translate(-50%, 50px); }
}

@media (orientation: landscape) and (max-height: 500px) {
    /* В landscape высота — главное ограничение, поэтому масштабируем
       все элементы относительно vh, а не vw. */

    body.game-page #gameLogo { width: clamp(110px, 32vh, 180px); }
    body.game-page #recordTextBig { font-size: clamp(15px, 4.5vh, 22px); }
    body.game-page .play-btn-img { width: clamp(120px, 35vh, 180px); }
    body.game-page .menu-btn { width: clamp(42px, 11vh, 56px); height: clamp(42px, 11vh, 56px); }
    body.game-page .menu-buttons { margin-top: 28px; }
    body.game-page .record-play-group,
    body.game-page #menuCenter { gap: 12px; }

    body.game-page #topGroup { top: 8px; }
    body.game-page.in-game #topGroup {
        top: 4px;
        transform: translateX(-50%) scale(0.75);
    }

    /* Счёт сразу под уменьшенным лого */
    body.game-page #scoreDisplay {
        font-size: 13px;
        top: clamp(50px, 26vh, 90px);
    }

    /* Меню точно в центре viewport */
    body.game-page #menuCenter {
        top: 50%;
        transform: translate(-50%, -50%);
    }

    /* Монетка справа сверху — компактно */
    body.game-page .coins-display { top: 22px; right: 12px; }
    body.game-page .coins-display img { width: 22px; height: 22px; margin-right: 6px; }
    body.game-page #coinsCount { font-size: 16px; }

    /* На странице скинов плашка "Скины" слишком крупная и перекрывает
       контент в landscape — убираем её. Кнопка назад и монетка остаются. */
    #screen-skins .skins-title-banner { display: none; }   /* SPA: было body.skins-page */

    .floating-message { top: 100px; }

    /* --- ИСПРАВЛЕНИЯ ПРАЗДНИЧНОГО ВИЗУАЛА ДЛЯ ГОРИЗОНТАЛЬНОГО РЕЖИМА --- */
    #holidayBackground .holiday-confetti {
        top: 5%; /* Поднимаем конфетти к самому верху */
        width: clamp(30px, 12vw, 100px); /* Делаем конфетти чуть меньше */
    }
    
    #holidayBackground .holiday-ten {
        top: 45%; /* Поднимаем 10-ку выше, чтобы не тонула в земле */
        width: clamp(100px, 20vw, 300px); /* Уменьшаем размер 10-ки, чтобы влезала в узкий экран */
    }
}

/* ========================================================= */
/* --- СТИЛИ ДЛЯ СТРАНИЦЫ ВЫБОРА СКИНОВ ---                  */
/* ========================================================= */

body.skins-page {
    overflow: hidden;
    position: relative;
    height: 100vh;
    width: 100vw;
    background-color: #f0f0f0; 
    display: flex;
    justify-content: center;
    align-items: center;
}

/* UI Блок монет */
.coins-display {
    position: absolute;
    /* По вертикали выравниваем по той же линии, что и .skins-back-btn
       и .skins-title-banner — центр на y=40. */
    top: 40px;
    right: 20px;
    transform: translateY(-50%);
    display: flex;
    align-items: center;
    z-index: 50; 
}

.coins-display img { width: 24px; height: 24px; margin-right: 8px; }
#skinsCoinsCount { color: #ffffff; font-size: 18px; font-weight: bold; text-shadow: 1px 1px 2px rgba(0,0,0,0.5); }

/* 1. Основной фон */
.skins-bg {
    position: absolute; bottom: 0; left: 0; width: 100%; height: 400px; 
    background-image: url('assets/img/skins/background.webp?v=1.4');
    background-repeat: repeat-x; background-position: bottom center; background-size: auto 400px; z-index: 1;
}

/* 2. Центральная сцена-контейнер */
.skins-scene-center {
    position: absolute; bottom: 80px; left: 50%; transform: translateX(-50%); width: 300px; height: 400px; z-index: 10;
}

.skin-viewport { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 15; }

.skin-stage {
    position: absolute; top: 0; left: 0; width: 100%; height: 100%;
    display: flex; flex-direction: column; align-items: center; justify-content: flex-end; padding-bottom: 0px; 
    transition: transform 0.4s ease-in-out, opacity 0.4s ease-in-out; will-change: transform, opacity; pointer-events: none;
}

.skin-stage.active { transform: translateX(0); opacity: 1; z-index: 20; }
.skin-stage.next { transform: translateX(100vw); opacity: 0; z-index: 15; }

.skin-info-block {
    position: absolute; bottom: -50px; left: 0; width: 100%; display: flex; flex-direction: column; align-items: center; z-index: 40; pointer-events: auto; 
}
.skin-name-display {
    color: #4a4a4a; font-weight: bold; font-size: 20px; text-shadow: 1px 1px 2px rgba(255, 255, 255, 0.6); margin-bottom: 10px; text-align: center;
}

.action-btn { padding: 10px 20px; font-size: 16px; min-width: 140px; }

.skin-character { position: relative; width: 110px; height: auto; z-index: 12; margin-bottom: 40px; }
.skin-shadow { position: absolute; bottom: 30px; width: 160px; height: auto; z-index: 11; }

.skins-scene-center.anim-next-out #stageCurrent { transform: translateX(-100vw); opacity: 0; }
.skins-scene-center.anim-next-in #stageNext { transform: translateX(0); opacity: 1; }
.skins-scene-center.anim-prev-out #stageCurrent { transform: translateX(100vw); opacity: 0; }
.skins-scene-center.anim-prev-in #stageNext { transform: translateX(0); opacity: 1; }
.skins-scene-center.anim-prev-prepare #stageNext { transform: translateX(-100vw); opacity: 0; transition: none; }

.dark-overlay {
    position: absolute; bottom: -170px; left: 50%; transform: translateX(-50%) translateZ(0); width: 200vw; height: 200vh;
    -webkit-backface-visibility: hidden; backface-visibility: hidden;
    background-color: rgba(123, 122, 122, 0.75); z-index: 9; pointer-events: none;
    -webkit-mask-image: url('assets/img/skins/mask.webp?v=1.3'), linear-gradient(#fff, #fff);
    -webkit-mask-position: center bottom 160px, center center; -webkit-mask-size: 300px auto, 100% 100%; 
    -webkit-mask-repeat: no-repeat, no-repeat; -webkit-mask-composite: destination-out;
    mask-image: url('assets/img/skins/mask.webp?v=1.3'), linear-gradient(#fff, #fff);
    mask-position: center bottom 160px, center center; mask-size: 300px auto, 100% 100%;
    mask-repeat: no-repeat, no-repeat; mask-composite: exclude; 
}

/* iOS Safari: при transform-анимации карусели скинов замаскированное серое
   затемнение (.dark-overlay) из-за бага композитинга в position:fixed-оверлее
   наезжало на верхнюю панель — она серела и мигала. Поднимаем верхнюю панель на
   собственные стабильные GPU-слои (translateZ + backface-visibility): тогда iOS
   надёжно держит их НАД сценой по z-index. Существующие трансформы сохраняем. */
#screen-skins .coins-display,
#screen-skins .skins-title-banner,
#screen-skins .skins-back-btn {
    -webkit-backface-visibility: hidden;
    backface-visibility: hidden;
}
#screen-skins .coins-display      { transform: translateY(-50%) translateZ(0); }
#screen-skins .skins-title-banner { transform: translate(-50%, -50%) translateZ(0); }
#screen-skins .skins-back-btn     { transform: translateZ(0); }

.fx-penumbra { position: absolute; bottom: -3px; left: 50%; transform: translateX(-50%); width: 300px; height: auto; z-index: 10; pointer-events: none; }

.skins-ui-arrows {
    position: absolute; bottom: 140px; left: 50%; transform: translateX(-50%); width: 100%; max-width: 550px; 
    display: flex; justify-content: space-between; padding: 0 30px; box-sizing: border-box; z-index: 20; pointer-events: none; 
}

.nav-arrow {
    pointer-events: auto; background: none; border: none; cursor: pointer; padding: 10px; transition: transform 0.1s ease; user-select: none; outline: none; -webkit-tap-highlight-color: transparent; 
}
.nav-arrow:active { transform: scale(0.85) !important; }
.nav-arrow img { width: 55px; height: auto; }

.back-btn-wrapper { position: absolute; bottom: 30px; left: 0; width: 100%; display: flex; justify-content: center; z-index: 30; }

.stars-area { position: absolute; bottom: 200px; left: 50%; transform: translateX(-50%); width: 100vw; max-width: 400px; height: 300px; z-index: 13; pointer-events: none; }

.star-sprite { position: absolute; pointer-events: none; user-select: none; opacity: 0; animation: starFadeIn 0.5s ease-out forwards; }
@keyframes starFadeIn { from { opacity: 0; transform: scale(0); } to { opacity: 0.9; transform: scale(1); } }

/* ============================================================= */
/* --- СТИЛИ ДЛЯ СТРАНИЦЫ ДОСТИЖЕНИЙ ---                         */
/* ============================================================= */

/* --- Шрифт Polyplast: одно семейство, два начертания ------------------- */
/* Browser сам подберёт нужный файл по font-weight (500=Medium, 400=Regular). */
/* Только OTF. Файлы woff2/woff на сервере собраны кривым конвертером (woff раздут
   до ~576КБ при otf ~210КБ), и Safari такой woff2 отвергает → текст откатывался на
   системный шрифт (на iPhone «шрифт загрузился, но нигде не отображается»). OTF —
   исходный валидный файл, читается и Safari, и Chrome, поэтому woff2/woff здесь
   больше не подключаем (их файлы можно удалить). Сделаешь правильные woff2 —
   добавишь их первыми в src для меньшего веса. */
@font-face {
    font-family: 'Polyplast';
    src: url('assets/fonts/Polyplast-Semibold.otf') format('opentype');
    font-weight: 500;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Polyplast';
    src: url('assets/fonts/Polyplast-Regular.otf') format('opentype');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}
/* font-weight:bold (700) → Semibold-файл (своего Bold нет; иначе Safari откатывает
   жирный текст на системный). */
@font-face {
    font-family: 'Polyplast';
    src: url('assets/fonts/Polyplast-Semibold.otf') format('opentype');
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

body.achievements-page {
    background: #d8d8d8;             /* внешний фон страницы — чуть темнее */
    min-height: 100vh;
    padding: 12px 8px 24px;
    box-sizing: border-box;
    overflow-x: hidden;
    overflow-y: auto;
}

/* --- Внутренний «лист» (фон подложен SVG-картинкой sheet_bg.svg) -------- */
.achievements-sheet {
    position: relative;              /* якорь для абсолютной кнопки и SVG-фона */
    padding: 16px 14px 20px;
    max-width: 600px;
    margin: 0 auto;
    box-sizing: border-box;
}

/* Header и список нужно поднять над абсолютно-позиционированным sheet-bg —
   иначе CSS-правила стэкинга кладут positioned-элементы поверх обычных. */
.achievements-header,
.achievements-list {
    position: relative;
    z-index: 1;
}

/* --- Кнопка «назад»: обычный flex-item, выравнивается по общему центру
       с плашкой «Достижения» через align-items: center на header --------- */
.achievements-back-btn {
    flex-shrink: 0;
    width: 48px;
    height: 48px;
    background: transparent;
    border: none;
    padding: 0;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: transform 0.1s ease;
}
.achievements-back-btn:active { transform: scale(0.9); }
.achievements-back-btn img {
    width: 100%;
    height: 100%;
    image-rendering: pixelated;
    pointer-events: none;
}

/* --- Шапка: 3 flex-айтема (кнопка | плашка | спейсер) с равной кнопке
       шириной по бокам — это даёт идеальное центрирование плашки и
       выравнивание её центра с центром кнопки по вертикали ------------- */
.achievements-header {
    display: flex;
    align-items: center;              /* общий центр по вертикали */
    justify-content: space-between;   /* кнопка ← край, спейсер → край */
    margin-bottom: 22px;
    min-height: 56px;
}

.achievements-header-spacer {
    flex-shrink: 0;
    width: 48px;                      /* ровно как back-btn — для симметрии */
    height: 48px;
    visibility: hidden;
}

.achievements-title-img {
    height: clamp(48px, 13vw, 64px);
    width: auto;
    max-width: 100%;
    pointer-events: none;
    image-rendering: pixelated;
}

/* --- Список карточек ---------------------------------------------------- */
.achievements-list {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

/* --- Сообщение об ошибке загрузки -------------------------------------- */
.ach-load-error {
    text-align: center;
    padding: 30px 10px;
    color: #888;
    font-family: Arial, sans-serif;
    font-size: 14px;
}

/* ============================================================= */
/* --- БАЗОВАЯ КАРТОЧКА ДОСТИЖЕНИЯ ------------------------------*/
/* ============================================================= */
/*
   Форма карточки (рамка с пиксельными уголками) рендерится как
   inline-SVG поверх .achievement-card, а контент сидит над ней
   через z-index. Цвет заливки SVG берётся из CSS-переменной
   --ach-card-fill, которую мы переопределяем для разных состояний.
*/
.achievement-card {
    --ach-card-fill: #e2e2e2;        /* серый по умолчанию */
    position: relative;
    width: 100%;
    box-sizing: border-box;
}

.ach-card-bg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    pointer-events: none;
    display: block;
}
.ach-card-bg path {
    fill: var(--ach-card-fill);
}

.ach-card-inner {
    position: relative;
    z-index: 1;                       /* контент над фоновой формой */
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 16px 16px;
    box-sizing: border-box;
    background: transparent;
}

/* --- Состояние «получено» ---------------------------------------------- */
/* Светло-серый, чтобы карточка выделялась на фоне белого листа,
   но была заметно светлее не полученных (#e2e2e2). */
.achievement-card.state-claimed {
    --ach-card-fill: #78B551;
}

/* --- Состояние «готово к получению» ------------------------------------ */
/* Вся карточка плавно увеличивается-уменьшается и подсвечивается.        */
.achievement-card.state-ready {
    animation: achievementReadyPulse 1.15s ease-in-out infinite;
    transform-origin: center center;
    cursor: pointer;
}

@keyframes achievementReadyPulse {
    0%, 100% {
        transform: scale(1);
        filter: brightness(1) saturate(1);
    }
    50% {
        transform: scale(1.035);
        filter: brightness(1.18) saturate(1.15);
    }
}

/* ============================================================= */
/* --- ВНУТРЕННИЕ ЭЛЕМЕНТЫ КАРТОЧКИ ------------------------------*/
/* ============================================================= */

.ach-icon {
    flex-shrink: 0;
    width: clamp(48px, 14vw, 64px);
    height: clamp(48px, 14vw, 64px);
    display: flex;
    align-items: center;
    justify-content: center;
}
.ach-icon img {
    width: 100%;
    height: 100%;
    image-rendering: pixelated;
    pointer-events: none;
}

.ach-info {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    justify-content: center;          /* блок целиком центрирован по вертикали */
    /* gap убран — расстояния задаются вручную через margin-top на детях,
       потому что они между разными парами элементов разные (41 / 25). */
}

.ach-title {
    font-family: 'Polyplast', Arial, sans-serif;
    font-weight: 500;                 /* Polyplast-Medium */
    font-size: clamp(15px, 4.5vw, 19px);
    color: #1a1a1a;
    line-height: 1.15;
    word-wrap: break-word;
    overflow-wrap: break-word;
    hyphens: auto;
}

.ach-progress-text {
    font-family: 'Polyplast', Arial, sans-serif;
    font-weight: 400;                 /* Polyplast-Regular */
    font-size: clamp(11px, 3.2vw, 13px);
    color: #555;
    margin-top: 5px;                 /* отступ от названия (пропорция 41:25 ≈ 13:8) */
}

.ach-claimed-label {
    font-family: 'Polyplast', Arial, sans-serif;
    font-weight: 500;                 /* Polyplast-Medium — выделяет финальный статус */
    font-size: clamp(11px, 3.2vw, 13px);
    color: #1E3E66;
    margin-top: 5px;                  /* выровнено с прогресс-текстом на in_progress */
}

/* --- Прогресс-бар ------------------------------------------------------- */
.ach-progress-bar {
    width: 100%;
    height: 6px;
    background: #a0a0a0;
    margin-top: 4px;                  /* отступ от текста "X/Y завершено" */
    overflow: hidden;
    border-radius: 1px;
    position: relative;
}
.ach-progress-fill {
    height: 100%;
    background: #1a1a1a;
    transition: width 0.6s ease-out;
}

/* --- Награда (монетка + множитель) ------------------------------------- */
.ach-reward {
    flex-shrink: 0;
    position: relative;
    width: clamp(46px, 13vw, 60px);
    height: clamp(46px, 13vw, 60px);
    display: flex;
    align-items: center;
    justify-content: center;
}
.ach-reward-coin {
    width: 100%;
    height: 100%;
    image-rendering: pixelated;
    pointer-events: none;
}
.ach-reward-skin {
    width: 100%;
    height: 100%;
    object-fit: contain;
    image-rendering: pixelated;
    pointer-events: none;
}
/* --- Подписочные достижения: кнопки «Подписаться» / «Проверить» --- */
.ach-sub-actions {
    display: flex;
    gap: clamp(6px, 2vw, 10px);
    align-items: center;
    margin-top: 4px;
    flex-wrap: wrap;
}

/* Кнопка в форме рамки card_frame.svg. Сама рамка — SVG-подложка (.ach-sub-frame),
   текст — поверх (.ach-sub-frame-label). Цвет рамки задаётся заливкой path. */
.ach-sub-btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: clamp(5px, 1.5vw, 7px) clamp(14px, 4vw, 20px);
    min-width: clamp(96px, 30vw, 130px);
    border: none;
    background: none;
    cursor: pointer;
    text-decoration: none;
    line-height: 1.1;
    /* лёгкая отзывчивость на нажатие */
    transition: transform 0.06s ease;
}
.ach-sub-btn:active {
    transform: translateY(1px) scale(0.98);
}
.ach-sub-frame {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    pointer-events: none;
    display: block;
    /* мягкая тень под плашку-кнопку */
    filter: drop-shadow(0 2px 0 rgba(0, 0, 0, 0.18));
}
.ach-sub-frame-label {
    position: relative;
    z-index: 1;
    font-family: inherit;
    font-size: clamp(11px, 3vw, 13px);
    font-weight: bold;
    white-space: nowrap;
    pointer-events: none;
}
/* Цвета рамок: «Подписаться» — голубой, «Проверить» — жёлтый. */
.ach-sub-link  .ach-sub-frame path { fill: #2aabee; }
.ach-sub-link  .ach-sub-frame-label { color: #fff; }
.ach-sub-check .ach-sub-frame path { fill: #f0c419; }
.ach-sub-check .ach-sub-frame-label { color: #1a1a1a; }

.ach-sub-check:disabled {
    cursor: default;
}
.ach-sub-check:disabled .ach-sub-frame { filter: none; opacity: 0.75; }
.ach-reward-mult {
    position: absolute;
    bottom: -2px;
    right: -6px;
    /* Подложка-пилюля под текстом — повторяет форму Ресурс.svg. */
    background: #f0f0f0;
    border-radius: 999px;
    padding: 2px 8px;
    font-family: Arial, sans-serif;
    font-size: clamp(11px, 3vw, 13px);
    font-weight: bold;
    color: #1a1a1a;
    line-height: 1.1;
    white-space: nowrap;
}

/* =============================================================== */
/* --- ОПИСАНИЕ ДОСТИЖЕНИЯ (флип по тапу) -------------------------- */
/* =============================================================== */
/*
   Оверлей с текстом «как получить» сидит абсолютом поверх
   .ach-card-inner и в обычном состоянии невидим (opacity: 0,
   pointer-events: none). При клике по карточке навешивается класс
   .show-description — контент-блок плавно скрывается, описание
   плавно проявляется. Высоту карточки определяет ach-card-inner —
   поэтому при флипе геометрия SVG-рамки не прыгает.
   Тап по другой карточке закроет это описание (логика в achievements.js).
   Тап в пустое место — тоже (document-level handler там же).
*/
.achievement-card .ach-card-inner {
    transition: opacity 0.25s ease;
}
.achievement-card .ach-description {
    position: absolute;
    inset: 0;
    z-index: 2;
    padding: 14px 22px;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    font-family: 'Polyplast', Arial, sans-serif;
    font-weight: 400;
    font-size: clamp(12px, 3.6vw, 15px);
    line-height: 1.3;
    color: #1a1a1a;
    /* В JSON-описаниях допустим \n — переносы строки сохраняем. */
    white-space: pre-line;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.25s ease;
}
.achievement-card.show-description .ach-card-inner {
    opacity: 0;
    pointer-events: none;
}
.achievement-card.show-description .ach-description {
    opacity: 1;
}

/* =============================================================== */
/* --- ПУЛЬС КНОПКИ ДОСТИЖЕНИЙ В ГЛАВНОМ МЕНЮ --------------------- */
/* =============================================================== */
/*
   Когда у юзера есть незабранная награда (флаг
   userProfile.has_unclaimed_achievements из get_profile.php),
   игровой код навешивает на #achievementsBtn класс .has-unclaimed.
   Анимация ритмически совпадает с пульсом state-ready на карточках.

   Особенность: achievementsBtn — это 2-й menu-btn, у него
   статически выставлен transform: translateY(10px) (шахматный
   сдвиг макета). Поэтому keyframes ниже включают этот сдвиг
   в свои значения transform, иначе кнопка прыгнет вверх на
   время анимации.
*/
#achievementsBtn.has-unclaimed {
    animation: achievementBtnReadyPulse 1.15s ease-in-out infinite;
    transform-origin: center center;
}
@keyframes achievementBtnReadyPulse {
    0%, 100% {
        transform: translateY(10px) scale(1);
        filter: brightness(1) saturate(1);
    }
    50% {
        transform: translateY(10px) scale(1.06);
        filter: brightness(1.18) saturate(1.15);
    }
}

/* Кнопка «Рекорды» на главной мигает, если есть НЕпросмотренный промокод.
   recordsBtn — тоже 4-й menu-btn с resting transform: translateY(10px),
   поэтому переиспользуем тот же кадр пульса, что и у достижений. */
@keyframes recordsBtnPromoPulse {
    0%, 100% {
        transform: translateY(10px) scale(1);
        filter: brightness(1) saturate(1);
    }
    50% {
        transform: translateY(10px) scale(1.06);
        filter: brightness(1.18) saturate(1.15);
    }
}
#recordsBtn.has-promo {
    animation: recordsBtnPromoPulse 1.15s ease-in-out infinite !important;
    transform-origin: center center;
}

/* =============================================================== */
/* --- КНОПКА «ОТКРЫВАЕТСЯ ЗА ДОСТИЖЕНИЕ» НА СТРАНИЦЕ СКИНОВ ------ */
/* =============================================================== */
/*
   Скины с полем unlockedBy в config.json купить за монеты нельзя —
   только разблокировать соответствующим достижением. Текст
   «Открывается за достижение» длинный, ужимаем шрифт и разрешаем
   перенос на две строки. Класс навешивает skins.js (updateStageUI).
*/
.action-btn.action-btn--locked {
    font-size: 13px;
    line-height: 1.15;
    padding: 8px 12px;
    white-space: normal;
    cursor: not-allowed;
}
/* ================================================================= */
/* === Промокоды на странице рекордов (Этап 3) ===================== */
/* ================================================================= */
/* Кнопка-тикет справа от заголовка; мигает при наличии невыданного кода
   (по аналогии с пульсом кнопки достижений). */
.page-ticket-btn {
    flex-shrink: 0;
    width: 48px;
    height: 48px;
    background: transparent;
    border: none;
    padding: 0;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    transition: transform 0.1s ease;
}
.page-ticket-btn:active { transform: scale(0.9); }
.page-ticket-btn img {
    width: 100%;
    height: 100%;
    image-rendering: pixelated;
    pointer-events: none;
}
.page-ticket-btn.has-new {
    animation: ticketReadyPulse 1.15s ease-in-out infinite;
    transform-origin: center center;
}
@keyframes ticketReadyPulse {
    0%, 100% { transform: scale(1);    filter: brightness(1)   saturate(1); }
    50%      { transform: scale(1.12); filter: brightness(1.2) saturate(1.15); }
}

/* Затемнённый фон + окно поверх страницы. */
.promo-overlay {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.45);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 24px 14px;
    z-index: 1000;
    overflow-y: auto;
}
/* hidden-атрибут должен прятать оверлей несмотря на display:flex выше. */
.promo-overlay[hidden] { display: none; }

/* Окно — та же пиксельная панель (clip-path), но чуть ТЕМНЕЕ белых листов,
   чтобы выделяться на фоне таблиц. */
.promo-window {
    position: relative;
    background: #e7e7e2;
    clip-path: var(--pixel-corner);
    max-width: 460px;
    width: 100%;
    margin: auto 0;
    padding: 0 16px 20px;
    box-sizing: border-box;
    font-family: 'Polyplast', Arial, sans-serif;
}

/* Кнопка сворачивания — прижата к самому верху окна, врастает в верхнюю
   границу: верхние углы прямые, пиксельные только нижние. Белая, со стрелкой
   вверх (готовый шеврон, без поворота). */
.promo-close {
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 0 auto 16px;
    width: 70%;
    max-width: 260px;
    height: 38px;
    background: #ffffff;
    border: none;
    padding: 0;
    cursor: pointer;
    clip-path: var(--pixel-corner-bottom);
    -webkit-tap-highlight-color: transparent;
    transition: transform 0.1s ease, filter 0.1s ease;
}
.promo-close:active { transform: scale(0.97); filter: brightness(0.96); }
.promo-close img {
    width: auto;
    height: 22px;
    image-rendering: pixelated;
    pointer-events: none;
}

.promo-intro {
    text-align: center;
    font-size: 15px;
    font-weight: bold;
    color: #3a2b22;
    margin: 6px 8px 14px;
    line-height: 1.3;
}
.promo-list { display: flex; flex-direction: column; gap: 10px; }
.promo-empty {
    text-align: center; color: #8a7d72; font-size: 14px;
    padding: 16px 0; line-height: 1.4;
}

/* Карточка кода — каноничные пиксельные углы (без скруглений). */
.promo-card {
    background: #fffdf8;
    clip-path: var(--pixel-corner);
    padding: 12px 14px;
    text-align: center;
}
.promo-card-prize { font-size: 15px; font-weight: bold; color: #8b1811; }
.promo-card-ctx   { font-size: 12px; color: #8a7d72; margin-top: 2px; }
.promo-card-code  {
    font-size: 20px;
    font-weight: bold;
    letter-spacing: 2px;
    color: #1a1a1a;
    margin: 8px 0 4px;
    user-select: text;
    -webkit-user-select: text;
}
.promo-card-exp   { font-size: 12px; color: #9a8d80; }

/* Кнопки в форме рамки card_frame.svg (как кнопки подписки на достижениях):
   SVG-подложка .promo-btn-frame + текст .promo-btn-label поверх.
   «использовать» — красная рамка, «вернуть» — серая. */
.promo-use-btn, .promo-revert-btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-top: 10px;
    padding: 8px 22px;
    border: none;
    background: none;
    cursor: pointer;
    line-height: 1.1;
    transition: transform 0.06s ease;
}
.promo-use-btn:active, .promo-revert-btn:active { transform: translateY(1px) scale(0.98); }
.promo-btn-frame {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    pointer-events: none;
    display: block;
    filter: drop-shadow(0 2px 0 rgba(0, 0, 0, 0.18));
}
.promo-btn-label {
    position: relative;
    z-index: 1;
    font-family: inherit;
    font-size: 13px;
    font-weight: bold;
    white-space: nowrap;
    pointer-events: none;
}
.promo-use-btn    .promo-btn-frame path { fill: #8b1811; }
.promo-use-btn    .promo-btn-label { color: #fff; }
.promo-revert-btn .promo-btn-frame path { fill: #cfc7bd; }
.promo-revert-btn .promo-btn-label { color: #6f6f6f; }

/* Использованный код — серый (сама карточка). */
.promo-card.used { opacity: 0.65; }
.promo-card.used .promo-card-prize { color: #777; }
.promo-card.used .promo-card-code  { color: #777; text-decoration: line-through; }

.promo-foot {
    text-align: center;
    font-size: 13px;
    color: #5a4a3e;
    margin-top: 16px;
    font-style: italic;
}
/* ============================================================= */
/* --- SPA-ЭКРАНЫ (оверлеи поверх игры, переключает router.js) -- */
/* ============================================================= */

/* Базовый контейнер экрана: полноэкранный оверлей над игрой/меню.
   z-index 1000 — выше игрового UI (макс. ~15) и канваса (5), ниже сплэша. */
.app-screen {
    position: fixed;
    top: 0; right: 0; bottom: 0; left: 0;
    z-index: 1000;
    overflow-x: hidden;
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    display: none;
}
.app-screen.is-open { display: block; }

/* --- Кнопка «?» (правила розыгрышей) и её экран ------------------------- */
#rulesBtn {
    position: fixed;
    left: calc(12px + env(safe-area-inset-left, 0px));
    bottom: calc(12px + env(safe-area-inset-bottom, 0px));
    width: clamp(36px, 9vw, 44px);
    height: clamp(36px, 9vw, 44px);
    background: none; border: none; padding: 0;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
    z-index: 40;
    transition: transform 0.1s ease;
}
#rulesBtn:active { transform: scale(0.92); }
#rulesBtn img { width: 100%; height: 100%; display: block; image-rendering: pixelated; }
body.in-game #rulesBtn { display: none; }      /* прячем в игре, как и меню */

#screen-rules { background: #d8d8d8; box-sizing: border-box; }
#screen-rules .rules-header {
    display: flex; align-items: center; gap: 8px;
    padding: 12px 10px;
    position: sticky; top: 0; z-index: 2;
    background: #d8d8d8;
}
#screen-rules .rules-title { flex: 1; text-align: center; font-weight: 700; font-size: 16px; color: #333; }
#screen-rules .rules-header-spacer { flex: 0 0 40px; }
#screen-rules .rules-body { padding: 0 8px 28px; max-width: 820px; margin: 0 auto; text-align: center; }
#screen-rules .rules-page {
    display: block; width: 100%; height: auto;
    margin: 10px 0; background: #fff;
    clip-path: var(--pixel-corner);   /* пиксельные ступенчатые углы, как у листов других вкладок */
}

/* Экран звука: повторяет фон/паддинг бывшего body.sound-page. */
#screen-sound {
    background: #d8d8d8;
    padding: 12px 8px 24px;
    box-sizing: border-box;
}

/* Достижения и рекорды: фон/паддинг бывших body.achievements-page / body.records-page. */
#screen-achievements,
#screen-records {
    background: #d8d8d8;
    padding: 12px 8px 24px;
    box-sizing: border-box;
}

/* Скины: полноэкранная сцена — фон/центрирование бывшего body.skins-page.
   id-селектор перекрывает overflow/display из .app-screen. */
#screen-skins {
    background: #f0f0f0;
    overflow: hidden;
}
#screen-skins.is-open {
    display: flex;
    justify-content: center;
    align-items: center;
}
/* Таблица найденных игроков: колонки те же, что в топах, но место здесь — по
   всей базе, а не по видимой тройке, и бывает пятизначным. Поэтому под номер
   отводим чуть больше 12%, иначе «12345» обрезалось бы на узком телефоне.
   Блок стоит в конце файла намеренно: перебивает правила таблиц топов,
   у которых такая же специфичность. */
#searchResults th:nth-child(1), #searchResults td:nth-child(1) { width: 17%; }
#searchResults th:nth-child(2), #searchResults td:nth-child(2) { width: 47%; text-align: left; }
#searchResults th:nth-child(3), #searchResults td:nth-child(3) { width: 18%; }
#searchResults th:nth-child(4), #searchResults td:nth-child(4) { width: 18%; }
