/* =============================================================================
   MineUse — компоненты страниц

   app.css держит каркас, который есть на каждой странице: шапка, сетка,
   плитки, формы. Здесь то, что встречается один-два раза — модальные окна,
   таблицы, просмотр скина, главная. Разделено, чтобы в первом файле можно
   было найти нужное, не пролистывая тысячу строк.
   ========================================================================== */

/* --- Главная -------------------------------------------------------------- */

.hero {
    position: relative;
    display: grid;
    grid-template-columns: minmax(0, 1fr) 300px;
    gap: var(--s-7);
    padding: var(--s-7) var(--s-6);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    background: var(--surface);
    overflow: hidden;
}

/* Сетка 24px поверх фона — пол из блоков, уходящий за край. Рисуется
   градиентами, отдельной картинки не требует. */
.hero::before {
    content: '';
    position: absolute;
    inset: 0;
    background-image:
        linear-gradient(to right, var(--line) 1px, transparent 1px),
        linear-gradient(to bottom, var(--line) 1px, transparent 1px);
    background-size: 24px 24px;
    -webkit-mask-image: radial-gradient(110% 80% at 70% 20%, #000 0%, transparent 72%);
    mask-image: radial-gradient(110% 80% at 70% 20%, #000 0%, transparent 72%);
    opacity: .55;
    pointer-events: none;
}

.hero__inner { position: relative; }

.hero h1 { font-size: 38px; max-width: 18ch; }

.hero__lead {
    max-width: 46ch;
    margin-top: var(--s-4);
    color: var(--text-muted);
    font-size: 17px;
}

.hero__actions {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
    margin-top: var(--s-5);
}

.hero__links {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-1) var(--s-4);
    margin-top: var(--s-5);
    font-size: 14px;
}

.hero__links a { color: var(--text-muted); text-decoration: underline; text-underline-offset: 3px; }
.hero__links a:hover { color: var(--accent); }

/* Работы из каталога вместо пустого поля справа. Та же шахматка, что
   и в плитках: это продолжение каталога, а не картинка-заглушка. */
.hero__art {
    position: relative;
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 1px;
    align-self: center;
    /* Фон — цвет ячейки, а не линии: в каталоге может не набраться четырёх
       работ, и пустая клетка тогда выглядит пустой клеткой, а не полосой. */
    background: var(--surface-sunken);
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    overflow: hidden;
}

.hero__art-cell {
    display: grid;
    place-items: center;
    aspect-ratio: 1;
    padding: var(--s-3);
    background-color: var(--surface-sunken);
    background-image:
        linear-gradient(45deg, var(--canvas) 25%, transparent 25%),
        linear-gradient(-45deg, var(--canvas) 25%, transparent 25%),
        linear-gradient(45deg, transparent 75%, var(--canvas) 75%),
        linear-gradient(-45deg, transparent 75%, var(--canvas) 75%);
    background-size: 12px 12px;
    background-position: 0 0, 0 6px, 6px -6px, -6px 0;
}

.hero__art-cell img { max-height: 100%; object-fit: contain; }

.hero__stats {
    position: relative;
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-6);
    margin-top: var(--s-2);
    padding-top: var(--s-5);
    border-top: 1px solid var(--line);
}

.hero__stat-value {
    font-size: 24px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.hero__stat-label { color: var(--text-muted); font-size: 13px; }

/* Переходы в разделы: та же общая рамка, что у сетки плиток. */
.routes {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
    gap: 1px;
    background: var(--line);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    overflow: hidden;
}

.route {
    display: grid;
    align-content: start;
    gap: var(--s-1);
    padding: var(--s-4);
    background: var(--surface);
    color: var(--text);
}

.route:hover { background: var(--surface-sunken); color: var(--text); }
.route:hover .route__name { color: var(--accent); }

.route__icon { margin-bottom: var(--s-2); font-size: 20px; color: var(--accent); }
.route__name { font-weight: 600; }
.route__note { color: var(--text-muted); font-size: 13px; }

/* --- Модальное окно ------------------------------------------------------- */

/* Родной <dialog>: браузер сам держит фокус внутри окна, закрывает по Esc и
   рисует подложку. Прежняя разметка тянула за собой весь bootstrap.bundle. */
.modal {
    width: min(520px, calc(100vw - var(--s-5)));
    max-height: calc(100vh - var(--s-7));
    padding: 0;
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    background: var(--surface);
    color: var(--text);
}

.modal::backdrop { background: rgba(11, 23, 39, .55); }

.modal__head {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    padding: var(--s-4) var(--s-5);
    border-bottom: 1px solid var(--line);
}

.modal__title { font-size: 17px; font-weight: 600; }

.modal__close {
    margin-inline-start: auto;
    display: grid;
    place-items: center;
    padding: var(--s-1);
    border: none;
    border-radius: var(--r-sm);
    background: none;
    color: var(--text-muted);
    font-size: 18px;
    cursor: pointer;
}

.modal__close:hover { color: var(--text); }

.modal__body { padding: var(--s-5); }

/* --- Выбор издания -------------------------------------------------------- */

/* Два варианта, и оба должны быть видны сразу: выпадающий список ради двух
   строк заставляет открывать его, чтобы узнать, что там вообще есть. */
.editions {
    display: flex;
    gap: var(--s-2);
}

.editions input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.editions label {
    flex: 1 1 0;
    padding: var(--s-3);
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    background: var(--surface-sunken);
    color: var(--text-muted);
    text-align: center;
    cursor: pointer;
    transition: border-color .15s ease, color .15s ease;
}

.editions label:hover { color: var(--text); }

.editions input:checked + label {
    border-color: var(--accent);
    color: var(--text);
}

.editions input:focus-visible + label { box-shadow: var(--focus); }

/* --- Формы ---------------------------------------------------------------- */

.form { display: grid; gap: var(--s-4); }

.form__row { display: grid; gap: var(--s-2); }

/* Поля в ряд. Выравнивание по верху обязательно: у соседа снизу может быть
   подсказка, и без него поле без подсказки растягивалось на её высоту —
   два поля в одном ряду получались разной высоты. */
.form__grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    align-items: start;
    gap: var(--s-4);
}

/* Подпись, поле и подсказка — три строки по своему содержимому: иначе поле
   тянется на весь остаток ячейки. */
.form__row { grid-auto-rows: min-content; }

textarea.field {
    min-height: 96px;
    resize: vertical;
    line-height: 1.5;
}

/* Родное поле файла выглядит по-разному в каждом браузере, поэтому кнопку
   рисуем сами, а само поле прячем внутри label. */
.file {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    padding: var(--s-3) var(--s-4);
    border: 1px dashed var(--line-strong);
    border-radius: var(--r-md);
    background: var(--surface-sunken);
    color: var(--text-muted);
    cursor: pointer;
}

.file:hover { border-color: var(--accent); color: var(--text); }
.file input { position: absolute; width: 1px; height: 1px; opacity: 0; }
.file__name { font-size: 13px; }

.progress {
    height: 6px;
    border-radius: var(--r-pill);
    background: var(--surface-sunken);
    overflow: hidden;
}

.progress__bar {
    height: 100%;
    width: 0;
    background: var(--positive);
    transition: width .2s ease;
}

.checklist {
    display: grid;
    gap: var(--s-2);
    max-height: 260px;
    overflow-y: auto;
}

/* --- Таблица -------------------------------------------------------------- */

.table-wrap { overflow-x: auto; }

.table {
    width: 100%;
    border-collapse: collapse;
    font-size: 14px;
}

.table th,
.table td {
    padding: var(--s-3);
    text-align: start;
    border-bottom: 1px solid var(--line);
    vertical-align: middle;
}

.table th {
    color: var(--text-muted);
    font-size: 13px;
    font-weight: 600;
    white-space: nowrap;
}

.table tr:last-child td { border-bottom: none; }
.table tbody tr:hover { background: var(--surface-sunken); }

/* --- Вкладки -------------------------------------------------------------- */

.tabs {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-1);
    margin-bottom: var(--s-4);
    border-bottom: 1px solid var(--line);
}

.tabs a,
.tabs button {
    padding: var(--s-3) var(--s-4);
    border: none;
    border-bottom: 2px solid transparent;
    background: none;
    color: var(--text-muted);
    font-weight: 500;
    cursor: pointer;
}

.tabs a:hover,
.tabs button:hover { color: var(--text); }

.tabs [aria-current='page'],
.tabs [aria-selected='true'] {
    border-bottom-color: var(--accent);
    color: var(--text);
}

/* --- Место под рекламу ---------------------------------------------------- */

/* Разметка места выводится, только когда блок действительно есть: пустого
   контейнера с отступами в вёрстке не остаётся. */
[data-ad-slot] {
    margin-bottom: var(--s-4);
    border-radius: var(--r-md);
    overflow: hidden;
}

.sticky-sidebar {
    position: sticky;
    top: calc(var(--header-height) + var(--s-4));
}

/* --- Заметка -------------------------------------------------------------- */

.note {
    display: flex;
    gap: var(--s-3);
    padding: var(--s-4);
    border: 1px solid var(--line);
    border-inline-start: 3px solid var(--accent);
    border-radius: var(--r-md);
    background: var(--surface);
    font-size: 14px;
}

.note--warning { border-inline-start-color: var(--warning); }
.note--danger { border-inline-start-color: var(--danger); }
.note__icon { flex: none; color: var(--accent); font-size: 18px; }

/* --- Место в мониторинге -------------------------------------------------- */

.rank {
    display: grid;
    place-items: center;
    min-width: 26px;
    height: 26px;
    border-radius: var(--r-sm);
    background: var(--surface-sunken);
    color: var(--text-muted);
    font-size: 13px;
    font-variant-numeric: tabular-nums;
}

/* Тройка лидеров выделена цветом: место в списке — то, ради чего владельцы
   серверов вообще заходят в мониторинг. */
.rank--top { background: var(--accent-soft); color: var(--accent); font-weight: 600; }

/* --- Мелочи --------------------------------------------------------------- */

.stack { display: grid; gap: var(--s-4); }
.stack--tight { gap: var(--s-2); }
.row { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s-2); }
.row--between { justify-content: space-between; }
.grow { flex: 1 1 auto; min-width: 0; }
.text-center { text-align: center; }
.nowrap { white-space: nowrap; }

@media (max-width: 760px) {
    .hero { padding: var(--s-6) var(--s-4); }
    .hero h1 { font-size: 28px; }
    .hero__stats { gap: var(--s-5); }
    .viewer { min-height: 320px; }
}

/* --- Вход ----------------------------------------------------------------- */

/* Разделитель «или войти через»: линия с подписью посередине. */
.auth__divider {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    margin-block: var(--s-5) var(--s-4);
    color: var(--text-muted);
    font-size: 13px;
}

.auth__divider::before,
.auth__divider::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--line);
}

/* Выбор аккаунта на втором шаге входа через соцсеть. */
.account {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    width: 100%;
    padding: var(--s-3) 0;
    border: none;
    background: none;
    color: var(--text);
    text-align: start;
    cursor: pointer;
}

.account:hover .account__name { color: var(--accent); }

.account__avatar {
    width: 40px;
    height: 40px;
    border-radius: var(--r-sm);
    background: var(--surface-sunken);
}

.account__name { flex: 1; font-weight: 500; }

.account__chevron {
    color: var(--text-muted);
    transform: rotate(-90deg);
}

/* --- Страница сервера ----------------------------------------------------- */

.server-head {
    display: flex;
    align-items: center;
    gap: var(--s-4);
}

.server-head__icon {
    flex: none;
    width: 64px;
    height: 64px;
    border-radius: var(--r-md);
    background: var(--surface-sunken);
}

/* Метки сервера: режимы, мини-игры, плагины, моды. Разложены по видам —
   вперемешку десяток плагинов и пара режимов читается как свалка, а вопрос
   у игрока конкретный: во что тут играют и чем это сделано. */
.tag-groups {
    display: grid;
    gap: var(--s-4);
    margin-top: var(--s-3);
}

.tag-group {
    display: grid;
    grid-template-columns: 120px minmax(0, 1fr);
    gap: var(--s-3);
    align-items: baseline;
}

.tag-group__title {
    color: var(--text-muted);
    font-size: 13px;
}

.tag-group__items {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
}

@media (max-width: 640px) {
    /* На телефоне подпись вида встаёт над метками: в две колонки они
       сжимаются до одного слова в строке. */
    .tag-group { grid-template-columns: minmax(0, 1fr); gap: var(--s-2); }
}

.server-tag {
    padding: 3px var(--s-3);
    border: 1px solid var(--line);
    border-radius: var(--r-pill);
    background: var(--surface-sunken);
    color: var(--text-muted);
    font-size: 13px;
    transition: border-color .15s ease, color .15s ease;
}

.server-tag:hover {
    border-color: var(--accent);
    color: var(--text);
}

/* Режимы проекта — тот же список серверов, только без рейтинга и баннеров:
   это не рейтинг, а оглавление одного проекта. */
.servers--modes .server {
    grid-template-columns: minmax(0, 1fr) auto;
    padding: var(--s-3) var(--s-4);
}

/* Состояние и издание — столбиком справа от названия: строкой они
   расходились по краям шапки и читались как два разных блока. */
.server-head__state {
    flex: none;
    display: grid;
    justify-items: end;
    gap: var(--s-2);
}

.server-head__banner {
    width: 100%;
    margin-top: var(--s-4);
    border-radius: var(--r-md);
    border: 1px solid var(--line);
}

/* Адрес во всю ширину колонки: это главное, зачем открывают страницу. */
.address--block {
    justify-content: center;
    width: 100%;
    margin-top: var(--s-2);
    padding-block: var(--s-3);
    font-size: 15px;
}

@media (max-width: 560px) {
    .server-head { flex-wrap: wrap; }
    .server-head__icon { width: 48px; height: 48px; }
}

/* --- Длинный текст -------------------------------------------------------- */

/* Политика, справка, инструкции. В отличие от .prose внизу каталога здесь
   одна колонка: такой текст читают подряд, а не просматривают. */
.article {
    max-width: 72ch;
    color: var(--text);
}

.article h2 {
    margin-top: var(--s-6);
    margin-bottom: var(--s-3);
    font-size: 22px;
}

.article h3 {
    margin-top: var(--s-5);
    margin-bottom: var(--s-2);
    font-size: 17px;
}

.article p + p,
.article p + ul,
.article p + ol { margin-top: var(--s-3); }

.article ul,
.article ol {
    margin: var(--s-3) 0;
    padding-inline-start: var(--s-5);
    color: var(--text-muted);
}

.article li + li { margin-top: var(--s-1); }

.article p { color: var(--text-muted); }

/* Снимок экрана в инструкции: с рамкой, иначе светлый скриншот сливается
   с фоном страницы. */
.article figure {
    margin: var(--s-5) 0;
}

.article figure img {
    width: 100%;
    border: 1px solid var(--line);
    border-radius: var(--r-md);
}

.article figcaption {
    margin-top: var(--s-2);
    color: var(--text-muted);
    font-size: 13px;
}

/* --- Страница ошибки ------------------------------------------------------ */

.status {
    max-width: 46ch;
    margin: var(--s-8) auto;
    text-align: center;
}

/* Крупный номер — не украшение: по нему сразу понятно, что случилось, даже
   если текст не прочитали. */
.status__code {
    font-size: 72px;
    font-weight: 700;
    line-height: 1;
    color: var(--line-strong);
    font-variant-numeric: tabular-nums;
}

.status__title { margin-top: var(--s-4); }

.status__text {
    margin-block: var(--s-3) var(--s-5);
    color: var(--text-muted);
}

/* --- Профиль -------------------------------------------------------------- */

/* Работы автора лежат полками: полка шириной по числу работ, а не во всю
   строку. У автора их бывает одна-две, и растянутая на всю ширину панель
   с одной плиткой выглядела обрезком таблицы. */
.tiles--shelf {
    grid-template-columns: repeat(auto-fit, 176px);
    justify-content: start;
    width: max-content;
    max-width: 100%;
}

.people {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));
    gap: var(--s-4);
}

.person {
    display: grid;
    justify-items: center;
    gap: var(--s-2);
    color: var(--text);
    font-size: 13px;
    text-align: center;
}

.person__avatar {
    width: 56px;
    height: 56px;
    border-radius: var(--r-md);
    background: var(--surface-sunken);
}

.person:hover .person__name { color: var(--accent); }

/* Лента активности. */
.event {
    display: flex;
    gap: var(--s-3);
    padding-block: var(--s-3);
}

.event__icon {
    flex: none;
    margin-top: 3px;
    font-size: 16px;
    color: var(--text-muted);
}

.event__text { font-size: 14px; }
.event__time { color: var(--text-muted); font-size: 12px; }

/* --- Выбор аватара -------------------------------------------------------- */

.avatars {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
}

.avatars__item {
    padding: 3px;
    border: 2px solid transparent;
    border-radius: var(--r-md);
    background: var(--surface-sunken);
    cursor: pointer;
}

.avatars__item img { width: 48px; height: 48px; border-radius: var(--r-sm); }
.avatars__item:hover { border-color: var(--line-strong); }
.avatars__item[aria-pressed='true'] { border-color: var(--accent); }

/* --- Мои сервера ---------------------------------------------------------- */

.pending {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s-3);
    padding-block: var(--s-4);
}

.pending__host { font-weight: 600; }

.server-row {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    padding-block: var(--s-4);
    color: var(--text);
}

.server-row:hover .server__name { color: var(--accent); }

.server-row__chevron {
    flex: none;
    color: var(--text-muted);
    transform: rotate(-90deg);
}

.note code {
    padding: 1px 5px;
    border-radius: var(--r-sm);
    background: var(--surface-sunken);
    font-family: var(--font-mono);
    font-size: .9em;
}

/* --- Загруженные картинки ------------------------------------------------- */

.uploads {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: var(--s-2);
    margin-top: var(--s-2);
}

.upload {
    position: relative;
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    overflow: hidden;
}

.upload img { width: 100%; display: block; }

/* Помеченная на удаление картинка гаснет, но остаётся на месте: нажатие
   крестика можно отменить до сохранения. */
.upload--removed { opacity: .35; }
.upload--removed .upload__remove { background: var(--positive); }

.upload__remove {
    position: absolute;
    top: var(--s-2);
    right: var(--s-2);
    display: grid;
    place-items: center;
    width: 26px;
    height: 26px;
    border: none;
    border-radius: var(--r-sm);
    background: var(--danger);
    color: #fff;
    cursor: pointer;
}

/* --- Цифры сервера -------------------------------------------------------- */

/* Четыре числа сразу под шапкой: онлайн, вместимость, рекорд и версия — то,
   ради чего страницу открывают. Раньше всё это лежало в таблице сбоку и
   читалось только после прокрутки. */
.server-facts {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 1px;
    margin-top: var(--s-5);
    background: var(--line);
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    overflow: hidden;
}

.server-fact {
    display: grid;
    gap: 2px;
    padding: var(--s-3) var(--s-4);
    background: var(--surface-sunken);
}

.server-fact__value {
    font-size: 20px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.server-fact__label { color: var(--text-muted); font-size: 12px; }

/* Порядок действий для тех, кто заходит на сервер впервые. */
.steps {
    display: grid;
    gap: var(--s-2);
    margin: var(--s-4) 0 0;
    padding: 0;
    list-style: none;
    counter-reset: step;
    font-size: 14px;
    color: var(--text-muted);
}

.steps li {
    display: grid;
    grid-template-columns: 22px minmax(0, 1fr);
    gap: var(--s-2);
    align-items: start;
    counter-increment: step;
}

.steps li::before {
    content: counter(step);
    display: grid;
    place-items: center;
    width: 22px;
    height: 22px;
    border-radius: var(--r-sm);
    background: var(--accent-soft);
    color: var(--accent);
    font-size: 12px;
    font-weight: 600;
}

@media (max-width: 560px) {
    .server-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* --- Галерея снимков ------------------------------------------------------ */

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

.shots__radio {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

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

   Фон ровный. Раньше здесь лежала шахматка «прозрачности», но превью давно
   непрозрачные, и клетки читались как часть самих картинок. */
.shots__frame {
    position: relative;
    height: clamp(260px, 34vw, 520px);
    overflow: hidden;
    background: var(--surface-sunken);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
}

.shots__track {
    display: flex;
    width: calc(100% * var(--shots, 1));
    height: 100%;
    transition: transform .35s cubic-bezier(.22, .61, .36, 1);
}

/* Раскладка внутри снимка — flex, а не grid. У сетки высота строки зависит
   от картинки, а высота картинки — от строки; браузер разрывает этот круг
   тем, что перестаёт считать max-height в процентах, и снимок вылезает за
   кадр. */
/* Снимок занимает кадр целиком, без полей. Поля вокруг него выглядят рамкой
   в рамке: у самого снимка почти всегда своё небо или фон, и светлая полоса
   по краю читается как обрезка. */
.shots__slide {
    flex: 0 0 calc(100% / var(--shots, 1));
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    margin: 0;
    padding: 0;
}

.shots__image {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain;
}

/* Стрелки и счётчик лежат поверх кадра, а не внутри снимков: снимки едут
   лентой, и всё, что лежало в них, уезжало вместе с картинкой. Слой сквозной
   для пальца — иначе он перехватывал бы свайп, — а сами кнопки нажимаются. */
.shots__navs {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.shots__nav { display: none; }

.shots__nav .shots__arrow,
.shots__nav .shots__counter { pointer-events: auto; }

.shots__arrow {
    position: absolute;
    top: 50%;
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    margin-top: -20px;
    border: 1px solid var(--line);
    border-radius: 50%;
    background: var(--surface);
    color: var(--text-muted);
    cursor: pointer;
    transition: color .15s ease, border-color .15s ease;
}

.shots__arrow--prev { inset-inline-start: var(--s-3); }
.shots__arrow--next { inset-inline-end: var(--s-3); }

.shots__arrow svg { width: 20px; height: 20px; }

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

   Только там, где наведение вообще есть: на телефоне указателя нет, стрелки
   остаются на месте, и листать можно и ими, и пальцем. Фокус с клавиатуры
   тоже показывает стрелку — иначе по ней нельзя было бы пройти табом. */
/* Там, где указателя нет, стрелок нет вовсе: на телефоне листают пальцем,
   а кнопки поверх снимка только закрывают его. */
@media (hover: none) {
    .shots__arrow { display: none; }
}

@media (hover: hover) {
    .shots__arrow {
        opacity: 0;
        transition: opacity .18s ease, transform .18s ease,
                    color .15s ease, border-color .15s ease;
    }

    .shots__arrow--prev { transform: translateX(-8px); }
    .shots__arrow--next { transform: translateX(8px); }

    .shots__frame:hover .shots__arrow,
    .shots__arrow:focus-visible {
        opacity: 1;
        transform: none;
    }
}

.shots__arrow:hover {
    border-color: var(--line-strong);
    color: var(--text);
}

.shots__counter {
    position: absolute;
    inset-block-end: var(--s-3);
    inset-inline-end: var(--s-3);
    padding: 2px var(--s-2);
    border: 1px solid var(--line);
    border-radius: var(--r-pill);
    background: var(--surface);
    color: var(--text-muted);
    font-size: 12px;
    font-variant-numeric: tabular-nums;
}

/* Сдвиг ленты. Снимок шириной ровно в кадр, поэтому шаг — доля ленты,
   делённая на число снимков. Восьми хватает с запасом: у пака их три,
   у шейдера до пяти. */
.shots__radio:nth-of-type(2):checked ~ .shots__frame .shots__track { transform: translateX(calc(-100% / var(--shots))); }
.shots__radio:nth-of-type(3):checked ~ .shots__frame .shots__track { transform: translateX(calc(-200% / var(--shots))); }
.shots__radio:nth-of-type(4):checked ~ .shots__frame .shots__track { transform: translateX(calc(-300% / var(--shots))); }
.shots__radio:nth-of-type(5):checked ~ .shots__frame .shots__track { transform: translateX(calc(-400% / var(--shots))); }
.shots__radio:nth-of-type(6):checked ~ .shots__frame .shots__track { transform: translateX(calc(-500% / var(--shots))); }
.shots__radio:nth-of-type(7):checked ~ .shots__frame .shots__track { transform: translateX(calc(-600% / var(--shots))); }
.shots__radio:nth-of-type(8):checked ~ .shots__frame .shots__track { transform: translateX(calc(-700% / var(--shots))); }

/* Показана та пара стрелок, что отвечает выбранному снимку: она знает своих
   соседей, поэтому «назад» и «вперёд» ведут туда, куда надо. */
.shots__radio:nth-of-type(1):checked ~ .shots__frame .shots__nav:nth-of-type(1),
.shots__radio:nth-of-type(2):checked ~ .shots__frame .shots__nav:nth-of-type(2),
.shots__radio:nth-of-type(3):checked ~ .shots__frame .shots__nav:nth-of-type(3),
.shots__radio:nth-of-type(4):checked ~ .shots__frame .shots__nav:nth-of-type(4),
.shots__radio:nth-of-type(5):checked ~ .shots__frame .shots__nav:nth-of-type(5),
.shots__radio:nth-of-type(6):checked ~ .shots__frame .shots__nav:nth-of-type(6),
.shots__radio:nth-of-type(7):checked ~ .shots__frame .shots__nav:nth-of-type(7),
.shots__radio:nth-of-type(8):checked ~ .shots__frame .shots__nav:nth-of-type(8) {
    display: block;
}

/* Переключатель не виден, поэтому фокус с клавиатуры показывает кадр. */
.shots__radio:focus-visible ~ .shots__frame { box-shadow: var(--focus); }

/* Ссылка вокруг снимка не должна участвовать в раскладке: кадр подгоняет
   картинку по своей высоте, а лишняя коробка между ними эту подгонку ломает.
   display: contents убирает коробку, ссылка при этом работает. */
.shots__open { display: contents; }

.shots__open .shots__image { cursor: zoom-in; }

/* Миниатюры не растягиваются на всю ширину: три снимка во всю строку — это
   уже не миниатюры, а вторая галерея. Верхний предел держит их лентой.

   Раскладка на flex, а не на сетке. Сетка с repeat(auto-fit, minmax(96px,
   168px)) считала число колонок по верхней границе: в строку помещалось
   ровно четыре ленты по 168, и пятая миниатюра уезжала на вторую строку,
   хотя справа оставалось пустое место. Здесь миниатюры сами делят строку
   и сжимаются, пока помещаются. */
.shots__thumbs {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
    margin-top: var(--s-2);
}

.shots__thumb {
    /* min-width: 0 обязателен: без него flex не даёт миниатюре стать уже
       собственной картинки, и на телефоне лента вылезает за край экрана
       вместо того, чтобы перенестись. */
    flex: 1 1 96px;
    min-width: 0;
    max-width: 168px;
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    background: var(--surface-sunken);
    overflow: hidden;
    cursor: pointer;
}

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

   Пропорции те же, что у снимков: и скриншоты серверов, и превью паков —
   шестнадцать к девяти, и в такой рамке они заполняют её без полей. Прежние
   четыре к трём оставляли по краям пустые поля у каждой миниатюры. */
.shots__thumb img {
    display: block;
    width: 100%;
    aspect-ratio: 16 / 9;
    object-fit: contain;
    opacity: .75;
    transition: opacity .15s ease;
}

.shots__thumb:hover img { opacity: 1; }

.shots__radio:nth-of-type(1):checked ~ .shots__thumbs .shots__thumb:nth-child(1),
.shots__radio:nth-of-type(2):checked ~ .shots__thumbs .shots__thumb:nth-child(2),
.shots__radio:nth-of-type(3):checked ~ .shots__thumbs .shots__thumb:nth-child(3),
.shots__radio:nth-of-type(4):checked ~ .shots__thumbs .shots__thumb:nth-child(4),
.shots__radio:nth-of-type(5):checked ~ .shots__thumbs .shots__thumb:nth-child(5),
.shots__radio:nth-of-type(6):checked ~ .shots__thumbs .shots__thumb:nth-child(6),
.shots__radio:nth-of-type(7):checked ~ .shots__thumbs .shots__thumb:nth-child(7),
.shots__radio:nth-of-type(8):checked ~ .shots__thumbs .shots__thumb:nth-child(8) {
    border-color: var(--accent);
}

.shots__radio:nth-of-type(1):checked ~ .shots__thumbs .shots__thumb:nth-child(1) img,
.shots__radio:nth-of-type(2):checked ~ .shots__thumbs .shots__thumb:nth-child(2) img,
.shots__radio:nth-of-type(3):checked ~ .shots__thumbs .shots__thumb:nth-child(3) img,
.shots__radio:nth-of-type(4):checked ~ .shots__thumbs .shots__thumb:nth-child(4) img,
.shots__radio:nth-of-type(5):checked ~ .shots__thumbs .shots__thumb:nth-child(5) img,
.shots__radio:nth-of-type(6):checked ~ .shots__thumbs .shots__thumb:nth-child(6) img,
.shots__radio:nth-of-type(7):checked ~ .shots__thumbs .shots__thumb:nth-child(7) img,
.shots__radio:nth-of-type(8):checked ~ .shots__thumbs .shots__thumb:nth-child(8) img {
    opacity: 1;
}

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

    .shots__arrow {
        transition: opacity .18s ease;
        transform: none;
    }
}

/* --- Снимок целиком ------------------------------------------------------- */

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

   Само окно прозрачное: рамка и фон вокруг снимка только съедали бы место —
   подложку рисует браузер. */
.lightbox {
    width: min(1280px, calc(100vw - var(--s-5)));
    max-width: none;
    max-height: calc(100vh - var(--s-5));
    padding: 0;
    border: none;
    background: none;
    overflow: visible;
}

.lightbox::backdrop { background: rgba(6, 12, 22, .86); }

.lightbox__image {
    display: block;
    width: 100%;
    max-height: calc(100vh - var(--s-5));
    margin: 0 auto;
    object-fit: contain;
    border-radius: var(--r-lg);
}

/* Кнопки лежат поверх снимка, а не рядом: снимок и так занимает весь экран,
   и отдавать полосу под управление незачем. */
.lightbox__close,
.lightbox__arrow {
    position: absolute;
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    border: 1px solid var(--line);
    border-radius: 50%;
    background: var(--surface);
    color: var(--text-muted);
    cursor: pointer;
    transition: color .15s ease, border-color .15s ease;
}

.lightbox__close:hover,
.lightbox__arrow:hover {
    border-color: var(--line-strong);
    color: var(--text);
}

.lightbox__close {
    top: var(--s-3);
    inset-inline-end: var(--s-3);
}

.lightbox__arrow {
    top: 50%;
    margin-top: -22px;
}

.lightbox__arrow--prev { inset-inline-start: var(--s-3); }
.lightbox__arrow--next { inset-inline-end: var(--s-3); }

.lightbox__close svg,
.lightbox__arrow svg { width: 22px; height: 22px; }

.lightbox__counter {
    position: absolute;
    inset-block-end: var(--s-3);
    inset-inline-end: var(--s-3);
    padding: 2px var(--s-2);
    border: 1px solid var(--line);
    border-radius: var(--r-pill);
    background: var(--surface);
    color: var(--text-muted);
    font-size: 12px;
    font-variant-numeric: tabular-nums;
}

@media (max-width: 640px) {
    .lightbox__close,
    .lightbox__arrow {
        width: 36px;
        height: 36px;
    }

    .lightbox__arrow { margin-top: -18px; }
}

@media (max-width: 640px) {
    .shots__arrow {
        width: 34px;
        height: 34px;
        margin-top: -17px;
    }

    /* На телефоне миниатюры мельче: иначе в строку их влезает три, и лента
       занимает пол-экрана. Правило под стать раскладке — flex, а не сетка. */
    .shots__thumb {
        flex-basis: 72px;
        max-width: 108px;
    }
}

/* --- Совместимость с версиями --------------------------------------------- */

/* Ресурспак не привязан к одной версии игры: один pack_format покрывает целое
   поколение выпусков. Поэтому вместо одной строчки «1.21.4» — список
   поколений, и каждое ведёт в свой раздел каталога. */

.compat__range {
    margin: var(--s-2) 0 var(--s-3);
    font-size: 22px;
    font-weight: 600;
    line-height: 1.2;
}

.compat__list {
    display: grid;
    gap: 1px;
    margin: 0;
    padding: 0;
    list-style: none;
    background: var(--line);
    border: 1px solid var(--line);
    border-radius: var(--r-md);
    overflow: hidden;
}

.compat__item {
    display: block;
    padding: 9px var(--s-3);
    background: var(--surface);
    color: var(--text);
    font-size: 14px;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}

.compat__item:hover { background: var(--accent-soft); color: var(--accent); }

.compat__rest {
    margin: var(--s-2) 0 0;
    color: var(--text-muted);
    font-size: 13px;
}

.compat__more {
    display: inline-block;
    color: var(--accent);
    font-size: 14px;
    font-weight: 500;
}

/* Тот же список в основной колонке, но подробнее: здесь он и отвечает на
   вопрос «а на моей версии пойдёт», и ведёт в разделы по версиям.

   Карточки в ряд, а не в сетку: у пака под одну версию карточка одна, и
   пустая ячейка рядом с ней выглядела бы потерянной работой. */
.version-grid {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-3);
}

.version-card {
    display: grid;
    gap: 2px;
    flex: 0 1 236px;
    padding: var(--s-4);
    background: var(--surface);
    border: 1px solid var(--line);
    border-radius: var(--r-lg);
    color: var(--text);
}

.version-card:hover { border-color: var(--accent); color: var(--text); }

.version-card__name {
    font-size: 16px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.version-card__more {
    margin-top: var(--s-2);
    color: var(--accent);
    font-size: 13px;
    font-weight: 500;
}
