:root {
    /* Паттерн в переменных: его использует и страница, и карточки с шапкой. */
    --pattern: url("../images/background.jpg");
    --pattern-size: 640px;
    /* Карточки полупрозрачные: собственного фона у них нет, сквозь них видно
       паттерн страницы. Приподнимает их над фоном тень, а не заливка. */
    --surface-edge: rgba(255, 255, 255, .5);
    /* Косой градиент вместо ровной заливки — стекло ловит свет сверху слева. */
    --surface-gloss: linear-gradient(
        160deg,
        rgba(255, 255, 255, .56) 0%,
        rgba(255, 255, 255, .30) 45%,
        rgba(255, 255, 255, .24) 100%
    );
    /* Для горизонтальной панели блик вертикальный: свет падает сверху. */
    --surface-gloss-bar: linear-gradient(
        180deg,
        rgba(255, 255, 255, .60) 0%,
        rgba(255, 255, 255, .40) 55%,
        rgba(255, 255, 255, .26) 100%
    );
    --shadow: 0 14px 34px rgba(0, 0, 0, .38);
    --rail: 60px;        /* свёрнутая левая панель */
    --rail-open: 232px;  /* она же при наведении */

    --bg: #c3d92a;
    --panel-2: rgba(255, 255, 255, .72);
    --text: #15180d;
    --muted: #4d5533;
    --accent: #6b4e00;
    --green: #2e7d32;
    --green-soft: #d8ecd9;
    --yellow: #7a6410;
    --red: #7a1f1f;
    --border: rgba(0, 0, 0, .22);
}
* { box-sizing: border-box; }
body {
    margin: 0;
    font-family: -apple-system, Segoe UI, Roboto, Arial, sans-serif;
    /* Бесшовный паттерн: тайлим и уменьшаем — исходник 2560px, иначе на экран
       попадёт пара мотивов. fixed — чтобы фон не ехал при прокрутке. */
    background: var(--pattern) repeat fixed;
    background-size: var(--pattern-size);
    background-color: var(--bg);
    color: var(--text);
    line-height: 1.5;
    /* Место под левую панель: она fixed и иначе накрыла бы контент. */
    padding-left: var(--rail);
}
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ---- Баннер ---- */
/* Надписи вшиты в картинку, поэтому она не обрезается, а уменьшается
   целиком: пропорции сохраняются при любой ширине окна. Высота — треть
   экрана, но не больше 320px: на ПК надписи остаются читаемыми, а баннер
   не занимает пол-экрана. На телефоне картинку раньше ограничивает ширина.
   Поля по бокам чёрные, как края картинки. */
.main-banner {
    background: #000;
    border-bottom: 1px solid var(--surface-edge);
    box-shadow: var(--shadow);
}
.main-banner img {
    display: block;
    width: auto; max-width: 100%;
    height: auto; max-height: min(180px, 35vh);
    margin: 0 auto;
}

/* ---- Левая панель ---- */
/* Свёрнута в иконки, разворачивается наведением. Ширину меняет только сама
   панель, а контент отодвинут постоянным отступом body — поэтому при
   раскрытии страница не перекомпоновывается. */
.sprite { display: none; }
.ico {
    width: 22px; height: 22px; flex: none;
    fill: none; stroke: currentColor; stroke-width: 1.8;
    stroke-linecap: round; stroke-linejoin: round;
}
.sidebar {
    position: fixed; top: 0; left: 0; bottom: 0; z-index: 20;
    width: var(--rail); overflow: hidden;
    background: var(--surface-gloss-bar);
    backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
    border-right: 1px solid var(--surface-edge);
    box-shadow: var(--shadow);
    transition: width .18s ease;
}
.sidebar:hover, .sidebar:focus-within { width: var(--rail-open); }
.sidebar nav { display: flex; flex-direction: column; padding: .7rem 0; }
.sidebar nav a {
    display: flex; align-items: center; gap: .85rem; white-space: nowrap;
    /* Отступ слева таков, что иконка встаёт по центру свёрнутой полосы. */
    padding: .72rem 0 .72rem 19px; color: var(--text);
}
.sidebar nav a:hover { background: rgba(255, 255, 255, .45); text-decoration: none; }
.sidebar nav a > span { opacity: 0; transition: opacity .14s ease; }
.sidebar:hover nav a > span, .sidebar:focus-within nav a > span { opacity: 1; }

/* Кнопка-якорь. Закреплённая панель не сворачивается по уходу курсора и
   переживает переход на другую страницу — состояние в localStorage. */
.pin {
    display: flex; align-items: center; gap: .85rem; width: 100%;
    padding: .72rem 0 .72rem 19px; white-space: nowrap; cursor: pointer;
    background: none; border: 0; border-bottom: 1px solid var(--surface-edge);
    border-radius: 0; color: var(--muted); font: inherit; text-align: left;
}
.pin:hover { background: rgba(255, 255, 255, .45); opacity: 1; }
.pin > span { opacity: 0; transition: opacity .14s ease; }
.sidebar:hover .pin > span, .sidebar:focus-within .pin > span { opacity: 1; }
.rail-pinned .pin { color: var(--accent); background: rgba(255, 255, 255, .35); }
.rail-pinned .sidebar { width: var(--rail-open); }
.rail-pinned .sidebar nav a > span, .rail-pinned .pin > span { opacity: 1; }
/* Контент отодвигается вместе с панелью, иначе закреплённая накроет его. */
html.rail-pinned body { padding-left: var(--rail-open); }

/* Появляются только на узком экране. */
.mobilebar, .menu-close, .scrim { display: none; }
.container { max-width: 960px; margin: 2rem auto; padding: 0 1.5rem; }
.card {
    /* Своего фона нет — сквозь карточку видно паттерн страницы. Лёгкое
       матирование, чтобы мотивы не мешали читать текст. Объём собирается из
       трёх вещей: блик градиентом, фаска внутренними тенями (светлая верхняя
       кромка, притенённая нижняя) и контактная тень под краем. */
    background: var(--surface-gloss);
    backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
    border: 1px solid var(--surface-edge);
    border-radius: 12px; padding: 1.2rem 1.4rem; margin-bottom: 1.2rem;
    box-shadow:
        var(--shadow),
        0 2px 6px rgba(0, 0, 0, .18),
        inset 0 1px 0 rgba(255, 255, 255, .8),
        inset 0 -1px 0 rgba(0, 0, 0, .12);
}
h1 { font-size: 1.5rem; } h2 { font-size: 1.2rem; }
label { display: block; margin: .7rem 0 .25rem; color: var(--muted); font-size: .9rem; }
input, select, textarea {
    width: 100%; padding: .55rem .7rem; background: var(--panel-2);
    border: 1px solid var(--border); border-radius: 8px; color: var(--text);
    font-size: .95rem;
}
textarea { min-height: 90px; resize: vertical; }
button, .btn {
    display: inline-block; padding: .55rem 1rem; border: none; border-radius: 8px;
    /* Тёмная заливка со светлым текстом: на светлой карточке кнопка так заметнее. */
    background: var(--accent); color: #fff; font-weight: 600; cursor: pointer;
    font-size: .9rem;
}
button.secondary, .btn.secondary { background: var(--panel-2); color: var(--text); border: 1px solid var(--border); }
button.danger { background: var(--red); color: #fff; }
button.ok { background: var(--green); color: #fff; }
button:hover { opacity: .92; }
.muted { color: var(--muted); }
.alert { padding: .7rem 1rem; border-radius: 8px; margin-bottom: 1rem; }
.alert.error { background: var(--red); color: #fff; }
.alert.info { background: var(--green-soft); color: #1d4620; border: 1px solid var(--green); }
.row { display: flex; gap: 1rem; flex-wrap: wrap; }
.row > * { flex: 1; min-width: 180px; }
table { width: 100%; border-collapse: collapse; font-size: .9rem; }
th, td { padding: .5rem .6rem; border: 1px solid var(--border); text-align: left; }
th { background: var(--panel-2); position: sticky; }
.badge { padding: .15rem .5rem; border-radius: 999px; font-size: .75rem; font-weight: 600; }
.badge.pending { background: var(--yellow); color: #fff; }
.badge.approved { background: var(--green); color: #fff; }
.badge.rejected { background: var(--red); color: #fff; }
.badge.blocked { background: var(--red); color: #fff; }
.badge.paid { background: var(--green); color: #fff; }
.badge.unpaid { background: var(--panel-2); color: var(--muted); border: 1px solid var(--border); }

/* Заполненность профиля. */
.progress {
    height: 10px; border-radius: 999px; overflow: hidden;
    background: var(--panel-2); border: 1px solid var(--border);
}
.progress > i { display: block; height: 100%; background: var(--green); }

/* Статус марафона: крупная плашка рядом с периодом. */
.status-pill {
    display: inline-block; margin-left: .5rem; padding: .2rem .8rem; border-radius: 999px;
    font-size: .85rem; font-weight: 700; letter-spacing: .01em; vertical-align: middle;
}
.status-pill.s-draft { background: var(--panel-2); color: var(--muted); border: 1px solid var(--border); }
.status-pill.s-active { background: var(--green); color: #fff; }
.status-pill.s-finished { background: var(--muted); color: #fff; }

/* Чекбоксы: общее правило растягивает поля на всю ширину, флажкам это не нужно. */
input[type="checkbox"] { width: auto; margin-right: .3rem; vertical-align: middle; }
label.check { display: inline-block; margin: 0 .8rem 0 0; color: var(--text); font-size: .85rem; }
.weekdays { display: flex; flex-wrap: wrap; gap: .2rem .4rem; margin-top: .3rem; }

/* ---- Дни тренировок в ленте ---- */
/* Колонка слева от постов: весь марафон целиком, чтобы участник видел и то,
   что уже открыто, и то, что впереди. */
/* Лента с колонкой дней шире обычной страницы: иначе колонка съедает
   ширину постов. Старые браузеры без :has() просто оставят 960px. */
.container:has(.feedgrid) { max-width: 1280px; }
/* Таблицам на 960px на ПК тесно. Страницы с текстом и формами остаются
   узкими: так их легче читать. */
.container:has(table) { max-width: 1440px; }
.feedgrid { display: grid; grid-template-columns: 210px minmax(0, 1fr); gap: 1.2rem; align-items: start; }
.days { position: sticky; top: 1rem; }
.days h2 { margin: 0 0 .6rem; font-size: 1rem; }
.days ul { list-style: none; margin: 0; padding: 0; }
.days li + li { border-top: 1px solid var(--border); }
.days a, .days span { display: block; padding: .45rem 0; font-size: .85rem; line-height: 1.3; }
/* Наступивший день — синим, прошедшие — чёрным, оба открыты. */
.d-today { color: #1d6fd0; font-weight: 700; }
.d-past { color: var(--text); }
.d-today:hover, .d-past:hover { text-decoration: underline; }
/* Открытое сейчас задание — залитая строка. */
.d-current { background: rgba(0, 0, 0, .14); border-radius: 6px; padding-left: .4rem; padding-right: .4rem; }
/* Будущий день недоступен: серым и без ссылки. */
.d-future { color: #8a9270; cursor: default; }

/* Турнирная таблица */
.tournament { overflow-x: auto; }
.tournament td.cell { text-align: center; width: 44px; padding: 3px; }
/* В дне может быть несколько тренировок — ячейка делится на сегменты по числу заданий. */
.cell .segs { display: flex; gap: 2px; height: 20px; }
.cell .seg { flex: 1; border-radius: 3px; }
.seg.s-none { background: transparent; border: 1px solid var(--border); }
.seg.s-pending { background: var(--yellow); }
.seg.s-approved { background: var(--green); }
.seg.s-rejected { background: var(--red); }
.col-today { outline: 2px solid var(--accent); background: rgba(212,160,23,.12); }
.dot { display:inline-block; width:12px;height:12px;border-radius:3px; vertical-align:middle;}

/* Страница ошибки: «не найдено», «доступ закрыт» и другие. */
.notfound { max-width: 560px; margin: 2.5rem auto; padding: 2.4rem 1.6rem; text-align: center; }
.notfound-code {
    font-size: clamp(4.5rem, 16vw, 7.5rem); font-weight: 800; line-height: 1; letter-spacing: .04em;
    color: var(--accent); text-shadow: 0 3px 0 rgba(255, 255, 255, .45);
}
.notfound h1 { margin: .7rem 0 .5rem; }
.notfound p { margin: 0 auto; max-width: 38ch; line-height: 1.55; }
.notfound-actions { display: flex; gap: .6rem; justify-content: center; flex-wrap: wrap; margin-top: 1.4rem; }

/* Итоги марафона: таблица во всю ширину, шапка и колонка с участником
   закреплены — при прокрутке по дням видно, чья это строка. Закреплённым
   клеткам нужен сплошной фон, иначе под ними просвечивают соседние:
   цвет совпадает с --panel-2 поверх фона страницы. */
.tournament.results { max-height: 78vh; overflow: auto; }
.results th { top: 0; z-index: 2; background: #eef4c3; white-space: nowrap; }
.results .r-name { position: sticky; left: 0; z-index: 1; background: #eef4c3; white-space: nowrap; }
.results th.r-name { z-index: 3; }
.results .r-place { display: inline-block; min-width: 1.6rem; font-weight: 700; color: var(--muted); }
.results .r-num { text-align: center; }
.results td.cell { width: 34px; }
.results .cell .segs { height: 24px; }
.col-future { opacity: .45; }
.person-nav { display: flex; align-items: center; gap: .8rem; flex-wrap: wrap; margin: -.4rem 0 1rem; }
.legend span { margin-right: 1rem; font-size: .8rem; color: var(--muted); }

/* Переключатель «таблица / календарь» */
.view-switch { display: flex; gap: .4rem; margin-bottom: .8rem; }
.view-switch button.active { background: var(--accent); color: #fff; border-color: transparent; }

/* Календарь заданий: неделя в строке, понедельник первым. */
.cal { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
.cal-head {
    text-align: center; font-size: .8rem; font-weight: 600; color: var(--muted);
    padding: .2rem 0;
}
.cal-day {
    min-height: 82px; padding: .3rem; border-radius: 8px;
    background: var(--panel-2); border: 1px solid var(--border);
}
/* Дни за границами марафона нужны только чтобы сетка недель не рвалась. */
.cal-day.out { opacity: .35; }
.cal-day.today { outline: 2px solid var(--accent); }
.cal-date {
    display: flex; align-items: center; justify-content: space-between;
    font-size: .75rem; color: var(--muted); margin-bottom: .2rem;
}
.cal-add {
    padding: 0 .35rem; font-size: .85rem; line-height: 1.3;
    background: transparent; color: var(--muted); border: 1px solid var(--border);
}
.cal-add:hover { color: var(--text); }
.chip {
    display: block; margin-top: 2px; padding: .15rem .35rem; border-radius: 5px;
    font-size: .75rem; line-height: 1.25; background: var(--green); color: #fff;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chip:hover { text-decoration: none; opacity: .9; }
/* Заготовка без описания — участнику показывать пока нечего. */
.chip.empty { background: var(--panel-2); color: var(--muted); border: 1px dashed var(--border); }

@media (max-width: 700px) {
    /* Семь колонок на телефоне нечитаемы — разворачиваем календарь в две. */
    .cal { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .cal-head { display: none; }
    .cal-day.out { display: none; }
}

/* Чат: свои сообщения справа, ответы собеседника слева. */
.chat {
    max-height: 60vh; overflow-y: auto; padding: .2rem;
    display: flex; flex-direction: column; gap: .5rem; margin-bottom: 1rem;
}
.msg { max-width: 78%; padding: .45rem .7rem; border-radius: 10px; }
.msg.mine { align-self: flex-end; background: var(--green); color: #fff; }
.msg.theirs { align-self: flex-start; background: var(--panel-2); border: 1px solid var(--border); }
.msg-body { white-space: pre-wrap; word-break: break-word; }
.msg-meta { margin-top: .2rem; font-size: .7rem; opacity: .75; }

/* Лента */
.post { border-left: 3px solid var(--accent); }
/* Заглавный материал поста: показывается целиком, не обрезаясь по краям. */
.post-media {
    display: block; width: 100%; max-height: 60vh; object-fit: contain;
    margin: .6rem 0; border-radius: 10px; background: rgba(0, 0, 0, .06);
}

/* Обучающее видео: в посте — первый кадр с кнопкой, по нажатию — во весь экран. */
.tv {
    position: relative; margin: .6rem 0; border-radius: 10px; overflow: hidden;
    background: #000; cursor: pointer; user-select: none; -webkit-user-select: none;
}
/* Превью в посте — небольшое: смотрят видео во весь экран, а в ленте оно
   не должно занимать весь экран телефона. */
.tv video { display: block; width: 100%; max-height: min(300px, 40vh); object-fit: contain; background: #000; }
.tv-play {
    position: absolute; inset: 0; width: 100%; border: 0; border-radius: 0;
    display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .6rem;
    background: linear-gradient(rgba(0, 0, 0, .1), rgba(0, 0, 0, .5));
    color: #fff; font-size: 1rem; font-weight: 600; text-shadow: 0 1px 3px rgba(0, 0, 0, .6);
}
.tv-play::before {
    content: ""; width: 64px; height: 64px; border-radius: 50%;
    background: rgba(255, 255, 255, .92) no-repeat 55% 50% / 26px
        url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M6 4l15 8-15 8z' fill='%2315180d'/%3E%3C/svg%3E");
    box-shadow: 0 4px 14px rgba(0, 0, 0, .4);
}
.tv-play:hover { opacity: 1; }
.tv.playing { cursor: default; }
/* Обучающие видео в посте — небольшими плитками в ряд, как фото: первый кадр,
   кнопка и название. Смотрят во весь экран, поэтому превью ни к чему большое.
   Большое превью остаётся на странице видео в админке. */
.tv-list { display: flex; flex-wrap: wrap; gap: .45rem; margin: .6rem 0; }
.tv-list .tv { margin: 0; width: 120px; }
.tv-list .tv video { width: 120px; height: 170px; max-height: none; object-fit: cover; }
.tv-list .tv.playing video { object-fit: contain; }
.tv-list .tv-play { gap: .35rem; font-size: .78rem; line-height: 1.2; }
.tv-list .tv-play::before { width: 38px; height: 38px; background-size: 16px; }
.tv-play { padding: 0 .5rem; text-align: center; }
.tv.playing .tv-play { display: none; }

/* Обучающие фото: миниатюры в ряд, по нажатию — в полный размер. */
.tp { display: flex; flex-wrap: wrap; gap: .45rem; margin: .6rem 0; }
.tp a, .tp-del img {
    display: block; width: 88px; height: 88px; border-radius: 8px; overflow: hidden;
    background: rgba(0, 0, 0, .06);
}
.tp a img, .tp-del img { width: 88px; height: 88px; object-fit: cover; display: block; }
.tp-del { display: flex; flex-direction: column; gap: .2rem; margin: 0; font-size: .78rem; color: var(--text); }
.photo-row { display: flex; gap: .35rem; align-items: center; }
.photo-row + .photo-row, .photo-inputs + button { margin-top: .35rem; }
.photo-row button { flex: none; padding: .45rem .75rem; font-size: 1.1rem; line-height: 1; }

/* Выбор обучающих видео: выпадающий список с галочками. Заголовок выглядит
   как обычный select, раскрытый список — сплошной и с прокруткой. */
.video-pick summary {
    position: relative; list-style: none; cursor: pointer; padding: .55rem 2rem .55rem .7rem;
    background: var(--panel-2); border: 1px solid var(--border); border-radius: 8px; font-size: .95rem;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.video-pick summary::-webkit-details-marker { display: none; }
.video-pick summary::after { content: "▾"; position: absolute; right: .7rem; top: 50%; transform: translateY(-50%); color: var(--muted); }
.video-pick[open] summary::after { content: "▴"; }
.video-pick-list {
    margin-top: .25rem; padding: .35rem .7rem; max-height: 260px; overflow: auto;
    background: #eef4c3; border: 1px solid var(--border); border-radius: 8px;
}
.video-pick-list label.check { display: block; margin: 0; padding: .25rem 0; font-size: .9rem; }

/* Просмотр фото во весь экран. */
.lb {
    position: fixed; inset: 0; z-index: 1000; display: flex; align-items: center; justify-content: center;
    background: rgba(0, 0, 0, .92); cursor: zoom-out;
}
.lb[hidden] { display: none; }
.lb img { max-width: 100vw; max-height: 100vh; object-fit: contain; }
.lb button {
    position: absolute; border: 0; border-radius: 50%; width: 44px; height: 44px; padding: 0;
    background: rgba(255, 255, 255, .15); color: #fff; font-size: 1.8rem; line-height: 1; cursor: pointer;
}
.lb-close { top: 12px; right: 12px; }
.lb-prev, .lb-next { top: 50%; transform: translateY(-50%); display: none; }
.lb-prev { left: 12px; }
.lb-next { right: 12px; }
.lb.multi .lb-prev, .lb.multi .lb-next { display: block; }

/* История проверки результата: попытки участника и ответы проверяющего. */
.sub-log { display: flex; flex-direction: column; gap: .4rem; margin: .5rem 0; }
.sub-event {
    max-width: 88%; padding: .4rem .65rem; border-radius: 9px;
    background: var(--panel-2); border: 1px solid var(--border);
}
.sub-event.mine { align-self: flex-end; }
.sub-event.theirs { align-self: flex-start; }
.sub-event-head { font-size: .75rem; font-weight: 600; color: var(--muted); }
.sub-event-time { margin-left: .4rem; font-weight: 400; font-size: .7rem; }
.sub-event-body { font-size: .85rem; white-space: pre-wrap; word-break: break-word; }
.sub-event-files { font-size: .85rem; }
.sub-event-files .tp { margin: .35rem 0; }

/* Подтверждение необратимого действия. */
.modal {
    padding: 0; max-width: 420px; border: 1px solid var(--surface-edge);
    border-radius: 12px; background: var(--panel-2); color: var(--text);
    box-shadow: var(--shadow);
}
.modal::backdrop { background: rgba(0, 0, 0, .45); }
.modal form { padding: 1.1rem 1.3rem; }
.modal h3 { margin: 0 0 .5rem; font-size: 1.05rem; }
.modal p { margin: 0; font-size: .9rem; color: var(--muted); }
.modal-actions { display: flex; justify-content: flex-end; gap: .6rem; margin-top: 1.1rem; }
.modal-actions button { padding: .4rem 1rem; font-size: .85rem; }

/* Отправка результата — тот же язык, что и у комментариев: строка ввода,
   которая разворачивается при фокусе, и действия, не занимающие место впустую. */
.submit-form { margin-top: .6rem; }
.submit-form textarea {
    min-height: 0; padding: .4rem .7rem; font-size: .9rem;
    resize: none; overflow: hidden;
}
/* Высоту поля при фокусе не меняем: это подбрасывало бы комментарии под ним.
   Растянуть его пользователь может сам за уголок. */
.submit-form textarea:focus { resize: vertical; }
/* Высота строки действий постоянна: иначе при наведении кнопки появлялись бы
   из ниоткуда и подбрасывали всё, что ниже. */
.submit-actions {
    display: flex; align-items: center; gap: .9rem; margin-top: .45rem;
    flex-wrap: wrap; min-height: 26px;
}
/* Нативное поле файла громоздкое — прячем его, оставляя кликабельной подпись. */
.attach { margin: 0; cursor: pointer; }
.attach input[type="file"] { position: absolute; width: 1px; height: 1px; opacity: 0; }
/* Скрепка — заметная кнопка с обводкой, того же размера, что «Отправить
   результат»: фото и видео — главное в результате, а не мелкая приписка. */
.attach-label {
    display: inline-block; padding: .22rem .7rem; border: 1px solid var(--accent); border-radius: 8px;
    background: var(--panel-2); color: var(--accent); font-size: .75rem; font-weight: 600;
}
.attach:hover .attach-label { background: var(--accent); color: #fff; }
.attach input:focus-visible + .attach-label { outline: 2px solid var(--accent); outline-offset: 2px; }
/* Кнопка и скрепка видны всегда: при наведении они уже не проявляются —
   участник сразу видит, как сдать результат. */
.submit-form button { padding: .22rem .7rem; font-size: .75rem; font-weight: 600; }

/* Несколько файлов в форме результата: выбранные подписаны, «×» убирает. */
.attach-list { display: inline-flex; flex-wrap: wrap; align-items: center; gap: .2rem .8rem; }
.attach-item { display: inline-flex; align-items: center; gap: .1rem; }
.submit-form .attach-x { padding: 0 .3rem; background: none; border: 0; color: var(--muted);
                         font-size: .95rem; font-weight: 400; line-height: 1; }
.submit-form .attach-x:hover { color: var(--red); }
/* У кнопок свой display, он перебил бы атрибут hidden. */
.attach-x[hidden] { display: none; }
/* Помощь: оглавление ссылками и картинки-примеры в тексте. */
.help-toc { display: flex; flex-wrap: wrap; gap: .4rem .9rem; }
.help-toc a { font-size: .9rem; }
.help-section h2 { margin-top: 0; }
.help-section img { display: block; max-width: 100%; margin: .7rem 0 .2rem;
                    border: 1px solid var(--border); border-radius: 10px; }
.help-section p, .help-section li { line-height: 1.55; }

/* Напоминания о конце приёма в настройке тренировки: строка «за N часов» и
   под ней текст сообщения. */
.reminder-when { display: flex; gap: .35rem; align-items: center; }
.reminder-when input[type="number"] { max-width: 5.5rem; }
.reminder-when select { max-width: 8rem; }
.reminder-when button { flex: none; padding: .45rem .75rem; font-size: 1.1rem; line-height: 1; }
.reminder-row textarea { min-height: 52px; margin-top: .25rem; }
.reminder-row + .reminder-row { margin-top: .5rem; }
.reminder-rows + button { margin-top: .35rem; }

/* Загрузка файлов результата прямо в хранилище: общий прогресс под формой. */
.submit-progress { margin-top: .5rem; }
.submit-progress .submit-status { margin: .3rem 0 0; color: var(--muted); }
.submit-progress .submit-status.error { color: var(--red); }

/* Файлы результата: видео — плеером, в истории — ссылкой. */
.result-video { margin: .5rem 0; }
.result-video video { display: block; width: 100%; max-height: min(360px, 50vh); border-radius: 10px; background: #000; }
.result-link { margin-right: .8rem; }

/* Обсуждение под заданием.
   Читается как отдельная лента под постом: своя подложка во всю ширину карточки,
   отделённая линией и скруглённая по нижнему краю. */
.comments {
    margin: 1rem -1.4rem -1.2rem;
    padding: .8rem 1.4rem 1rem;
    background: rgba(255, 255, 255, .34);
    border-top: 1px solid var(--surface-edge);
    border-radius: 0 0 12px 12px;
}
.comments-head { font-size: .8rem; font-weight: 600; color: var(--muted); margin-bottom: .6rem; }
.comment { position: relative; display: flex; gap: .6rem; margin-bottom: .7rem; }
.comment.reply { margin: .5rem 0 0 0; }
.comment-avatar {
    width: 32px; height: 32px; flex: 0 0 32px; border-radius: 50%;
    object-fit: cover; border: 1px solid var(--border);
}
.comment-avatar.empty { background: var(--panel-2); }
.comment-main { flex: 1; min-width: 0; }
.comment-author { font-size: .85rem; font-weight: 600; }
.comment-time { margin-left: .4rem; font-weight: 400; font-size: .72rem; color: var(--muted); }
.comment-body { white-space: pre-wrap; word-break: break-word; font-size: .9rem; }

/* Удаление — крестик в углу комментария, появляется при наведении. */
.comment-del { position: absolute; top: 0; right: 0; line-height: 1; }
.comment-del button {
    padding: 0 .25rem; background: transparent; border: none; box-shadow: none;
    color: var(--muted); font-size: 1.05rem; font-weight: 700; line-height: 1;
}
.comment-del button:hover { color: var(--red); opacity: 1; }

/* «Ответить» — небольшая подпись под комментарием, видна всегда. */
.comment-reply-box > summary {
    display: inline-block; margin-top: .1rem;
    font-size: .75rem; color: var(--muted); cursor: pointer; list-style: none;
}
.comment-reply-box > summary::-webkit-details-marker { display: none; }
.comment-reply-box > summary:hover { color: var(--text); }

/* Крестик удаления — всплывающий: проявляется при наведении на комментарий. */
.comment-del { opacity: 0; transition: opacity .12s ease; }
.comment:hover > .comment-del,
.comment:focus-within > .comment-del { opacity: 1; }

/* Поле ввода в одну строку; кнопка отправки появляется, когда в него встали. */
.comment-form { margin-top: .4rem; }
.comment-form textarea {
    min-height: 0; padding: .35rem .6rem; font-size: .85rem;
    resize: none; overflow: hidden;
}
/* Пока в поле есть текст, оно остаётся раскрытым, а кнопка — видимой, даже
   когда фокус ушёл. Иначе при нажатии кнопки поле схлопывалось между нажатием
   и отпусканием мыши, кнопка уезжала из-под курсора, и первое нажатие пропадало. */
.comment-form textarea:focus,
.comment-form textarea:not(:placeholder-shown) { min-height: 58px; resize: vertical; }
.comment-form button { display: none; margin-top: .4rem; padding: .35rem .8rem; font-size: .8rem; }
.comment-form:focus-within button,
.comment-form textarea:not(:placeholder-shown) ~ button { display: inline-block; }

@media (hover: none) {
    /* На сенсорных экранах наведения нет — показываем действия сразу. */
    .comment-del, .comment-form button { opacity: 1; display: inline-block; }
}

.avatar { width: 90px; height: 90px; border-radius: 50%; object-fit: cover; border: 2px solid var(--border); }
.inline-form { display: inline; }
/* Открытие сдачи после срока на странице участника. */
.extend { display: flex; flex-wrap: wrap; align-items: center; gap: .4rem .6rem; margin-top: .7rem;
          padding-top: .6rem; border-top: 1px dashed var(--border); }
.extend select { width: auto; padding: .3rem .5rem; }
.small { font-size: .8rem; }

/* Мобильные экраны */
@media (max-width: 700px) {
    /* Тайл 640px на узком экране даёт меньше одного повтора — мотивы выходят
       крупнее, чем на десктопе. Уменьшаем, чтобы масштаб рисунка совпадал. */
    :root { --pattern-size: 300px; }

    /* Эти таблицы лежат в карточке без обёртки с прокруткой и на узком экране
       вылезали за её правый край. Делаем саму таблицу блоком со своей
       горизонтальной прокруткой. Турнирная таблица сюда не попадает — она
       вложена в .tournament, где прокрутка уже есть. */
    .card > table { display: block; overflow-x: auto; }

    /* Полосы слева нет: её место занимает шторка, выезжающая сверху,
       поэтому закрепление здесь бессмысленно. */
    body, html.rail-pinned body { padding-left: 0; }
    .pin { display: none; }
    .rail-pinned .sidebar { width: auto; }

    .mobilebar {
        display: flex; align-items: center; gap: .7rem;
        padding: .6rem 1rem; position: sticky; top: 0; z-index: 25;
        background: var(--surface-gloss-bar);
        backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
        border-bottom: 1px solid var(--surface-edge);
        box-shadow: 0 2px 10px rgba(0, 0, 0, .25);
    }
    .mobilebar-title { font-weight: 700; }
    .burger {
        display: flex; flex-direction: column; justify-content: center; gap: 4px;
        width: 40px; height: 34px; padding: 0 8px; background: none; border: 0;
    }
    .burger span { display: block; height: 2px; background: var(--text); border-radius: 2px; }

    .sidebar {
        top: 0; left: 0; right: 0; bottom: auto;
        /* Выше мобильной шапки: шторка накрывает её целиком, иначе бургер
           остаётся поверх меню и дублирует крестик. */
        z-index: 30;
        width: auto; max-height: 86vh; overflow-y: auto;
        border-right: 0; border-bottom: 1px solid var(--surface-edge);
        /* Прячем вверх за край экрана, а не шириной: раскрытие по наведению
           на сенсорном экране не работает, нужна явная кнопка.
           visibility страхует от percentage-transform: он считается от высоты
           самой шторки, и при её изменении (загрузка шрифтов, картинки) край
           меню успевал показаться из-за края экрана. */
        transform: translateY(-100%);
        visibility: hidden;
        transition: transform .22s ease, visibility 0s linear .22s;
    }
    .sidebar:hover, .sidebar:focus-within { width: auto; }
    .sidebar nav { padding: .4rem 0 1rem; }
    .sidebar nav a { padding: .85rem 1.2rem; }
    .sidebar nav a > span { opacity: 1; }
    body.menu-open .sidebar {
        transform: none; visibility: visible;
        transition: transform .22s ease, visibility 0s;
    }
    body.menu-open { overflow: hidden; }

    .menu-close {
        display: block; margin: .6rem .7rem -.2rem auto;
        width: 38px; height: 38px; padding: 0; line-height: 1;
        font-size: 1.5rem; color: var(--text);
        background: rgba(255, 255, 255, .55); border: 1px solid var(--border);
        border-radius: 50%;
    }
    .scrim {
        display: block; position: fixed; inset: 0; z-index: 15;
        background: rgba(0, 0, 0, .45);
        opacity: 0; pointer-events: none; transition: opacity .2s ease;
    }
    body.menu-open .scrim { opacity: 1; pointer-events: auto; }

    /* Две колонки на узком экране не помещаются: дни встают над лентой. */
    .feedgrid { grid-template-columns: 1fr; }
    .days { position: static; }
}
@media (pointer: coarse) {
    /* На iOS background-attachment: fixed привязывает фон к документу и не
       перерисовывает его при прокрутке — фон уезжает и выглядит увеличенным. */
    body { background-attachment: scroll; }
}
